Skip to content

Commit

Permalink
Support symbol procs in definition
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Apr 26, 2024
1 parent 3f55bbb commit f34194a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
23 changes: 16 additions & 7 deletions lib/ruby_lsp/listeners/definition.rb
Expand Up @@ -30,6 +30,7 @@ def initialize(response_builder, global_state, uri, nesting, dispatcher, typeche
dispatcher.register(
self,
:on_call_node_enter,
:on_block_argument_node_enter,
:on_constant_read_node_enter,
:on_constant_path_node_enter,
)
Expand All @@ -42,10 +43,21 @@ def on_call_node_enter(node)
if message == :require || message == :require_relative
handle_require_definition(node)
else
handle_method_definition(node)
handle_method_definition(message.to_s, self_receiver?(node))
end
end

sig { params(node: Prism::BlockArgumentNode).void }
def on_block_argument_node_enter(node)
expression = node.expression
return unless expression.is_a?(Prism::SymbolNode)

value = expression.value
return unless value

handle_method_definition(value, false)
end

sig { params(node: Prism::ConstantPathNode).void }
def on_constant_path_node_enter(node)
name = constant_name(node)
Expand All @@ -64,12 +76,9 @@ def on_constant_read_node_enter(node)

private

sig { params(node: Prism::CallNode).void }
def handle_method_definition(node)
message = node.message
return unless message

methods = if self_receiver?(node)
sig { params(message: String, self_receiver: T::Boolean).void }
def handle_method_definition(message, self_receiver)
methods = if self_receiver
@index.resolve_method(message, @nesting.join("::"))
else
# If the method doesn't have a receiver, then we provide a few candidates to jump to
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby_lsp/requests/definition.rb
Expand Up @@ -47,7 +47,7 @@ def initialize(document, global_state, position, dispatcher, typechecker_enabled

target, parent, nesting = document.locate_node(
position,
node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode],
node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::BlockArgumentNode],
)

if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
Expand Down
10 changes: 6 additions & 4 deletions test/requests/definition_expectations_test.rb
Expand Up @@ -407,6 +407,8 @@ def test_definition_precision_for_methods_with_block_arguments
source = <<~RUBY
class Foo
def foo(&block); end
def argument; end
end
bar.foo(&:argument)
Expand All @@ -417,16 +419,16 @@ def foo(&block); end
server.process_message(
id: 1,
method: "textDocument/definition",
params: { textDocument: { uri: uri }, position: { character: 12, line: 4 } },
params: { textDocument: { uri: uri }, position: { character: 12, line: 6 } },
)
assert_empty(server.pop_response.response)
assert_equal(3, server.pop_response.response.first.range.start.line)

server.process_message(
id: 1,
method: "textDocument/definition",
params: { textDocument: { uri: uri }, position: { character: 4, line: 4 } },
params: { textDocument: { uri: uri }, position: { character: 4, line: 6 } },
)
refute_empty(server.pop_response.response)
assert_equal(1, server.pop_response.response.first.range.start.line)
end
end

Expand Down

0 comments on commit f34194a

Please sign in to comment.