diff --git a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb index 08c268bbe..c9a0f309d 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb @@ -152,16 +152,17 @@ def on_singleton_class_node_enter(node) if current_owner expression = node.expression - @stack << (expression.is_a?(Prism::SelfNode) ? "" : "") + name = (expression.is_a?(Prism::SelfNode) ? "" : "") + real_nesting = actual_nesting(name) - existing_entries = T.cast(@index[@stack.join("::")], T.nilable(T::Array[Entry::SingletonClass])) + existing_entries = T.cast(@index[real_nesting.join("::")], T.nilable(T::Array[Entry::SingletonClass])) if existing_entries entry = T.must(existing_entries.first) entry.update_singleton_information(node.location, expression.location, collect_comments(node)) else entry = Entry::SingletonClass.new( - @stack, + real_nesting, @file_path, node.location, expression.location, @@ -172,6 +173,7 @@ def on_singleton_class_node_enter(node) end @owner_stack << entry + @stack << name end end diff --git a/lib/ruby_indexer/test/classes_and_modules_test.rb b/lib/ruby_indexer/test/classes_and_modules_test.rb index 782334ab7..eae6d6a45 100644 --- a/lib/ruby_indexer/test/classes_and_modules_test.rb +++ b/lib/ruby_indexer/test/classes_and_modules_test.rb @@ -564,6 +564,27 @@ class Bar assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:1-2:2-5") end + def test_indexing_singletons_inside_top_level_references + index(<<~RUBY) + module ::Foo + class Bar + class << self + end + end + end + RUBY + + # We want to explicitly verify that we didn't introduce the leading `::` by accident, but `Index#[]` deletes the + # prefix when we use `refute_entry` + entries = @index.instance_variable_get(:@entries) + refute(entries.key?("::Foo")) + refute(entries.key?("::Foo::Bar")) + refute(entries.key?("::Foo::Bar::")) + assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:5-3") + assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:1-2:4-5") + assert_entry("Foo::Bar::", Entry::SingletonClass, "/fake/path/foo.rb:2-4:3-7") + end + def test_indexing_namespaces_inside_nested_top_level_references index(<<~RUBY) class Baz