diff --git a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb index 166fcf1d8..4db621c53 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb @@ -317,7 +317,7 @@ def on_call_node_enter(node) @enhancements.each do |enhancement| enhancement.on_call_node_enter(@index, @owner_stack.last, node, @file_path, @code_units_cache) rescue StandardError => e - @indexing_errors << "Indexing error in #{@file_path} with '#{enhancement.class.name}' enhancement: #{e.message}" + @indexing_errors << "Indexing error in #{@file_path} with '#{enhancement.class.name}' on call node enter enhancement: #{e.message}" end end @@ -332,6 +332,12 @@ def on_call_node_leave(node) @visibility_stack.pop end end + + @enhancements.each do |enhancement| + enhancement.on_call_node_leave(@index, @owner_stack.last, node, @file_path, @code_units_cache) + rescue StandardError => e + @indexing_errors << "Indexing error in #{@file_path} with '#{enhancement.class.name}' on call node leave enhancement: #{e.message}" + end end sig { params(node: Prism::DefNode).void } diff --git a/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb b/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb index 04cfc7111..c6d59e857 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb @@ -26,5 +26,19 @@ module Enhancement ).void end def on_call_node_enter(index, owner, node, file_path, code_units_cache); end + + sig do + abstract.params( + index: Index, + owner: T.nilable(Entry::Namespace), + node: Prism::CallNode, + file_path: String, + code_units_cache: T.any( + T.proc.params(arg0: Integer).returns(Integer), + Prism::CodeUnitsCache, + ), + ).void + end + def on_call_node_leave(index, owner, node, file_path, code_units_cache); end end end diff --git a/lib/ruby_indexer/test/enhancements_test.rb b/lib/ruby_indexer/test/enhancements_test.rb index 510c5b582..551799fe7 100644 --- a/lib/ruby_indexer/test/enhancements_test.rb +++ b/lib/ruby_indexer/test/enhancements_test.rb @@ -48,6 +48,10 @@ def on_call_node_enter(index, owner, node, file_path, code_units_cache) # Do nothing end end + + def on_call_node_leave(index, owner, node, file_path, code_units_cache) + # Do nothing + end end @index.register_enhancement(enhancement_class.new) @@ -126,6 +130,10 @@ def on_call_node_enter(index, owner, node, file_path, code_units_cache) owner, )) end + + def on_call_node_leave(index, owner, node, file_path, code_units_cache) + # Do nothing + end end @index.register_enhancement(enhancement_class.new) @@ -160,11 +168,56 @@ class User < ActiveRecord::Base assert_entry("posts", Entry::Method, "/fake/path/foo.rb:23-11:23-17") end - def test_error_handling_in_enhancement + def test_error_handling_in_on_call_node_enter_enhancement + enhancement_class = Class.new do + include Enhancement + + def on_call_node_enter(index, owner, node, file_path, code_units_cache) + raise "Error" + end + + def on_call_node_leave(index, owner, node, file_path, code_units_cache) + # Do nothing + end + + class << self + def name + "TestEnhancement" + end + end + end + + @index.register_enhancement(enhancement_class.new) + + _stdout, stderr = capture_io do + index(<<~RUBY) + module ActiveSupport + module Concern + def self.extended(base) + base.class_eval("def new_method(a); end") + end + end + end + RUBY + end + + assert_match( + %r{Indexing error in /fake/path/foo\.rb with 'TestEnhancement' on call node enter enhancement}, + stderr, + ) + # The module should still be indexed + assert_entry("ActiveSupport::Concern", Entry::Module, "/fake/path/foo.rb:1-2:5-5") + end + + def test_error_handling_in_on_call_node_leave_enhancement enhancement_class = Class.new do include Enhancement def on_call_node_enter(index, owner, node, file_path, code_units_cache) + # Do nothing + end + + def on_call_node_leave(index, owner, node, file_path, code_units_cache) raise "Error" end @@ -189,7 +242,10 @@ def self.extended(base) RUBY end - assert_match(%r{Indexing error in /fake/path/foo\.rb with 'TestEnhancement' enhancement}, stderr) + assert_match( + %r{Indexing error in /fake/path/foo\.rb with 'TestEnhancement' on call node leave enhancement}, + stderr, + ) # The module should still be indexed assert_entry("ActiveSupport::Concern", Entry::Module, "/fake/path/foo.rb:1-2:5-5") end