[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
@ -1,12 +1,17 @@
|
|||||||
require_relative "version"
|
require_relative "version"
|
||||||
|
|
||||||
module ErrorHighlight
|
module ErrorHighlight
|
||||||
# Identify the code fragment that seems associated with a given error
|
# Identify the code fragment at that a given exception occurred.
|
||||||
#
|
#
|
||||||
# Arguments:
|
# Options:
|
||||||
# node: RubyVM::AbstractSyntaxTree::Node (script_lines should be enabled)
|
#
|
||||||
# point_type: :name | :args
|
# 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:
|
# Returns:
|
||||||
# {
|
# {
|
||||||
@ -15,9 +20,47 @@ module ErrorHighlight
|
|||||||
# last_lineno: Integer,
|
# last_lineno: Integer,
|
||||||
# last_column: Integer,
|
# last_column: Integer,
|
||||||
# snippet: String,
|
# snippet: String,
|
||||||
|
# script_lines: [String],
|
||||||
# } | nil
|
# } | nil
|
||||||
def self.spot(...)
|
def self.spot(obj, **opts)
|
||||||
Spotter.new(...).spot
|
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
|
end
|
||||||
|
|
||||||
class Spotter
|
class Spotter
|
||||||
@ -122,6 +165,7 @@ module ErrorHighlight
|
|||||||
last_lineno: @end_lineno,
|
last_lineno: @end_lineno,
|
||||||
last_column: @end_column,
|
last_column: @end_column,
|
||||||
snippet: @snippet,
|
snippet: @snippet,
|
||||||
|
script_lines: @node.script_lines,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
|
@ -3,36 +3,9 @@ require_relative "formatter"
|
|||||||
module ErrorHighlight
|
module ErrorHighlight
|
||||||
module CoreExt
|
module CoreExt
|
||||||
private def generate_snippet
|
private def generate_snippet
|
||||||
locs = backtrace_locations
|
spot = ErrorHighlight.spot(self)
|
||||||
return "" unless locs
|
return "" unless spot
|
||||||
|
return ErrorHighlight.formatter.message_for(spot)
|
||||||
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
|
|
||||||
return ErrorHighlight.formatter.message_for(spot)
|
|
||||||
end
|
|
||||||
|
|
||||||
""
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if Exception.method_defined?(:detailed_message)
|
if Exception.method_defined?(:detailed_message)
|
||||||
|
@ -1150,7 +1150,7 @@ nil can't be coerced into Integer
|
|||||||
def test_custom_formatter
|
def test_custom_formatter
|
||||||
custom_formatter = Object.new
|
custom_formatter = Object.new
|
||||||
def custom_formatter.message_for(spot)
|
def custom_formatter.message_for(spot)
|
||||||
"\n\n" + spot.inspect
|
"\n\n" + spot.except(:script_lines).inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
original_formatter, ErrorHighlight.formatter = ErrorHighlight.formatter, custom_formatter
|
original_formatter, ErrorHighlight.formatter = ErrorHighlight.formatter, custom_formatter
|
||||||
|
Loading…
x
Reference in New Issue
Block a user