Skip to content

Commit

Permalink
Fix singleton class nesting when inside top level reference
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Aug 20, 2024
1 parent 931f6a5 commit 5da622f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,16 +152,17 @@ def on_singleton_class_node_enter(node)

if current_owner
expression = node.expression
@stack << (expression.is_a?(Prism::SelfNode) ? "<Class:#{@stack.last}>" : "<Class:#{expression.slice}>")
name = (expression.is_a?(Prism::SelfNode) ? "<Class:#{@stack.last}>" : "<Class:#{expression.slice}>")
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,
Expand All @@ -172,6 +173,7 @@ def on_singleton_class_node_enter(node)
end

@owner_stack << entry
@stack << name
end
end

Expand Down
21 changes: 21 additions & 0 deletions lib/ruby_indexer/test/classes_and_modules_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Class: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::<Class: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
Expand Down

0 comments on commit 5da622f

Please sign in to comment.