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
 
| 
         @@ -16,8 +16,8 @@ module RubyIndexer 
     | 
|
| 
       16 
16 
     | 
    
         
             
                sig { returns(String) }
         
     | 
| 
       17 
17 
     | 
    
         
             
                attr_reader :name
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                sig { returns( 
     | 
| 
       20 
     | 
    
         
            -
                attr_reader : 
     | 
| 
      
 19 
     | 
    
         
            +
                sig { returns(URI::Generic) }
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_reader :uri
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                sig { returns(RubyIndexer::Location) }
         
     | 
| 
       23 
23 
     | 
    
         
             
                attr_reader :location
         
     | 
| 
         @@ -30,14 +30,14 @@ module RubyIndexer 
     | 
|
| 
       30 
30 
     | 
    
         
             
                sig do
         
     | 
| 
       31 
31 
     | 
    
         
             
                  params(
         
     | 
| 
       32 
32 
     | 
    
         
             
                    name: String,
         
     | 
| 
       33 
     | 
    
         
            -
                     
     | 
| 
      
 33 
     | 
    
         
            +
                    uri: URI::Generic,
         
     | 
| 
       34 
34 
     | 
    
         
             
                    location: Location,
         
     | 
| 
       35 
35 
     | 
    
         
             
                    comments: T.nilable(String),
         
     | 
| 
       36 
36 
     | 
    
         
             
                  ).void
         
     | 
| 
       37 
37 
     | 
    
         
             
                end
         
     | 
| 
       38 
     | 
    
         
            -
                def initialize(name,  
     | 
| 
      
 38 
     | 
    
         
            +
                def initialize(name, uri, location, comments)
         
     | 
| 
       39 
39 
     | 
    
         
             
                  @name = name
         
     | 
| 
       40 
     | 
    
         
            -
                  @ 
     | 
| 
      
 40 
     | 
    
         
            +
                  @uri = uri
         
     | 
| 
       41 
41 
     | 
    
         
             
                  @comments = comments
         
     | 
| 
       42 
42 
     | 
    
         
             
                  @visibility = T.let(Visibility::PUBLIC, Visibility)
         
     | 
| 
       43 
43 
     | 
    
         
             
                  @location = location
         
     | 
| 
         @@ -60,14 +60,24 @@ module RubyIndexer 
     | 
|
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
                sig { returns(String) }
         
     | 
| 
       62 
62 
     | 
    
         
             
                def file_name
         
     | 
| 
       63 
     | 
    
         
            -
                   
     | 
| 
      
 63 
     | 
    
         
            +
                  if @uri.scheme == "untitled"
         
     | 
| 
      
 64 
     | 
    
         
            +
                    T.must(@uri.opaque)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  else
         
     | 
| 
      
 66 
     | 
    
         
            +
                    File.basename(T.must(file_path))
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                sig { returns(T.nilable(String)) }
         
     | 
| 
      
 71 
     | 
    
         
            +
                def file_path
         
     | 
| 
      
 72 
     | 
    
         
            +
                  @uri.full_path
         
     | 
| 
       64 
73 
     | 
    
         
             
                end
         
     | 
| 
       65 
74 
     | 
    
         | 
| 
       66 
75 
     | 
    
         
             
                sig { returns(String) }
         
     | 
| 
       67 
76 
     | 
    
         
             
                def comments
         
     | 
| 
       68 
77 
     | 
    
         
             
                  @comments ||= begin
         
     | 
| 
       69 
78 
     | 
    
         
             
                    # Parse only the comments based on the file path, which is much faster than parsing the entire file
         
     | 
| 
       70 
     | 
    
         
            -
                     
     | 
| 
      
 79 
     | 
    
         
            +
                    path = file_path
         
     | 
| 
      
 80 
     | 
    
         
            +
                    parsed_comments = path ? Prism.parse_file_comments(path) : []
         
     | 
| 
       71 
81 
     | 
    
         | 
| 
       72 
82 
     | 
    
         
             
                    # Group comments based on whether they belong to a single block of comments
         
     | 
| 
       73 
83 
     | 
    
         
             
                    grouped = parsed_comments.slice_when do |left, right|
         
     | 
| 
         @@ -137,18 +147,18 @@ module RubyIndexer 
     | 
|
| 
       137 
147 
     | 
    
         
             
                  sig do
         
     | 
| 
       138 
148 
     | 
    
         
             
                    params(
         
     | 
| 
       139 
149 
     | 
    
         
             
                      nesting: T::Array[String],
         
     | 
| 
       140 
     | 
    
         
            -
                       
     | 
| 
      
 150 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       141 
151 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       142 
152 
     | 
    
         
             
                      name_location: Location,
         
     | 
| 
       143 
153 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
       144 
154 
     | 
    
         
             
                    ).void
         
     | 
| 
       145 
155 
     | 
    
         
             
                  end
         
     | 
| 
       146 
     | 
    
         
            -
                  def initialize(nesting,  
     | 
| 
      
 156 
     | 
    
         
            +
                  def initialize(nesting, uri, location, name_location, comments)
         
     | 
| 
       147 
157 
     | 
    
         
             
                    @name = T.let(nesting.join("::"), String)
         
     | 
| 
       148 
158 
     | 
    
         
             
                    # The original nesting where this namespace was discovered
         
     | 
| 
       149 
159 
     | 
    
         
             
                    @nesting = nesting
         
     | 
| 
       150 
160 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
                    super(@name,  
     | 
| 
      
 161 
     | 
    
         
            +
                    super(@name, uri, location, comments)
         
     | 
| 
       152 
162 
     | 
    
         | 
| 
       153 
163 
     | 
    
         
             
                    @name_location = name_location
         
     | 
| 
       154 
164 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -186,15 +196,15 @@ module RubyIndexer 
     | 
|
| 
       186 
196 
     | 
    
         
             
                  sig do
         
     | 
| 
       187 
197 
     | 
    
         
             
                    params(
         
     | 
| 
       188 
198 
     | 
    
         
             
                      nesting: T::Array[String],
         
     | 
| 
       189 
     | 
    
         
            -
                       
     | 
| 
      
 199 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       190 
200 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       191 
201 
     | 
    
         
             
                      name_location:  Location,
         
     | 
| 
       192 
202 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
       193 
203 
     | 
    
         
             
                      parent_class: T.nilable(String),
         
     | 
| 
       194 
204 
     | 
    
         
             
                    ).void
         
     | 
| 
       195 
205 
     | 
    
         
             
                  end
         
     | 
| 
       196 
     | 
    
         
            -
                  def initialize(nesting,  
     | 
| 
       197 
     | 
    
         
            -
                    super(nesting,  
     | 
| 
      
 206 
     | 
    
         
            +
                  def initialize(nesting, uri, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
         
     | 
| 
      
 207 
     | 
    
         
            +
                    super(nesting, uri, location, name_location, comments)
         
     | 
| 
       198 
208 
     | 
    
         
             
                    @parent_class = parent_class
         
     | 
| 
       199 
209 
     | 
    
         
             
                  end
         
     | 
| 
       200 
210 
     | 
    
         | 
| 
         @@ -332,15 +342,15 @@ module RubyIndexer 
     | 
|
| 
       332 
342 
     | 
    
         
             
                  sig do
         
     | 
| 
       333 
343 
     | 
    
         
             
                    params(
         
     | 
| 
       334 
344 
     | 
    
         
             
                      name: String,
         
     | 
| 
       335 
     | 
    
         
            -
                       
     | 
| 
      
 345 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       336 
346 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       337 
347 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
       338 
348 
     | 
    
         
             
                      visibility: Visibility,
         
     | 
| 
       339 
349 
     | 
    
         
             
                      owner: T.nilable(Entry::Namespace),
         
     | 
| 
       340 
350 
     | 
    
         
             
                    ).void
         
     | 
| 
       341 
351 
     | 
    
         
             
                  end
         
     | 
| 
       342 
     | 
    
         
            -
                  def initialize(name,  
     | 
| 
       343 
     | 
    
         
            -
                    super(name,  
     | 
| 
      
 352 
     | 
    
         
            +
                  def initialize(name, uri, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists
         
     | 
| 
      
 353 
     | 
    
         
            +
                    super(name, uri, location, comments)
         
     | 
| 
       344 
354 
     | 
    
         
             
                    @visibility = visibility
         
     | 
| 
       345 
355 
     | 
    
         
             
                    @owner = owner
         
     | 
| 
       346 
356 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -399,7 +409,7 @@ module RubyIndexer 
     | 
|
| 
       399 
409 
     | 
    
         
             
                  sig do
         
     | 
| 
       400 
410 
     | 
    
         
             
                    params(
         
     | 
| 
       401 
411 
     | 
    
         
             
                      name: String,
         
     | 
| 
       402 
     | 
    
         
            -
                       
     | 
| 
      
 412 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       403 
413 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       404 
414 
     | 
    
         
             
                      name_location: Location,
         
     | 
| 
       405 
415 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
         @@ -408,8 +418,8 @@ module RubyIndexer 
     | 
|
| 
       408 
418 
     | 
    
         
             
                      owner: T.nilable(Entry::Namespace),
         
     | 
| 
       409 
419 
     | 
    
         
             
                    ).void
         
     | 
| 
       410 
420 
     | 
    
         
             
                  end
         
     | 
| 
       411 
     | 
    
         
            -
                  def initialize(name,  
     | 
| 
       412 
     | 
    
         
            -
                    super(name,  
     | 
| 
      
 421 
     | 
    
         
            +
                  def initialize(name, uri, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
         
     | 
| 
      
 422 
     | 
    
         
            +
                    super(name, uri, location, comments, visibility, owner)
         
     | 
| 
       413 
423 
     | 
    
         
             
                    @signatures = signatures
         
     | 
| 
       414 
424 
     | 
    
         
             
                    @name_location = name_location
         
     | 
| 
       415 
425 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -439,13 +449,13 @@ module RubyIndexer 
     | 
|
| 
       439 
449 
     | 
    
         
             
                      target: String,
         
     | 
| 
       440 
450 
     | 
    
         
             
                      nesting: T::Array[String],
         
     | 
| 
       441 
451 
     | 
    
         
             
                      name: String,
         
     | 
| 
       442 
     | 
    
         
            -
                       
     | 
| 
      
 452 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       443 
453 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       444 
454 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
       445 
455 
     | 
    
         
             
                    ).void
         
     | 
| 
       446 
456 
     | 
    
         
             
                  end
         
     | 
| 
       447 
     | 
    
         
            -
                  def initialize(target, nesting, name,  
     | 
| 
       448 
     | 
    
         
            -
                    super(name,  
     | 
| 
      
 457 
     | 
    
         
            +
                  def initialize(target, nesting, name, uri, location, comments) # rubocop:disable Metrics/ParameterLists
         
     | 
| 
      
 458 
     | 
    
         
            +
                    super(name, uri, location, comments)
         
     | 
| 
       449 
459 
     | 
    
         | 
| 
       450 
460 
     | 
    
         
             
                    @target = target
         
     | 
| 
       451 
461 
     | 
    
         
             
                    @nesting = nesting
         
     | 
| 
         @@ -463,7 +473,7 @@ module RubyIndexer 
     | 
|
| 
       463 
473 
     | 
    
         
             
                  def initialize(target, unresolved_alias)
         
     | 
| 
       464 
474 
     | 
    
         
             
                    super(
         
     | 
| 
       465 
475 
     | 
    
         
             
                      unresolved_alias.name,
         
     | 
| 
       466 
     | 
    
         
            -
                      unresolved_alias. 
     | 
| 
      
 476 
     | 
    
         
            +
                      unresolved_alias.uri,
         
     | 
| 
       467 
477 
     | 
    
         
             
                      unresolved_alias.location,
         
     | 
| 
       468 
478 
     | 
    
         
             
                      unresolved_alias.comments,
         
     | 
| 
       469 
479 
     | 
    
         
             
                    )
         
     | 
| 
         @@ -476,6 +486,26 @@ module RubyIndexer 
     | 
|
| 
       476 
486 
     | 
    
         
             
                # Represents a global variable e.g.: $DEBUG
         
     | 
| 
       477 
487 
     | 
    
         
             
                class GlobalVariable < Entry; end
         
     | 
| 
       478 
488 
     | 
    
         | 
| 
      
 489 
     | 
    
         
            +
                # Represents a class variable e.g.: @@a = 1
         
     | 
| 
      
 490 
     | 
    
         
            +
                class ClassVariable < Entry
         
     | 
| 
      
 491 
     | 
    
         
            +
                  sig { returns(T.nilable(Entry::Namespace)) }
         
     | 
| 
      
 492 
     | 
    
         
            +
                  attr_reader :owner
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
      
 494 
     | 
    
         
            +
                  sig do
         
     | 
| 
      
 495 
     | 
    
         
            +
                    params(
         
     | 
| 
      
 496 
     | 
    
         
            +
                      name: String,
         
     | 
| 
      
 497 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
      
 498 
     | 
    
         
            +
                      location: Location,
         
     | 
| 
      
 499 
     | 
    
         
            +
                      comments: T.nilable(String),
         
     | 
| 
      
 500 
     | 
    
         
            +
                      owner: T.nilable(Entry::Namespace),
         
     | 
| 
      
 501 
     | 
    
         
            +
                    ).void
         
     | 
| 
      
 502 
     | 
    
         
            +
                  end
         
     | 
| 
      
 503 
     | 
    
         
            +
                  def initialize(name, uri, location, comments, owner)
         
     | 
| 
      
 504 
     | 
    
         
            +
                    super(name, uri, location, comments)
         
     | 
| 
      
 505 
     | 
    
         
            +
                    @owner = owner
         
     | 
| 
      
 506 
     | 
    
         
            +
                  end
         
     | 
| 
      
 507 
     | 
    
         
            +
                end
         
     | 
| 
      
 508 
     | 
    
         
            +
             
     | 
| 
       479 
509 
     | 
    
         
             
                # Represents an instance variable e.g.: @a = 1
         
     | 
| 
       480 
510 
     | 
    
         
             
                class InstanceVariable < Entry
         
     | 
| 
       481 
511 
     | 
    
         
             
                  sig { returns(T.nilable(Entry::Namespace)) }
         
     | 
| 
         @@ -484,14 +514,14 @@ module RubyIndexer 
     | 
|
| 
       484 
514 
     | 
    
         
             
                  sig do
         
     | 
| 
       485 
515 
     | 
    
         
             
                    params(
         
     | 
| 
       486 
516 
     | 
    
         
             
                      name: String,
         
     | 
| 
       487 
     | 
    
         
            -
                       
     | 
| 
      
 517 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       488 
518 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       489 
519 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
       490 
520 
     | 
    
         
             
                      owner: T.nilable(Entry::Namespace),
         
     | 
| 
       491 
521 
     | 
    
         
             
                    ).void
         
     | 
| 
       492 
522 
     | 
    
         
             
                  end
         
     | 
| 
       493 
     | 
    
         
            -
                  def initialize(name,  
     | 
| 
       494 
     | 
    
         
            -
                    super(name,  
     | 
| 
      
 523 
     | 
    
         
            +
                  def initialize(name, uri, location, comments, owner)
         
     | 
| 
      
 524 
     | 
    
         
            +
                    super(name, uri, location, comments)
         
     | 
| 
       495 
525 
     | 
    
         
             
                    @owner = owner
         
     | 
| 
       496 
526 
     | 
    
         
             
                  end
         
     | 
| 
       497 
527 
     | 
    
         
             
                end
         
     | 
| 
         @@ -513,13 +543,13 @@ module RubyIndexer 
     | 
|
| 
       513 
543 
     | 
    
         
             
                      new_name: String,
         
     | 
| 
       514 
544 
     | 
    
         
             
                      old_name: String,
         
     | 
| 
       515 
545 
     | 
    
         
             
                      owner: T.nilable(Entry::Namespace),
         
     | 
| 
       516 
     | 
    
         
            -
                       
     | 
| 
      
 546 
     | 
    
         
            +
                      uri: URI::Generic,
         
     | 
| 
       517 
547 
     | 
    
         
             
                      location: Location,
         
     | 
| 
       518 
548 
     | 
    
         
             
                      comments: T.nilable(String),
         
     | 
| 
       519 
549 
     | 
    
         
             
                    ).void
         
     | 
| 
       520 
550 
     | 
    
         
             
                  end
         
     | 
| 
       521 
     | 
    
         
            -
                  def initialize(new_name, old_name, owner,  
     | 
| 
       522 
     | 
    
         
            -
                    super(new_name,  
     | 
| 
      
 551 
     | 
    
         
            +
                  def initialize(new_name, old_name, owner, uri, location, comments) # rubocop:disable Metrics/ParameterLists
         
     | 
| 
      
 552 
     | 
    
         
            +
                    super(new_name, uri, location, comments)
         
     | 
| 
       523 
553 
     | 
    
         | 
| 
       524 
554 
     | 
    
         
             
                    @new_name = new_name
         
     | 
| 
       525 
555 
     | 
    
         
             
                    @old_name = old_name
         
     | 
| 
         @@ -547,7 +577,7 @@ module RubyIndexer 
     | 
|
| 
       547 
577 
     | 
    
         | 
| 
       548 
578 
     | 
    
         
             
                    super(
         
     | 
| 
       549 
579 
     | 
    
         
             
                      unresolved_alias.new_name,
         
     | 
| 
       550 
     | 
    
         
            -
                      unresolved_alias. 
     | 
| 
      
 580 
     | 
    
         
            +
                      unresolved_alias.uri,
         
     | 
| 
       551 
581 
     | 
    
         
             
                      unresolved_alias.location,
         
     | 
| 
       552 
582 
     | 
    
         
             
                      full_comments,
         
     | 
| 
       553 
583 
     | 
    
         
             
                    )
         
     | 
| 
         @@ -15,6 +15,45 @@ module RubyIndexer 
     | 
|
| 
       15 
15 
     | 
    
         
             
                sig { returns(Configuration) }
         
     | 
| 
       16 
16 
     | 
    
         
             
                attr_reader :configuration
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 19 
     | 
    
         
            +
                  extend T::Sig
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Returns the real nesting of a constant name taking into account top level
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # references that may be included anywhere in the name or nesting where that
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # constant was found
         
     | 
| 
      
 24 
     | 
    
         
            +
                  sig { params(stack: T::Array[String], name: String).returns(T::Array[String]) }
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def actual_nesting(stack, name)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    nesting = stack + [name]
         
     | 
| 
      
 27 
     | 
    
         
            +
                    corrected_nesting = []
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    nesting.reverse_each do |name|
         
     | 
| 
      
 30 
     | 
    
         
            +
                      corrected_nesting.prepend(name.delete_prefix("::"))
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      break if name.start_with?("::")
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    corrected_nesting
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  # Returns the unresolved name for a constant reference including all parts of a constant path, or `nil` if the
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # constant contains dynamic or incomplete parts
         
     | 
| 
      
 40 
     | 
    
         
            +
                  sig do
         
     | 
| 
      
 41 
     | 
    
         
            +
                    params(
         
     | 
| 
      
 42 
     | 
    
         
            +
                      node: T.any(
         
     | 
| 
      
 43 
     | 
    
         
            +
                        Prism::ConstantPathNode,
         
     | 
| 
      
 44 
     | 
    
         
            +
                        Prism::ConstantReadNode,
         
     | 
| 
      
 45 
     | 
    
         
            +
                        Prism::ConstantPathTargetNode,
         
     | 
| 
      
 46 
     | 
    
         
            +
                      ),
         
     | 
| 
      
 47 
     | 
    
         
            +
                    ).returns(T.nilable(String))
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def constant_name(node)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    node.full_name
         
     | 
| 
      
 51 
     | 
    
         
            +
                  rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError,
         
     | 
| 
      
 52 
     | 
    
         
            +
                         Prism::ConstantPathNode::MissingNodesInConstantPathError
         
     | 
| 
      
 53 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       18 
57 
     | 
    
         
             
                sig { void }
         
     | 
| 
       19 
58 
     | 
    
         
             
                def initialize
         
     | 
| 
       20 
59 
     | 
    
         
             
                  # Holds all entries in the index using the following format:
         
     | 
| 
         @@ -29,13 +68,14 @@ module RubyIndexer 
     | 
|
| 
       29 
68 
     | 
    
         | 
| 
       30 
69 
     | 
    
         
             
                  # Holds references to where entries where discovered so that we can easily delete them
         
     | 
| 
       31 
70 
     | 
    
         
             
                  # {
         
     | 
| 
       32 
     | 
    
         
            -
                  #  " 
     | 
| 
       33 
     | 
    
         
            -
                  #  " 
     | 
| 
      
 71 
     | 
    
         
            +
                  #  "file:///my/project/foo.rb" => [#<Entry::Class>, #<Entry::Class>],
         
     | 
| 
      
 72 
     | 
    
         
            +
                  #  "file:///my/project/bar.rb" => [#<Entry::Class>],
         
     | 
| 
      
 73 
     | 
    
         
            +
                  #  "untitled:Untitled-1" => [#<Entry::Class>],
         
     | 
| 
       34 
74 
     | 
    
         
             
                  # }
         
     | 
| 
       35 
     | 
    
         
            -
                  @ 
     | 
| 
      
 75 
     | 
    
         
            +
                  @uris_to_entries = T.let({}, T::Hash[String, T::Array[Entry]])
         
     | 
| 
       36 
76 
     | 
    
         | 
| 
       37 
77 
     | 
    
         
             
                  # Holds all require paths for every indexed item so that we can provide autocomplete for requires
         
     | 
| 
       38 
     | 
    
         
            -
                  @require_paths_tree = T.let(PrefixTree[ 
     | 
| 
      
 78 
     | 
    
         
            +
                  @require_paths_tree = T.let(PrefixTree[URI::Generic].new, PrefixTree[URI::Generic])
         
     | 
| 
       39 
79 
     | 
    
         | 
| 
       40 
80 
     | 
    
         
             
                  # Holds the linearized ancestors list for every namespace
         
     | 
| 
       41 
81 
     | 
    
         
             
                  @ancestors = T.let({}, T::Hash[String, T::Array[String]])
         
     | 
| 
         @@ -47,6 +87,8 @@ module RubyIndexer 
     | 
|
| 
       47 
87 
     | 
    
         
             
                  )
         
     | 
| 
       48 
88 
     | 
    
         | 
| 
       49 
89 
     | 
    
         
             
                  @configuration = T.let(RubyIndexer::Configuration.new, Configuration)
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  @initial_indexing_completed = T.let(false, T::Boolean)
         
     | 
| 
       50 
92 
     | 
    
         
             
                end
         
     | 
| 
       51 
93 
     | 
    
         | 
| 
       52 
94 
     | 
    
         
             
                # Register an included `hook` that will be executed when `module_name` is included into any namespace
         
     | 
| 
         @@ -55,11 +97,12 @@ module RubyIndexer 
     | 
|
| 
       55 
97 
     | 
    
         
             
                  (@included_hooks[module_name] ||= []) << hook
         
     | 
| 
       56 
98 
     | 
    
         
             
                end
         
     | 
| 
       57 
99 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
                sig { params( 
     | 
| 
       59 
     | 
    
         
            -
                def delete( 
     | 
| 
      
 100 
     | 
    
         
            +
                sig { params(uri: URI::Generic, skip_require_paths_tree: T::Boolean).void }
         
     | 
| 
      
 101 
     | 
    
         
            +
                def delete(uri, skip_require_paths_tree: false)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  key = uri.to_s
         
     | 
| 
       60 
103 
     | 
    
         
             
                  # For each constant discovered in `path`, delete the associated entry from the index. If there are no entries
         
     | 
| 
       61 
104 
     | 
    
         
             
                  # left, delete the constant from the index.
         
     | 
| 
       62 
     | 
    
         
            -
                  @ 
     | 
| 
      
 105 
     | 
    
         
            +
                  @uris_to_entries[key]&.each do |entry|
         
     | 
| 
       63 
106 
     | 
    
         
             
                    name = entry.name
         
     | 
| 
       64 
107 
     | 
    
         
             
                    entries = @entries[name]
         
     | 
| 
       65 
108 
     | 
    
         
             
                    next unless entries
         
     | 
| 
         @@ -77,9 +120,10 @@ module RubyIndexer 
     | 
|
| 
       77 
120 
     | 
    
         
             
                    end
         
     | 
| 
       78 
121 
     | 
    
         
             
                  end
         
     | 
| 
       79 
122 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
                  @ 
     | 
| 
      
 123 
     | 
    
         
            +
                  @uris_to_entries.delete(key)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  return if skip_require_paths_tree
         
     | 
| 
       81 
125 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                  require_path =  
     | 
| 
      
 126 
     | 
    
         
            +
                  require_path = uri.require_path
         
     | 
| 
       83 
127 
     | 
    
         
             
                  @require_paths_tree.delete(require_path) if require_path
         
     | 
| 
       84 
128 
     | 
    
         
             
                end
         
     | 
| 
       85 
129 
     | 
    
         | 
| 
         @@ -88,7 +132,7 @@ module RubyIndexer 
     | 
|
| 
       88 
132 
     | 
    
         
             
                  name = entry.name
         
     | 
| 
       89 
133 
     | 
    
         | 
| 
       90 
134 
     | 
    
         
             
                  (@entries[name] ||= []) << entry
         
     | 
| 
       91 
     | 
    
         
            -
                  (@ 
     | 
| 
      
 135 
     | 
    
         
            +
                  (@uris_to_entries[entry.uri.to_s] ||= []) << entry
         
     | 
| 
       92 
136 
     | 
    
         
             
                  @entries_tree.insert(name, T.must(@entries[name])) unless skip_prefix_tree
         
     | 
| 
       93 
137 
     | 
    
         
             
                end
         
     | 
| 
       94 
138 
     | 
    
         | 
| 
         @@ -97,7 +141,7 @@ module RubyIndexer 
     | 
|
| 
       97 
141 
     | 
    
         
             
                  @entries[fully_qualified_name.delete_prefix("::")]
         
     | 
| 
       98 
142 
     | 
    
         
             
                end
         
     | 
| 
       99 
143 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
                sig { params(query: String).returns(T::Array[ 
     | 
| 
      
 144 
     | 
    
         
            +
                sig { params(query: String).returns(T::Array[URI::Generic]) }
         
     | 
| 
       101 
145 
     | 
    
         
             
                def search_require_paths(query)
         
     | 
| 
       102 
146 
     | 
    
         
             
                  @require_paths_tree.search(query)
         
     | 
| 
       103 
147 
     | 
    
         
             
                end
         
     | 
| 
         @@ -115,8 +159,16 @@ module RubyIndexer 
     | 
|
| 
       115 
159 
     | 
    
         
             
                  )]))
         
     | 
| 
       116 
160 
     | 
    
         
             
                end
         
     | 
| 
       117 
161 
     | 
    
         
             
                def first_unqualified_const(name)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  # Look for an exact match first
         
     | 
| 
       118 
163 
     | 
    
         
             
                  _name, entries = @entries.find do |const_name, _entries|
         
     | 
| 
       119 
     | 
    
         
            -
                    const_name.end_with?(name)
         
     | 
| 
      
 164 
     | 
    
         
            +
                    const_name == name || const_name.end_with?("::#{name}")
         
     | 
| 
      
 165 
     | 
    
         
            +
                  end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  # If an exact match is not found, then try to find a constant that ends with the name
         
     | 
| 
      
 168 
     | 
    
         
            +
                  unless entries
         
     | 
| 
      
 169 
     | 
    
         
            +
                    _name, entries = @entries.find do |const_name, _entries|
         
     | 
| 
      
 170 
     | 
    
         
            +
                      const_name.end_with?(name)
         
     | 
| 
      
 171 
     | 
    
         
            +
                    end
         
     | 
| 
       120 
172 
     | 
    
         
             
                  end
         
     | 
| 
       121 
173 
     | 
    
         | 
| 
       122 
174 
     | 
    
         
             
                  T.cast(
         
     | 
| 
         @@ -342,75 +394,70 @@ module RubyIndexer 
     | 
|
| 
       342 
394 
     | 
    
         
             
                  nil
         
     | 
| 
       343 
395 
     | 
    
         
             
                end
         
     | 
| 
       344 
396 
     | 
    
         | 
| 
       345 
     | 
    
         
            -
                # Index all files for the given  
     | 
| 
       346 
     | 
    
         
            -
                #  
     | 
| 
       347 
     | 
    
         
            -
                #  
     | 
| 
      
 397 
     | 
    
         
            +
                # Index all files for the given URIs, which defaults to what is configured. A block can be used to track and control
         
     | 
| 
      
 398 
     | 
    
         
            +
                # indexing progress. That block is invoked with the current progress percentage and should return `true` to continue
         
     | 
| 
      
 399 
     | 
    
         
            +
                # indexing or `false` to stop indexing.
         
     | 
| 
       348 
400 
     | 
    
         
             
                sig do
         
     | 
| 
       349 
401 
     | 
    
         
             
                  params(
         
     | 
| 
       350 
     | 
    
         
            -
                     
     | 
| 
      
 402 
     | 
    
         
            +
                    uris: T::Array[URI::Generic],
         
     | 
| 
       351 
403 
     | 
    
         
             
                    block: T.nilable(T.proc.params(progress: Integer).returns(T::Boolean)),
         
     | 
| 
       352 
404 
     | 
    
         
             
                  ).void
         
     | 
| 
       353 
405 
     | 
    
         
             
                end
         
     | 
| 
       354 
     | 
    
         
            -
                def index_all( 
     | 
| 
      
 406 
     | 
    
         
            +
                def index_all(uris: @configuration.indexable_uris, &block)
         
     | 
| 
       355 
407 
     | 
    
         
             
                  # When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the
         
     | 
| 
       356 
408 
     | 
    
         
             
                  # existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this
         
     | 
| 
       357 
409 
     | 
    
         
             
                  # behavior and can take appropriate action.
         
     | 
| 
       358 
     | 
    
         
            -
                   
     | 
| 
       359 
     | 
    
         
            -
                  if @entries.any?
         
     | 
| 
      
 410 
     | 
    
         
            +
                  if @initial_indexing_completed
         
     | 
| 
       360 
411 
     | 
    
         
             
                    raise IndexNotEmptyError,
         
     | 
| 
       361 
412 
     | 
    
         
             
                      "The index is not empty. To prevent invalid entries, `index_all` can only be called once."
         
     | 
| 
       362 
413 
     | 
    
         
             
                  end
         
     | 
| 
       363 
414 
     | 
    
         | 
| 
      
 415 
     | 
    
         
            +
                  @initial_indexing_completed = true
         
     | 
| 
      
 416 
     | 
    
         
            +
             
     | 
| 
       364 
417 
     | 
    
         
             
                  RBSIndexer.new(self).index_ruby_core
         
     | 
| 
       365 
418 
     | 
    
         
             
                  # Calculate how many paths are worth 1% of progress
         
     | 
| 
       366 
     | 
    
         
            -
                  progress_step = ( 
     | 
| 
      
 419 
     | 
    
         
            +
                  progress_step = (uris.length / 100.0).ceil
         
     | 
| 
       367 
420 
     | 
    
         | 
| 
       368 
     | 
    
         
            -
                   
     | 
| 
      
 421 
     | 
    
         
            +
                  uris.each_with_index do |uri, index|
         
     | 
| 
       369 
422 
     | 
    
         
             
                    if block && index % progress_step == 0
         
     | 
| 
       370 
423 
     | 
    
         
             
                      progress = (index / progress_step) + 1
         
     | 
| 
       371 
424 
     | 
    
         
             
                      break unless block.call(progress)
         
     | 
| 
       372 
425 
     | 
    
         
             
                    end
         
     | 
| 
       373 
426 
     | 
    
         | 
| 
       374 
     | 
    
         
            -
                     
     | 
| 
      
 427 
     | 
    
         
            +
                    index_file(uri, collect_comments: false)
         
     | 
| 
       375 
428 
     | 
    
         
             
                  end
         
     | 
| 
       376 
429 
     | 
    
         
             
                end
         
     | 
| 
       377 
430 
     | 
    
         | 
| 
       378 
     | 
    
         
            -
                sig { params( 
     | 
| 
       379 
     | 
    
         
            -
                def index_single( 
     | 
| 
       380 
     | 
    
         
            -
                  content = source || File.read(indexable_path.full_path)
         
     | 
| 
      
 431 
     | 
    
         
            +
                sig { params(uri: URI::Generic, source: String, collect_comments: T::Boolean).void }
         
     | 
| 
      
 432 
     | 
    
         
            +
                def index_single(uri, source, collect_comments: true)
         
     | 
| 
       381 
433 
     | 
    
         
             
                  dispatcher = Prism::Dispatcher.new
         
     | 
| 
       382 
434 
     | 
    
         | 
| 
       383 
     | 
    
         
            -
                  result = Prism.parse( 
     | 
| 
       384 
     | 
    
         
            -
                  listener = DeclarationListener.new(
         
     | 
| 
       385 
     | 
    
         
            -
                    self,
         
     | 
| 
       386 
     | 
    
         
            -
                    dispatcher,
         
     | 
| 
       387 
     | 
    
         
            -
                    result,
         
     | 
| 
       388 
     | 
    
         
            -
                    indexable_path.full_path,
         
     | 
| 
       389 
     | 
    
         
            -
                    collect_comments: collect_comments,
         
     | 
| 
       390 
     | 
    
         
            -
                  )
         
     | 
| 
      
 435 
     | 
    
         
            +
                  result = Prism.parse(source)
         
     | 
| 
      
 436 
     | 
    
         
            +
                  listener = DeclarationListener.new(self, dispatcher, result, uri, collect_comments: collect_comments)
         
     | 
| 
       391 
437 
     | 
    
         
             
                  dispatcher.dispatch(result.value)
         
     | 
| 
       392 
438 
     | 
    
         | 
| 
       393 
     | 
    
         
            -
                   
     | 
| 
       394 
     | 
    
         
            -
             
     | 
| 
       395 
     | 
    
         
            -
                  require_path = indexable_path.require_path
         
     | 
| 
       396 
     | 
    
         
            -
                  @require_paths_tree.insert(require_path, indexable_path) if require_path
         
     | 
| 
      
 439 
     | 
    
         
            +
                  require_path = uri.require_path
         
     | 
| 
      
 440 
     | 
    
         
            +
                  @require_paths_tree.insert(require_path, uri) if require_path
         
     | 
| 
       397 
441 
     | 
    
         | 
| 
       398 
     | 
    
         
            -
                   
     | 
| 
       399 
     | 
    
         
            -
             
     | 
| 
       400 
     | 
    
         
            -
                      $stderr.puts error
         
     | 
| 
       401 
     | 
    
         
            -
                    end
         
     | 
| 
       402 
     | 
    
         
            -
                  end
         
     | 
| 
       403 
     | 
    
         
            -
                rescue Errno::EISDIR, Errno::ENOENT
         
     | 
| 
       404 
     | 
    
         
            -
                  # If `path` is a directory, just ignore it and continue indexing. If the file doesn't exist, then we also ignore
         
     | 
| 
       405 
     | 
    
         
            -
                  # it
         
     | 
| 
      
 442 
     | 
    
         
            +
                  indexing_errors = listener.indexing_errors.uniq
         
     | 
| 
      
 443 
     | 
    
         
            +
                  indexing_errors.each { |error| $stderr.puts(error) } if indexing_errors.any?
         
     | 
| 
       406 
444 
     | 
    
         
             
                rescue SystemStackError => e
         
     | 
| 
       407 
445 
     | 
    
         
             
                  if e.backtrace&.first&.include?("prism")
         
     | 
| 
       408 
     | 
    
         
            -
                    $stderr.puts "Prism error indexing #{ 
     | 
| 
      
 446 
     | 
    
         
            +
                    $stderr.puts "Prism error indexing #{uri}: #{e.message}"
         
     | 
| 
       409 
447 
     | 
    
         
             
                  else
         
     | 
| 
       410 
448 
     | 
    
         
             
                    raise
         
     | 
| 
       411 
449 
     | 
    
         
             
                  end
         
     | 
| 
       412 
450 
     | 
    
         
             
                end
         
     | 
| 
       413 
451 
     | 
    
         | 
| 
      
 452 
     | 
    
         
            +
                # Indexes a File URI by reading the contents from disk
         
     | 
| 
      
 453 
     | 
    
         
            +
                sig { params(uri: URI::Generic, collect_comments: T::Boolean).void }
         
     | 
| 
      
 454 
     | 
    
         
            +
                def index_file(uri, collect_comments: true)
         
     | 
| 
      
 455 
     | 
    
         
            +
                  index_single(uri, File.read(T.must(uri.full_path)), collect_comments: collect_comments)
         
     | 
| 
      
 456 
     | 
    
         
            +
                rescue Errno::EISDIR, Errno::ENOENT
         
     | 
| 
      
 457 
     | 
    
         
            +
                  # If `path` is a directory, just ignore it and continue indexing. If the file doesn't exist, then we also ignore
         
     | 
| 
      
 458 
     | 
    
         
            +
                  # it
         
     | 
| 
      
 459 
     | 
    
         
            +
                end
         
     | 
| 
      
 460 
     | 
    
         
            +
             
     | 
| 
       414 
461 
     | 
    
         
             
                # Follows aliases in a namespace. The algorithm keeps checking if the name is an alias and then recursively follows
         
     | 
| 
       415 
462 
     | 
    
         
             
                # it. The idea is that we test the name in parts starting from the complete name to the first namespace. For
         
     | 
| 
       416 
463 
     | 
    
         
             
                # `Foo::Bar::Baz`, we would test:
         
     | 
| 
         @@ -588,29 +635,81 @@ module RubyIndexer 
     | 
|
| 
       588 
635 
     | 
    
         
             
                  entries.select { |e| ancestors.include?(e.owner&.name) }
         
     | 
| 
       589 
636 
     | 
    
         
             
                end
         
     | 
| 
       590 
637 
     | 
    
         | 
| 
      
 638 
     | 
    
         
            +
                sig { params(variable_name: String, owner_name: String).returns(T.nilable(T::Array[Entry::ClassVariable])) }
         
     | 
| 
      
 639 
     | 
    
         
            +
                def resolve_class_variable(variable_name, owner_name)
         
     | 
| 
      
 640 
     | 
    
         
            +
                  entries = self[variable_name]&.grep(Entry::ClassVariable)
         
     | 
| 
      
 641 
     | 
    
         
            +
                  return unless entries&.any?
         
     | 
| 
      
 642 
     | 
    
         
            +
             
     | 
| 
      
 643 
     | 
    
         
            +
                  ancestors = linearized_attached_ancestors(owner_name)
         
     | 
| 
      
 644 
     | 
    
         
            +
                  return if ancestors.empty?
         
     | 
| 
      
 645 
     | 
    
         
            +
             
     | 
| 
      
 646 
     | 
    
         
            +
                  entries.select { |e| ancestors.include?(e.owner&.name) }
         
     | 
| 
      
 647 
     | 
    
         
            +
                end
         
     | 
| 
      
 648 
     | 
    
         
            +
             
     | 
| 
       591 
649 
     | 
    
         
             
                # Returns a list of possible candidates for completion of instance variables for a given owner name. The name must
         
     | 
| 
       592 
650 
     | 
    
         
             
                # include the `@` prefix
         
     | 
| 
       593 
     | 
    
         
            -
                sig  
     | 
| 
      
 651 
     | 
    
         
            +
                sig do
         
     | 
| 
      
 652 
     | 
    
         
            +
                  params(name: String, owner_name: String).returns(T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
         
     | 
| 
      
 653 
     | 
    
         
            +
                end
         
     | 
| 
       594 
654 
     | 
    
         
             
                def instance_variable_completion_candidates(name, owner_name)
         
     | 
| 
       595 
     | 
    
         
            -
                  entries = T.cast(prefix_search(name).flatten, T::Array[Entry::InstanceVariable])
         
     | 
| 
      
 655 
     | 
    
         
            +
                  entries = T.cast(prefix_search(name).flatten, T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
         
     | 
| 
      
 656 
     | 
    
         
            +
                  # Avoid wasting time linearizing ancestors if we didn't find anything
         
     | 
| 
      
 657 
     | 
    
         
            +
                  return entries if entries.empty?
         
     | 
| 
      
 658 
     | 
    
         
            +
             
     | 
| 
       596 
659 
     | 
    
         
             
                  ancestors = linearized_ancestors_of(owner_name)
         
     | 
| 
       597 
660 
     | 
    
         | 
| 
       598 
     | 
    
         
            -
                   
     | 
| 
      
 661 
     | 
    
         
            +
                  instance_variables, class_variables = entries.partition { |e| e.is_a?(Entry::InstanceVariable) }
         
     | 
| 
      
 662 
     | 
    
         
            +
                  variables = instance_variables.select { |e| ancestors.any?(e.owner&.name) }
         
     | 
| 
      
 663 
     | 
    
         
            +
             
     | 
| 
      
 664 
     | 
    
         
            +
                  # Class variables are only owned by the attached class in our representation. If the owner is in a singleton
         
     | 
| 
      
 665 
     | 
    
         
            +
                  # context, we have to search for ancestors of the attached class
         
     | 
| 
      
 666 
     | 
    
         
            +
                  if class_variables.any?
         
     | 
| 
      
 667 
     | 
    
         
            +
                    name_parts = owner_name.split("::")
         
     | 
| 
      
 668 
     | 
    
         
            +
             
     | 
| 
      
 669 
     | 
    
         
            +
                    if name_parts.last&.start_with?("<Class:")
         
     | 
| 
      
 670 
     | 
    
         
            +
                      attached_name = T.must(name_parts[0..-2]).join("::")
         
     | 
| 
      
 671 
     | 
    
         
            +
                      attached_ancestors = linearized_ancestors_of(attached_name)
         
     | 
| 
      
 672 
     | 
    
         
            +
                      variables.concat(class_variables.select { |e| attached_ancestors.any?(e.owner&.name) })
         
     | 
| 
      
 673 
     | 
    
         
            +
                    else
         
     | 
| 
      
 674 
     | 
    
         
            +
                      variables.concat(class_variables.select { |e| ancestors.any?(e.owner&.name) })
         
     | 
| 
      
 675 
     | 
    
         
            +
                    end
         
     | 
| 
      
 676 
     | 
    
         
            +
                  end
         
     | 
| 
      
 677 
     | 
    
         
            +
             
     | 
| 
       599 
678 
     | 
    
         
             
                  variables.uniq!(&:name)
         
     | 
| 
       600 
679 
     | 
    
         
             
                  variables
         
     | 
| 
       601 
680 
     | 
    
         
             
                end
         
     | 
| 
       602 
681 
     | 
    
         | 
| 
       603 
     | 
    
         
            -
                 
     | 
| 
       604 
     | 
    
         
            -
                 
     | 
| 
       605 
     | 
    
         
            -
             
     | 
| 
       606 
     | 
    
         
            -
             
     | 
| 
       607 
     | 
    
         
            -
                   
     | 
| 
      
 682 
     | 
    
         
            +
                sig { params(name: String, owner_name: String).returns(T::Array[Entry::ClassVariable]) }
         
     | 
| 
      
 683 
     | 
    
         
            +
                def class_variable_completion_candidates(name, owner_name)
         
     | 
| 
      
 684 
     | 
    
         
            +
                  entries = T.cast(prefix_search(name).flatten, T::Array[Entry::ClassVariable])
         
     | 
| 
      
 685 
     | 
    
         
            +
                  # Avoid wasting time linearizing ancestors if we didn't find anything
         
     | 
| 
      
 686 
     | 
    
         
            +
                  return entries if entries.empty?
         
     | 
| 
       608 
687 
     | 
    
         | 
| 
       609 
     | 
    
         
            -
                   
     | 
| 
       610 
     | 
    
         
            -
                   
     | 
| 
      
 688 
     | 
    
         
            +
                  ancestors = linearized_attached_ancestors(owner_name)
         
     | 
| 
      
 689 
     | 
    
         
            +
                  variables = entries.select { |e| ancestors.any?(e.owner&.name) }
         
     | 
| 
      
 690 
     | 
    
         
            +
                  variables.uniq!(&:name)
         
     | 
| 
      
 691 
     | 
    
         
            +
                  variables
         
     | 
| 
      
 692 
     | 
    
         
            +
                end
         
     | 
| 
       611 
693 
     | 
    
         | 
| 
       612 
     | 
    
         
            -
             
     | 
| 
      
 694 
     | 
    
         
            +
                # Synchronizes a change made to the given URI. This method will ensure that new declarations are indexed, removed
         
     | 
| 
      
 695 
     | 
    
         
            +
                # declarations removed and that the ancestor linearization cache is cleared if necessary. If a block is passed, the
         
     | 
| 
      
 696 
     | 
    
         
            +
                # consumer of this API has to handle deleting and inserting/updating entries in the index instead of passing the
         
     | 
| 
      
 697 
     | 
    
         
            +
                # document's source (used to handle unsaved changes to files)
         
     | 
| 
      
 698 
     | 
    
         
            +
                sig do
         
     | 
| 
      
 699 
     | 
    
         
            +
                  params(uri: URI::Generic, source: T.nilable(String), block: T.nilable(T.proc.params(index: Index).void)).void
         
     | 
| 
      
 700 
     | 
    
         
            +
                end
         
     | 
| 
      
 701 
     | 
    
         
            +
                def handle_change(uri, source = nil, &block)
         
     | 
| 
      
 702 
     | 
    
         
            +
                  key = uri.to_s
         
     | 
| 
      
 703 
     | 
    
         
            +
                  original_entries = @uris_to_entries[key]
         
     | 
| 
       613 
704 
     | 
    
         | 
| 
      
 705 
     | 
    
         
            +
                  if block
         
     | 
| 
      
 706 
     | 
    
         
            +
                    block.call(self)
         
     | 
| 
      
 707 
     | 
    
         
            +
                  else
         
     | 
| 
      
 708 
     | 
    
         
            +
                    delete(uri)
         
     | 
| 
      
 709 
     | 
    
         
            +
                    index_single(uri, T.must(source))
         
     | 
| 
      
 710 
     | 
    
         
            +
                  end
         
     | 
| 
      
 711 
     | 
    
         
            +
             
     | 
| 
      
 712 
     | 
    
         
            +
                  updated_entries = @uris_to_entries[key]
         
     | 
| 
       614 
713 
     | 
    
         
             
                  return unless original_entries && updated_entries
         
     | 
| 
       615 
714 
     | 
    
         | 
| 
       616 
715 
     | 
    
         
             
                  # A change in one ancestor may impact several different others, which could be including that ancestor through
         
     | 
| 
         @@ -661,7 +760,7 @@ module RubyIndexer 
     | 
|
| 
       661 
760 
     | 
    
         | 
| 
       662 
761 
     | 
    
         
             
                    singleton = Entry::SingletonClass.new(
         
     | 
| 
       663 
762 
     | 
    
         
             
                      [full_singleton_name],
         
     | 
| 
       664 
     | 
    
         
            -
                      attached_ancestor. 
     | 
| 
      
 763 
     | 
    
         
            +
                      attached_ancestor.uri,
         
     | 
| 
       665 
764 
     | 
    
         
             
                      attached_ancestor.location,
         
     | 
| 
       666 
765 
     | 
    
         
             
                      attached_ancestor.name_location,
         
     | 
| 
       667 
766 
     | 
    
         
             
                      nil,
         
     | 
| 
         @@ -675,12 +774,12 @@ module RubyIndexer 
     | 
|
| 
       675 
774 
     | 
    
         | 
| 
       676 
775 
     | 
    
         
             
                sig do
         
     | 
| 
       677 
776 
     | 
    
         
             
                  type_parameters(:T).params(
         
     | 
| 
       678 
     | 
    
         
            -
                     
     | 
| 
      
 777 
     | 
    
         
            +
                    uri: String,
         
     | 
| 
       679 
778 
     | 
    
         
             
                    type: T.nilable(T::Class[T.all(T.type_parameter(:T), Entry)]),
         
     | 
| 
       680 
779 
     | 
    
         
             
                  ).returns(T.nilable(T.any(T::Array[Entry], T::Array[T.type_parameter(:T)])))
         
     | 
| 
       681 
780 
     | 
    
         
             
                end
         
     | 
| 
       682 
     | 
    
         
            -
                def entries_for( 
     | 
| 
       683 
     | 
    
         
            -
                  entries = @ 
     | 
| 
      
 781 
     | 
    
         
            +
                def entries_for(uri, type = nil)
         
     | 
| 
      
 782 
     | 
    
         
            +
                  entries = @uris_to_entries[uri.to_s]
         
     | 
| 
       684 
783 
     | 
    
         
             
                  return entries unless type
         
     | 
| 
       685 
784 
     | 
    
         | 
| 
       686 
785 
     | 
    
         
             
                  entries&.grep(type)
         
     | 
| 
         @@ -688,6 +787,20 @@ module RubyIndexer 
     | 
|
| 
       688 
787 
     | 
    
         | 
| 
       689 
788 
     | 
    
         
             
                private
         
     | 
| 
       690 
789 
     | 
    
         | 
| 
      
 790 
     | 
    
         
            +
                # Always returns the linearized ancestors for the attached class, regardless of whether `name` refers to a singleton
         
     | 
| 
      
 791 
     | 
    
         
            +
                # or attached namespace
         
     | 
| 
      
 792 
     | 
    
         
            +
                sig { params(name: String).returns(T::Array[String]) }
         
     | 
| 
      
 793 
     | 
    
         
            +
                def linearized_attached_ancestors(name)
         
     | 
| 
      
 794 
     | 
    
         
            +
                  name_parts = name.split("::")
         
     | 
| 
      
 795 
     | 
    
         
            +
             
     | 
| 
      
 796 
     | 
    
         
            +
                  if name_parts.last&.start_with?("<Class:")
         
     | 
| 
      
 797 
     | 
    
         
            +
                    attached_name = T.must(name_parts[0..-2]).join("::")
         
     | 
| 
      
 798 
     | 
    
         
            +
                    linearized_ancestors_of(attached_name)
         
     | 
| 
      
 799 
     | 
    
         
            +
                  else
         
     | 
| 
      
 800 
     | 
    
         
            +
                    linearized_ancestors_of(name)
         
     | 
| 
      
 801 
     | 
    
         
            +
                  end
         
     | 
| 
      
 802 
     | 
    
         
            +
                end
         
     | 
| 
      
 803 
     | 
    
         
            +
             
     | 
| 
       691 
804 
     | 
    
         
             
                # Runs the registered included hooks
         
     | 
| 
       692 
805 
     | 
    
         
             
                sig { params(fully_qualified_name: String, nesting: T::Array[String]).void }
         
     | 
| 
       693 
806 
     | 
    
         
             
                def run_included_hooks(fully_qualified_name, nesting)
         
     | 
| 
         @@ -44,5 +44,17 @@ module RubyIndexer 
     | 
|
| 
       44 
44 
     | 
    
         
             
                  @start_column = start_column
         
     | 
| 
       45 
45 
     | 
    
         
             
                  @end_column = end_column
         
     | 
| 
       46 
46 
     | 
    
         
             
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                sig do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  params(
         
     | 
| 
      
 50 
     | 
    
         
            +
                    other: T.any(Location, Prism::Location),
         
     | 
| 
      
 51 
     | 
    
         
            +
                  ).returns(T::Boolean)
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  start_line == other.start_line &&
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end_line == other.end_line &&
         
     | 
| 
      
 56 
     | 
    
         
            +
                    start_column == other.start_column &&
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end_column == other.end_column
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
       47 
59 
     | 
    
         
             
              end
         
     | 
| 
       48 
60 
     | 
    
         
             
            end
         
     |