ruby-lsp 0.22.1 → 0.23.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +2 -2
 - data/VERSION +1 -1
 - data/exe/ruby-lsp +12 -11
 - data/exe/ruby-lsp-check +5 -5
 - data/exe/ruby-lsp-launcher +41 -15
 - data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +26 -20
 - data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +191 -100
 - data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +60 -30
 - data/lib/ruby_indexer/lib/ruby_indexer/index.rb +174 -61
 - data/lib/ruby_indexer/lib/ruby_indexer/location.rb +12 -0
 - data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +16 -14
 - data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +82 -61
 - data/lib/{core_ext → ruby_indexer/lib/ruby_indexer}/uri.rb +29 -3
 - data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +36 -0
 - data/lib/ruby_indexer/ruby_indexer.rb +2 -1
 - data/lib/ruby_indexer/test/class_variables_test.rb +140 -0
 - data/lib/ruby_indexer/test/classes_and_modules_test.rb +30 -6
 - data/lib/ruby_indexer/test/configuration_test.rb +116 -51
 - data/lib/ruby_indexer/test/enhancements_test.rb +2 -2
 - data/lib/ruby_indexer/test/index_test.rb +143 -44
 - data/lib/ruby_indexer/test/instance_variables_test.rb +20 -0
 - data/lib/ruby_indexer/test/method_test.rb +86 -8
 - data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
 - data/lib/ruby_indexer/test/reference_finder_test.rb +90 -2
 - data/lib/ruby_indexer/test/test_case.rb +2 -2
 - data/lib/ruby_indexer/test/uri_test.rb +72 -0
 - data/lib/ruby_lsp/addon.rb +9 -0
 - data/lib/ruby_lsp/base_server.rb +17 -18
 - data/lib/ruby_lsp/client_capabilities.rb +7 -1
 - data/lib/ruby_lsp/document.rb +72 -10
 - data/lib/ruby_lsp/erb_document.rb +5 -3
 - data/lib/ruby_lsp/global_state.rb +42 -3
 - data/lib/ruby_lsp/internal.rb +3 -1
 - data/lib/ruby_lsp/listeners/code_lens.rb +9 -5
 - data/lib/ruby_lsp/listeners/completion.rb +78 -6
 - data/lib/ruby_lsp/listeners/definition.rb +80 -19
 - data/lib/ruby_lsp/listeners/document_highlight.rb +3 -2
 - data/lib/ruby_lsp/listeners/document_link.rb +21 -3
 - data/lib/ruby_lsp/listeners/document_symbol.rb +12 -1
 - data/lib/ruby_lsp/listeners/folding_ranges.rb +1 -1
 - data/lib/ruby_lsp/listeners/hover.rb +59 -2
 - data/lib/ruby_lsp/load_sorbet.rb +3 -3
 - data/lib/ruby_lsp/rbs_document.rb +2 -2
 - data/lib/ruby_lsp/requests/code_action_resolve.rb +90 -6
 - data/lib/ruby_lsp/requests/code_actions.rb +57 -1
 - data/lib/ruby_lsp/requests/completion.rb +8 -1
 - data/lib/ruby_lsp/requests/completion_resolve.rb +2 -1
 - data/lib/ruby_lsp/requests/definition.rb +7 -1
 - data/lib/ruby_lsp/requests/diagnostics.rb +1 -1
 - data/lib/ruby_lsp/requests/document_highlight.rb +1 -1
 - data/lib/ruby_lsp/requests/folding_ranges.rb +2 -6
 - data/lib/ruby_lsp/requests/formatting.rb +2 -6
 - data/lib/ruby_lsp/requests/hover.rb +1 -1
 - data/lib/ruby_lsp/requests/on_type_formatting.rb +2 -2
 - data/lib/ruby_lsp/requests/prepare_rename.rb +51 -0
 - data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +1 -1
 - data/lib/ruby_lsp/requests/references.rb +29 -2
 - data/lib/ruby_lsp/requests/rename.rb +17 -7
 - data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
 - data/lib/ruby_lsp/requests/show_syntax_tree.rb +1 -4
 - data/lib/ruby_lsp/requests/signature_help.rb +1 -1
 - data/lib/ruby_lsp/requests/support/common.rb +2 -9
 - data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +3 -3
 - data/lib/ruby_lsp/requests/support/rubocop_runner.rb +13 -13
 - data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +1 -1
 - data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -3
 - data/lib/ruby_lsp/ruby_document.rb +80 -6
 - data/lib/ruby_lsp/scripts/compose_bundle.rb +1 -1
 - data/lib/ruby_lsp/server.rb +205 -61
 - data/lib/ruby_lsp/setup_bundler.rb +50 -43
 - data/lib/ruby_lsp/store.rb +7 -7
 - data/lib/ruby_lsp/test_helper.rb +45 -11
 - data/lib/ruby_lsp/type_inferrer.rb +60 -31
 - data/lib/ruby_lsp/utils.rb +63 -3
 - metadata +8 -8
 - data/lib/ruby_indexer/lib/ruby_indexer/indexable_path.rb +0 -29
 
| 
         @@ -97,6 +97,12 @@ module RubyLsp 
     | 
|
| 
       97 
97 
     | 
    
         
             
                      :on_instance_variable_operator_write_node_enter,
         
     | 
| 
       98 
98 
     | 
    
         
             
                      :on_instance_variable_or_write_node_enter,
         
     | 
| 
       99 
99 
     | 
    
         
             
                      :on_instance_variable_target_node_enter,
         
     | 
| 
      
 100 
     | 
    
         
            +
                      :on_class_variable_and_write_node_enter,
         
     | 
| 
      
 101 
     | 
    
         
            +
                      :on_class_variable_operator_write_node_enter,
         
     | 
| 
      
 102 
     | 
    
         
            +
                      :on_class_variable_or_write_node_enter,
         
     | 
| 
      
 103 
     | 
    
         
            +
                      :on_class_variable_read_node_enter,
         
     | 
| 
      
 104 
     | 
    
         
            +
                      :on_class_variable_target_node_enter,
         
     | 
| 
      
 105 
     | 
    
         
            +
                      :on_class_variable_write_node_enter,
         
     | 
| 
       100 
106 
     | 
    
         
             
                    )
         
     | 
| 
       101 
107 
     | 
    
         
             
                  end
         
     | 
| 
       102 
108 
     | 
    
         | 
| 
         @@ -107,16 +113,17 @@ module RubyLsp 
     | 
|
| 
       107 
113 
     | 
    
         
             
                    # no sigil, Sorbet will still provide completion for constants
         
     | 
| 
       108 
114 
     | 
    
         
             
                    return if @sorbet_level != RubyDocument::SorbetLevel::Ignore
         
     | 
| 
       109 
115 
     | 
    
         | 
| 
       110 
     | 
    
         
            -
                    name = constant_name(node)
         
     | 
| 
      
 116 
     | 
    
         
            +
                    name = RubyIndexer::Index.constant_name(node)
         
     | 
| 
       111 
117 
     | 
    
         
             
                    return if name.nil?
         
     | 
| 
       112 
118 
     | 
    
         | 
| 
      
 119 
     | 
    
         
            +
                    range = range_from_location(node.location)
         
     | 
| 
       113 
120 
     | 
    
         
             
                    candidates = @index.constant_completion_candidates(name, @node_context.nesting)
         
     | 
| 
       114 
121 
     | 
    
         
             
                    candidates.each do |entries|
         
     | 
| 
       115 
122 
     | 
    
         
             
                      complete_name = T.must(entries.first).name
         
     | 
| 
       116 
123 
     | 
    
         
             
                      @response_builder << build_entry_completion(
         
     | 
| 
       117 
124 
     | 
    
         
             
                        complete_name,
         
     | 
| 
       118 
125 
     | 
    
         
             
                        name,
         
     | 
| 
       119 
     | 
    
         
            -
                         
     | 
| 
      
 126 
     | 
    
         
            +
                        range,
         
     | 
| 
       120 
127 
     | 
    
         
             
                        entries,
         
     | 
| 
       121 
128 
     | 
    
         
             
                        top_level?(complete_name),
         
     | 
| 
       122 
129 
     | 
    
         
             
                      )
         
     | 
