ruby-lsp 0.19.1 → 0.20.1
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/VERSION +1 -1
- data/exe/ruby-lsp +7 -1
- data/lib/core_ext/uri.rb +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +63 -12
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +85 -36
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +5 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +39 -98
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +12 -19
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +22 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -7
- data/lib/ruby_indexer/test/enhancements_test.rb +5 -7
- data/lib/ruby_indexer/test/global_variable_test.rb +49 -0
- data/lib/ruby_indexer/test/index_test.rb +89 -0
- data/lib/ruby_lsp/erb_document.rb +15 -2
- data/lib/ruby_lsp/listeners/definition.rb +20 -0
- data/lib/ruby_lsp/listeners/folding_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/code_action_resolve.rb +8 -2
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +2 -1
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/range_formatting.rb +4 -2
- data/lib/ruby_lsp/requests/references.rb +3 -1
- data/lib/ruby_lsp/requests/rename.rb +3 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +1 -1
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +6 -6
- data/lib/ruby_lsp/response_builders/document_symbol.rb +2 -2
- data/lib/ruby_lsp/response_builders/hover.rb +2 -2
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +14 -8
- data/lib/ruby_lsp/response_builders/signature_help.rb +2 -2
- data/lib/ruby_lsp/ruby_document.rb +33 -12
- data/lib/ruby_lsp/setup_bundler.rb +30 -8
- data/lib/ruby_lsp/type_inferrer.rb +1 -1
- metadata +6 -5
| @@ -31,30 +31,16 @@ module RubyIndexer | |
| 31 31 | 
             
                  params(
         | 
| 32 32 | 
             
                    name: String,
         | 
| 33 33 | 
             
                    file_path: String,
         | 
| 34 | 
            -
                    location:  | 
| 34 | 
            +
                    location: Location,
         | 
| 35 35 | 
             
                    comments: T.nilable(String),
         | 
| 36 | 
            -
                    encoding: Encoding,
         | 
| 37 36 | 
             
                  ).void
         | 
| 38 37 | 
             
                end
         | 
