Class: RubyLsp::Requests::Definition
- Extended by:
- T::Generic, T::Sig
- Defined in:
- lib/ruby_lsp/requests/definition.rb
Overview

The [definition request](microsoft.github.io/language-server-protocol/specification#textDocument_definition) jumps to the definition of the symbol under the cursor.
Currently supported targets:
-
Classes
-
Modules
-
Constants
-
Require paths
-
Methods invoked on self only and on receivers where the type is unknown
-
Instance variables
# Example
“‘ruby require “some_gem/file” # <- Request go to definition on this string will take you to the file Product.new # <- Request go to definition on this class name will take you to its declaration. “`
Constant Summary collapse
- SPECIAL_METHOD_CALLS =
[ :require, :require_relative, :autoload, ].freeze
Instance Method Summary collapse
-
#initialize(document, global_state, position, dispatcher, sorbet_level) ⇒ Definition
constructor
A new instance of Definition.
- #perform ⇒ Object
Constructor Details
#initialize(document, global_state, position, dispatcher, sorbet_level) ⇒ Definition
Returns a new instance of Definition.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ruby_lsp/requests/definition.rb', line 48 def initialize(document, global_state, position, dispatcher, sorbet_level) super() @response_builder = T.let( ResponseBuilders::CollectionResponseBuilder[T.any(Interface::Location, Interface::LocationLink)].new, ResponseBuilders::CollectionResponseBuilder[T.any(Interface::Location, Interface::LocationLink)], ) @dispatcher = dispatcher node_context = document.locate_node( position, node_types: [ Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::BlockArgumentNode, Prism::InstanceVariableReadNode, Prism::InstanceVariableAndWriteNode, Prism::InstanceVariableOperatorWriteNode, Prism::InstanceVariableOrWriteNode, Prism::InstanceVariableTargetNode, Prism::InstanceVariableWriteNode, Prism::SymbolNode, Prism::StringNode, Prism::SuperNode, Prism::ForwardingSuperNode, ], ) target = node_context.node parent = node_context.parent if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode) # If the target is part of a constant path node, we need to find the exact portion of the constant that the # user is requesting to go to definition for target = determine_target( target, parent, position, ) elsif target.is_a?(Prism::CallNode) && !SPECIAL_METHOD_CALLS.include?(target.) && !covers_position?( target., position ) # If the target is a method call, we need to ensure that the requested position is exactly on top of the # method identifier. Otherwise, we risk showing definitions for unrelated things target = nil # For methods with block arguments using symbol-to-proc elsif target.is_a?(Prism::SymbolNode) && parent.is_a?(Prism::BlockArgumentNode) target = parent end if target Listeners::Definition.new( @response_builder, global_state, document.language_id, document.uri, node_context, dispatcher, sorbet_level, ) Addon.addons.each do |addon| addon.create_definition_listener(@response_builder, document.uri, node_context, dispatcher) end end @target = T.let(target, T.nilable(Prism::Node)) end |
Instance Method Details
#perform ⇒ Object
118 119 120 121 |
# File 'lib/ruby_lsp/requests/definition.rb', line 118 def perform @dispatcher.dispatch_once(@target) if @target @response_builder.response end |