Skip to content

Commit

Permalink
Fix top level namespace declaration indexing (#2297)
Browse files Browse the repository at this point in the history
Co-authored-by: Emily Samp <egiurleo@users.noreply.github.com>
  • Loading branch information
vinistock and egiurleo authored Jul 12, 2024
1 parent a6ddd5b commit 29c03ac
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
19 changes: 16 additions & 3 deletions lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def on_class_node_enter(node)

superclass = node.superclass

nesting = name.start_with?("::") ? [name.delete_prefix("::")] : @stack + [name.delete_prefix("::")]
nesting = actual_nesting(name)

parent_class = case superclass
when Prism::ConstantReadNode, Prism::ConstantPathNode
Expand Down Expand Up @@ -119,8 +119,7 @@ def on_module_node_enter(node)

comments = collect_comments(node)

nesting = name.start_with?("::") ? [name.delete_prefix("::")] : @stack + [name.delete_prefix("::")]
entry = Entry::Module.new(nesting, @file_path, node.location, constant_path.location, comments)
entry = Entry::Module.new(actual_nesting(name), @file_path, node.location, constant_path.location, comments)

@owner_stack << entry
@index.add(entry)
Expand Down Expand Up @@ -709,5 +708,19 @@ def parameter_name(node)
:"(#{names_with_commas})"
end
end

sig { params(name: String).returns(T::Array[String]) }
def actual_nesting(name)
nesting = @stack + [name]
corrected_nesting = []

nesting.reverse_each do |name|
corrected_nesting.prepend(name.delete_prefix("::"))

break if name.start_with?("::")
end

corrected_nesting
end
end
end
38 changes: 38 additions & 0 deletions lib/ruby_indexer/test/classes_and_modules_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -546,5 +546,43 @@ def bar; end
assert_equal(7, name_location.start_column)
assert_equal(10, name_location.end_column)
end

def test_indexing_namespaces_inside_top_level_references
index(<<~RUBY)
module ::Foo
class Bar
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"))
assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:3-3")
assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:1-2:2-5")
end

def test_indexing_namespaces_inside_nested_top_level_references
index(<<~RUBY)
class Baz
module ::Foo
class Bar
end
class ::Qux
end
end
end
RUBY

refute_entry("Baz::Foo")
refute_entry("Baz::Foo::Bar")
assert_entry("Baz", Entry::Class, "/fake/path/foo.rb:0-0:8-3")
assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:1-2:7-5")
assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:2-4:3-7")
assert_entry("Qux", Entry::Class, "/fake/path/foo.rb:5-4:6-7")
end
end
end

0 comments on commit 29c03ac

Please sign in to comment.