| 39 | 
            -
                def initialize(name, file_path, location, comments | 
| 38 | 
            +
                def initialize(name, file_path, location, comments)
         | 
| 40 39 | 
             
                  @name = name
         | 
| 41 40 | 
             
                  @file_path = file_path
         | 
| 42 41 | 
             
                  @comments = comments
         | 
| 43 42 | 
             
                  @visibility = T.let(Visibility::PUBLIC, Visibility)
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                  @location = T.let(
         | 
| 46 | 
            -
                    if location.is_a?(Prism::Location)
         | 
| 47 | 
            -
                      Location.new(
         | 
| 48 | 
            -
                        location.start_line,
         | 
| 49 | 
            -
                        location.end_line,
         | 
| 50 | 
            -
                        location.start_code_units_column(encoding),
         | 
| 51 | 
            -
                        location.end_code_units_column(encoding),
         | 
| 52 | 
            -
                      )
         | 
| 53 | 
            -
                    else
         | 
| 54 | 
            -
                      location
         | 
| 55 | 
            -
                    end,
         | 
| 56 | 
            -
                    RubyIndexer::Location,
         | 
| 57 | 
            -
                  )
         | 
| 43 | 
            +
                  @location = location
         | 
| 58 44 | 
             
                end
         | 
| 59 45 |  | 
| 60 46 | 
             
                sig { returns(T::Boolean) }
         | 
| @@ -152,32 +138,19 @@ module RubyIndexer | |
| 152 138 | 
             
                    params(
         | 
| 153 139 | 
             
                      nesting: T::Array[String],
         | 
| 154 140 | 
             
                      file_path: String,
         | 
| 155 | 
            -
                      location:  | 
| 156 | 
            -
                      name_location:  | 
| 141 | 
            +
                      location: Location,
         | 
| 142 | 
            +
                      name_location: Location,
         | 
| 157 143 | 
             
                      comments: T.nilable(String),
         | 
| 158 | 
            -
                      encoding: Encoding,
         | 
| 159 144 | 
             
                    ).void
         | 
| 160 145 | 
             
                  end
         | 
| 161 | 
            -
                  def initialize(nesting, file_path, location, name_location, comments | 
| 146 | 
            +
                  def initialize(nesting, file_path, location, name_location, comments)
         | 
| 162 147 | 
             
                    @name = T.let(nesting.join("::"), String)
         | 
| 163 148 | 
             
                    # The original nesting where this namespace was discovered
         | 
| 164 149 | 
             
                    @nesting = nesting
         | 
| 165 150 |  | 
| 166 | 
            -
                    super(@name, file_path, location, comments | 
| 167 | 
            -
             | 
| 168 | 
            -
                    @name_location =  | 
| 169 | 
            -
                      if name_location.is_a?(Prism::Location)
         | 
| 170 | 
            -
                        Location.new(
         | 
| 171 | 
            -
                          name_location.start_line,
         | 
| 172 | 
            -
                          name_location.end_line,
         | 
| 173 | 
            -
                          name_location.start_code_units_column(encoding),
         | 
| 174 | 
            -
                          name_location.end_code_units_column(encoding),
         | 
| 175 | 
            -
                        )
         | 
| 176 | 
            -
                      else
         | 
| 177 | 
            -
                        name_location
         | 
| 178 | 
            -
                      end,
         | 
| 179 | 
            -
                      RubyIndexer::Location,
         | 
| 180 | 
            -
                    )
         | 
| 151 | 
            +
                    super(@name, file_path, location, comments)
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                    @name_location = name_location
         | 
| 181 154 | 
             
                  end
         | 
| 182 155 |  | 
| 183 156 | 
             
                  sig { returns(T::Array[String]) }
         | 
| @@ -214,15 +187,14 @@ module RubyIndexer | |
| 214 187 | 
             
                    params(
         | 
| 215 188 | 
             
                      nesting: T::Array[String],
         | 
| 216 189 | 
             
                      file_path: String,
         | 
| 217 | 
            -
                      location:  | 
| 218 | 
            -
                      name_location: | 
| 190 | 
            +
                      location: Location,
         | 
| 191 | 
            +
                      name_location:  Location,
         | 
| 219 192 | 
             
                      comments: T.nilable(String),
         | 
| 220 | 
            -
                      encoding: Encoding,
         | 
| 221 193 | 
             
                      parent_class: T.nilable(String),
         | 
| 222 194 | 
             
                    ).void
         | 
| 223 195 | 
             
                  end
         | 
| 224 | 
            -
                  def initialize(nesting, file_path, location, name_location, comments,  | 
| 225 | 
            -
                    super(nesting, file_path, location, name_location, comments | 
| 196 | 
            +
                  def initialize(nesting, file_path, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
         | 
| 197 | 
            +
                    super(nesting, file_path, location, name_location, comments)
         | 
| 226 198 | 
             
                    @parent_class = parent_class
         | 
| 227 199 | 
             
                  end
         | 
| 228 200 |  | 
| @@ -237,26 +209,14 @@ module RubyIndexer | |
| 237 209 |  | 
| 238 210 | 
             
                  sig do
         | 
| 239 211 | 
             
                    params(
         | 
| 240 | 
            -
                      location:  | 
| 241 | 
            -
                      name_location:  | 
| 212 | 
            +
                      location: Location,
         | 
| 213 | 
            +
                      name_location: Location,
         | 
| 242 214 | 
             
                      comments: T.nilable(String),
         | 
| 243 | 
            -
                      encoding: Encoding,
         | 
| 244 215 | 
             
                    ).void
         | 
| 245 216 | 
             
                  end
         | 
| 246 | 
            -
                  def update_singleton_information(location, name_location, comments | 
| 247 | 
            -
                     | 
| 248 | 
            -
                    @ | 
| 249 | 
            -
                      location.start_line,
         | 
| 250 | 
            -
                      location.end_line,
         | 
| 251 | 
            -
                      location.start_code_units_column(encoding),
         | 
| 252 | 
            -
                      location.end_code_units_column(encoding),
         | 
| 253 | 
            -
                    )
         | 
| 254 | 
            -
                    @name_location = Location.new(
         | 
| 255 | 
            -
                      name_location.start_line,
         | 
| 256 | 
            -
                      name_location.end_line,
         | 
| 257 | 
            -
                      name_location.start_code_units_column(encoding),
         | 
| 258 | 
            -
                      name_location.end_code_units_column(encoding),
         | 
| 259 | 
            -
                    )
         | 
| 217 | 
            +
                  def update_singleton_information(location, name_location, comments)
         | 
| 218 | 
            +
                    @location = location
         | 
| 219 | 
            +
                    @name_location = name_location
         | 
| 260 220 | 
             
                    (@comments ||= +"") << comments if comments
         | 
| 261 221 | 
             
                  end
         | 
| 262 222 | 
             
                end
         | 
| @@ -373,15 +333,14 @@ module RubyIndexer | |
| 373 333 | 
             
                    params(
         | 
| 374 334 | 
             
                      name: String,
         | 
| 375 335 | 
             
                      file_path: String,
         | 
| 376 | 
            -
                      location:  | 
| 336 | 
            +
                      location: Location,
         | 
| 377 337 | 
             
                      comments: T.nilable(String),
         | 
| 378 | 
            -
                      encoding: Encoding,
         | 
| 379 338 | 
             
                      visibility: Visibility,
         | 
| 380 339 | 
             
                      owner: T.nilable(Entry::Namespace),
         | 
| 381 340 | 
             
                    ).void
         | 
| 382 341 | 
             
                  end
         | 
| 383 | 
            -
                  def initialize(name, file_path, location, comments,  | 
| 384 | 
            -
                    super(name, file_path, location, comments | 
| 342 | 
            +
                  def initialize(name, file_path, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists
         | 
| 343 | 
            +
                    super(name, file_path, location, comments)
         | 
| 385 344 | 
             
                    @visibility = visibility
         | 
| 386 345 | 
             
                    @owner = owner
         | 
| 387 346 | 
             
                  end
         | 
| @@ -441,31 +400,18 @@ module RubyIndexer | |
| 441 400 | 
             
                    params(
         | 
| 442 401 | 
             
                      name: String,
         | 
| 443 402 | 
             
                      file_path: String,
         | 
| 444 | 
            -
                      location:  | 
| 445 | 
            -
                      name_location:  | 
| 403 | 
            +
                      location: Location,
         | 
| 404 | 
            +
                      name_location: Location,
         | 
| 446 405 | 
             
                      comments: T.nilable(String),
         | 
| 447 | 
            -
                      encoding: Encoding,
         | 
| 448 406 | 
             
                      signatures: T::Array[Signature],
         | 
| 449 407 | 
             
                      visibility: Visibility,
         | 
| 450 408 | 
             
                      owner: T.nilable(Entry::Namespace),
         | 
| 451 409 | 
             
                    ).void
         | 
| 452 410 | 
             
                  end
         | 
| 453 | 
            -
                  def initialize(name, file_path, location, name_location, comments,  | 
| 454 | 
            -
                    super(name, file_path, location, comments,  | 
| 411 | 
            +
                  def initialize(name, file_path, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
         | 
| 412 | 
            +
                    super(name, file_path, location, comments, visibility, owner)
         | 
| 455 413 | 
             
                    @signatures = signatures
         | 
| 456 | 
            -
                    @name_location =  | 
| 457 | 
            -
                      if name_location.is_a?(Prism::Location)
         | 
| 458 | 
            -
                        Location.new(
         | 
| 459 | 
            -
                          name_location.start_line,
         | 
| 460 | 
            -
                          name_location.end_line,
         | 
| 461 | 
            -
                          name_location.start_code_units_column(encoding),
         | 
| 462 | 
            -
                          name_location.end_code_units_column(encoding),
         | 
| 463 | 
            -
                        )
         | 
| 464 | 
            -
                      else
         | 
| 465 | 
            -
                        name_location
         | 
| 466 | 
            -
                      end,
         | 
| 467 | 
            -
                      RubyIndexer::Location,
         | 
| 468 | 
            -
                    )
         | 
| 414 | 
            +
                    @name_location = name_location
         | 
| 469 415 | 
             
                  end
         | 
| 470 416 | 
             
                end
         | 
| 471 417 |  | 
| @@ -494,13 +440,12 @@ module RubyIndexer | |
| 494 440 | 
             
                      nesting: T::Array[String],
         | 
| 495 441 | 
             
                      name: String,
         | 
| 496 442 | 
             
                      file_path: String,
         | 
| 497 | 
            -
                      location:  | 
| 443 | 
            +
                      location: Location,
         | 
| 498 444 | 
             
                      comments: T.nilable(String),
         | 
| 499 | 
            -
                      encoding: Encoding,
         | 
| 500 445 | 
             
                    ).void
         | 
| 501 446 | 
             
                  end
         | 
| 502 | 
            -
                  def initialize(target, nesting, name, file_path, location, comments | 
| 503 | 
            -
                    super(name, file_path, location, comments | 
| 447 | 
            +
                  def initialize(target, nesting, name, file_path, location, comments) # rubocop:disable Metrics/ParameterLists
         | 
| 448 | 
            +
                    super(name, file_path, location, comments)
         | 
| 504 449 |  | 
| 505 450 | 
             
                    @target = target
         | 
| 506 451 | 
             
                    @nesting = nesting
         | 
| @@ -514,14 +459,13 @@ module RubyIndexer | |
| 514 459 | 
             
                  sig { returns(String) }
         | 
| 515 460 | 
             
                  attr_reader :target
         | 
| 516 461 |  | 
| 517 | 
            -
                  sig { params(target: String, unresolved_alias: UnresolvedConstantAlias | 
| 518 | 
            -
                  def initialize(target, unresolved_alias | 
| 462 | 
            +
                  sig { params(target: String, unresolved_alias: UnresolvedConstantAlias).void }
         | 
| 463 | 
            +
                  def initialize(target, unresolved_alias)
         | 
| 519 464 | 
             
                    super(
         | 
| 520 465 | 
             
                      unresolved_alias.name,
         | 
| 521 466 | 
             
                      unresolved_alias.file_path,
         | 
| 522 467 | 
             
                      unresolved_alias.location,
         | 
| 523 468 | 
             
                      unresolved_alias.comments,
         | 
| 524 | 
            -
                      encoding
         | 
| 525 469 | 
             
                    )
         | 
| 526 470 |  | 
| 527 471 | 
             
                    @visibility = unresolved_alias.visibility
         | 
| @@ -541,14 +485,13 @@ module RubyIndexer | |
| 541 485 | 
             
                    params(
         | 
| 542 486 | 
             
                      name: String,
         | 
| 543 487 | 
             
                      file_path: String,
         | 
| 544 | 
            -
                      location:  | 
| 488 | 
            +
                      location: Location,
         | 
| 545 489 | 
             
                      comments: T.nilable(String),
         | 
| 546 | 
            -
                      encoding: Encoding,
         | 
| 547 490 | 
             
                      owner: T.nilable(Entry::Namespace),
         | 
| 548 491 | 
             
                    ).void
         | 
| 549 492 | 
             
                  end
         | 
| 550 | 
            -
                  def initialize(name, file_path, location, comments,  | 
| 551 | 
            -
                    super(name, file_path, location, comments | 
| 493 | 
            +
                  def initialize(name, file_path, location, comments, owner)
         | 
| 494 | 
            +
                    super(name, file_path, location, comments)
         | 
| 552 495 | 
             
                    @owner = owner
         | 
| 553 496 | 
             
                  end
         | 
| 554 497 | 
             
                end
         | 
| @@ -571,13 +514,12 @@ module RubyIndexer | |
| 571 514 | 
             
                      old_name: String,
         | 
| 572 515 | 
             
                      owner: T.nilable(Entry::Namespace),
         | 
| 573 516 | 
             
                      file_path: String,
         | 
| 574 | 
            -
                      location:  | 
| 517 | 
            +
                      location: Location,
         | 
| 575 518 | 
             
                      comments: T.nilable(String),
         | 
| 576 | 
            -
                      encoding: Encoding,
         | 
| 577 519 | 
             
                    ).void
         | 
| 578 520 | 
             
                  end
         | 
| 579 | 
            -
                  def initialize(new_name, old_name, owner, file_path, location, comments | 
| 580 | 
            -
                    super(new_name, file_path, location, comments | 
| 521 | 
            +
                  def initialize(new_name, old_name, owner, file_path, location, comments) # rubocop:disable Metrics/ParameterLists
         | 
| 522 | 
            +
                    super(new_name, file_path, location, comments)
         | 
| 581 523 |  | 
| 582 524 | 
             
                    @new_name = new_name
         | 
| 583 525 | 
             
                    @old_name = old_name
         | 
| @@ -596,9 +538,9 @@ module RubyIndexer | |
| 596 538 | 
             
                  attr_reader :owner
         | 
| 597 539 |  | 
| 598 540 | 
             
                  sig do
         | 
| 599 | 
            -
                    params(target: T.any(Member, MethodAlias), unresolved_alias: UnresolvedMethodAlias | 
| 541 | 
            +
                    params(target: T.any(Member, MethodAlias), unresolved_alias: UnresolvedMethodAlias).void
         | 
| 600 542 | 
             
                  end
         | 
| 601 | 
            -
                  def initialize(target, unresolved_alias | 
| 543 | 
            +
                  def initialize(target, unresolved_alias)
         | 
| 602 544 | 
             
                    full_comments = +"Alias for #{target.name}\n"
         | 
| 603 545 | 
             
                    full_comments << "#{unresolved_alias.comments}\n"
         | 
| 604 546 | 
             
                    full_comments << target.comments
         | 
| @@ -608,7 +550,6 @@ module RubyIndexer | |
| 608 550 | 
             
                      unresolved_alias.file_path,
         | 
| 609 551 | 
             
                      unresolved_alias.location,
         | 
| 610 552 | 
             
                      full_comments,
         | 
| 611 | 
            -
                      encoding
         | 
| 612 553 | 
             
                    )
         | 
| 613 554 |  | 
| 614 555 | 
             
                    @target = target
         | 
| @@ -665,7 +665,6 @@ module RubyIndexer | |
| 665 665 | 
             
                      attached_ancestor.location,
         | 
| 666 666 | 
             
                      attached_ancestor.name_location,
         | 
| 667 667 | 
             
                      nil,
         | 
| 668 | 
            -
                      @configuration.encoding,
         | 
| 669 668 | 
             
                      nil,
         | 
| 670 669 | 
             
                    )
         | 
| 671 670 | 
             
                    add(singleton, skip_prefix_tree: true)
         | 
| @@ -859,7 +858,7 @@ module RubyIndexer | |
| 859 858 | 
             
                  return entry unless target
         | 
| 860 859 |  | 
| 861 860 | 
             
                  target_name = T.must(target.first).name
         | 
| 862 | 
            -
                  resolved_alias = Entry::ConstantAlias.new(target_name, entry | 
| 861 | 
            +
                  resolved_alias = Entry::ConstantAlias.new(target_name, entry)
         | 
| 863 862 |  | 
| 864 863 | 
             
                  # Replace the UnresolvedAlias by a resolved one so that we don't have to do this again later
         | 
| 865 864 | 
             
                  original_entries = T.must(@entries[alias_name])
         | 
| @@ -981,29 +980,23 @@ module RubyIndexer | |
| 981 980 | 
             
                # nesting
         | 
| 982 981 | 
             
                sig { params(name: String, nesting: T::Array[String]).returns(String) }
         | 
| 983 982 | 
             
                def build_non_redundant_full_name(name, nesting)
         | 
| 983 | 
            +
                  # If there's no nesting, then we can just return the name as is
         | 
| 984 984 | 
             
                  return name if nesting.empty?
         | 
| 985 985 |  | 
| 986 | 
            -
                  namespace = nesting.join("::")
         | 
| 987 | 
            -
             | 
| 988 986 | 
             
                  # If the name is not qualified, we can just concatenate the nesting and the name
         | 
| 989 | 
            -
                  return "#{ | 
| 987 | 
            +
                  return "#{nesting.join("::")}::#{name}" unless name.include?("::")
         | 
| 990 988 |  | 
| 991 989 | 
             
                  name_parts = name.split("::")
         | 
| 990 | 
            +
                  first_redundant_part = nesting.index(name_parts[0])
         | 
| 992 991 |  | 
| 993 | 
            -
                  #  | 
| 994 | 
            -
                   | 
| 992 | 
            +
                  # If there are no redundant parts between the name and the nesting, then the full name is both combined
         | 
| 993 | 
            +
                  return "#{nesting.join("::")}::#{name}" unless first_redundant_part
         | 
| 995 994 |  | 
| 996 | 
            -
                  if  | 
| 997 | 
            -
             | 
| 998 | 
            -
             | 
| 999 | 
            -
             | 
| 1000 | 
            -
                   | 
| 1001 | 
            -
                    # No parts of the nesting are in the name, we can concatenate the namespace and the name
         | 
| 1002 | 
            -
                    "#{namespace}::#{name}"
         | 
| 1003 | 
            -
                  else
         | 
| 1004 | 
            -
                    # The name includes some parts of the nesting. We need to remove the redundant parts
         | 
| 1005 | 
            -
                    "#{namespace}::#{T.must(name_parts[index..-1]).join("::")}"
         | 
| 1006 | 
            -
                  end
         | 
| 995 | 
            +
                  # Otherwise, push all of the leading parts of the nesting that aren't redundant into the name. For example, if we
         | 
| 996 | 
            +
                  # have a reference to `Foo::Bar` inside the `[Namespace, Foo]` nesting, then only the `Foo` part is redundant, but
         | 
| 997 | 
            +
                  # we still need to include the `Namespace` part
         | 
| 998 | 
            +
                  T.unsafe(name_parts).unshift(*nesting[0...first_redundant_part])
         | 
| 999 | 
            +
                  name_parts.join("::")
         | 
| 1007 1000 | 
             
                end
         | 
| 1008 1001 |  | 
| 1009 1002 | 
             
                sig do
         | 
| @@ -1050,7 +1043,7 @@ module RubyIndexer | |
| 1050 1043 | 
             
                  target_method_entries = resolve_method(entry.old_name, receiver_name, seen_names)
         | 
| 1051 1044 | 
             
                  return entry unless target_method_entries
         | 
| 1052 1045 |  | 
| 1053 | 
            -
                  resolved_alias = Entry::MethodAlias.new(T.must(target_method_entries.first), entry | 
| 1046 | 
            +
                  resolved_alias = Entry::MethodAlias.new(T.must(target_method_entries.first), entry)
         | 
| 1054 1047 | 
             
                  original_entries = T.must(@entries[new_name])
         | 
| 1055 1048 | 
             
                  original_entries.delete(entry)
         | 
| 1056 1049 | 
             
                  original_entries << resolved_alias
         | 
| @@ -5,6 +5,28 @@ module RubyIndexer | |
| 5 5 | 
             
              class Location
         | 
| 6 6 | 
             
                extend T::Sig
         | 
| 7 7 |  | 
| 8 | 
            +
                class << self
         | 
| 9 | 
            +
                  extend T::Sig
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  sig do
         | 
| 12 | 
            +
                    params(
         | 
| 13 | 
            +
                      prism_location: Prism::Location,
         | 
| 14 | 
            +
                      code_units_cache: T.any(
         | 
| 15 | 
            +
                        T.proc.params(arg0: Integer).returns(Integer),
         | 
| 16 | 
            +
                        Prism::CodeUnitsCache,
         | 
| 17 | 
            +
                      ),
         | 
| 18 | 
            +
                    ).returns(T.attached_class)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  def from_prism_location(prism_location, code_units_cache)
         | 
| 21 | 
            +
                    new(
         | 
| 22 | 
            +
                      prism_location.start_line,
         | 
| 23 | 
            +
                      prism_location.end_line,
         | 
| 24 | 
            +
                      prism_location.cached_start_code_units_column(code_units_cache),
         | 
| 25 | 
            +
                      prism_location.cached_end_code_units_column(code_units_cache),
         | 
| 26 | 
            +
                    )
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 8 30 | 
             
                sig { returns(Integer) }
         | 
| 9 31 | 
             
                attr_reader :start_line, :end_line, :start_column, :end_column
         | 
| 10 32 |  | 
| @@ -61,9 +61,9 @@ module RubyIndexer | |
| 61 61 | 
             
                  comments = comments_to_string(declaration)
         | 
| 62 62 | 
             
                  entry = if declaration.is_a?(RBS::AST::Declarations::Class)
         | 
| 63 63 | 
             
                    parent_class = declaration.super_class&.name&.name&.to_s
         | 
| 64 | 
            -
                    Entry::Class.new(nesting, file_path, location, location, comments,  | 
| 64 | 
            +
                    Entry::Class.new(nesting, file_path, location, location, comments, parent_class)
         | 
| 65 65 | 
             
                  else
         | 
| 66 | 
            -
                    Entry::Module.new(nesting, file_path, location, location, comments | 
| 66 | 
            +
                    Entry::Module.new(nesting, file_path, location, location, comments)
         | 
| 67 67 | 
             
                  end
         | 
| 68 68 | 
             
                  add_declaration_mixins_to_entry(declaration, entry)
         | 
| 69 69 | 
             
                  @index.add(entry)
         | 
| @@ -136,7 +136,6 @@ module RubyIndexer | |
| 136 136 | 
             
                    location,
         | 
| 137 137 | 
             
                    location,
         | 
| 138 138 | 
             
                    comments,
         | 
| 139 | 
            -
                    @index.configuration.encoding,
         | 
| 140 139 | 
             
                    signatures,
         | 
| 141 140 | 
             
                    visibility,
         | 
| 142 141 | 
             
                    real_owner,
         | 
| @@ -269,7 +268,6 @@ module RubyIndexer | |
| 269 268 | 
             
                    file_path,
         | 
| 270 269 | 
             
                    to_ruby_indexer_location(declaration.location),
         | 
| 271 270 | 
             
                    comments_to_string(declaration),
         | 
| 272 | 
            -
                    @index.configuration.encoding,
         | 
| 273 271 | 
             
                  ))
         | 
| 274 272 | 
             
                end
         | 
| 275 273 |  | 
| @@ -279,14 +277,12 @@ module RubyIndexer | |
| 279 277 | 
             
                  file_path = pathname.to_s
         | 
| 280 278 | 
             
                  location = to_ruby_indexer_location(declaration.location)
         | 
| 281 279 | 
             
                  comments = comments_to_string(declaration)
         | 
| 282 | 
            -
                  encoding = @index.configuration.encoding
         | 
| 283 280 |  | 
| 284 281 | 
             
                  @index.add(Entry::GlobalVariable.new(
         | 
| 285 282 | 
             
                    name,
         | 
| 286 283 | 
             
                    file_path,
         | 
| 287 284 | 
             
                    location,
         | 
| 288 285 | 
             
                    comments,
         | 
| 289 | 
            -
                    encoding,
         | 
| 290 286 | 
             
                  ))
         | 
| 291 287 | 
             
                end
         | 
| 292 288 |  | 
| @@ -302,7 +298,6 @@ module RubyIndexer | |
| 302 298 | 
             
                    file_path,
         | 
| 303 299 | 
             
                    to_ruby_indexer_location(member.location),
         | 
| 304 300 | 
             
                    comments,
         | 
| 305 | 
            -
                    @index.configuration.encoding,
         | 
| 306 301 | 
             
                  )
         | 
| 307 302 |  | 
| 308 303 | 
             
                  @index.add(entry)
         | 
| @@ -9,14 +9,14 @@ module RubyIndexer | |
| 9 9 | 
             
                  enhancement_class = Class.new do
         | 
| 10 10 | 
             
                    include Enhancement
         | 
| 11 11 |  | 
| 12 | 
            -
                    def on_call_node(index, owner, node, file_path)
         | 
| 12 | 
            +
                    def on_call_node(index, owner, node, file_path, code_units_cache)
         | 
| 13 13 | 
             
                      return unless owner
         | 
| 14 14 | 
             
                      return unless node.name == :extend
         | 
| 15 15 |  | 
| 16 16 | 
             
                      arguments = node.arguments&.arguments
         | 
| 17 17 | 
             
                      return unless arguments
         | 
| 18 18 |  | 
| 19 | 
            -
                      location = node.location
         | 
| 19 | 
            +
                      location = Location.from_prism_location(node.location, code_units_cache)
         | 
| 20 20 |  | 
| 21 21 | 
             
                      arguments.each do |node|
         | 
| 22 22 | 
             
                        next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
         | 
| @@ -39,7 +39,6 @@ module RubyIndexer | |
| 39 39 | 
             
                          location,
         | 
| 40 40 | 
             
                          location,
         | 
| 41 41 | 
             
                          nil,
         | 
| 42 | 
            -
                          index.configuration.encoding,
         | 
| 43 42 | 
             
                          [Entry::Signature.new([Entry::RequiredParameter.new(name: :a)])],
         | 
| 44 43 | 
             
                          Entry::Visibility::PUBLIC,
         | 
| 45 44 | 
             
                          owner,
         | 
| @@ -102,7 +101,7 @@ module RubyIndexer | |
| 102 101 | 
             
                  enhancement_class = Class.new do
         | 
| 103 102 | 
             
                    include Enhancement
         | 
| 104 103 |  | 
| 105 | 
            -
                    def on_call_node(index, owner, node, file_path)
         | 
| 104 | 
            +
                    def on_call_node(index, owner, node, file_path, code_units_cache)
         | 
| 106 105 | 
             
                      return unless owner
         | 
| 107 106 |  | 
| 108 107 | 
             
                      name = node.name
         | 
| @@ -114,7 +113,7 @@ module RubyIndexer | |
| 114 113 | 
             
                      association_name = arguments.first
         | 
| 115 114 | 
             
                      return unless association_name.is_a?(Prism::SymbolNode)
         | 
| 116 115 |  | 
| 117 | 
            -
                      location = association_name.location
         | 
| 116 | 
            +
                      location = Location.from_prism_location(association_name.location, code_units_cache)
         | 
| 118 117 |  | 
| 119 118 | 
             
                      index.add(Entry::Method.new(
         | 
| 120 119 | 
             
                        T.must(association_name.value),
         | 
| @@ -122,7 +121,6 @@ module RubyIndexer | |
| 122 121 | 
             
                        location,
         | 
| 123 122 | 
             
                        location,
         | 
| 124 123 | 
             
                        nil,
         | 
| 125 | 
            -
                        index.configuration.encoding,
         | 
| 126 124 | 
             
                        [],
         | 
| 127 125 | 
             
                        Entry::Visibility::PUBLIC,
         | 
| 128 126 | 
             
                        owner,
         | 
| @@ -166,7 +164,7 @@ module RubyIndexer | |
| 166 164 | 
             
                  enhancement_class = Class.new do
         | 
| 167 165 | 
             
                    include Enhancement
         | 
| 168 166 |  | 
| 169 | 
            -
                    def on_call_node(index, owner, node, file_path)
         | 
| 167 | 
            +
                    def on_call_node(index, owner, node, file_path, code_units_cache)
         | 
| 170 168 | 
             
                      raise "Error"
         | 
| 171 169 | 
             
                    end
         | 
| 172 170 |  | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            # typed: true
         | 
| 2 | 
            +
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require_relative "test_case"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module RubyIndexer
         | 
| 7 | 
            +
              class GlobalVariableTest < TestCase
         | 
| 8 | 
            +
                def test_global_variable_and_write
         | 
| 9 | 
            +
                  index(<<~RUBY)
         | 
| 10 | 
            +
                    $foo &&= 1
         | 
| 11 | 
            +
                  RUBY
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def test_global_variable_operator_write
         | 
| 17 | 
            +
                  index(<<~RUBY)
         | 
| 18 | 
            +
                    $foo += 1
         | 
| 19 | 
            +
                  RUBY
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def test_global_variable_or_write
         | 
| 25 | 
            +
                  index(<<~RUBY)
         | 
| 26 | 
            +
                    $foo ||= 1
         | 
| 27 | 
            +
                  RUBY
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def test_global_variable_target_node
         | 
| 33 | 
            +
                  index(<<~RUBY)
         | 
| 34 | 
            +
                    $foo, $bar = 1
         | 
| 35 | 
            +
                  RUBY
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
         | 
| 38 | 
            +
                  assert_entry("$bar", Entry::GlobalVariable, "/fake/path/foo.rb:0-6:0-10")
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def test_global_variable_write
         | 
| 42 | 
            +
                  index(<<~RUBY)
         | 
| 43 | 
            +
                    $foo = 1
         | 
| 44 | 
            +
                  RUBY
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| @@ -1934,5 +1934,94 @@ module RubyIndexer | |
| 1934 1934 | 
             
                  real_namespace = @index.follow_aliased_namespace("Namespace::Second")
         | 
| 1935 1935 | 
             
                  assert_equal("First::Second", real_namespace)
         | 
| 1936 1936 | 
             
                end
         | 
| 1937 | 
            +
             | 
| 1938 | 
            +
                def test_resolving_alias_to_non_existing_namespace
         | 
| 1939 | 
            +
                  index(<<~RUBY)
         | 
| 1940 | 
            +
                    module Namespace
         | 
| 1941 | 
            +
                      class Foo
         | 
| 1942 | 
            +
                        module InnerNamespace
         | 
| 1943 | 
            +
                          Constants = Namespace::Foo::Constants
         | 
| 1944 | 
            +
                        end
         | 
| 1945 | 
            +
                      end
         | 
| 1946 | 
            +
                    end
         | 
| 1947 | 
            +
                  RUBY
         | 
| 1948 | 
            +
             | 
| 1949 | 
            +
                  entry = @index.resolve("Constants", ["Namespace", "Foo", "InnerNamespace"])&.first
         | 
| 1950 | 
            +
                  assert_instance_of(Entry::UnresolvedConstantAlias, entry)
         | 
| 1951 | 
            +
             | 
| 1952 | 
            +
                  entry = @index.resolve("Namespace::Foo::Constants", ["Namespace", "Foo", "InnerNamespace"])&.first
         | 
| 1953 | 
            +
                  assert_nil(entry)
         | 
| 1954 | 
            +
                end
         | 
| 1955 | 
            +
             | 
| 1956 | 
            +
                def test_resolving_alias_to_existing_constant_from_inner_namespace
         | 
| 1957 | 
            +
                  index(<<~RUBY)
         | 
| 1958 | 
            +
                    module Parent
         | 
| 1959 | 
            +
                      CONST = 123
         | 
| 1960 | 
            +
                    end
         | 
| 1961 | 
            +
             | 
| 1962 | 
            +
                    module First
         | 
| 1963 | 
            +
                      module Namespace
         | 
| 1964 | 
            +
                        class Foo
         | 
| 1965 | 
            +
                          include Parent
         | 
| 1966 | 
            +
             | 
| 1967 | 
            +
                          module InnerNamespace
         | 
| 1968 | 
            +
                            Constants = Namespace::Foo::CONST
         | 
| 1969 | 
            +
                          end
         | 
| 1970 | 
            +
                        end
         | 
| 1971 | 
            +
                      end
         | 
| 1972 | 
            +
                    end
         | 
| 1973 | 
            +
                  RUBY
         | 
| 1974 | 
            +
             | 
| 1975 | 
            +
                  entry = @index.resolve("Namespace::Foo::CONST", ["First", "Namespace", "Foo", "InnerNamespace"])&.first
         | 
| 1976 | 
            +
                  assert_equal("Parent::CONST", entry.name)
         | 
| 1977 | 
            +
                  assert_instance_of(Entry::Constant, entry)
         | 
| 1978 | 
            +
                end
         | 
| 1979 | 
            +
             | 
| 1980 | 
            +
                def test_build_non_redundant_name
         | 
| 1981 | 
            +
                  assert_equal(
         | 
| 1982 | 
            +
                    "Namespace::Foo::Constants",
         | 
| 1983 | 
            +
                    @index.send(
         | 
| 1984 | 
            +
                      :build_non_redundant_full_name,
         | 
| 1985 | 
            +
                      "Namespace::Foo::Constants",
         | 
| 1986 | 
            +
                      ["Namespace", "Foo", "InnerNamespace"],
         | 
| 1987 | 
            +
                    ),
         | 
| 1988 | 
            +
                  )
         | 
| 1989 | 
            +
             | 
| 1990 | 
            +
                  assert_equal(
         | 
| 1991 | 
            +
                    "Namespace::Foo::Constants",
         | 
| 1992 | 
            +
                    @index.send(
         | 
| 1993 | 
            +
                      :build_non_redundant_full_name,
         | 
| 1994 | 
            +
                      "Namespace::Foo::Constants",
         | 
| 1995 | 
            +
                      ["Namespace", "Foo"],
         | 
| 1996 | 
            +
                    ),
         | 
| 1997 | 
            +
                  )
         | 
| 1998 | 
            +
             | 
| 1999 | 
            +
                  assert_equal(
         | 
| 2000 | 
            +
                    "Namespace::Foo::Constants",
         | 
| 2001 | 
            +
                    @index.send(
         | 
| 2002 | 
            +
                      :build_non_redundant_full_name,
         | 
| 2003 | 
            +
                      "Foo::Constants",
         | 
| 2004 | 
            +
                      ["Namespace", "Foo"],
         | 
| 2005 | 
            +
                    ),
         | 
| 2006 | 
            +
                  )
         | 
| 2007 | 
            +
             | 
| 2008 | 
            +
                  assert_equal(
         | 
| 2009 | 
            +
                    "Bar::Namespace::Foo::Constants",
         | 
| 2010 | 
            +
                    @index.send(
         | 
| 2011 | 
            +
                      :build_non_redundant_full_name,
         | 
| 2012 | 
            +
                      "Namespace::Foo::Constants",
         | 
| 2013 | 
            +
                      ["Bar"],
         | 
| 2014 | 
            +
                    ),
         | 
| 2015 | 
            +
                  )
         | 
| 2016 | 
            +
             | 
| 2017 | 
            +
                  assert_equal(
         | 
| 2018 | 
            +
                    "First::Namespace::Foo::Constants",
         | 
| 2019 | 
            +
                    @index.send(
         | 
| 2020 | 
            +
                      :build_non_redundant_full_name,
         | 
| 2021 | 
            +
                      "Namespace::Foo::Constants",
         | 
| 2022 | 
            +
                      ["First", "Namespace", "Foo", "InnerNamespace"],
         | 
| 2023 | 
            +
                    ),
         | 
| 2024 | 
            +
                  )
         | 
| 2025 | 
            +
                end
         | 
| 1937 2026 | 
             
              end
         | 
| 1938 2027 | 
             
            end
         | 
| @@ -6,10 +6,18 @@ module RubyLsp | |
| 6 6 | 
             
                extend T::Sig
         | 
| 7 7 | 
             
                extend T::Generic
         | 
| 8 8 |  | 
| 9 | 
            +
                ParseResultType = type_member { { fixed: Prism::ParseResult } }
         | 
| 10 | 
            +
             | 
| 9 11 | 
             
                sig { returns(String) }
         | 
| 10 12 | 
             
                attr_reader :host_language_source
         | 
| 11 13 |  | 
| 12 | 
            -
                 | 
| 14 | 
            +
                sig do
         | 
| 15 | 
            +
                  returns(T.any(
         | 
| 16 | 
            +
                    T.proc.params(arg0: Integer).returns(Integer),
         | 
| 17 | 
            +
                    Prism::CodeUnitsCache,
         | 
| 18 | 
            +
                  ))
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                attr_reader :code_units_cache
         | 
| 13 21 |  | 
| 14 22 | 
             
                sig { params(source: String, version: Integer, uri: URI::Generic, encoding: Encoding).void }
         | 
| 15 23 | 
             
                def initialize(source:, version:, uri:, encoding: Encoding::UTF_8)
         | 
| @@ -17,6 +25,10 @@ module RubyLsp | |
| 17 25 | 
             
                  # overrides this with the proper virtual host language source
         | 
| 18 26 | 
             
                  @host_language_source = T.let("", String)
         | 
| 19 27 | 
             
                  super
         | 
| 28 | 
            +
                  @code_units_cache = T.let(@parse_result.code_units_cache(@encoding), T.any(
         | 
| 29 | 
            +
                    T.proc.params(arg0: Integer).returns(Integer),
         | 
| 30 | 
            +
                    Prism::CodeUnitsCache,
         | 
| 31 | 
            +
                  ))
         | 
| 20 32 | 
             
                end
         | 
| 21 33 |  | 
| 22 34 | 
             
                sig { override.returns(T::Boolean) }
         | 
| @@ -30,6 +42,7 @@ module RubyLsp | |
| 30 42 | 
             
                  # Use partial script to avoid syntax errors in ERB files where keywords may be used without the full context in
         | 
| 31 43 | 
             
                  # which they will be evaluated
         | 
| 32 44 | 
             
                  @parse_result = Prism.parse(scanner.ruby, partial_script: true)
         | 
| 45 | 
            +
                  @code_units_cache = @parse_result.code_units_cache(@encoding)
         | 
| 33 46 | 
             
                  true
         | 
| 34 47 | 
             
                end
         | 
| 35 48 |  | 
| @@ -53,8 +66,8 @@ module RubyLsp | |
| 53 66 | 
             
                  RubyDocument.locate(
         | 
| 54 67 | 
             
                    @parse_result.value,
         | 
| 55 68 | 
             
                    create_scanner.find_char_position(position),
         | 
| 69 | 
            +
                    code_units_cache: @code_units_cache,
         | 
| 56 70 | 
             
                    node_types: node_types,
         | 
| 57 | 
            -
                    encoding: @encoding,
         | 
| 58 71 | 
             
                  )
         | 
| 59 72 | 
             
                end
         | 
| 60 73 |  |