[ruby/error_highlight] Support nodes in `spot`

Fixes a bug where `spot` was using the wrong local variable.

We want to use error highlight with code that has been eval'd,
specifically ERB templates. We can recover the compiled source code of
the ERB template but we need an API to pass the node into error
highlight's `spot`.

Required Ruby PR: https://github.com/ruby/ruby/pull/6593

https://github.com/ruby/error_highlight/commit/0b1b650a59

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commit is contained in:
eileencodes 2022-10-19 13:50:30 -04:00 committed by git
parent 3391c51eff
commit 350d0aa023
2 changed files with 33 additions and 2 deletions

View File

@ -59,8 +59,7 @@ module ErrorHighlight
Spotter.new(node, **opts).spot
when RubyVM::AbstractSyntaxTree::Node
# Just for compatibility
Spotter.new(node, **opts).spot
Spotter.new(obj, **opts).spot
else
raise TypeError, "Exception is expected"

View File

@ -1257,4 +1257,36 @@ undefined method `foo' for nil:NilClass
assert_equal(22, spot[:last_column])
assert_equal(" raise_name_error\n", spot[:snippet])
end
def test_spot_with_node
omit unless RubyVM::AbstractSyntaxTree.respond_to?(:node_id_for_backtrace_location)
begin
raise_name_error
rescue NameError => exc
end
bl = exc.backtrace_locations.first
expected_spot = ErrorHighlight.spot(exc, backtrace_location: bl)
ast = RubyVM::AbstractSyntaxTree.parse_file(__FILE__, keep_script_lines: true)
node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(bl)
node = find_node_by_id(ast, node_id)
actual_spot = ErrorHighlight.spot(node)
assert_equal expected_spot, actual_spot
end
private
def find_node_by_id(node, node_id)
return node if node.node_id == node_id
node.children.each do |child|
next unless child.is_a?(RubyVM::AbstractSyntaxTree::Node)
found = find_node_by_id(child, node_id)
return found if found
end
return false
end
end