Skip to content

Commit

Permalink
feat: handle all kind of global variable nodes in definition request
Browse files Browse the repository at this point in the history
  • Loading branch information
snutij committed Oct 22, 2024
1 parent dd376e9 commit 6609b53
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 13 deletions.
61 changes: 48 additions & 13 deletions lib/ruby_lsp/listeners/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ def initialize(response_builder, global_state, language_id, uri, node_context, d
:on_block_argument_node_enter,
:on_constant_read_node_enter,
:on_constant_path_node_enter,
:on_global_variable_and_write_node_enter,
:on_global_variable_operator_write_node_enter,
:on_global_variable_or_write_node_enter,
:on_global_variable_read_node_enter,
:on_global_variable_target_node_enter,
:on_global_variable_write_node_enter,
:on_instance_variable_read_node_enter,
:on_instance_variable_write_node_enter,
:on_instance_variable_and_write_node_enter,
Expand Down Expand Up @@ -121,23 +126,34 @@ def on_constant_read_node_enter(node)
find_in_index(name)
end

sig { params(node: Prism::GlobalVariableAndWriteNode).void }
def on_global_variable_and_write_node_enter(node)
handle_global_variable_definition(node.name.to_s)
end

sig { params(node: Prism::GlobalVariableOperatorWriteNode).void }
def on_global_variable_operator_write_node_enter(node)
handle_global_variable_definition(node.name.to_s)
end

sig { params(node: Prism::GlobalVariableOrWriteNode).void }
def on_global_variable_or_write_node_enter(node)
handle_global_variable_definition(node.name.to_s)
end

sig { params(node: Prism::GlobalVariableReadNode).void }
def on_global_variable_read_node_enter(node)
entries = @index[node.name.to_s]

return unless entries
handle_global_variable_definition(node.name.to_s)
end

entries.each do |entry|
location = entry.location
sig { params(node: Prism::GlobalVariableTargetNode).void }
def on_global_variable_target_node_enter(node)
handle_global_variable_definition(node.name.to_s)
end

@response_builder << Interface::Location.new(
uri: URI::Generic.from_path(path: entry.file_path).to_s,
range: Interface::Range.new(
start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
),
)
end
sig { params(node: Prism::GlobalVariableWriteNode).void }
def on_global_variable_write_node_enter(node)
handle_global_variable_definition(node.name.to_s)
end

sig { params(node: Prism::InstanceVariableReadNode).void }
Expand Down Expand Up @@ -197,6 +213,25 @@ def handle_super_node_definition
)
end

sig { params(name: String).void }
def handle_global_variable_definition(name)
entries = @index[name]

return unless entries

entries.each do |entry|
location = entry.location

@response_builder << Interface::Location.new(
uri: URI::Generic.from_path(path: entry.file_path).to_s,
range: Interface::Range.new(
start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
),
)
end
end

sig { params(name: String).void }
def handle_instance_variable_definition(name)
# Sorbet enforces that all instance variables be declared on typed strict or higher, which means it will be able
Expand Down
5 changes: 5 additions & 0 deletions lib/ruby_lsp/requests/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ def initialize(document, global_state, position, dispatcher, sorbet_level)
Prism::ConstantReadNode,
Prism::ConstantPathNode,
Prism::BlockArgumentNode,
Prism::GlobalVariableAndWriteNode,
Prism::GlobalVariableOperatorWriteNode,
Prism::GlobalVariableOrWriteNode,
Prism::GlobalVariableReadNode,
Prism::GlobalVariableTargetNode,
Prism::GlobalVariableWriteNode,
Prism::InstanceVariableReadNode,
Prism::InstanceVariableAndWriteNode,
Prism::InstanceVariableOperatorWriteNode,
Expand Down
30 changes: 30 additions & 0 deletions test/requests/definition_expectations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ def baz

def test_definition_for_global_variables
source = <<~RUBY
$bar &&= 1
$bar += 1
$foo ||= 1
$bar, $foo = 1
$foo = 1
$DEBUG
RUBY

Expand All @@ -685,6 +690,31 @@ def test_definition_for_global_variables
method: "textDocument/definition",
params: { textDocument: { uri: uri }, position: { character: 1, line: 0 } },
)

response = server.pop_response.response
assert_equal(3, response.size)
assert_equal(0, response[0].range.start.line)
assert_equal(1, response[1].range.start.line)
assert_equal(3, response[2].range.start.line)

server.process_message(
id: 1,
method: "textDocument/definition",
params: { textDocument: { uri: uri }, position: { character: 1, line: 2 } },
)

response = server.pop_response.response
assert_equal(3, response.size)
assert_equal(2, response[0].range.start.line)
assert_equal(3, response[1].range.start.line)
assert_equal(4, response[2].range.start.line)

server.process_message(
id: 1,
method: "textDocument/definition",
params: { textDocument: { uri: uri }, position: { character: 1, line: 5 } },
)

response = server.pop_response.response.first
assert_match(%r{/gems/rbs-.*/core/global_variables.rbs}, response.uri)
assert_equal(response.range.start.line, response.range.end.line)
Expand Down

0 comments on commit 6609b53

Please sign in to comment.