From 79c47fb382e53ecf0c37b526fe8b27194a4beb2f Mon Sep 17 00:00:00 2001 From: Ryo Nakamura Date: Fri, 30 Sep 2022 07:18:40 +0900 Subject: [PATCH] Support shadowing on highlight --- ...ext_document_document_highlight_handler.rb | 18 ++++- ...ocument_document_highlight_handler_spec.rb | 66 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/lib/rucoa/handlers/text_document_document_highlight_handler.rb b/lib/rucoa/handlers/text_document_document_highlight_handler.rb index a4062ae..cc3aee9 100644 --- a/lib/rucoa/handlers/text_document_document_highlight_handler.rb +++ b/lib/rucoa/handlers/text_document_document_highlight_handler.rb @@ -427,7 +427,6 @@ def nodes ].compact end - # @todo Support shadowing. # @return [Enumerable] def reference_nodes return [] unless assignment_node @@ -446,6 +445,13 @@ def reference_nodes node, *node.descendants ] + end.take_while do |node| # FIXME: flat_map and take_while are not correct solution for shadowing. + case node + when Nodes::ArgNode, Nodes::LvasgnNode + node.equal?(assignment_node) || node.name != assignment_node.name + else + true + end end.select do |node| case node when Nodes::LvarNode @@ -453,6 +459,16 @@ def reference_nodes end end end + + class UnshadowedNodeVisitor + def initialize( + node:, + &block + ) + @block = block + @node = node + end + end end class ModuleMapper < Base diff --git a/spec/rucoa/handlers/text_document_document_highlight_handler_spec.rb b/spec/rucoa/handlers/text_document_document_highlight_handler_spec.rb index 9f325fe..2999755 100644 --- a/spec/rucoa/handlers/text_document_document_highlight_handler_spec.rb +++ b/spec/rucoa/handlers/text_document_document_highlight_handler_spec.rb @@ -1335,5 +1335,71 @@ def a ) end end + + context 'when local variable is shadowed by local variable assignment' do + let(:content) do + <<~RUBY + a = 1 + b = 2 + a + a = 2 + a + RUBY + end + + let(:position) do + Rucoa::Position.new( + column: 0, + line: 1 + ) + end + + it 'returns highlights' do + subject + expect(server.responses).to match( + [ + hash_including( + 'id' => 1, + 'result' => Array.new(2) do + a_kind_of(Hash) + end + ) + ] + ) + end + end + + context 'when local variable is shadowed by block argument' do + let(:content) do + <<~RUBY + a = 1 + a + foo do |a| + a + end + RUBY + end + + let(:position) do + Rucoa::Position.new( + column: 0, + line: 1 + ) + end + + it 'returns highlights' do + subject + expect(server.responses).to match( + [ + hash_including( + 'id' => 1, + 'result' => Array.new(2) do + a_kind_of(Hash) + end + ) + ] + ) + end + end end end