| 
         @@ -155,7 +162,7 @@ module RubyLsp 
     | 
|
| 
       155 
162 
     | 
    
         
             
                      if (receiver.is_a?(Prism::ConstantReadNode) || receiver.is_a?(Prism::ConstantPathNode)) &&
         
     | 
| 
       156 
163 
     | 
    
         
             
                          node.call_operator == "::"
         
     | 
| 
       157 
164 
     | 
    
         | 
| 
       158 
     | 
    
         
            -
                        name = constant_name(receiver)
         
     | 
| 
      
 165 
     | 
    
         
            +
                        name = RubyIndexer::Index.constant_name(receiver)
         
     | 
| 
       159 
166 
     | 
    
         | 
| 
       160 
167 
     | 
    
         
             
                        if name
         
     | 
| 
       161 
168 
     | 
    
         
             
                          start_loc = node.location
         
     | 
| 
         @@ -246,6 +253,36 @@ module RubyLsp 
     | 
|
| 
       246 
253 
     | 
    
         
             
                    handle_instance_variable_completion(node.name.to_s, node.location)
         
     | 
| 
       247 
254 
     | 
    
         
             
                  end
         
     | 
| 
       248 
255 
     | 
    
         | 
| 
      
 256 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableAndWriteNode).void }
         
     | 
| 
      
 257 
     | 
    
         
            +
                  def on_class_variable_and_write_node_enter(node)
         
     | 
| 
      
 258 
     | 
    
         
            +
                    handle_class_variable_completion(node.name.to_s, node.name_loc)
         
     | 
| 
      
 259 
     | 
    
         
            +
                  end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableOperatorWriteNode).void }
         
     | 
| 
      
 262 
     | 
    
         
            +
                  def on_class_variable_operator_write_node_enter(node)
         
     | 
| 
      
 263 
     | 
    
         
            +
                    handle_class_variable_completion(node.name.to_s, node.name_loc)
         
     | 
| 
      
 264 
     | 
    
         
            +
                  end
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableOrWriteNode).void }
         
     | 
| 
      
 267 
     | 
    
         
            +
                  def on_class_variable_or_write_node_enter(node)
         
     | 
| 
      
 268 
     | 
    
         
            +
                    handle_class_variable_completion(node.name.to_s, node.name_loc)
         
     | 
| 
      
 269 
     | 
    
         
            +
                  end
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableTargetNode).void }
         
     | 
| 
      
 272 
     | 
    
         
            +
                  def on_class_variable_target_node_enter(node)
         
     | 
| 
      
 273 
     | 
    
         
            +
                    handle_class_variable_completion(node.name.to_s, node.location)
         
     | 
| 
      
 274 
     | 
    
         
            +
                  end
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableReadNode).void }
         
     | 
| 
      
 277 
     | 
    
         
            +
                  def on_class_variable_read_node_enter(node)
         
     | 
| 
      
 278 
     | 
    
         
            +
                    handle_class_variable_completion(node.name.to_s, node.location)
         
     | 
| 
      
 279 
     | 
    
         
            +
                  end
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
      
 281 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableWriteNode).void }
         
     | 
| 
      
 282 
     | 
    
         
            +
                  def on_class_variable_write_node_enter(node)
         
     | 
| 
      
 283 
     | 
    
         
            +
                    handle_class_variable_completion(node.name.to_s, node.name_loc)
         
     | 
| 
      
 284 
     | 
    
         
            +
                  end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
       249 
286 
     | 
    
         
             
                  private
         
     | 
| 
       250 
287 
     | 
    
         | 
| 
       251 
288 
     | 
    
         
             
                  sig { params(name: String, range: Interface::Range).void }
         
     | 
| 
         @@ -326,6 +363,37 @@ module RubyLsp 
     | 
|
| 
       326 
363 
     | 
    
         
             
                    end
         
     | 
| 
       327 
364 
     | 
    
         
             
                  end
         
     | 
| 
       328 
365 
     | 
    
         | 
| 
      
 366 
     | 
    
         
            +
                  sig { params(name: String, location: Prism::Location).void }
         
     | 
| 
      
 367 
     | 
    
         
            +
                  def handle_class_variable_completion(name, location)
         
     | 
| 
      
 368 
     | 
    
         
            +
                    type = @type_inferrer.infer_receiver_type(@node_context)
         
     | 
| 
      
 369 
     | 
    
         
            +
                    return unless type
         
     | 
| 
      
 370 
     | 
    
         
            +
             
     | 
| 
      
 371 
     | 
    
         
            +
                    range = range_from_location(location)
         
     | 
| 
      
 372 
     | 
    
         
            +
             
     | 
| 
      
 373 
     | 
    
         
            +
                    @index.class_variable_completion_candidates(name, type.name).each do |entry|
         
     | 
| 
      
 374 
     | 
    
         
            +
                      variable_name = entry.name
         
     | 
| 
      
 375 
     | 
    
         
            +
             
     | 
| 
      
 376 
     | 
    
         
            +
                      label_details = Interface::CompletionItemLabelDetails.new(
         
     | 
| 
      
 377 
     | 
    
         
            +
                        description: entry.file_name,
         
     | 
| 
      
 378 
     | 
    
         
            +
                      )
         
     | 
| 
      
 379 
     | 
    
         
            +
             
     | 
| 
      
 380 
     | 
    
         
            +
                      @response_builder << Interface::CompletionItem.new(
         
     | 
| 
      
 381 
     | 
    
         
            +
                        label: variable_name,
         
     | 
| 
      
 382 
     | 
    
         
            +
                        label_details: label_details,
         
     | 
| 
      
 383 
     | 
    
         
            +
                        text_edit: Interface::TextEdit.new(
         
     | 
| 
      
 384 
     | 
    
         
            +
                          range: range,
         
     | 
| 
      
 385 
     | 
    
         
            +
                          new_text: variable_name,
         
     | 
| 
      
 386 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 387 
     | 
    
         
            +
                        kind: Constant::CompletionItemKind::FIELD,
         
     | 
| 
      
 388 
     | 
    
         
            +
                        data: {
         
     | 
| 
      
 389 
     | 
    
         
            +
                          owner_name: entry.owner&.name,
         
     | 
| 
      
 390 
     | 
    
         
            +
                        },
         
     | 
| 
      
 391 
     | 
    
         
            +
                      )
         
     | 
| 
      
 392 
     | 
    
         
            +
                    end
         
     | 
| 
      
 393 
     | 
    
         
            +
                  rescue RubyIndexer::Index::NonExistingNamespaceError
         
     | 
| 
      
 394 
     | 
    
         
            +
                    # If by any chance we haven't indexed the owner, then there's no way to find the right declaration
         
     | 
| 
      
 395 
     | 
    
         
            +
                  end
         
     | 
| 
      
 396 
     | 
    
         
            +
             
     | 
| 
       329 
397 
     | 
    
         
             
                  sig { params(name: String, location: Prism::Location).void }
         
     | 
| 
       330 
398 
     | 
    
         
             
                  def handle_instance_variable_completion(name, location)
         
     | 
| 
       331 
399 
     | 
    
         
             
                    # Sorbet enforces that all instance variables be declared on typed strict or higher, which means it will be able
         
     | 
| 
         @@ -335,6 +403,7 @@ module RubyLsp 
     | 
|
| 
       335 
403 
     | 
    
         
             
                    type = @type_inferrer.infer_receiver_type(@node_context)
         
     | 
| 
       336 
404 
     | 
    
         
             
                    return unless type
         
     | 
| 
       337 
405 
     | 
    
         | 
| 
      
 406 
     | 
    
         
            +
                    range = range_from_location(location)
         
     | 
| 
       338 
407 
     | 
    
         
             
                    @index.instance_variable_completion_candidates(name, type.name).each do |entry|
         
     | 
| 
       339 
408 
     | 
    
         
             
                      variable_name = entry.name
         
     | 
| 
       340 
409 
     | 
    
         | 
| 
         @@ -346,7 +415,7 @@ module RubyLsp 
     | 
|
| 
       346 
415 
     | 
    
         
             
                        label: variable_name,
         
     | 
| 
       347 
416 
     | 
    
         
             
                        label_details: label_details,
         
     | 
| 
       348 
417 
     | 
    
         
             
                        text_edit: Interface::TextEdit.new(
         
     | 
| 
       349 
     | 
    
         
            -
                          range:  
     | 
| 
      
 418 
     | 
    
         
            +
                          range: range,
         
     | 
| 
       350 
419 
     | 
    
         
             
                          new_text: variable_name,
         
     | 
| 
       351 
420 
     | 
    
         
             
                        ),
         
     | 
| 
       352 
421 
     | 
    
         
             
                        kind: Constant::CompletionItemKind::FIELD,
         
     | 
| 
         @@ -368,9 +437,9 @@ module RubyLsp 
     | 
|
| 
       368 
437 
     | 
    
         | 
| 
       369 
438 
     | 
    
         
             
                    return unless path_node_to_complete.is_a?(Prism::StringNode)
         
     | 
| 
       370 
439 
     | 
    
         | 
| 
       371 
     | 
    
         
            -
                     
     | 
| 
      
 440 
     | 
    
         
            +
                    matched_uris = @index.search_require_paths(path_node_to_complete.content)
         
     | 
| 
       372 
441 
     | 
    
         | 
| 
       373 
     | 
    
         
            -
                     
     | 
| 
      
 442 
     | 
    
         
            +
                    matched_uris.map!(&:require_path).sort!.each do |path|
         
     | 
| 
       374 
443 
     | 
    
         
             
                      @response_builder << build_completion(T.must(path), path_node_to_complete)
         
     | 
| 
       375 
444 
     | 
    
         
             
                    end
         
     | 
| 
       376 
445 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -402,6 +471,9 @@ module RubyLsp 
     | 
|
| 
       402 
471 
     | 
    
         
             
                        path_node_to_complete,
         
     | 
| 
       403 
472 
     | 
    
         
             
                      )
         
     | 
