From 31b8c9093ca4a3e0d98fad20cebdf1e97b288684 Mon Sep 17 00:00:00 2001 From: Weilong Date: Tue, 22 Oct 2024 22:35:29 -0400 Subject: [PATCH] handle setting multiple methods and support StringNode --- .../lib/ruby_indexer/declaration_listener.rb | 48 +++++++++++-------- lib/ruby_indexer/test/method_test.rb | 43 ++++++++--------- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb index 39b6dc53a..8668dceb2 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb @@ -758,33 +758,39 @@ def handle_module_function(node) arguments_node = node.arguments return unless arguments_node - name_argument = arguments_node.arguments.first - return unless name_argument.is_a?(Prism::SymbolNode) - - method_name = name_argument.value.to_s owner_name = @owner_stack.last&.name return unless owner_name - entries = @index.resolve_method(method_name, owner_name) - return unless entries + arguments_node.arguments.each do |argument| + method_name = case argument + when Prism::StringNode + argument.content + when Prism::SymbolNode + argument.value + end + next unless method_name - entries.each do |entry| - entry_owner_name = entry.owner&.name - next unless entry_owner_name + entries = @index.resolve_method(method_name, owner_name) + next unless entries - entry.visibility = Entry::Visibility::PRIVATE + entries.each do |entry| + entry_owner_name = entry.owner&.name + next unless entry_owner_name - singleton = @index.existing_or_new_singleton_class(entry_owner_name) - @index.add(Entry::Method.new( - method_name, - @file_path, - Location.from_prism_location(node.location, @code_units_cache), - Location.from_prism_location(T.must(node.message_loc), @code_units_cache), - collect_comments(node), - [], - Entry::Visibility::PUBLIC, - singleton, - )) + entry.visibility = Entry::Visibility::PRIVATE + + singleton = @index.existing_or_new_singleton_class(entry_owner_name) + @index.add(Entry::Method.new( + method_name, + @file_path, + Location.from_prism_location(node.location, @code_units_cache), + Location.from_prism_location(T.must(node.message_loc), @code_units_cache), + collect_comments(node), + entry.signatures, + Entry::Visibility::PUBLIC, + singleton, + )) + end end end diff --git a/lib/ruby_indexer/test/method_test.rb b/lib/ruby_indexer/test/method_test.rb index 4841af705..809980e18 100644 --- a/lib/ruby_indexer/test/method_test.rb +++ b/lib/ruby_indexer/test/method_test.rb @@ -125,29 +125,28 @@ def baz; end def test_visibility_tracking_with_module_function index(<<~RUBY) - module Foo + module Test def foo; end - module_function :foo - end - - class Bar - include Foo - end - RUBY - - entries = T.must(@index["foo"]) - # receive two entries because module_function creates a singleton method - # for the Foo module and a private method for classes include Foo module - assert_equal(entries.size, 2) - first_entry, second_entry = *entries - # The first entry points to the location of the module_function call - assert_equal("Foo", first_entry.owner.name) - assert_instance_of(Entry::Module, first_entry.owner) - assert_equal(Entry::Visibility::PRIVATE, first_entry.visibility) - # The second entry points to the public singleton method - assert_equal("Foo::", second_entry.owner.name) - assert_instance_of(Entry::SingletonClass, second_entry.owner) - assert_equal(Entry::Visibility::PUBLIC, second_entry.visibility) + def bar; end + module_function :foo, "bar" + end + RUBY + + ["foo", "bar"].each do |keyword| + entries = T.must(@index[keyword]) + # should receive two entries because module_function creates a singleton method + # for the Test module and a private method for classes include the Test module + assert_equal(entries.size, 2) + first_entry, second_entry = *entries + # The first entry points to the location of the module_function call + assert_equal("Test", first_entry.owner.name) + assert_instance_of(Entry::Module, first_entry.owner) + assert_equal(Entry::Visibility::PRIVATE, first_entry.visibility) + # The second entry points to the public singleton method + assert_equal("Test::", second_entry.owner.name) + assert_instance_of(Entry::SingletonClass, second_entry.owner) + assert_equal(Entry::Visibility::PUBLIC, second_entry.visibility) + end end def test_method_with_parameters