mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[ruby/error_highlight] Make ErrorHighlight.spot accept Exception (https://github.com/ruby/error_highlight/pull/25)
... and move things from core_ext.rb to base.rb. This will confine CRuby-dependent things to ErrorHighlight.spot. https://github.com/ruby/error_highlight/commit/22d1dd7824
This commit is contained in:
parent
1139bc8c20
commit
99e7fa5b37
3 changed files with 55 additions and 38 deletions
|
@ -1,12 +1,17 @@
|
|||
require_relative "version"
|
||||
|
||||
module ErrorHighlight
|
||||
# Identify the code fragment that seems associated with a given error
|
||||
# Identify the code fragment at that a given exception occurred.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# Arguments:
|
||||
# node: RubyVM::AbstractSyntaxTree::Node (script_lines should be enabled)
|
||||
# point_type: :name | :args
|
||||
# name: The name associated with the NameError/NoMethodError
|
||||
# :name (default) points the method/variable name that the exception occurred.
|
||||
# :args points the arguments of the method call that the exception occurred.
|
||||
#
|
||||
# backtrace_location: Thread::Backtrace::Location
|
||||
# It locates the code fragment of the given backtrace_location.
|
||||
# By default, it uses the first frame of backtrace_locations of the given exception.
|
||||
#
|
||||
# Returns:
|
||||
# {
|
||||
|
@ -15,9 +20,47 @@ module ErrorHighlight
|
|||
# last_lineno: Integer,
|
||||
# last_column: Integer,
|
||||
# snippet: String,
|
||||
# script_lines: [String],
|
||||
# } | nil
|
||||
def self.spot(...)
|
||||
Spotter.new(...).spot
|
||||
def self.spot(obj, **opts)
|
||||
case obj
|
||||
when Exception
|
||||
exc = obj
|
||||
opts = { point_type: opts.fetch(:point_type, :name) }
|
||||
|
||||
loc = opts[:backtrace_location]
|
||||
unless loc
|
||||
case exc
|
||||
when TypeError, ArgumentError
|
||||
opts[:point_type] = :args
|
||||
end
|
||||
|
||||
locs = exc.backtrace_locations
|
||||
return nil unless locs
|
||||
|
||||
loc = locs.first
|
||||
return nil unless loc
|
||||
|
||||
opts[:name] = exc.name if NameError === obj
|
||||
end
|
||||
|
||||
node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
|
||||
|
||||
Spotter.new(node, **opts).spot
|
||||
|
||||
when RubyVM::AbstractSyntaxTree::Node
|
||||
# Just for compatibility
|
||||
Spotter.new(node, **opts).spot
|
||||
|
||||
else
|
||||
raise TypeError, "Exception is expected"
|
||||
end
|
||||
|
||||
rescue SyntaxError,
|
||||
SystemCallError, # file not found or something
|
||||
ArgumentError # eval'ed code
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
class Spotter
|
||||
|
@ -122,6 +165,7 @@ module ErrorHighlight
|
|||
last_lineno: @end_lineno,
|
||||
last_column: @end_column,
|
||||
snippet: @snippet,
|
||||
script_lines: @node.script_lines,
|
||||
}
|
||||
else
|
||||
return nil
|
||||
|
|
|
@ -3,38 +3,11 @@ require_relative "formatter"
|
|||
module ErrorHighlight
|
||||
module CoreExt
|
||||
private def generate_snippet
|
||||
locs = backtrace_locations
|
||||
return "" unless locs
|
||||
|
||||
loc = locs.first
|
||||
return "" unless loc
|
||||
|
||||
begin
|
||||
node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
|
||||
opts = {}
|
||||
|
||||
case self
|
||||
when NoMethodError, NameError
|
||||
opts[:point_type] = :name
|
||||
opts[:name] = name
|
||||
when TypeError, ArgumentError
|
||||
opts[:point_type] = :args
|
||||
end
|
||||
|
||||
spot = ErrorHighlight.spot(node, **opts)
|
||||
|
||||
rescue SyntaxError
|
||||
rescue SystemCallError # file not found or something
|
||||
rescue ArgumentError # eval'ed code
|
||||
end
|
||||
|
||||
if spot
|
||||
spot = ErrorHighlight.spot(self)
|
||||
return "" unless spot
|
||||
return ErrorHighlight.formatter.message_for(spot)
|
||||
end
|
||||
|
||||
""
|
||||
end
|
||||
|
||||
if Exception.method_defined?(:detailed_message)
|
||||
def detailed_message(highlight: false, error_highlight: true, **)
|
||||
return super unless error_highlight
|
||||
|
|
|
@ -1150,7 +1150,7 @@ nil can't be coerced into Integer
|
|||
def test_custom_formatter
|
||||
custom_formatter = Object.new
|
||||
def custom_formatter.message_for(spot)
|
||||
"\n\n" + spot.inspect
|
||||
"\n\n" + spot.except(:script_lines).inspect
|
||||
end
|
||||
|
||||
original_formatter, ErrorHighlight.formatter = ErrorHighlight.formatter, custom_formatter
|
||||
|
|
Loading…
Add table
Reference in a new issue