| 
       404 
473 
     | 
    
         
             
                    end
         
     | 
| 
      
 474 
     | 
    
         
            +
                  rescue Errno::EPERM
         
     | 
| 
      
 475 
     | 
    
         
            +
                    # If the user writes a relative require pointing to a path that the editor has no permissions to read, then glob
         
     | 
| 
      
 476 
     | 
    
         
            +
                    # might fail with EPERM
         
     | 
| 
       405 
477 
     | 
    
         
             
                  end
         
     | 
| 
       406 
478 
     | 
    
         | 
| 
       407 
479 
     | 
    
         
             
                  sig { params(node: Prism::CallNode, name: String).void }
         
     | 
| 
         @@ -55,6 +55,12 @@ module RubyLsp 
     | 
|
| 
       55 
55 
     | 
    
         
             
                      :on_symbol_node_enter,
         
     | 
| 
       56 
56 
     | 
    
         
             
                      :on_super_node_enter,
         
     | 
| 
       57 
57 
     | 
    
         
             
                      :on_forwarding_super_node_enter,
         
     | 
| 
      
 58 
     | 
    
         
            +
                      :on_class_variable_and_write_node_enter,
         
     | 
| 
      
 59 
     | 
    
         
            +
                      :on_class_variable_operator_write_node_enter,
         
     | 
| 
      
 60 
     | 
    
         
            +
                      :on_class_variable_or_write_node_enter,
         
     | 
| 
      
 61 
     | 
    
         
            +
                      :on_class_variable_read_node_enter,
         
     | 
| 
      
 62 
     | 
    
         
            +
                      :on_class_variable_target_node_enter,
         
     | 
| 
      
 63 
     | 
    
         
            +
                      :on_class_variable_write_node_enter,
         
     | 
| 
       58 
64 
     | 
    
         
             
                    )
         
     | 
| 
       59 
65 
     | 
    
         
             
                  end
         
     | 
| 
       60 
66 
     | 
    
         | 
| 
         @@ -112,7 +118,7 @@ module RubyLsp 
     | 
|
| 
       112 
118 
     | 
    
         | 
| 
       113 
119 
     | 
    
         
             
                  sig { params(node: Prism::ConstantPathNode).void }
         
     | 
| 
       114 
120 
     | 
    
         
             
                  def on_constant_path_node_enter(node)
         
     | 
| 
       115 
     | 
    
         
            -
                    name = constant_name(node)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    name = RubyIndexer::Index.constant_name(node)
         
     | 
| 
       116 
122 
     | 
    
         
             
                    return if name.nil?
         
     | 
| 
       117 
123 
     | 
    
         | 
| 
       118 
124 
     | 
    
         
             
                    find_in_index(name)
         
     | 
| 
         @@ -120,7 +126,7 @@ module RubyLsp 
     | 
|
| 
       120 
126 
     | 
    
         | 
| 
       121 
127 
     | 
    
         
             
                  sig { params(node: Prism::ConstantReadNode).void }
         
     | 
| 
       122 
128 
     | 
    
         
             
                  def on_constant_read_node_enter(node)
         
     | 
| 
       123 
     | 
    
         
            -
                    name = constant_name(node)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    name = RubyIndexer::Index.constant_name(node)
         
     | 
| 
       124 
130 
     | 
    
         
             
                    return if name.nil?
         
     | 
| 
       125 
131 
     | 
    
         | 
| 
       126 
132 
     | 
    
         
             
                    find_in_index(name)
         
     | 
| 
         @@ -196,6 +202,36 @@ module RubyLsp 
     | 
|
| 
       196 
202 
     | 
    
         
             
                    handle_super_node_definition
         
     | 
| 
       197 
203 
     | 
    
         
             
                  end
         
     | 
| 
       198 
204 
     | 
    
         | 
| 
      
 205 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableAndWriteNode).void }
         
     | 
| 
      
 206 
     | 
    
         
            +
                  def on_class_variable_and_write_node_enter(node)
         
     | 
| 
      
 207 
     | 
    
         
            +
                    handle_class_variable_definition(node.name.to_s)
         
     | 
| 
      
 208 
     | 
    
         
            +
                  end
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableOperatorWriteNode).void }
         
     | 
| 
      
 211 
     | 
    
         
            +
                  def on_class_variable_operator_write_node_enter(node)
         
     | 
| 
      
 212 
     | 
    
         
            +
                    handle_class_variable_definition(node.name.to_s)
         
     | 
| 
      
 213 
     | 
    
         
            +
                  end
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableOrWriteNode).void }
         
     | 
| 
      
 216 
     | 
    
         
            +
                  def on_class_variable_or_write_node_enter(node)
         
     | 
| 
      
 217 
     | 
    
         
            +
                    handle_class_variable_definition(node.name.to_s)
         
     | 
| 
      
 218 
     | 
    
         
            +
                  end
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableTargetNode).void }
         
     | 
| 
      
 221 
     | 
    
         
            +
                  def on_class_variable_target_node_enter(node)
         
     | 
| 
      
 222 
     | 
    
         
            +
                    handle_class_variable_definition(node.name.to_s)
         
     | 
| 
      
 223 
     | 
    
         
            +
                  end
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableReadNode).void }
         
     | 
| 
      
 226 
     | 
    
         
            +
                  def on_class_variable_read_node_enter(node)
         
     | 
| 
      
 227 
     | 
    
         
            +
                    handle_class_variable_definition(node.name.to_s)
         
     | 
| 
      
 228 
     | 
    
         
            +
                  end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableWriteNode).void }
         
     | 
| 
      
 231 
     | 
    
         
            +
                  def on_class_variable_write_node_enter(node)
         
     | 
| 
      
 232 
     | 
    
         
            +
                    handle_class_variable_definition(node.name.to_s)
         
     | 
| 
      
 233 
     | 
    
         
            +
                  end
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
       199 
235 
     | 
    
         
             
                  private
         
     | 
| 
       200 
236 
     | 
    
         | 
| 
       201 
237 
     | 
    
         
             
                  sig { void }
         
     | 
| 
         @@ -223,7 +259,7 @@ module RubyLsp 
     | 
|
| 
       223 
259 
     | 
    
         
             
                      location = entry.location
         
     | 
| 
       224 
260 
     | 
    
         | 
| 
       225 
