Skip to content

Commit

Permalink
Index constant targets (#1034)
Browse files Browse the repository at this point in the history
Index constant targets and constant path targets
  • Loading branch information
vinistock authored Oct 13, 2023
1 parent 11ea6e8 commit 212d8dd
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
27 changes: 25 additions & 2 deletions lib/ruby_indexer/lib/ruby_indexer/visitor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ def visit_module_node(node)
add_index_entry(node, Index::Entry::Module)
end

sig { override.params(node: YARP::MultiWriteNode).void }
def visit_multi_write_node(node)
value = node.value
values = value.is_a?(YARP::ArrayNode) && value.opening_loc ? value.elements : []

node.targets.each_with_index do |target, i|
current_value = values[i]
# The moment we find a splat on the right hand side of the assignment, we can no longer figure out which value
# gets assigned to what
values.clear if current_value.is_a?(YARP::SplatNode)

case target
when YARP::ConstantTargetNode
add_constant(target, fully_qualify_name(target.name.to_s), current_value)
when YARP::ConstantPathTargetNode
add_constant(target, fully_qualify_name(target.slice), current_value)
end
end
end

sig { override.params(node: YARP::ConstantPathWriteNode).void }
def visit_constant_path_write_node(node)
# ignore variable constants like `var::FOO` or `self.class::FOO`
Expand Down Expand Up @@ -138,12 +158,15 @@ def handle_private_constant(node)
YARP::ConstantPathOrWriteNode,
YARP::ConstantPathOperatorWriteNode,
YARP::ConstantPathAndWriteNode,
YARP::ConstantTargetNode,
YARP::ConstantPathTargetNode,
),
name: String,
value: T.nilable(YARP::Node),
).void
end
def add_constant(node, name)
value = node.value
def add_constant(node, name, value = nil)
value = node.value unless node.is_a?(YARP::ConstantTargetNode) || node.is_a?(YARP::ConstantPathTargetNode)
comments = collect_comments(node)

@index << case value
Expand Down
63 changes: 63 additions & 0 deletions lib/ruby_indexer/test/constant_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -324,5 +324,68 @@ def test_indexing_or_and_operator_nodes
assert_entry("F::G", Index::Entry::Constant, "/fake/path/foo.rb:4-0:4-10")
assert_entry("H::I", Index::Entry::Constant, "/fake/path/foo.rb:5-0:5-9")
end

def test_indexing_constant_targets
index(<<~RUBY)
module A
B, C = [1, Y]
D::E, F::G = [Z, 4]
H, I::J = [5, B]
K, L = C
end
module Real
Z = 1
Y = 2
end
RUBY

assert_entry("A::B", Index::Entry::Constant, "/fake/path/foo.rb:1-2:1-3")
assert_entry("A::C", Index::Entry::UnresolvedAlias, "/fake/path/foo.rb:1-5:1-6")
assert_entry("A::D::E", Index::Entry::UnresolvedAlias, "/fake/path/foo.rb:2-2:2-6")
assert_entry("A::F::G", Index::Entry::Constant, "/fake/path/foo.rb:2-8:2-12")
assert_entry("A::H", Index::Entry::Constant, "/fake/path/foo.rb:3-2:3-3")
assert_entry("A::I::J", Index::Entry::UnresolvedAlias, "/fake/path/foo.rb:3-5:3-9")
assert_entry("A::K", Index::Entry::Constant, "/fake/path/foo.rb:4-2:4-3")
assert_entry("A::L", Index::Entry::Constant, "/fake/path/foo.rb:4-5:4-6")
end

def test_indexing_constant_targets_with_splats
index(<<~RUBY)
A, *, B = baz
C, = bar
(D, E) = baz
F, G = *baz, qux
H, I = [baz, *qux]
J, L = [*something, String]
M = [String]
RUBY

assert_entry("A", Index::Entry::Constant, "/fake/path/foo.rb:0-0:0-1")
assert_entry("B", Index::Entry::Constant, "/fake/path/foo.rb:0-6:0-7")
assert_entry("D", Index::Entry::Constant, "/fake/path/foo.rb:2-1:2-2")
assert_entry("E", Index::Entry::Constant, "/fake/path/foo.rb:2-4:2-5")
assert_entry("F", Index::Entry::Constant, "/fake/path/foo.rb:3-0:3-1")
assert_entry("G", Index::Entry::Constant, "/fake/path/foo.rb:3-3:3-4")
assert_entry("H", Index::Entry::Constant, "/fake/path/foo.rb:4-0:4-1")
assert_entry("I", Index::Entry::Constant, "/fake/path/foo.rb:4-3:4-4")
assert_entry("J", Index::Entry::Constant, "/fake/path/foo.rb:5-0:5-1")
assert_entry("L", Index::Entry::Constant, "/fake/path/foo.rb:5-3:5-4")
assert_entry("M", Index::Entry::Constant, "/fake/path/foo.rb:6-0:6-12")
end

def test_indexing_destructuring_an_array
index(<<~RUBY)
Baz = [1, 2]
Foo, Bar = Baz
This, That = foo, bar
RUBY

assert_entry("Baz", Index::Entry::Constant, "/fake/path/foo.rb:0-0:0-12")
assert_entry("Foo", Index::Entry::Constant, "/fake/path/foo.rb:1-0:1-3")
assert_entry("Bar", Index::Entry::Constant, "/fake/path/foo.rb:1-5:1-8")
assert_entry("This", Index::Entry::Constant, "/fake/path/foo.rb:2-0:2-4")
assert_entry("That", Index::Entry::Constant, "/fake/path/foo.rb:2-6:2-10")
end
end
end

0 comments on commit 212d8dd

Please sign in to comment.