class Parser::Diagnostic
@return [Array<Parser::Source::Range>]
Supplementary error-related source ranges.
@!attribute [r] highlights
@return [Parser::Source::Range]
Main error-related source range.
@!attribute [r] location
@return [String] error message
@!attribute [r] message
@return [Symbol] extended arguments that describe the error
@see Parser::MESSAGES
@!attribute [r] arguments
@return [Symbol] reason for error
@see Parser::MESSAGES
@!attribute [r] reason
@return [Symbol] diagnostic level
@see LEVELS
@!attribute [r] level
@api public
#
def first_line_only(range)
-
(Parser::Source::Range)
-
def first_line_only(range) if range.line != range.last_line range.resize(range.source =~ /\n/) else range end end
def initialize(level, reason, arguments, location, highlights=[])
-
highlights
(Array
) -- -
location
(Parser::Source::Range
) -- -
arguments
(Hash
) -- -
reason
(Symbol
) -- -
level
(Symbol
) --
def initialize(level, reason, arguments, location, highlights=[]) unless LEVELS.include?(level) raise ArgumentError, "Diagnostic#level must be one of #{LEVELS.join(', ')}; " \ "#{level.inspect} provided." end raise 'Expected a location' unless location @level = level @reason = reason @arguments = (arguments || {}).dup.freeze @location = location @highlights = highlights.dup.freeze freeze end
def last_line_only(range)
-
(Parser::Source::Range)
-
def last_line_only(range) if range.line != range.last_line range.adjust(begin_pos: range.source =~ /[^\n]*\z/) else range end end
def message
-
(String)
- the rendered message.
def message Messages.compile(@reason, @arguments) end
def render
-
(Array
-)
def render if @location.line == @location.last_line || @location.is?("\n") ["#{@location}: #{@level}: #{message}"] + render_line(@location) else # multi-line diagnostic first_line = first_line_only(@location) last_line = last_line_only(@location) num_lines = (@location.last_line - @location.line) + 1 buffer = @location.source_buffer last_lineno, last_column = buffer.decompose_position(@location.end_pos) ["#{@location}-#{last_lineno}:#{last_column}: #{@level}: #{message}"] + render_line(first_line, num_lines > 2, false) + render_line(last_line, false, true) end end
def render_line(range, ellipsis=false, range_end=false)
-
(Array
-)
def render_line(range, ellipsis=false, range_end=false) source_line = range.source_line highlight_line = ' ' * source_line.length @highlights.each do |highlight| line_range = range.source_buffer.line_range(range.line) if highlight = highlight.intersect(line_range) highlight_line[highlight.column_range] = '~' * highlight.size end end if range.is?("\n") highlight_line += "^" else if !range_end && range.size >= 1 highlight_line[range.column_range] = '^' + '~' * (range.size - 1) else highlight_line[range.column_range] = '~' * range.size end end highlight_line += '...' if ellipsis [source_line, highlight_line]. map { |line| "#{range.source_buffer.name}:#{range.line}: #{line}" } end