261 
     | 
    
         
             
                      @response_builder << Interface::Location.new(
         
     | 
| 
       226 
     | 
    
         
            -
                        uri:  
     | 
| 
      
 262 
     | 
    
         
            +
                        uri: entry.uri.to_s,
         
     | 
| 
       227 
263 
     | 
    
         
             
                        range: Interface::Range.new(
         
     | 
| 
       228 
264 
     | 
    
         
             
                          start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
         
     | 
| 
       229 
265 
     | 
    
         
             
                          end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
         
     | 
| 
         @@ -232,6 +268,24 @@ module RubyLsp 
     | 
|
| 
       232 
268 
     | 
    
         
             
                    end
         
     | 
| 
       233 
269 
     | 
    
         
             
                  end
         
     | 
| 
       234 
270 
     | 
    
         | 
| 
      
 271 
     | 
    
         
            +
                  sig { params(name: String).void }
         
     | 
| 
      
 272 
     | 
    
         
            +
                  def handle_class_variable_definition(name)
         
     | 
| 
      
 273 
     | 
    
         
            +
                    type = @type_inferrer.infer_receiver_type(@node_context)
         
     | 
| 
      
 274 
     | 
    
         
            +
                    return unless type
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
                    entries = @index.resolve_class_variable(name, type.name)
         
     | 
| 
      
 277 
     | 
    
         
            +
                    return unless entries
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
                    entries.each do |entry|
         
     | 
| 
      
 280 
     | 
    
         
            +
                      @response_builder << Interface::Location.new(
         
     | 
| 
      
 281 
     | 
    
         
            +
                        uri: entry.uri.to_s,
         
     | 
| 
      
 282 
     | 
    
         
            +
                        range: range_from_location(entry.location),
         
     | 
| 
      
 283 
     | 
    
         
            +
                      )
         
     | 
| 
      
 284 
     | 
    
         
            +
                    end
         
     | 
| 
      
 285 
     | 
    
         
            +
                  rescue RubyIndexer::Index::NonExistingNamespaceError
         
     | 
| 
      
 286 
     | 
    
         
            +
                    # If by any chance we haven't indexed the owner, then there's no way to find the right declaration
         
     | 
| 
      
 287 
     | 
    
         
            +
                  end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
       235 
289 
     | 
    
         
             
                  sig { params(name: String).void }
         
     | 
| 
       236 
290 
     | 
    
         
             
                  def handle_instance_variable_definition(name)
         
     | 
| 
       237 
291 
     | 
    
         
             
                    # Sorbet enforces that all instance variables be declared on typed strict or higher, which means it will be able
         
     | 
| 
         @@ -248,7 +302,7 @@ module RubyLsp 
     | 
|
| 
       248 
302 
     | 
    
         
             
                      location = entry.location
         
     | 
| 
       249 
303 
     | 
    
         | 
| 
       250 
304 
     | 
    
         
             
                      @response_builder << Interface::Location.new(
         
     | 
| 
       251 
     | 
    
         
            -
                        uri:  
     | 
| 
      
 305 
     | 
    
         
            +
                        uri: entry.uri.to_s,
         
     | 
| 
       252 
306 
     | 
    
         
             
                        range: Interface::Range.new(
         
     | 
| 
       253 
307 
     | 
    
         
             
                          start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
         
     | 
| 
       254 
308 
     | 
    
         
             
                          end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
         
     | 
| 
         @@ -275,11 +329,12 @@ module RubyLsp 
     | 
|
| 
       275 
329 
     | 
    
         
             
                    return unless methods
         
     | 
| 
       276 
330 
     | 
    
         | 
| 
       277 
331 
     | 
    
         
             
                    methods.each do |target_method|
         
     | 
| 
       278 
     | 
    
         
            -
                       
     | 
| 
       279 
     | 
    
         
            -
                       
     | 
| 
      
 332 
     | 
    
         
            +
                      uri = target_method.uri
         
     | 
| 
      
 333 
     | 
    
         
            +
                      full_path = uri.full_path
         
     | 
| 
      
 334 
     | 
    
         
            +
                      next if sorbet_level_true_or_higher?(@sorbet_level) && (!full_path || not_in_dependencies?(full_path))
         
     | 
| 
       280 
335 
     | 
    
         | 
| 
       281 
336 
     | 
    
         
             
                      @response_builder << Interface::LocationLink.new(
         
     | 
| 
       282 
     | 
    
         
            -
                        target_uri:  
     | 
| 
      
 337 
     | 
    
         
            +
                        target_uri: uri.to_s,
         
     | 
| 
       283 
338 
     | 
    
         
             
                        target_range: range_from_location(target_method.location),
         
     | 
| 
       284 
339 
     | 
    
         
             
                        target_selection_range: range_from_location(target_method.name_location),
         
     | 
| 
       285 
340 
     | 
    
         
             
                      )
         
     | 
| 
         @@ -290,20 +345,22 @@ module RubyLsp 
     | 
|
| 
       290 
345 
     | 
    
         
             
                  def handle_require_definition(node, message)
         
     | 
| 
       291 
346 
     | 
    
         
             
                    case message
         
     | 
| 
       292 
347 
     | 
    
         
             
                    when :require
         
     | 
| 
       293 
     | 
    
         
            -
                      entry = @index.search_require_paths(node.content).find do | 
     | 
| 
       294 
     | 
    
         
            -
                         
     | 
| 
      
 348 
     | 
    
         
            +
                      entry = @index.search_require_paths(node.content).find do |uri|
         
     | 
| 
      
 349 
     | 
    
         
            +
                        uri.require_path == node.content
         
     | 
| 
       295 
350 
     | 
    
         
             
                      end
         
     | 
| 
       296 
351 
     | 
    
         | 
| 
       297 
352 
     | 
    
         
             
                      if entry
         
     | 
| 
       298 
353 
     | 
    
         
             
                        candidate = entry.full_path
         
     | 
| 
       299 
354 
     | 
    
         | 
| 
       300 
     | 
    
         
            -
                         
     | 
| 
       301 
     | 
    
         
            -
                           
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
                             
     | 
| 
       304 
     | 
    
         
            -
             
     | 
| 
       305 
     | 
    
         
            -
             
     | 
| 
       306 
     | 
    
         
            -
             
     | 
| 
      
 355 
     | 
    
         
            +
                        if candidate
         
     | 
| 
      
 356 
     | 
    
         
            +
                          @response_builder << Interface::Location.new(
         
     | 
| 
      
 357 
     | 
    
         
            +
                            uri: URI::Generic.from_path(path: candidate).to_s,
         
     | 
| 
      
 358 
     | 
    
         
            +
                            range: Interface::Range.new(
         
     | 
| 
      
 359 
     | 
    
         
            +
                              start: Interface::Position.new(line: 0, character: 0),
         
     | 
| 
      
 360 
     | 
    
         
            +
                              end: Interface::Position.new(line: 0, character: 0),
         
     | 
| 
      
 361 
     | 
    
         
            +
                            ),
         
     | 
| 
      
 362 
     | 
    
         
            +
                          )
         
     | 
| 
      
 363 
     | 
    
         
            +
                        end
         
     | 
| 
       307 
364 
     | 
    
         
             
                      end
         
     | 
| 
       308 
365 
     | 
    
         
             
                    when :require_relative
         
     | 
| 
       309 
366 
     | 
    
         
             
                      required_file = "#{node.content}.rb"
         
     | 
| 
         @@ -346,11 +403,15 @@ module RubyLsp 
     | 
|
| 
       346 
403 
     | 
    
         
             
                      # If the project has Sorbet, then we only want to handle go to definition for constants defined in gems, as an
         
     | 
| 
       347 
404 
     | 
    
         
             
                      # additional behavior on top of jumping to RBIs. The only sigil where Sorbet cannot handle constants is typed
         
     | 
| 
       348 
405 
     | 
    
         
             
                      # ignore
         
     | 
| 
       349 
     | 
    
         
            -
                       
     | 
| 
       350 
     | 
    
         
            -
                       
     | 
| 
      
 406 
     | 
    
         
            +
                      uri = entry.uri
         
     | 
| 
      
 407 
     | 
    
         
            +
                      full_path = uri.full_path
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
      
 409 
     | 
    
         
            +
                      if @sorbet_level != RubyDocument::SorbetLevel::Ignore && (!full_path || not_in_dependencies?(full_path))
         
     | 
| 
      
 410 
     | 
    
         
            +
                        next
         
     | 
| 
      
 411 
     | 
    
         
            +
                      end
         
     | 
| 
       351 
412 
     | 
    
         | 
| 
       352 
413 
     | 
    
         
             
                      @response_builder << Interface::LocationLink.new(
         
     | 
| 
       353 
     | 
    
         
            -
                        target_uri:  
     | 
| 
      
 414 
     | 
    
         
            +
                        target_uri: uri.to_s,
         
     | 
| 
       354 
415 
     | 
    
         
             
                        target_range: range_from_location(entry.location),
         
     | 
| 
       355 
416 
     | 
    
         
             
                        target_selection_range: range_from_location(entry.name_location),
         
     | 
| 
       356 
417 
     | 
    
         
             
                      )
         
     | 
| 
         @@ -120,7 +120,7 @@ module RubyLsp 
     | 
|
| 
       120 
120 
     | 
    
         
             
                        [target, node_value(target)]
         
     | 
| 
       121 
121 
     | 
    
         
             
                      when Prism::ModuleNode, Prism::ClassNode, Prism::SingletonClassNode, Prism::DefNode, Prism::CaseNode,
         
     | 
| 
       122 
122 
     | 
    
         
             
                        Prism::WhileNode, Prism::UntilNode, Prism::ForNode, Prism::IfNode, Prism::UnlessNode
         
     | 
| 
       123 
     | 
    
         
            -
                        target
         
     | 
| 
      
 123 
     | 
    
         
            +
                        [target, nil]
         
     | 
| 
       124 
124 
     | 
    
         
             
                      end
         
     | 
| 
       125 
125 
     | 
    
         | 
| 
       126 
126 
     | 
    
         
             
                    @target = T.let(highlight_target, T.nilable(Prism::Node))
         
     | 
| 
         @@ -620,7 +620,8 @@ module RubyLsp 
     | 
|
| 
       620 
620 
     | 
    
         | 
| 
       621 
621 
     | 
    
         
             
                  sig { params(keyword_loc: T.nilable(Prism::Location), end_loc: T.nilable(Prism::Location)).void }
         
     | 
| 
       622 
622 
     | 
    
         
             
                  def add_matching_end_highlights(keyword_loc, end_loc)
         
     | 
| 
       623 
     | 
    
         
            -
                    return unless keyword_loc && end_loc 
     | 
| 
      
 623 
     | 
    
         
            +
                    return unless keyword_loc && end_loc
         
     | 
| 
      
 624 
     | 
    
         
            +
                    return unless end_loc.length.positive?
         
     | 
| 
       624 
625 
     | 
    
         
             
                    return unless covers_target_position?(keyword_loc) || covers_target_position?(end_loc)
         
     | 
| 
       625 
626 
     | 
    
         | 
| 
       626 
627 
     | 
    
         
             
                    add_highlight(Constant::DocumentHighlightKind::TEXT, keyword_loc)
         
     | 
| 
         @@ -124,11 +124,26 @@ module RubyLsp 
     | 
|
| 
       124 
124 
     | 
    
         
             
                    match = comment.location.slice.match(%r{source://.*#\d+$})
         
     | 
| 
       125 
125 
     | 
    
         
             
                    return unless match
         
     | 
| 
       126 
126 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
                    uri = T.cast( 
     | 
| 
      
 127 
     | 
    
         
            +
                    uri = T.cast(
         
     | 
| 
      
 128 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 129 
     | 
    
         
            +
                        URI(T.must(match[0]))
         
     | 
| 
      
 130 
     | 
    
         
            +
                      rescue URI::Error
         
     | 
| 
      
 131 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 132 
     | 
    
         
            +
                      end,
         
     | 
| 
      
 133 
     | 
    
         
            +
                      T.nilable(URI::Source),
         
     | 
| 
      
 134 
     | 
    
         
            +
                    )
         
     | 
| 
      
 135 
     | 
    
         
            +
                    return unless uri
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
       128 
137 
     | 
    
         
             
                    gem_version = resolve_version(uri)
         
     | 
| 
       129 
138 
     | 
    
         
             
                    return if gem_version.nil?
         
     | 
| 
       130 
139 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                     
     | 
| 
      
 140 
     | 
    
         
            +
                    path = uri.path
         
     | 
| 
      
 141 
     | 
    
         
            +
                    return unless path
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                    gem_name = uri.gem_name
         
     | 
| 
      
 144 
     | 
    
         
            +
                    return unless gem_name
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                    file_path = self.class.gem_paths.dig(gem_name, gem_version, CGI.unescape(path))
         
     | 
| 
       132 
147 
     | 
    
         
             
                    return if file_path.nil?
         
     | 
| 
       133 
148 
     | 
    
         | 
| 
       134 
149 
     | 
    
         
             
                    @response_builder << Interface::DocumentLink.new(
         
     | 
| 
         @@ -149,7 +164,10 @@ module RubyLsp 
     | 
|
| 
       149 
164 
     | 
    
         | 
| 
       150 
165 
     | 
    
         
             
                    return @gem_version unless @gem_version.nil? || @gem_version.empty?
         
     | 
| 
       151 
166 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
                     
     | 
| 
      
 167 
     | 
    
         
            +
                    gem_name = uri.gem_name
         
     | 
| 
      
 168 
     | 
    
         
            +
                    return unless gem_name
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                    GEM_TO_VERSION_MAP[gem_name]
         
     | 
| 
       153 
171 
     | 
    
         
             
                  end
         
     | 
| 
       154 
172 
     | 
    
         
             
                end
         
     | 
| 
       155 
173 
     | 
    
         
             
              end
         
     | 
| 
         @@ -41,6 +41,7 @@ module RubyLsp 
     | 
|
| 
       41 
41 
     | 
    
         
             
                      :on_module_node_enter,
         
     | 
| 
       42 
42 
     | 
    
         
             
                      :on_module_node_leave,
         
     | 
| 
       43 
43 
     | 
    
         
             
                      :on_instance_variable_write_node_enter,
         
     | 
| 
      
 44 
     | 
    
         
            +
                      :on_instance_variable_target_node_enter,
         
     | 
| 
       44 
45 
     | 
    
         
             
                      :on_instance_variable_operator_write_node_enter,
         
     | 
| 
       45 
46 
     | 
    
         
             
                      :on_instance_variable_or_write_node_enter,
         
     | 
| 
       46 
47 
     | 
    
         
             
                      :on_instance_variable_and_write_node_enter,
         
     | 
| 
         @@ -272,6 +273,16 @@ module RubyLsp 
     | 
|
| 
       272 
273 
     | 
    
         
             
                    )
         
     | 
| 
       273 
274 
     | 
    
         
             
                  end
         
     | 
| 
       274 
275 
     | 
    
         | 
| 
      
 276 
     | 
    
         
            +
                  sig { params(node: Prism::InstanceVariableTargetNode).void }
         
     | 
| 
      
 277 
     | 
    
         
            +
                  def on_instance_variable_target_node_enter(node)
         
     | 
| 
      
 278 
     | 
    
         
            +
                    create_document_symbol(
         
     | 
| 
      
 279 
     | 
    
         
            +
                      name: node.name.to_s,
         
     | 
| 
      
 280 
     | 
    
         
            +
                      kind: Constant::SymbolKind::FIELD,
         
     | 
| 
      
 281 
     | 
    
         
            +
                      range_location: node.location,
         
     | 
| 
      
 282 
     | 
    
         
            +
                      selection_range_location: node.location,
         
     | 
| 
      
 283 
     | 
    
         
            +
                    )
         
     | 
| 
      
 284 
     | 
    
         
            +
                  end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
       275 
286 
     | 
    
         
             
                  sig { params(node: Prism::InstanceVariableOperatorWriteNode).void }
         
     | 
| 
       276 
287 
     | 
    
         
             
                  def on_instance_variable_operator_write_node_enter(node)
         
     | 
| 
       277 
288 
     | 
    
         
             
                    create_document_symbol(
         
     | 
| 
         @@ -329,7 +340,7 @@ module RubyLsp 
     | 
|
| 
       329 
340 
     | 
    
         
             
                    ).returns(Interface::DocumentSymbol)
         
     | 
| 
       330 
341 
     | 
    
         
             
                  end
         
     | 
| 
       331 
342 
     | 
    
         
             
                  def create_document_symbol(name:, kind:, range_location:, selection_range_location:)
         
     | 
| 
       332 
     | 
    
         
            -
                    name = "<blank>" if name.empty?
         
     | 
| 
      
 343 
     | 
    
         
            +
                    name = "<blank>" if name.strip.empty?
         
     | 
| 
       333 
344 
     | 
    
         
             
                    symbol = Interface::DocumentSymbol.new(
         
     | 
| 
       334 
345 
     | 
    
         
             
                      name: name,
         
     | 
| 
       335 
346 
     | 
    
         
             
                      kind: kind,
         
     | 
| 
         @@ -195,7 +195,7 @@ module RubyLsp 
     | 
|
| 
       195 
195 
     | 
    
         
             
                  def push_comment_ranges
         
     | 
| 
       196 
196 
     | 
    
         
             
                    # Group comments that are on consecutive lines and then push ranges for each group that has at least 2 comments
         
     | 
| 
       197 
197 
     | 
    
         
             
                    @comments.chunk_while do |this, other|
         
     | 
| 
       198 
     | 
    
         
            -
                      this.location.end_line + 1 == other.location.start_line
         
     | 
| 
      
 198 
     | 
    
         
            +
                      this.location.end_line + 1 == other.location.start_line && !this.trailing? && !other.trailing?
         
     | 
| 
       199 
199 
     | 
    
         
             
                    end.each do |chunk|
         
     | 
| 
       200 
200 
     | 
    
         
             
                      next if chunk.length == 1
         
     | 
| 
       201 
201 
     | 
    
         | 
| 
         @@ -31,6 +31,12 @@ module RubyLsp 
     | 
|
| 
       31 
31 
     | 
    
         
             
                      Prism::SuperNode,
         
     | 
| 
       32 
32 
     | 
    
         
             
                      Prism::ForwardingSuperNode,
         
     | 
| 
       33 
33 
     | 
    
         
             
                      Prism::YieldNode,
         
     | 
| 
      
 34 
     | 
    
         
            +
                      Prism::ClassVariableAndWriteNode,
         
     | 
| 
      
 35 
     | 
    
         
            +
                      Prism::ClassVariableOperatorWriteNode,
         
     | 
| 
      
 36 
     | 
    
         
            +
                      Prism::ClassVariableOrWriteNode,
         
     | 
| 
      
 37 
     | 
    
         
            +
                      Prism::ClassVariableReadNode,
         
     | 
| 
      
 38 
     | 
    
         
            +
                      Prism::ClassVariableTargetNode,
         
     | 
| 
      
 39 
     | 
    
         
            +
                      Prism::ClassVariableWriteNode,
         
     | 
| 
       34 
40 
     | 
    
         
             
                    ],
         
     | 
| 
       35 
41 
     | 
    
         
             
                    T::Array[T.class_of(Prism::Node)],
         
     | 
| 
       36 
42 
     | 
    
         
             
                  )
         
     | 
| 
         @@ -85,6 +91,12 @@ module RubyLsp 
     | 
|
| 
       85 
91 
     | 
    
         
             
                      :on_string_node_enter,
         
     | 
| 
       86 
92 
     | 
    
         
             
                      :on_interpolated_string_node_enter,
         
     | 
| 
       87 
93 
     | 
    
         
             
                      :on_yield_node_enter,
         
     | 
| 
      
 94 
     | 
    
         
            +
                      :on_class_variable_and_write_node_enter,
         
     | 
| 
      
 95 
     | 
    
         
            +
                      :on_class_variable_operator_write_node_enter,
         
     | 
| 
      
 96 
     | 
    
         
            +
                      :on_class_variable_or_write_node_enter,
         
     | 
| 
      
 97 
     | 
    
         
            +
                      :on_class_variable_read_node_enter,
         
     | 
| 
      
 98 
     | 
    
         
            +
                      :on_class_variable_target_node_enter,
         
     | 
| 
      
 99 
     | 
    
         
            +
                      :on_class_variable_write_node_enter,
         
     | 
| 
       88 
100 
     | 
    
         
             
                    )
         
     | 
| 
       89 
101 
     | 
    
         
             
                  end
         
     | 
| 
       90 
102 
     | 
    
         | 
| 
         @@ -102,7 +114,7 @@ module RubyLsp 
     | 
|
| 
       102 
114 
     | 
    
         
             
                  def on_constant_read_node_enter(node)
         
     | 
| 
       103 
115 
     | 
    
         
             
                    return if @sorbet_level != RubyDocument::SorbetLevel::Ignore
         
     | 
| 
       104 
116 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
                    name = constant_name(node)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    name = RubyIndexer::Index.constant_name(node)
         
     | 
| 
       106 
118 
     | 
    
         
             
                    return if name.nil?
         
     | 
| 
       107 
119 
     | 
    
         | 
| 
       108 
120 
     | 
    
         
             
                    generate_hover(name, node.location)
         
     | 
| 
         @@ -119,7 +131,7 @@ module RubyLsp 
     | 
|
| 
       119 
131 
     | 
    
         
             
                  def on_constant_path_node_enter(node)
         
     | 
| 
       120 
132 
     | 
    
         
             
                    return if @sorbet_level != RubyDocument::SorbetLevel::Ignore
         
     | 
| 
       121 
133 
     | 
    
         | 
| 
       122 
     | 
    
         
            -
                    name = constant_name(node)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    name = RubyIndexer::Index.constant_name(node)
         
     | 
| 
       123 
135 
     | 
    
         
             
                    return if name.nil?
         
     | 
| 
       124 
136 
     | 
    
         | 
| 
       125 
137 
     | 
    
         
             
                    generate_hover(name, node.location)
         
     | 
| 
         @@ -215,6 +227,36 @@ module RubyLsp 
     | 
|
| 
       215 
227 
     | 
    
         
             
                    handle_keyword_documentation(node.keyword)
         
     | 
| 
       216 
228 
     | 
    
         
             
                  end
         
     | 
| 
       217 
229 
     | 
    
         | 
| 
      
 230 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableAndWriteNode).void }
         
     | 
| 
      
 231 
     | 
    
         
            +
                  def on_class_variable_and_write_node_enter(node)
         
     | 
| 
      
 232 
     | 
    
         
            +
                    handle_class_variable_hover(node.name.to_s)
         
     | 
| 
      
 233 
     | 
    
         
            +
                  end
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableOperatorWriteNode).void }
         
     | 
| 
      
 236 
     | 
    
         
            +
                  def on_class_variable_operator_write_node_enter(node)
         
     | 
| 
      
 237 
     | 
    
         
            +
                    handle_class_variable_hover(node.name.to_s)
         
     | 
| 
      
 238 
     | 
    
         
            +
                  end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableOrWriteNode).void }
         
     | 
| 
      
 241 
     | 
    
         
            +
                  def on_class_variable_or_write_node_enter(node)
         
     | 
| 
      
 242 
     | 
    
         
            +
                    handle_class_variable_hover(node.name.to_s)
         
     | 
| 
      
 243 
     | 
    
         
            +
                  end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableTargetNode).void }
         
     | 
| 
      
 246 
     | 
    
         
            +
                  def on_class_variable_target_node_enter(node)
         
     | 
| 
      
 247 
     | 
    
         
            +
                    handle_class_variable_hover(node.name.to_s)
         
     | 
| 
      
 248 
     | 
    
         
            +
                  end
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableReadNode).void }
         
     | 
| 
      
 251 
     | 
    
         
            +
                  def on_class_variable_read_node_enter(node)
         
     | 
| 
      
 252 
     | 
    
         
            +
                    handle_class_variable_hover(node.name.to_s)
         
     | 
| 
      
 253 
     | 
    
         
            +
                  end
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                  sig { params(node: Prism::ClassVariableWriteNode).void }
         
     | 
| 
      
 256 
     | 
    
         
            +
                  def on_class_variable_write_node_enter(node)
         
     | 
| 
      
 257 
     | 
    
         
            +
                    handle_class_variable_hover(node.name.to_s)
         
     | 
| 
      
 258 
     | 
    
         
            +
                  end
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
       218 
260 
     | 
    
         
             
                  private
         
     | 
| 
       219 
261 
     | 
    
         | 
| 
       220 
262 
     | 
    
         
             
                  sig { params(node: T.any(Prism::InterpolatedStringNode, Prism::StringNode)).void }
         
     | 
| 
         @@ -317,6 +359,21 @@ module RubyLsp 
     | 
|
| 
       317 
359 
     | 
    
         
             
                    end
         
     | 
| 
       318 
360 
     | 
    
         
             
                  end
         
     | 
| 
       319 
361 
     | 
    
         | 
| 
      
 362 
     | 
    
         
            +
                  sig { params(name: String).void }
         
     | 
| 
      
 363 
     | 
    
         
            +
                  def handle_class_variable_hover(name)
         
     | 
| 
      
 364 
     | 
    
         
            +
                    type = @type_inferrer.infer_receiver_type(@node_context)
         
     | 
| 
      
 365 
     | 
    
         
            +
                    return unless type
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
                    entries = @index.resolve_class_variable(name, type.name)
         
     | 
| 
      
 368 
     | 
    
         
            +
                    return unless entries
         
     | 
| 
      
 369 
     | 
    
         
            +
             
     | 
| 
      
 370 
     | 
    
         
            +
                    categorized_markdown_from_index_entries(name, entries).each do |category, content|
         
     | 
| 
      
 371 
     | 
    
         
            +
                      @response_builder.push(content, category: category)
         
     | 
| 
      
 372 
     | 
    
         
            +
                    end
         
     | 
| 
      
 373 
     | 
    
         
            +
                  rescue RubyIndexer::Index::NonExistingNamespaceError
         
     | 
| 
      
 374 
     | 
    
         
            +
                    # If by any chance we haven't indexed the owner, then there's no way to find the right declaration
         
     | 
| 
      
 375 
     | 
    
         
            +
                  end
         
     | 
| 
      
 376 
     | 
    
         
            +
             
     | 
| 
       320 
377 
     | 
    
         
             
                  sig { params(name: String, location: Prism::Location).void }
         
     | 
| 
       321 
378 
     | 
    
         
             
                  def generate_hover(name, location)
         
     | 
| 
       322 
379 
     | 
    
         
             
                    entries = @index.resolve(name, @node_context.nesting)
         
     | 
    
        data/lib/ruby_lsp/load_sorbet.rb
    CHANGED
    
    | 
         @@ -6,11 +6,11 @@ require "sorbet-runtime" 
     | 
|
| 
       6 
6 
     | 
    
         
             
            begin
         
     | 
| 
       7 
7 
     | 
    
         
             
              T::Configuration.default_checked_level = :never
         
     | 
| 
       8 
8 
     | 
    
         
             
              # Suppresses call validation errors
         
     | 
| 
       9 
     | 
    
         
            -
              T::Configuration.call_validation_error_handler = ->(*) {}
         
     | 
| 
      
 9 
     | 
    
         
            +
              T::Configuration.call_validation_error_handler = ->(*arg) {}
         
     | 
| 
       10 
10 
     | 
    
         
             
              # Suppresses errors caused by T.cast, T.let, T.must, etc.
         
     | 
| 
       11 
     | 
    
         
            -
              T::Configuration.inline_type_error_handler = ->(*) {}
         
     | 
| 
      
 11 
     | 
    
         
            +
              T::Configuration.inline_type_error_handler = ->(*arg) {}
         
     | 
| 
       12 
12 
     | 
    
         
             
              # Suppresses errors caused by incorrect parameter ordering
         
     | 
| 
       13 
     | 
    
         
            -
              T::Configuration.sig_validation_error_handler = ->(*) {}
         
     | 
| 
      
 13 
     | 
    
         
            +
              T::Configuration.sig_validation_error_handler = ->(*arg) {}
         
     | 
| 
       14 
14 
     | 
    
         
             
            rescue
         
     | 
| 
       15 
15 
     | 
    
         
             
              # Need this rescue so that if another gem has
         
     | 
| 
       16 
16 
     | 
    
         
             
              # already set the checked level by the time we
         
     | 
| 
         @@ -8,8 +8,8 @@ module RubyLsp 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                ParseResultType = type_member { { fixed: T::Array[RBS::AST::Declarations::Base] } }
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                sig { params(source: String, version: Integer, uri: URI::Generic,  
     | 
| 
       12 
     | 
    
         
            -
                def initialize(source:, version:, uri:,  
     | 
| 
      
 11 
     | 
    
         
            +
                sig { params(source: String, version: Integer, uri: URI::Generic, global_state: GlobalState).void }
         
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(source:, version:, uri:, global_state:)
         
     | 
| 
       13 
13 
     | 
    
         
             
                  @syntax_error = T.let(false, T::Boolean)
         
     | 
| 
       14 
14 
     | 
    
         
             
                  super
         
     | 
| 
       15 
15 
     | 
    
         
             
                end
         
     | 
| 
         @@ -42,6 +42,10 @@ module RubyLsp 
     | 
|
| 
       42 
42 
     | 
    
         
             
                      refactor_method
         
     | 
| 
       43 
43 
     | 
    
         
             
                    when CodeActions::TOGGLE_BLOCK_STYLE_TITLE
         
     | 
| 
       44 
44 
     | 
    
         
             
                      switch_block_style
         
     | 
| 
      
 45 
     | 
    
         
            +
                    when CodeActions::CREATE_ATTRIBUTE_READER,
         
     | 
| 
      
 46 
     | 
    
         
            +
                         CodeActions::CREATE_ATTRIBUTE_WRITER,
         
     | 
| 
      
 47 
     | 
    
         
            +
                         CodeActions::CREATE_ATTRIBUTE_ACCESSOR
         
     | 
| 
      
 48 
     | 
    
         
            +
                      create_attribute_accessor
         
     | 
| 
       45 
49 
     | 
    
         
             
                    else
         
     | 
| 
       46 
50 
     | 
    
         
             
                      Error::UnknownCodeAction
         
     | 
| 
       47 
51 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -92,9 +96,7 @@ module RubyLsp 
     | 
|
| 
       92 
96 
     | 
    
         
             
                    source_range = @code_action.dig(:data, :range)
         
     | 
| 
       93 
97 
     | 
    
         
             
                    return Error::EmptySelection if source_range[:start] == source_range[:end]
         
     | 
| 
       94 
98 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
                     
     | 
| 
       96 
     | 
    
         
            -
                    start_index = scanner.find_char_position(source_range[:start])
         
     | 
| 
       97 
     | 
    
         
            -
                    end_index = scanner.find_char_position(source_range[:end])
         
     | 
| 
      
 99 
     | 
    
         
            +
                    start_index, end_index = @document.find_index_by_position(source_range[:start], source_range[:end])
         
     | 
| 
       98 
100 
     | 
    
         
             
                    extracted_source = T.must(@document.source[start_index...end_index])
         
     | 
| 
       99 
101 
     | 
    
         | 
| 
       100 
102 
     | 
    
         
             
                    # Find the closest statements node, so that we place the refactor in a valid position
         
     | 
| 
         @@ -192,9 +194,7 @@ module RubyLsp 
     | 
|
| 
       192 
194 
     | 
    
         
             
                    source_range = @code_action.dig(:data, :range)
         
     | 
| 
       193 
195 
     | 
    
         
             
                    return Error::EmptySelection if source_range[:start] == source_range[:end]
         
     | 
| 
       194 
196 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
                     
     | 
| 
       196 
     | 
    
         
            -
                    start_index = scanner.find_char_position(source_range[:start])
         
     | 
| 
       197 
     | 
    
         
            -
                    end_index = scanner.find_char_position(source_range[:end])
         
     | 
| 
      
 197 
     | 
    
         
            +
                    start_index, end_index = @document.find_index_by_position(source_range[:start], source_range[:end])
         
     | 
| 
       198 
198 
     | 
    
         
             
                    extracted_source = T.must(@document.source[start_index...end_index])
         
     | 
| 
       199 
199 
     | 
    
         | 
| 
       200 
200 
     | 
    
         
             
                    # Find the closest method declaration node, so that we place the refactor in a valid position
         
     | 
| 
         @@ -329,6 +329,90 @@ module RubyLsp 
     | 
|
| 
       329 
329 
     | 
    
         | 
| 
       330 
330 
     | 
    
         
             
                    indentation ? body_content.gsub(";", "\n") : "#{body_content.gsub("\n", ";")} "
         
     | 
| 
       331 
331 
     | 
    
         
             
                  end
         
     | 
| 
      
 332 
     | 
    
         
            +
             
     | 
| 
      
 333 
     | 
    
         
            +
                  sig { returns(T.any(Interface::CodeAction, Error)) }
         
     | 
| 
      
 334 
     | 
    
         
            +
                  def create_attribute_accessor
         
     | 
| 
      
 335 
     | 
    
         
            +
                    source_range = @code_action.dig(:data, :range)
         
     | 
| 
      
 336 
     | 
    
         
            +
             
     | 
| 
      
 337 
     | 
    
         
            +
                    node = if source_range[:start] != source_range[:end]
         
     | 
| 
      
 338 
     | 
    
         
            +
                      @document.locate_first_within_range(
         
     | 
| 
      
 339 
     | 
    
         
            +
                        @code_action.dig(:data, :range),
         
     | 
| 
      
 340 
     | 
    
         
            +
                        node_types: CodeActions::INSTANCE_VARIABLE_NODES,
         
     | 
| 
      
 341 
     | 
    
         
            +
                      )
         
     | 
| 
      
 342 
     | 
    
         
            +
                    end
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
                    if node.nil?
         
     | 
| 
      
 345 
     | 
    
         
            +
                      node_context = @document.locate_node(
         
     | 
| 
      
 346 
     | 
    
         
            +
                        source_range[:start],
         
     | 
| 
      
 347 
     | 
    
         
            +
                        node_types: CodeActions::INSTANCE_VARIABLE_NODES,
         
     | 
| 
      
 348 
     | 
    
         
            +
                      )
         
     | 
| 
      
 349 
     | 
    
         
            +
                      node = node_context.node
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
                      return Error::EmptySelection unless CodeActions::INSTANCE_VARIABLE_NODES.include?(node.class)
         
     | 
| 
      
 352 
     | 
    
         
            +
                    end
         
     | 
| 
      
 353 
     | 
    
         
            +
             
     | 
| 
      
 354 
     | 
    
         
            +
                    node = T.cast(
         
     | 
| 
      
 355 
     | 
    
         
            +
                      node,
         
     | 
| 
      
 356 
     | 
    
         
            +
                      T.any(
         
     | 
| 
      
 357 
     | 
    
         
            +
                        Prism::InstanceVariableAndWriteNode,
         
     | 
| 
      
 358 
     | 
    
         
            +
                        Prism::InstanceVariableOperatorWriteNode,
         
     | 
| 
      
 359 
     | 
    
         
            +
                        Prism::InstanceVariableOrWriteNode,
         
     | 
| 
      
 360 
     | 
    
         
            +
                        Prism::InstanceVariableReadNode,
         
     | 
| 
      
 361 
     | 
    
         
            +
                        Prism::InstanceVariableTargetNode,
         
     | 
| 
      
 362 
     | 
    
         
            +
                        Prism::InstanceVariableWriteNode,
         
     | 
| 
      
 363 
     | 
    
         
            +
                      ),
         
     | 
| 
      
 364 
     | 
    
         
            +
                    )
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
                    node_context = @document.locate_node(
         
     | 
| 
      
 367 
     | 
    
         
            +
                      {
         
     | 
| 
      
 368 
     | 
    
         
            +
                        line: node.location.start_line,
         
     | 
| 
      
 369 
     | 
    
         
            +
                        character: node.location.start_character_column,
         
     | 
| 
      
 370 
     | 
    
         
            +
                      },
         
     | 
| 
      
 371 
     | 
    
         
            +
                      node_types: [
         
     | 
| 
      
 372 
     | 
    
         
            +
                        Prism::ClassNode,
         
     | 
| 
      
 373 
     | 
    
         
            +
                        Prism::ModuleNode,
         
     | 
| 
      
 374 
     | 
    
         
            +
                        Prism::SingletonClassNode,
         
     | 
| 
      
 375 
     | 
    
         
            +
                      ],
         
     | 
| 
      
 376 
     | 
    
         
            +
                    )
         
     | 
| 
      
 377 
     | 
    
         
            +
                    closest_node = node_context.node
         
     | 
| 
      
 378 
     | 
    
         
            +
                    return Error::InvalidTargetRange if closest_node.nil?
         
     | 
| 
      
 379 
     | 
    
         
            +
             
     | 
| 
      
 380 
     | 
    
         
            +
                    attribute_name = node.name[1..]
         
     | 
| 
      
 381 
     | 
    
         
            +
                    indentation = " " * (closest_node.location.start_column + 2)
         
     | 
| 
      
 382 
     | 
    
         
            +
                    attribute_accessor_source = T.must(
         
     | 
| 
      
 383 
     | 
    
         
            +
                      case @code_action[:title]
         
     | 
| 
      
 384 
     | 
    
         
            +
                      when CodeActions::CREATE_ATTRIBUTE_READER
         
     | 
| 
      
 385 
     | 
    
         
            +
                        "#{indentation}attr_reader :#{attribute_name}\n\n"
         
     | 
| 
      
 386 
     | 
    
         
            +
                      when CodeActions::CREATE_ATTRIBUTE_WRITER
         
     | 
| 
      
 387 
     | 
    
         
            +
                        "#{indentation}attr_writer :#{attribute_name}\n\n"
         
     | 
| 
      
 388 
     | 
    
         
            +
                      when CodeActions::CREATE_ATTRIBUTE_ACCESSOR
         
     | 
| 
      
 389 
     | 
    
         
            +
                        "#{indentation}attr_accessor :#{attribute_name}\n\n"
         
     | 
| 
      
 390 
     | 
    
         
            +
                      end,
         
     | 
| 
      
 391 
     | 
    
         
            +
                    )
         
     | 
| 
      
 392 
     | 
    
         
            +
             
     | 
| 
      
 393 
     | 
    
         
            +
                    target_start_line = closest_node.location.start_line
         
     | 
| 
      
 394 
     | 
    
         
            +
                    target_range = {
         
     | 
| 
      
 395 
     | 
    
         
            +
                      start: { line: target_start_line, character: 0 },
         
     | 
| 
      
 396 
     | 
    
         
            +
                      end: { line: target_start_line, character: 0 },
         
     | 
| 
      
 397 
     | 
    
         
            +
                    }
         
     | 
| 
      
 398 
     | 
    
         
            +
             
     | 
| 
      
 399 
     | 
    
         
            +
                    Interface::CodeAction.new(
         
     | 
| 
      
 400 
     | 
    
         
            +
                      title: @code_action[:title],
         
     | 
| 
      
 401 
     | 
    
         
            +
                      edit: Interface::WorkspaceEdit.new(
         
     | 
| 
      
 402 
     | 
    
         
            +
                        document_changes: [
         
     | 
| 
      
 403 
     | 
    
         
            +
                          Interface::TextDocumentEdit.new(
         
     | 
| 
      
 404 
     | 
    
         
            +
                            text_document: Interface::OptionalVersionedTextDocumentIdentifier.new(
         
     | 
| 
      
 405 
     | 
    
         
            +
                              uri: @code_action.dig(:data, :uri),
         
     | 
| 
      
 406 
     | 
    
         
            +
                              version: nil,
         
     | 
| 
      
 407 
     | 
    
         
            +
                            ),
         
     | 
| 
      
 408 
     | 
    
         
            +
                            edits: [
         
     | 
| 
      
 409 
     | 
    
         
            +
                              create_text_edit(target_range, attribute_accessor_source),
         
     | 
| 
      
 410 
     | 
    
         
            +
                            ],
         
     | 
| 
      
 411 
     | 
    
         
            +
                          ),
         
     | 
| 
      
 412 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 413 
     | 
    
         
            +
                      ),
         
     | 
| 
      
 414 
     | 
    
         
            +
                    )
         
     | 
| 
      
 415 
     | 
    
         
            +
                  end
         
     | 
| 
       332 
416 
     | 
    
         
             
                end
         
     | 
| 
       333 
417 
     | 
    
         
             
              end
         
     | 
| 
       334 
418 
     | 
    
         
             
            end
         
     |