ruby-lsp 0.12.4 → 0.13.0
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-check +20 -4
- data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +36 -2
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +83 -12
- data/lib/ruby_indexer/test/configuration_test.rb +10 -0
- data/lib/ruby_indexer/test/index_test.rb +11 -0
- data/lib/ruby_indexer/test/method_test.rb +66 -0
- data/lib/ruby_lsp/addon.rb +9 -13
- data/lib/ruby_lsp/executor.rb +25 -27
- data/lib/ruby_lsp/listener.rb +4 -5
- data/lib/ruby_lsp/requests/code_lens.rb +16 -7
- data/lib/ruby_lsp/requests/completion.rb +16 -10
- data/lib/ruby_lsp/requests/definition.rb +3 -4
- data/lib/ruby_lsp/requests/diagnostics.rb +0 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +2 -3
- data/lib/ruby_lsp/requests/document_link.rb +2 -3
- data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
- data/lib/ruby_lsp/requests/folding_ranges.rb +12 -15
- data/lib/ruby_lsp/requests/formatting.rb +0 -5
- data/lib/ruby_lsp/requests/hover.rb +3 -4
- data/lib/ruby_lsp/requests/inlay_hints.rb +3 -3
- data/lib/ruby_lsp/requests/on_type_formatting.rb +2 -3
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +28 -11
- data/lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb +3 -8
- data/lib/ruby_lsp/requests/workspace_symbol.rb +2 -0
- data/lib/ruby_lsp/store.rb +4 -0
- data/lib/ruby_lsp/utils.rb +0 -4
- metadata +6 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d6bace664e1540c1333df9dabfb2e7bdd8bda0f910033b47b188e4a82ddacb15
         | 
| 4 | 
            +
              data.tar.gz: be9e5da0492b26b5cb6e07074d01d7874104b70286c1578342b9639158fed147
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 7d8e61433686271a68dafe8db79765ed509a115ab6f06060d7669d279f48218fe2eada2c12e3b45f155d27a41774771681cdab92700d27f426e75ed89287ca03
         | 
| 7 | 
            +
              data.tar.gz: 611c050b751050934d0fd93e9e52089fe63fc4d947be75a440dfa0465933814d2682268a10135d036c2cee83fa739156d2b11e42e679ecbed7de62acfee9d621
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0. | 
| 1 | 
            +
            0.13.0
         | 
    
        data/exe/ruby-lsp-check
    CHANGED
    
    | @@ -17,8 +17,6 @@ end | |
| 17 17 | 
             
            $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
         | 
| 18 18 | 
             
            require "ruby_lsp/internal"
         | 
| 19 19 |  | 
| 20 | 
            -
            RubyLsp::Addon.load_addons
         | 
| 21 | 
            -
             | 
| 22 20 | 
             
            T::Utils.run_all_sig_blocks
         | 
| 23 21 |  | 
| 24 22 | 
             
            files = Dir.glob("#{Dir.pwd}/**/*.rb")
         | 
| @@ -28,6 +26,7 @@ puts "Verifying that all automatic LSP requests execute successfully. This may t | |
| 28 26 | 
             
            errors = {}
         | 
| 29 27 | 
             
            store = RubyLsp::Store.new
         | 
| 30 28 | 
             
            message_queue = Thread::Queue.new
         | 
| 29 | 
            +
            RubyLsp::Addon.load_addons(message_queue)
         | 
| 31 30 | 
             
            executor = RubyLsp::Executor.new(store, message_queue)
         | 
| 32 31 |  | 
| 33 32 | 
             
            files.each_with_index do |file, index|
         | 
| @@ -50,13 +49,30 @@ end | |
| 50 49 | 
             
            puts "\n"
         | 
| 51 50 | 
             
            message_queue.close
         | 
| 52 51 |  | 
| 52 | 
            +
            # Indexing
         | 
| 53 | 
            +
            puts "Verifying that indexing executes successfully. This may take a while..."
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            index = RubyIndexer::Index.new
         | 
| 56 | 
            +
            indexables = RubyIndexer.configuration.indexables
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            indexables.each_with_index do |indexable, i|
         | 
| 59 | 
            +
              result = Prism.parse(File.read(indexable.full_path))
         | 
| 60 | 
            +
              collector = RubyIndexer::Collector.new(index, result, indexable.full_path)
         | 
| 61 | 
            +
              collector.collect(result.value)
         | 
| 62 | 
            +
            rescue => e
         | 
| 63 | 
            +
              errors[indexable.full_path] = e
         | 
| 64 | 
            +
            ensure
         | 
| 65 | 
            +
              print("\033[M\033[0KIndexed #{i + 1}/#{indexables.length}") unless ENV["CI"]
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
            puts "\n"
         | 
| 68 | 
            +
             | 
| 53 69 | 
             
            if errors.empty?
         | 
| 54 | 
            -
              puts "All  | 
| 70 | 
            +
              puts "All operations completed successfully!"
         | 
| 55 71 | 
             
              exit
         | 
| 56 72 | 
             
            end
         | 
| 57 73 |  | 
| 58 74 | 
             
            puts <<~ERRORS
         | 
| 59 | 
            -
              Errors while executing | 
| 75 | 
            +
              Errors while executing:
         | 
| 60 76 |  | 
| 61 77 | 
             
              #{errors.map { |file, error| "#{file}: #{error.message}" }.join("\n")}
         | 
| 62 78 | 
             
            ERRORS
         | 
| @@ -141,8 +141,18 @@ module RubyIndexer | |
| 141 141 |  | 
| 142 142 | 
             
                sig { params(node: Prism::CallNode).void }
         | 
| 143 143 | 
             
                def handle_call_node(node)
         | 
| 144 | 
            -
                  message = node. | 
| 145 | 
            -
             | 
| 144 | 
            +
                  message = node.name
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                  case message
         | 
| 147 | 
            +
                  when :private_constant
         | 
| 148 | 
            +
                    handle_private_constant(node)
         | 
| 149 | 
            +
                  when :attr_reader
         | 
| 150 | 
            +
                    handle_attribute(node, reader: true, writer: false)
         | 
| 151 | 
            +
                  when :attr_writer
         | 
| 152 | 
            +
                    handle_attribute(node, reader: false, writer: true)
         | 
| 153 | 
            +
                  when :attr_accessor
         | 
| 154 | 
            +
                    handle_attribute(node, reader: true, writer: true)
         | 
| 155 | 
            +
                  end
         | 
| 146 156 | 
             
                end
         | 
| 147 157 |  | 
| 148 158 | 
             
                sig { params(node: Prism::DefNode).void }
         | 
| @@ -312,5 +322,29 @@ module RubyIndexer | |
| 312 322 | 
             
                    "#{@stack.join("::")}::#{name}"
         | 
| 313 323 | 
             
                  end.delete_prefix("::")
         | 
| 314 324 | 
             
                end
         | 
| 325 | 
            +
             | 
| 326 | 
            +
                sig { params(node: Prism::CallNode, reader: T::Boolean, writer: T::Boolean).void }
         | 
| 327 | 
            +
                def handle_attribute(node, reader:, writer:)
         | 
| 328 | 
            +
                  arguments = node.arguments&.arguments
         | 
| 329 | 
            +
                  return unless arguments
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                  receiver = node.receiver
         | 
| 332 | 
            +
                  return unless receiver.nil? || receiver.is_a?(Prism::SelfNode)
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                  comments = collect_comments(node)
         | 
| 335 | 
            +
                  arguments.each do |argument|
         | 
| 336 | 
            +
                    name, loc = case argument
         | 
| 337 | 
            +
                    when Prism::SymbolNode
         | 
| 338 | 
            +
                      [argument.value, argument.value_loc]
         | 
| 339 | 
            +
                    when Prism::StringNode
         | 
| 340 | 
            +
                      [argument.content, argument.content_loc]
         | 
| 341 | 
            +
                    end
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                    next unless name && loc
         | 
| 344 | 
            +
             | 
| 345 | 
            +
                    @index << Entry::Accessor.new(name, @file_path, loc, comments, @current_owner) if reader
         | 
| 346 | 
            +
                    @index << Entry::Accessor.new("#{name}=", @file_path, loc, comments, @current_owner) if writer
         | 
| 347 | 
            +
                  end
         | 
| 348 | 
            +
                end
         | 
| 315 349 | 
             
              end
         | 
| 316 350 | 
             
            end
         | 
| @@ -120,7 +120,7 @@ module RubyIndexer | |
| 120 120 | 
             
                          IndexablePath.new(RbConfig::CONFIG["rubylibdir"], path)
         | 
| 121 121 | 
             
                        end,
         | 
| 122 122 | 
             
                      )
         | 
| 123 | 
            -
                     | 
| 123 | 
            +
                    elsif pathname.extname == ".rb"
         | 
| 124 124 | 
             
                      # If the default_path is a Ruby file, we index it
         | 
| 125 125 | 
             
                      indexables << IndexablePath.new(RbConfig::CONFIG["rubylibdir"], default_path)
         | 
| 126 126 | 
             
                    end
         | 
| @@ -90,20 +90,69 @@ module RubyIndexer | |
| 90 90 | 
             
                  end
         | 
| 91 91 | 
             
                end
         | 
| 92 92 |  | 
| 93 | 
            +
                # A required method parameter, e.g. `def foo(a)`
         | 
| 93 94 | 
             
                class RequiredParameter < Parameter
         | 
| 94 95 | 
             
                end
         | 
| 95 96 |  | 
| 96 | 
            -
                 | 
| 97 | 
            +
                # An optional method parameter, e.g. `def foo(a = 123)`
         | 
| 98 | 
            +
                class OptionalParameter < Parameter
         | 
| 99 | 
            +
                end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                # An required keyword method parameter, e.g. `def foo(a:)`
         | 
| 102 | 
            +
                class KeywordParameter < Parameter
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                # An optional keyword method parameter, e.g. `def foo(a: 123)`
         | 
| 106 | 
            +
                class OptionalKeywordParameter < Parameter
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                class Member < Entry
         | 
| 97 110 | 
             
                  extend T::Sig
         | 
| 98 111 | 
             
                  extend T::Helpers
         | 
| 99 | 
            -
                  abstract!
         | 
| 100 112 |  | 
| 101 | 
            -
                   | 
| 102 | 
            -
                  attr_reader :parameters
         | 
| 113 | 
            +
                  abstract!
         | 
| 103 114 |  | 
| 104 115 | 
             
                  sig { returns(T.nilable(Entry::Namespace)) }
         | 
| 105 116 | 
             
                  attr_reader :owner
         | 
| 106 117 |  | 
| 118 | 
            +
                  sig do
         | 
| 119 | 
            +
                    params(
         | 
| 120 | 
            +
                      name: String,
         | 
| 121 | 
            +
                      file_path: String,
         | 
| 122 | 
            +
                      location: Prism::Location,
         | 
| 123 | 
            +
                      comments: T::Array[String],
         | 
| 124 | 
            +
                      owner: T.nilable(Entry::Namespace),
         | 
| 125 | 
            +
                    ).void
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
                  def initialize(name, file_path, location, comments, owner)
         | 
| 128 | 
            +
                    super(name, file_path, location, comments)
         | 
| 129 | 
            +
                    @owner = owner
         | 
| 130 | 
            +
                  end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                  sig { abstract.returns(T::Array[Parameter]) }
         | 
| 133 | 
            +
                  def parameters; end
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                class Accessor < Member
         | 
| 137 | 
            +
                  extend T::Sig
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                  sig { override.returns(T::Array[Parameter]) }
         | 
| 140 | 
            +
                  def parameters
         | 
| 141 | 
            +
                    params = []
         | 
| 142 | 
            +
                    params << RequiredParameter.new(name: name.delete_suffix("=").to_sym) if name.end_with?("=")
         | 
| 143 | 
            +
                    params
         | 
| 144 | 
            +
                  end
         | 
| 145 | 
            +
                end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                class Method < Member
         | 
| 148 | 
            +
                  extend T::Sig
         | 
| 149 | 
            +
                  extend T::Helpers
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                  abstract!
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  sig { override.returns(T::Array[Parameter]) }
         | 
| 154 | 
            +
                  attr_reader :parameters
         | 
| 155 | 
            +
             | 
| 107 156 | 
             
                  sig do
         | 
| 108 157 | 
             
                    params(
         | 
| 109 158 | 
             
                      name: String,
         | 
| @@ -115,9 +164,9 @@ module RubyIndexer | |
| 115 164 | 
             
                    ).void
         | 
| 116 165 | 
             
                  end
         | 
| 117 166 | 
             
                  def initialize(name, file_path, location, comments, parameters_node, owner) # rubocop:disable Metrics/ParameterLists
         | 
| 118 | 
            -
                    super(name, file_path, location, comments)
         | 
| 167 | 
            +
                    super(name, file_path, location, comments, owner)
         | 
| 168 | 
            +
             | 
| 119 169 | 
             
                    @parameters = T.let(list_params(parameters_node), T::Array[Parameter])
         | 
| 120 | 
            -
                    @owner = owner
         | 
| 121 170 | 
             
                  end
         | 
| 122 171 |  | 
| 123 172 | 
             
                  private
         | 
| @@ -126,20 +175,42 @@ module RubyIndexer | |
| 126 175 | 
             
                  def list_params(parameters_node)
         | 
| 127 176 | 
             
                    return [] unless parameters_node
         | 
| 128 177 |  | 
| 129 | 
            -
                     | 
| 178 | 
            +
                    parameters = []
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                    parameters_node.requireds.each do |required|
         | 
| 130 181 | 
             
                      name = parameter_name(required)
         | 
| 131 182 | 
             
                      next unless name
         | 
| 132 183 |  | 
| 133 | 
            -
                      RequiredParameter.new(name: name)
         | 
| 184 | 
            +
                      parameters << RequiredParameter.new(name: name)
         | 
| 134 185 | 
             
                    end
         | 
| 135 | 
            -
                  end
         | 
| 136 186 |  | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 187 | 
            +
                    parameters_node.optionals.each do |optional|
         | 
| 188 | 
            +
                      name = parameter_name(optional)
         | 
| 189 | 
            +
                      next unless name
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                      parameters << OptionalParameter.new(name: name)
         | 
| 192 | 
            +
                    end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    parameters_node.keywords.each do |keyword|
         | 
| 195 | 
            +
                      name = parameter_name(keyword)
         | 
| 196 | 
            +
                      next unless name
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                      case keyword
         | 
| 199 | 
            +
                      when Prism::RequiredKeywordParameterNode
         | 
| 200 | 
            +
                        parameters << KeywordParameter.new(name: name)
         | 
| 201 | 
            +
                      when Prism::OptionalKeywordParameterNode
         | 
| 202 | 
            +
                        parameters << OptionalKeywordParameter.new(name: name)
         | 
| 203 | 
            +
                      end
         | 
| 204 | 
            +
                    end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                    parameters
         | 
| 139 207 | 
             
                  end
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                  sig { params(node: Prism::Node).returns(T.nilable(Symbol)) }
         | 
| 140 210 | 
             
                  def parameter_name(node)
         | 
| 141 211 | 
             
                    case node
         | 
| 142 | 
            -
                    when Prism::RequiredParameterNode
         | 
| 212 | 
            +
                    when Prism::RequiredParameterNode, Prism::OptionalParameterNode,
         | 
| 213 | 
            +
                      Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode
         | 
| 143 214 | 
             
                      node.name
         | 
| 144 215 | 
             
                    when Prism::MultiTargetNode
         | 
| 145 216 | 
             
                      names = [*node.lefts, *node.rest, *node.rights].map { |parameter_node| parameter_name(parameter_node) }
         | 
| @@ -84,6 +84,16 @@ module RubyIndexer | |
| 84 84 | 
             
                  )
         | 
| 85 85 | 
             
                end
         | 
| 86 86 |  | 
| 87 | 
            +
                def test_indexables_does_not_include_non_ruby_files_inside_rubylibdir
         | 
| 88 | 
            +
                  path = Pathname.new(RbConfig::CONFIG["rubylibdir"]).join("extra_file.txt").to_s
         | 
| 89 | 
            +
                  FileUtils.touch(path)
         | 
| 90 | 
            +
                  indexables = @config.indexables
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  assert(indexables.none? { |indexable| indexable.full_path == path })
         | 
| 93 | 
            +
                ensure
         | 
| 94 | 
            +
                  FileUtils.rm(T.must(path))
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 87 97 | 
             
                def test_paths_are_unique
         | 
| 88 98 | 
             
                  @config.load_config
         | 
| 89 99 | 
             
                  indexables = @config.indexables
         | 
| @@ -246,5 +246,16 @@ module RubyIndexer | |
| 246 246 | 
             
                  entry = T.must(entries.first).first
         | 
| 247 247 | 
             
                  assert_equal("baz", entry.name)
         | 
| 248 248 | 
             
                end
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                def test_indexing_prism_fixtures_succeeds
         | 
| 251 | 
            +
                  fixtures = Dir.glob("test/fixtures/prism/test/prism/fixtures/**/*.txt")
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                  fixtures.each do |fixture|
         | 
| 254 | 
            +
                    indexable_path = IndexablePath.new("", fixture)
         | 
| 255 | 
            +
                    @index.index_single(indexable_path)
         | 
| 256 | 
            +
                  end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                  refute_empty(@index.instance_variable_get(:@entries))
         | 
| 259 | 
            +
                end
         | 
| 249 260 | 
             
              end
         | 
| 250 261 | 
             
            end
         | 
| @@ -70,6 +70,42 @@ module RubyIndexer | |
| 70 70 | 
             
                  assert_instance_of(Entry::RequiredParameter, parameter)
         | 
| 71 71 | 
             
                end
         | 
| 72 72 |  | 
| 73 | 
            +
                def test_method_with_optional_parameters
         | 
| 74 | 
            +
                  index(<<~RUBY)
         | 
| 75 | 
            +
                    class Foo
         | 
| 76 | 
            +
                      def bar(a = 123)
         | 
| 77 | 
            +
                      end
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  RUBY
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
         | 
| 82 | 
            +
                  entry = T.must(@index["bar"].first)
         | 
| 83 | 
            +
                  assert_equal(1, entry.parameters.length)
         | 
| 84 | 
            +
                  parameter = entry.parameters.first
         | 
| 85 | 
            +
                  assert_equal(:a, parameter.name)
         | 
| 86 | 
            +
                  assert_instance_of(Entry::OptionalParameter, parameter)
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                def test_method_with_keyword_parameters
         | 
| 90 | 
            +
                  index(<<~RUBY)
         | 
| 91 | 
            +
                    class Foo
         | 
| 92 | 
            +
                      def bar(a:, b: 123)
         | 
| 93 | 
            +
                      end
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  RUBY
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
         | 
| 98 | 
            +
                  entry = T.must(@index["bar"].first)
         | 
| 99 | 
            +
                  assert_equal(2, entry.parameters.length)
         | 
| 100 | 
            +
                  a, b = entry.parameters
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  assert_equal(:a, a.name)
         | 
| 103 | 
            +
                  assert_instance_of(Entry::KeywordParameter, a)
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  assert_equal(:b, b.name)
         | 
| 106 | 
            +
                  assert_instance_of(Entry::OptionalKeywordParameter, b)
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 73 109 | 
             
                def test_keeps_track_of_method_owner
         | 
| 74 110 | 
             
                  index(<<~RUBY)
         | 
| 75 111 | 
             
                    class Foo
         | 
| @@ -83,5 +119,35 @@ module RubyIndexer | |
| 83 119 |  | 
| 84 120 | 
             
                  assert_equal("Foo", owner_name)
         | 
| 85 121 | 
             
                end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                def test_keeps_track_of_attributes
         | 
| 124 | 
            +
                  index(<<~RUBY)
         | 
| 125 | 
            +
                    class Foo
         | 
| 126 | 
            +
                      # Hello there
         | 
| 127 | 
            +
                      attr_reader :bar, :other
         | 
| 128 | 
            +
                      attr_writer :baz
         | 
| 129 | 
            +
                      attr_accessor :qux
         | 
| 130 | 
            +
                    end
         | 
| 131 | 
            +
                  RUBY
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                  assert_entry("bar", Entry::Accessor, "/fake/path/foo.rb:2-15:2-18")
         | 
| 134 | 
            +
                  assert_equal("Hello there", @index["bar"].first.comments.join("\n"))
         | 
| 135 | 
            +
                  assert_entry("other", Entry::Accessor, "/fake/path/foo.rb:2-21:2-26")
         | 
| 136 | 
            +
                  assert_equal("Hello there", @index["other"].first.comments.join("\n"))
         | 
| 137 | 
            +
                  assert_entry("baz=", Entry::Accessor, "/fake/path/foo.rb:3-15:3-18")
         | 
| 138 | 
            +
                  assert_entry("qux", Entry::Accessor, "/fake/path/foo.rb:4-17:4-20")
         | 
| 139 | 
            +
                  assert_entry("qux=", Entry::Accessor, "/fake/path/foo.rb:4-17:4-20")
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                def test_ignores_attributes_invoked_on_constant
         | 
| 143 | 
            +
                  index(<<~RUBY)
         | 
| 144 | 
            +
                    class Foo
         | 
| 145 | 
            +
                    end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                    Foo.attr_reader :bar
         | 
| 148 | 
            +
                  RUBY
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                  assert_no_entry("bar")
         | 
| 151 | 
            +
                end
         | 
| 86 152 | 
             
              end
         | 
| 87 153 | 
             
            end
         | 
    
        data/lib/ruby_lsp/addon.rb
    CHANGED
    
    | @@ -41,8 +41,8 @@ module RubyLsp | |
| 41 41 | 
             
                  end
         | 
| 42 42 |  | 
| 43 43 | 
             
                  # Discovers and loads all addons. Returns the list of activated addons
         | 
| 44 | 
            -
                  sig { returns(T::Array[Addon]) }
         | 
| 45 | 
            -
                  def load_addons
         | 
| 44 | 
            +
                  sig { params(message_queue: Thread::Queue).returns(T::Array[Addon]) }
         | 
| 45 | 
            +
                  def load_addons(message_queue)
         | 
| 46 46 | 
             
                    # Require all addons entry points, which should be placed under
         | 
| 47 47 | 
             
                    # `some_gem/lib/ruby_lsp/your_gem_name/addon.rb`
         | 
| 48 48 | 
             
                    Gem.find_files("ruby_lsp/**/addon.rb").each do |addon|
         | 
| @@ -55,7 +55,7 @@ module RubyLsp | |
| 55 55 | 
             
                    # Activate each one of the discovered addons. If any problems occur in the addons, we don't want to
         | 
| 56 56 | 
             
                    # fail to boot the server
         | 
| 57 57 | 
             
                    addons.each do |addon|
         | 
| 58 | 
            -
                      addon.activate
         | 
| 58 | 
            +
                      addon.activate(message_queue)
         | 
| 59 59 | 
             
                      nil
         | 
| 60 60 | 
             
                    rescue => e
         | 
| 61 61 | 
             
                      addon.add_error(e)
         | 
| @@ -94,8 +94,8 @@ module RubyLsp | |
| 94 94 |  | 
| 95 95 | 
             
                # Each addon should implement `MyAddon#activate` and use to perform any sort of initialization, such as
         | 
| 96 96 | 
             
                # reading information into memory or even spawning a separate process
         | 
| 97 | 
            -
                sig { abstract.void }
         | 
| 98 | 
            -
                def activate; end
         | 
| 97 | 
            +
                sig { abstract.params(message_queue: Thread::Queue).void }
         | 
| 98 | 
            +
                def activate(message_queue); end
         | 
| 99 99 |  | 
| 100 100 | 
             
                # Each addon should implement `MyAddon#deactivate` and use to perform any clean up, like shutting down a
         | 
| 101 101 | 
             
                # child process
         | 
| @@ -111,10 +111,9 @@ module RubyLsp | |
| 111 111 | 
             
                  overridable.params(
         | 
| 112 112 | 
             
                    uri: URI::Generic,
         | 
| 113 113 | 
             
                    dispatcher: Prism::Dispatcher,
         | 
| 114 | 
            -
                    message_queue: Thread::Queue,
         | 
| 115 114 | 
             
                  ).returns(T.nilable(Listener[T::Array[Interface::CodeLens]]))
         | 
| 116 115 | 
             
                end
         | 
| 117 | 
            -
                def create_code_lens_listener(uri, dispatcher | 
| 116 | 
            +
                def create_code_lens_listener(uri, dispatcher); end
         | 
| 118 117 |  | 
| 119 118 | 
             
                # Creates a new Hover listener. This method is invoked on every Hover request
         | 
| 120 119 | 
             
                sig do
         | 
| @@ -122,19 +121,17 @@ module RubyLsp | |
| 122 121 | 
             
                    nesting: T::Array[String],
         | 
| 123 122 | 
             
                    index: RubyIndexer::Index,
         | 
| 124 123 | 
             
                    dispatcher: Prism::Dispatcher,
         | 
| 125 | 
            -
                    message_queue: Thread::Queue,
         | 
| 126 124 | 
             
                  ).returns(T.nilable(Listener[T.nilable(Interface::Hover)]))
         | 
| 127 125 | 
             
                end
         | 
| 128 | 
            -
                def create_hover_listener(nesting, index, dispatcher | 
| 126 | 
            +
                def create_hover_listener(nesting, index, dispatcher); end
         | 
| 129 127 |  | 
| 130 128 | 
             
                # Creates a new DocumentSymbol listener. This method is invoked on every DocumentSymbol request
         | 
| 131 129 | 
             
                sig do
         | 
| 132 130 | 
             
                  overridable.params(
         | 
| 133 131 | 
             
                    dispatcher: Prism::Dispatcher,
         | 
| 134 | 
            -
                    message_queue: Thread::Queue,
         | 
| 135 132 | 
             
                  ).returns(T.nilable(Listener[T::Array[Interface::DocumentSymbol]]))
         | 
| 136 133 | 
             
                end
         | 
| 137 | 
            -
                def create_document_symbol_listener(dispatcher | 
| 134 | 
            +
                def create_document_symbol_listener(dispatcher); end
         | 
| 138 135 |  | 
| 139 136 | 
             
                # Creates a new Definition listener. This method is invoked on every Definition request
         | 
| 140 137 | 
             
                sig do
         | 
| @@ -143,9 +140,8 @@ module RubyLsp | |
| 143 140 | 
             
                    nesting: T::Array[String],
         | 
| 144 141 | 
             
                    index: RubyIndexer::Index,
         | 
| 145 142 | 
             
                    dispatcher: Prism::Dispatcher,
         | 
| 146 | 
            -
                    message_queue: Thread::Queue,
         | 
| 147 143 | 
             
                  ).returns(T.nilable(Listener[T.nilable(T.any(T::Array[Interface::Location], Interface::Location))]))
         | 
| 148 144 | 
             
                end
         | 
| 149 | 
            -
                def create_definition_listener(uri, nesting, index, dispatcher | 
| 145 | 
            +
                def create_definition_listener(uri, nesting, index, dispatcher); end
         | 
| 150 146 | 
             
              end
         | 
| 151 147 | 
             
            end
         | 
    
        data/lib/ruby_lsp/executor.rb
    CHANGED
    
    | @@ -41,7 +41,7 @@ module RubyLsp | |
| 41 41 | 
             
                  when "initialize"
         | 
| 42 42 | 
             
                    initialize_request(request.dig(:params))
         | 
| 43 43 | 
             
                  when "initialized"
         | 
| 44 | 
            -
                    Addon.load_addons
         | 
| 44 | 
            +
                    Addon.load_addons(@message_queue)
         | 
| 45 45 |  | 
| 46 46 | 
             
                    errored_addons = Addon.addons.select(&:error?)
         | 
| 47 47 |  | 
| @@ -95,12 +95,12 @@ module RubyLsp | |
| 95 95 |  | 
| 96 96 | 
             
                    # Run listeners for the document
         | 
| 97 97 | 
             
                    dispatcher = Prism::Dispatcher.new
         | 
| 98 | 
            -
                    folding_range = Requests::FoldingRanges.new(document.parse_result.comments, dispatcher | 
| 99 | 
            -
                    document_symbol = Requests::DocumentSymbol.new(dispatcher | 
| 100 | 
            -
                    document_link = Requests::DocumentLink.new(uri, document.comments, dispatcher | 
| 101 | 
            -
                    code_lens = Requests::CodeLens.new(uri, dispatcher | 
| 98 | 
            +
                    folding_range = Requests::FoldingRanges.new(document.parse_result.comments, dispatcher)
         | 
| 99 | 
            +
                    document_symbol = Requests::DocumentSymbol.new(dispatcher)
         | 
| 100 | 
            +
                    document_link = Requests::DocumentLink.new(uri, document.comments, dispatcher)
         | 
| 101 | 
            +
                    code_lens = Requests::CodeLens.new(uri, dispatcher)
         | 
| 102 102 |  | 
| 103 | 
            -
                    semantic_highlighting = Requests::SemanticHighlighting.new(dispatcher | 
| 103 | 
            +
                    semantic_highlighting = Requests::SemanticHighlighting.new(dispatcher)
         | 
| 104 104 | 
             
                    dispatcher.dispatch(document.tree)
         | 
| 105 105 |  | 
| 106 106 | 
             
                    # Store all responses retrieve in this round of visits in the cache and then return the response for the request
         | 
| @@ -265,13 +265,7 @@ module RubyLsp | |
| 265 265 | 
             
                  target = parent if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
         | 
| 266 266 |  | 
| 267 267 | 
             
                  dispatcher = Prism::Dispatcher.new
         | 
| 268 | 
            -
                  base_listener = Requests::Definition.new(
         | 
| 269 | 
            -
                    uri,
         | 
| 270 | 
            -
                    nesting,
         | 
| 271 | 
            -
                    @index,
         | 
| 272 | 
            -
                    dispatcher,
         | 
| 273 | 
            -
                    @message_queue,
         | 
| 274 | 
            -
                  )
         | 
| 268 | 
            +
                  base_listener = Requests::Definition.new(uri, nesting, @index, dispatcher)
         | 
| 275 269 | 
             
                  dispatcher.dispatch_once(target)
         | 
| 276 270 | 
             
                  base_listener.response
         | 
| 277 271 | 
             
                end
         | 
| @@ -297,7 +291,7 @@ module RubyLsp | |
| 297 291 |  | 
| 298 292 | 
             
                  # Instantiate all listeners
         | 
| 299 293 | 
             
                  dispatcher = Prism::Dispatcher.new
         | 
| 300 | 
            -
                  hover = Requests::Hover.new(@index, nesting, dispatcher | 
| 294 | 
            +
                  hover = Requests::Hover.new(@index, nesting, dispatcher)
         | 
| 301 295 |  | 
| 302 296 | 
             
                  # Emit events for all listeners
         | 
| 303 297 | 
             
                  dispatcher.dispatch_once(target)
         | 
| @@ -355,6 +349,11 @@ module RubyLsp | |
| 355 349 | 
             
                  # If formatter is set to `auto` but no supported formatting gem is found, don't attempt to format
         | 
| 356 350 | 
             
                  return if @store.formatter == "none"
         | 
| 357 351 |  | 
| 352 | 
            +
                  # Do not format files outside of the workspace. For example, if someone is looking at a gem's source code, we
         | 
| 353 | 
            +
                  # don't want to format it
         | 
| 354 | 
            +
                  path = uri.to_standardized_path
         | 
| 355 | 
            +
                  return unless path.nil? || path.start_with?(T.must(@store.workspace_uri.to_standardized_path))
         | 
| 356 | 
            +
             | 
| 358 357 | 
             
                  Requests::Formatting.new(@store.get(uri), formatter: @store.formatter).run
         | 
| 359 358 | 
             
                end
         | 
| 360 359 |  | 
| @@ -380,7 +379,7 @@ module RubyLsp | |
| 380 379 |  | 
| 381 380 | 
             
                  target, parent = document.locate_node(position)
         | 
| 382 381 | 
             
                  dispatcher = Prism::Dispatcher.new
         | 
| 383 | 
            -
                  listener = Requests::DocumentHighlight.new(target, parent, dispatcher | 
| 382 | 
            +
                  listener = Requests::DocumentHighlight.new(target, parent, dispatcher)
         | 
| 384 383 | 
             
                  dispatcher.visit(document.tree)
         | 
| 385 384 | 
             
                  listener.response
         | 
| 386 385 | 
             
                end
         | 
| @@ -393,7 +392,7 @@ module RubyLsp | |
| 393 392 | 
             
                  end_line = range.dig(:end, :line)
         | 
| 394 393 |  | 
| 395 394 | 
             
                  dispatcher = Prism::Dispatcher.new
         | 
| 396 | 
            -
                  listener = Requests::InlayHints.new(start_line..end_line, dispatcher | 
| 395 | 
            +
                  listener = Requests::InlayHints.new(start_line..end_line, dispatcher)
         | 
| 397 396 | 
             
                  dispatcher.visit(document.tree)
         | 
| 398 397 | 
             
                  listener.response
         | 
| 399 398 | 
             
                end
         | 
| @@ -443,6 +442,11 @@ module RubyLsp | |
| 443 442 |  | 
| 444 443 | 
             
                sig { params(uri: URI::Generic).returns(T.nilable(Interface::FullDocumentDiagnosticReport)) }
         | 
| 445 444 | 
             
                def diagnostic(uri)
         | 
| 445 | 
            +
                  # Do not compute diagnostics for files outside of the workspace. For example, if someone is looking at a gem's
         | 
| 446 | 
            +
                  # source code, we don't want to show diagnostics for it
         | 
| 447 | 
            +
                  path = uri.to_standardized_path
         | 
| 448 | 
            +
                  return unless path.nil? || path.start_with?(T.must(@store.workspace_uri.to_standardized_path))
         | 
| 449 | 
            +
             | 
| 446 450 | 
             
                  response = @store.cache_fetch(uri, "textDocument/diagnostic") do |document|
         | 
| 447 451 | 
             
                    Requests::Diagnostics.new(document).run
         | 
| 448 452 | 
             
                  end
         | 
| @@ -457,11 +461,7 @@ module RubyLsp | |
| 457 461 | 
             
                  end_line = range.dig(:end, :line)
         | 
| 458 462 |  | 
| 459 463 | 
             
                  dispatcher = Prism::Dispatcher.new
         | 
| 460 | 
            -
                  listener = Requests::SemanticHighlighting.new(
         | 
| 461 | 
            -
                    dispatcher,
         | 
| 462 | 
            -
                    @message_queue,
         | 
| 463 | 
            -
                    range: start_line..end_line,
         | 
| 464 | 
            -
                  )
         | 
| 464 | 
            +
                  listener = Requests::SemanticHighlighting.new(dispatcher, range: start_line..end_line)
         | 
| 465 465 | 
             
                  dispatcher.visit(document.tree)
         | 
| 466 466 |  | 
| 467 467 | 
             
                  Requests::Support::SemanticTokenEncoder.new.encode(listener.response)
         | 
| @@ -513,12 +513,7 @@ module RubyLsp | |
| 513 513 | 
             
                  return unless target
         | 
| 514 514 |  | 
| 515 515 | 
             
                  dispatcher = Prism::Dispatcher.new
         | 
| 516 | 
            -
                  listener = Requests::Completion.new(
         | 
| 517 | 
            -
                    @index,
         | 
| 518 | 
            -
                    nesting,
         | 
| 519 | 
            -
                    dispatcher,
         | 
| 520 | 
            -
                    @message_queue,
         | 
| 521 | 
            -
                  )
         | 
| 516 | 
            +
                  listener = Requests::Completion.new(@index, nesting, dispatcher)
         | 
| 522 517 | 
             
                  dispatcher.dispatch_once(target)
         | 
| 523 518 | 
             
                  listener.response
         | 
| 524 519 | 
             
                end
         | 
| @@ -583,6 +578,9 @@ module RubyLsp | |
| 583 578 | 
             
                def initialize_request(options)
         | 
| 584 579 | 
             
                  @store.clear
         | 
| 585 580 |  | 
| 581 | 
            +
                  workspace_uri = options.dig(:workspaceFolders, 0, :uri)
         | 
| 582 | 
            +
                  @store.workspace_uri = URI(workspace_uri) if workspace_uri
         | 
| 583 | 
            +
             | 
| 586 584 | 
             
                  encodings = options.dig(:capabilities, :general, :positionEncodings)
         | 
| 587 585 | 
             
                  @store.encoding = if encodings.nil? || encodings.empty?
         | 
| 588 586 | 
             
                    Constant::PositionEncodingKind::UTF16
         | 
    
        data/lib/ruby_lsp/listener.rb
    CHANGED
    
    | @@ -14,10 +14,9 @@ module RubyLsp | |
| 14 14 |  | 
| 15 15 | 
             
                abstract!
         | 
| 16 16 |  | 
| 17 | 
            -
                sig { params(dispatcher: Prism::Dispatcher | 
| 18 | 
            -
                def initialize(dispatcher | 
| 17 | 
            +
                sig { params(dispatcher: Prism::Dispatcher).void }
         | 
| 18 | 
            +
                def initialize(dispatcher)
         | 
| 19 19 | 
             
                  @dispatcher = dispatcher
         | 
| 20 | 
            -
                  @message_queue = message_queue
         | 
| 21 20 | 
             
                end
         | 
| 22 21 |  | 
| 23 22 | 
             
                sig { returns(ResponseType) }
         | 
| @@ -43,8 +42,8 @@ module RubyLsp | |
| 43 42 | 
             
                # When inheriting from ExtensibleListener, the `super` of constructor must be called **after** the subclass's own
         | 
| 44 43 | 
             
                # ivars have been initialized. This is because the constructor of ExtensibleListener calls
         | 
| 45 44 | 
             
                # `initialize_external_listener` which may depend on the subclass's ivars.
         | 
| 46 | 
            -
                sig { params(dispatcher: Prism::Dispatcher | 
| 47 | 
            -
                def initialize(dispatcher | 
| 45 | 
            +
                sig { params(dispatcher: Prism::Dispatcher).void }
         | 
| 46 | 
            +
                def initialize(dispatcher)
         | 
| 48 47 | 
             
                  super
         | 
| 49 48 | 
             
                  @response_merged = T.let(false, T::Boolean)
         | 
| 50 49 | 
             
                  @external_listeners = T.let(
         | 
| @@ -47,16 +47,18 @@ module RubyLsp | |
| 47 47 | 
             
                  sig { override.returns(ResponseType) }
         | 
| 48 48 | 
             
                  attr_reader :_response
         | 
| 49 49 |  | 
| 50 | 
            -
                  sig { params(uri: URI::Generic, dispatcher: Prism::Dispatcher | 
| 51 | 
            -
                  def initialize(uri, dispatcher | 
| 50 | 
            +
                  sig { params(uri: URI::Generic, dispatcher: Prism::Dispatcher).void }
         | 
| 51 | 
            +
                  def initialize(uri, dispatcher)
         | 
| 52 52 | 
             
                    @uri = T.let(uri, URI::Generic)
         | 
| 53 53 | 
             
                    @_response = T.let([], ResponseType)
         | 
| 54 54 | 
             
                    @path = T.let(uri.to_standardized_path, T.nilable(String))
         | 
| 55 55 | 
             
                    # visibility_stack is a stack of [current_visibility, previous_visibility]
         | 
| 56 56 | 
             
                    @visibility_stack = T.let([[:public, :public]], T::Array[T::Array[T.nilable(Symbol)]])
         | 
| 57 57 | 
             
                    @class_stack = T.let([], T::Array[String])
         | 
| 58 | 
            +
                    @group_id = T.let(1, Integer)
         | 
| 59 | 
            +
                    @group_id_stack = T.let([], T::Array[Integer])
         | 
| 58 60 |  | 
| 59 | 
            -
                    super(dispatcher | 
| 61 | 
            +
                    super(dispatcher)
         | 
| 60 62 |  | 
| 61 63 | 
             
                    dispatcher.register(
         | 
| 62 64 | 
             
                      self,
         | 
| @@ -82,12 +84,16 @@ module RubyLsp | |
| 82 84 | 
             
                        kind: :group,
         | 
| 83 85 | 
             
                      )
         | 
| 84 86 | 
             
                    end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                    @group_id_stack.push(@group_id)
         | 
| 89 | 
            +
                    @group_id += 1
         | 
| 85 90 | 
             
                  end
         | 
| 86 91 |  | 
| 87 92 | 
             
                  sig { params(node: Prism::ClassNode).void }
         | 
| 88 93 | 
             
                  def on_class_node_leave(node)
         | 
| 89 94 | 
             
                    @visibility_stack.pop
         | 
| 90 95 | 
             
                    @class_stack.pop
         | 
| 96 | 
            +
                    @group_id_stack.pop
         | 
| 91 97 | 
             
                  end
         | 
| 92 98 |  | 
| 93 99 | 
             
                  sig { params(node: Prism::DefNode).void }
         | 
| @@ -146,7 +152,7 @@ module RubyLsp | |
| 146 152 |  | 
| 147 153 | 
             
                  sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
         | 
| 148 154 | 
             
                  def initialize_external_listener(addon)
         | 
| 149 | 
            -
                    addon.create_code_lens_listener(@uri, @dispatcher | 
| 155 | 
            +
                    addon.create_code_lens_listener(@uri, @dispatcher)
         | 
| 150 156 | 
             
                  end
         | 
| 151 157 |  | 
| 152 158 | 
             
                  sig { override.params(other: Listener[ResponseType]).returns(T.self_type) }
         | 
| @@ -174,12 +180,15 @@ module RubyLsp | |
| 174 180 | 
             
                      },
         | 
| 175 181 | 
             
                    ]
         | 
| 176 182 |  | 
| 183 | 
            +
                    grouping_data = { group_id: @group_id_stack.last, kind: kind }
         | 
| 184 | 
            +
                    grouping_data[:id] = @group_id if kind == :group
         | 
| 185 | 
            +
             | 
| 177 186 | 
             
                    @_response << create_code_lens(
         | 
| 178 187 | 
             
                      node,
         | 
| 179 188 | 
             
                      title: "Run",
         | 
| 180 189 | 
             
                      command_name: "rubyLsp.runTest",
         | 
| 181 190 | 
             
                      arguments: arguments,
         | 
| 182 | 
            -
                      data: { type: "test",  | 
| 191 | 
            +
                      data: { type: "test", **grouping_data },
         | 
| 183 192 | 
             
                    )
         | 
| 184 193 |  | 
| 185 194 | 
             
                    @_response << create_code_lens(
         | 
| @@ -187,7 +196,7 @@ module RubyLsp | |
| 187 196 | 
             
                      title: "Run In Terminal",
         | 
| 188 197 | 
             
                      command_name: "rubyLsp.runTestInTerminal",
         | 
| 189 198 | 
             
                      arguments: arguments,
         | 
| 190 | 
            -
                      data: { type: "test_in_terminal",  | 
| 199 | 
            +
                      data: { type: "test_in_terminal", **grouping_data },
         | 
| 191 200 | 
             
                    )
         | 
| 192 201 |  | 
| 193 202 | 
             
                    @_response << create_code_lens(
         | 
| @@ -195,7 +204,7 @@ module RubyLsp | |
| 195 204 | 
             
                      title: "Debug",
         | 
| 196 205 | 
             
                      command_name: "rubyLsp.debugTest",
         | 
| 197 206 | 
             
                      arguments: arguments,
         | 
| 198 | 
            -
                      data: { type: "debug",  | 
| 207 | 
            +
                      data: { type: "debug", **grouping_data },
         | 
| 199 208 | 
             
                    )
         | 
| 200 209 | 
             
                  end
         | 
| 201 210 |  | 
| @@ -36,11 +36,10 @@ module RubyLsp | |
| 36 36 | 
             
                      index: RubyIndexer::Index,
         | 
| 37 37 | 
             
                      nesting: T::Array[String],
         | 
| 38 38 | 
             
                      dispatcher: Prism::Dispatcher,
         | 
| 39 | 
            -
                      message_queue: Thread::Queue,
         | 
| 40 39 | 
             
                    ).void
         | 
| 41 40 | 
             
                  end
         | 
| 42 | 
            -
                  def initialize(index, nesting, dispatcher | 
| 43 | 
            -
                    super(dispatcher | 
| 41 | 
            +
                  def initialize(index, nesting, dispatcher)
         | 
| 42 | 
            +
                    super(dispatcher)
         | 
| 44 43 | 
             
                    @_response = T.let([], ResponseType)
         | 
| 45 44 | 
             
                    @index = index
         | 
| 46 45 | 
             
                    @nesting = nesting
         | 
| @@ -137,18 +136,22 @@ module RubyLsp | |
| 137 136 |  | 
| 138 137 | 
             
                    receiver = T.must(receiver_entries.first)
         | 
| 139 138 |  | 
| 140 | 
            -
                     | 
| 141 | 
            -
             | 
| 142 | 
            -
                      entry = entries.find { |e| e.owner&.name == receiver.name }
         | 
| 139 | 
            +
                    @index.prefix_search(name).each do |entries|
         | 
| 140 | 
            +
                      entry = entries.find { |e| e.is_a?(RubyIndexer::Entry::Member) && e.owner&.name == receiver.name }
         | 
| 143 141 | 
             
                      next unless entry
         | 
| 144 142 |  | 
| 145 | 
            -
                      @_response << build_method_completion(entry, node)
         | 
| 143 | 
            +
                      @_response << build_method_completion(T.cast(entry, RubyIndexer::Entry::Member), node)
         | 
| 146 144 | 
             
                    end
         | 
| 147 145 | 
             
                  end
         | 
| 148 146 |  | 
| 149 147 | 
             
                  private
         | 
| 150 148 |  | 
| 151 | 
            -
                  sig  | 
| 149 | 
            +
                  sig do
         | 
| 150 | 
            +
                    params(
         | 
| 151 | 
            +
                      entry: RubyIndexer::Entry::Member,
         | 
| 152 | 
            +
                      node: Prism::CallNode,
         | 
| 153 | 
            +
                    ).returns(Interface::CompletionItem)
         | 
| 154 | 
            +
                  end
         | 
| 152 155 | 
             
                  def build_method_completion(entry, node)
         | 
| 153 156 | 
             
                    name = entry.name
         | 
| 154 157 | 
             
                    parameters = entry.parameters
         | 
| @@ -168,13 +171,16 @@ module RubyLsp | |
| 168 171 |  | 
| 169 172 | 
             
                  sig { params(label: String, node: Prism::StringNode).returns(Interface::CompletionItem) }
         | 
| 170 173 | 
             
                  def build_completion(label, node)
         | 
| 174 | 
            +
                    # We should use the content location as we only replace the content and not the delimiters of the string
         | 
| 175 | 
            +
                    loc = node.content_loc
         | 
| 176 | 
            +
             | 
| 171 177 | 
             
                    Interface::CompletionItem.new(
         | 
| 172 178 | 
             
                      label: label,
         | 
| 173 179 | 
             
                      text_edit: Interface::TextEdit.new(
         | 
| 174 | 
            -
                        range:  | 
| 180 | 
            +
                        range: range_from_location(loc),
         | 
| 175 181 | 
             
                        new_text: label,
         | 
| 176 182 | 
             
                      ),
         | 
| 177 | 
            -
                      kind: Constant::CompletionItemKind:: | 
| 183 | 
            +
                      kind: Constant::CompletionItemKind::FILE,
         | 
| 178 184 | 
             
                    )
         | 
| 179 185 | 
             
                  end
         | 
| 180 186 |  | 
| @@ -37,16 +37,15 @@ module RubyLsp | |
| 37 37 | 
             
                      nesting: T::Array[String],
         | 
| 38 38 | 
             
                      index: RubyIndexer::Index,
         | 
| 39 39 | 
             
                      dispatcher: Prism::Dispatcher,
         | 
| 40 | 
            -
                      message_queue: Thread::Queue,
         | 
| 41 40 | 
             
                    ).void
         | 
| 42 41 | 
             
                  end
         | 
| 43 | 
            -
                  def initialize(uri, nesting, index, dispatcher | 
| 42 | 
            +
                  def initialize(uri, nesting, index, dispatcher)
         | 
| 44 43 | 
             
                    @uri = uri
         | 
| 45 44 | 
             
                    @nesting = nesting
         | 
| 46 45 | 
             
                    @index = index
         | 
| 47 46 | 
             
                    @_response = T.let(nil, ResponseType)
         | 
| 48 47 |  | 
| 49 | 
            -
                    super(dispatcher | 
| 48 | 
            +
                    super(dispatcher)
         | 
| 50 49 |  | 
| 51 50 | 
             
                    dispatcher.register(
         | 
| 52 51 | 
             
                      self,
         | 
| @@ -58,7 +57,7 @@ module RubyLsp | |
| 58 57 |  | 
| 59 58 | 
             
                  sig { override.params(addon: Addon).returns(T.nilable(RubyLsp::Listener[ResponseType])) }
         | 
| 60 59 | 
             
                  def initialize_external_listener(addon)
         | 
| 61 | 
            -
                    addon.create_definition_listener(@uri, @nesting, @index, @dispatcher | 
| 60 | 
            +
                    addon.create_definition_listener(@uri, @nesting, @index, @dispatcher)
         | 
| 62 61 | 
             
                  end
         | 
| 63 62 |  | 
| 64 63 | 
             
                  sig { override.params(other: Listener[ResponseType]).returns(T.self_type) }
         | 
| @@ -32,13 +32,8 @@ module RubyLsp | |
| 32 32 | 
             
                  def run
         | 
| 33 33 | 
             
                    # Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
         | 
| 34 34 | 
             
                    return syntax_error_diagnostics if @document.syntax_error?
         | 
| 35 | 
            -
             | 
| 36 35 | 
             
                    return unless defined?(Support::RuboCopDiagnosticsRunner)
         | 
| 37 36 |  | 
| 38 | 
            -
                    # Don't try to run RuboCop diagnostics for files outside the current working directory
         | 
| 39 | 
            -
                    path = @uri.to_standardized_path
         | 
| 40 | 
            -
                    return unless path.nil? || path.start_with?(T.must(WORKSPACE_URI.to_standardized_path))
         | 
| 41 | 
            -
             | 
| 42 37 | 
             
                    Support::RuboCopDiagnosticsRunner.instance.run(@uri, @document).map!(&:to_lsp_diagnostic)
         | 
| 43 38 | 
             
                  end
         | 
| 44 39 |  | 
| @@ -114,11 +114,10 @@ module RubyLsp | |
| 114 114 | 
             
                      target: T.nilable(Prism::Node),
         | 
| 115 115 | 
             
                      parent: T.nilable(Prism::Node),
         | 
| 116 116 | 
             
                      dispatcher: Prism::Dispatcher,
         | 
| 117 | 
            -
                      message_queue: Thread::Queue,
         | 
| 118 117 | 
             
                    ).void
         | 
| 119 118 | 
             
                  end
         | 
| 120 | 
            -
                  def initialize(target, parent, dispatcher | 
| 121 | 
            -
                    super(dispatcher | 
| 119 | 
            +
                  def initialize(target, parent, dispatcher)
         | 
| 120 | 
            +
                    super(dispatcher)
         | 
| 122 121 |  | 
| 123 122 | 
             
                    @_response = T.let([], T::Array[Interface::DocumentHighlight])
         | 
| 124 123 |  | 
| @@ -80,11 +80,10 @@ module RubyLsp | |
| 80 80 | 
             
                      uri: URI::Generic,
         | 
| 81 81 | 
             
                      comments: T::Array[Prism::Comment],
         | 
| 82 82 | 
             
                      dispatcher: Prism::Dispatcher,
         | 
| 83 | 
            -
                      message_queue: Thread::Queue,
         | 
| 84 83 | 
             
                    ).void
         | 
| 85 84 | 
             
                  end
         | 
| 86 | 
            -
                  def initialize(uri, comments, dispatcher | 
| 87 | 
            -
                    super(dispatcher | 
| 85 | 
            +
                  def initialize(uri, comments, dispatcher)
         | 
| 86 | 
            +
                    super(dispatcher)
         | 
| 88 87 |  | 
| 89 88 | 
             
                    # Match the version based on the version in the RBI file name. Notice that the `@` symbol is sanitized to `%40`
         | 
| 90 89 | 
             
                    # in the URI
         | 
| @@ -49,8 +49,8 @@ module RubyLsp | |
| 49 49 | 
             
                  sig { override.returns(T::Array[Interface::DocumentSymbol]) }
         | 
| 50 50 | 
             
                  attr_reader :_response
         | 
| 51 51 |  | 
| 52 | 
            -
                  sig { params(dispatcher: Prism::Dispatcher | 
| 53 | 
            -
                  def initialize(dispatcher | 
| 52 | 
            +
                  sig { params(dispatcher: Prism::Dispatcher).void }
         | 
| 53 | 
            +
                  def initialize(dispatcher)
         | 
| 54 54 | 
             
                    @root = T.let(SymbolHierarchyRoot.new, SymbolHierarchyRoot)
         | 
| 55 55 | 
             
                    @_response = T.let(@root.children, T::Array[Interface::DocumentSymbol])
         | 
| 56 56 | 
             
                    @stack = T.let(
         | 
| @@ -80,7 +80,7 @@ module RubyLsp | |
| 80 80 |  | 
| 81 81 | 
             
                  sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
         | 
| 82 82 | 
             
                  def initialize_external_listener(addon)
         | 
| 83 | 
            -
                    addon.create_document_symbol_listener(@dispatcher | 
| 83 | 
            +
                    addon.create_document_symbol_listener(@dispatcher)
         | 
| 84 84 | 
             
                  end
         | 
| 85 85 |  | 
| 86 86 | 
             
                  # Merges responses from other listeners
         | 
| @@ -21,9 +21,9 @@ module RubyLsp | |
| 21 21 |  | 
| 22 22 | 
             
                  ResponseType = type_member { { fixed: T::Array[Interface::FoldingRange] } }
         | 
| 23 23 |  | 
| 24 | 
            -
                  sig { params(comments: T::Array[Prism::Comment], dispatcher: Prism::Dispatcher | 
| 25 | 
            -
                  def initialize(comments, dispatcher | 
| 26 | 
            -
                    super(dispatcher | 
| 24 | 
            +
                  sig { params(comments: T::Array[Prism::Comment], dispatcher: Prism::Dispatcher).void }
         | 
| 25 | 
            +
                  def initialize(comments, dispatcher)
         | 
| 26 | 
            +
                    super(dispatcher)
         | 
| 27 27 |  | 
| 28 28 | 
             
                    @_response = T.let([], ResponseType)
         | 
| 29 29 | 
             
                    @requires = T.let([], T::Array[Prism::CallNode])
         | 
| @@ -40,6 +40,7 @@ module RubyLsp | |
| 40 40 | 
             
                      :on_array_node_enter,
         | 
| 41 41 | 
             
                      :on_block_node_enter,
         | 
| 42 42 | 
             
                      :on_case_node_enter,
         | 
| 43 | 
            +
                      :on_case_match_node_enter,
         | 
| 43 44 | 
             
                      :on_class_node_enter,
         | 
| 44 45 | 
             
                      :on_module_node_enter,
         | 
| 45 46 | 
             
                      :on_for_node_enter,
         | 
| @@ -51,7 +52,6 @@ module RubyLsp | |
| 51 52 | 
             
                      :on_else_node_enter,
         | 
| 52 53 | 
             
                      :on_ensure_node_enter,
         | 
| 53 54 | 
             
                      :on_begin_node_enter,
         | 
| 54 | 
            -
                      :on_string_concat_node_enter,
         | 
| 55 55 | 
             
                      :on_def_node_enter,
         | 
| 56 56 | 
             
                      :on_call_node_enter,
         | 
| 57 57 | 
             
                      :on_lambda_node_enter,
         | 
| @@ -91,10 +91,10 @@ module RubyLsp | |
| 91 91 |  | 
| 92 92 | 
             
                  sig { params(node: Prism::InterpolatedStringNode).void }
         | 
| 93 93 | 
             
                  def on_interpolated_string_node_enter(node)
         | 
| 94 | 
            -
                    opening_loc = node.opening_loc
         | 
| 95 | 
            -
                    closing_loc = node.closing_loc
         | 
| 94 | 
            +
                    opening_loc = node.opening_loc || node.location
         | 
| 95 | 
            +
                    closing_loc = node.closing_loc || node.parts.last&.location || node.location
         | 
| 96 96 |  | 
| 97 | 
            -
                    add_lines_range(opening_loc.start_line, closing_loc.start_line - 1) | 
| 97 | 
            +
                    add_lines_range(opening_loc.start_line, closing_loc.start_line - 1)
         | 
| 98 98 | 
             
                  end
         | 
| 99 99 |  | 
| 100 100 | 
             
                  sig { params(node: Prism::ArrayNode).void }
         | 
| @@ -112,6 +112,11 @@ module RubyLsp | |
| 112 112 | 
             
                    add_simple_range(node)
         | 
| 113 113 | 
             
                  end
         | 
| 114 114 |  | 
| 115 | 
            +
                  sig { params(node: Prism::CaseMatchNode).void }
         | 
| 116 | 
            +
                  def on_case_match_node_enter(node)
         | 
| 117 | 
            +
                    add_simple_range(node)
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
             | 
| 115 120 | 
             
                  sig { params(node: Prism::ClassNode).void }
         | 
| 116 121 | 
             
                  def on_class_node_enter(node)
         | 
| 117 122 | 
             
                    add_simple_range(node)
         | 
| @@ -167,14 +172,6 @@ module RubyLsp | |
| 167 172 | 
             
                    add_simple_range(node)
         | 
| 168 173 | 
             
                  end
         | 
| 169 174 |  | 
| 170 | 
            -
                  sig { params(node: Prism::StringConcatNode).void }
         | 
| 171 | 
            -
                  def on_string_concat_node_enter(node)
         | 
| 172 | 
            -
                    left = T.let(node.left, Prism::Node)
         | 
| 173 | 
            -
                    left = left.left while left.is_a?(Prism::StringConcatNode)
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                    add_lines_range(left.location.start_line, node.right.location.end_line - 1)
         | 
| 176 | 
            -
                  end
         | 
| 177 | 
            -
             | 
| 178 175 | 
             
                  sig { params(node: Prism::DefNode).void }
         | 
| 179 176 | 
             
                  def on_def_node_enter(node)
         | 
| 180 177 | 
             
                    params = node.parameters
         | 
| @@ -64,11 +64,6 @@ module RubyLsp | |
| 64 64 | 
             
                  sig { override.returns(T.nilable(T.all(T::Array[Interface::TextEdit], Object))) }
         | 
| 65 65 | 
             
                  def run
         | 
| 66 66 | 
             
                    return if @formatter == "none"
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                    # Don't try to format files outside the current working directory
         | 
| 69 | 
            -
                    path = @uri.to_standardized_path
         | 
| 70 | 
            -
                    return unless path.nil? || path.start_with?(T.must(WORKSPACE_URI.to_standardized_path))
         | 
| 71 | 
            -
             | 
| 72 67 | 
             
                    return if @document.syntax_error?
         | 
| 73 68 |  | 
| 74 69 | 
             
                    formatted_text = formatted_file
         | 
| @@ -37,15 +37,14 @@ module RubyLsp | |
| 37 37 | 
             
                      index: RubyIndexer::Index,
         | 
| 38 38 | 
             
                      nesting: T::Array[String],
         | 
| 39 39 | 
             
                      dispatcher: Prism::Dispatcher,
         | 
| 40 | 
            -
                      message_queue: Thread::Queue,
         | 
| 41 40 | 
             
                    ).void
         | 
| 42 41 | 
             
                  end
         | 
| 43 | 
            -
                  def initialize(index, nesting, dispatcher | 
| 42 | 
            +
                  def initialize(index, nesting, dispatcher)
         | 
| 44 43 | 
             
                    @index = index
         | 
| 45 44 | 
             
                    @nesting = nesting
         | 
| 46 45 | 
             
                    @_response = T.let(nil, ResponseType)
         | 
| 47 46 |  | 
| 48 | 
            -
                    super(dispatcher | 
| 47 | 
            +
                    super(dispatcher)
         | 
| 49 48 | 
             
                    dispatcher.register(
         | 
| 50 49 | 
             
                      self,
         | 
| 51 50 | 
             
                      :on_constant_read_node_enter,
         | 
| @@ -57,7 +56,7 @@ module RubyLsp | |
| 57 56 |  | 
| 58 57 | 
             
                  sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
         | 
| 59 58 | 
             
                  def initialize_external_listener(addon)
         | 
| 60 | 
            -
                    addon.create_hover_listener(@nesting, @index, @dispatcher | 
| 59 | 
            +
                    addon.create_hover_listener(@nesting, @index, @dispatcher)
         | 
| 61 60 | 
             
                  end
         | 
| 62 61 |  | 
| 63 62 | 
             
                  # Merges responses from other hover listeners
         | 
| @@ -39,9 +39,9 @@ module RubyLsp | |
| 39 39 | 
             
                  sig { override.returns(ResponseType) }
         | 
| 40 40 | 
             
                  attr_reader :_response
         | 
| 41 41 |  | 
| 42 | 
            -
                  sig { params(range: T::Range[Integer], dispatcher: Prism::Dispatcher | 
| 43 | 
            -
                  def initialize(range, dispatcher | 
| 44 | 
            -
                    super(dispatcher | 
| 42 | 
            +
                  sig { params(range: T::Range[Integer], dispatcher: Prism::Dispatcher).void }
         | 
| 43 | 
            +
                  def initialize(range, dispatcher)
         | 
| 44 | 
            +
                    super(dispatcher)
         | 
| 45 45 |  | 
| 46 46 | 
             
                    @_response = T.let([], ResponseType)
         | 
| 47 47 | 
             
                    @range = range
         | 
| @@ -20,8 +20,8 @@ module RubyLsp | |
| 20 20 |  | 
| 21 21 | 
             
                  END_REGEXES = T.let(
         | 
| 22 22 | 
             
                    [
         | 
| 23 | 
            -
                       | 
| 24 | 
            -
                      /.*\ | 
| 23 | 
            +
                      /\b(if|unless|for|while|class|module|until|def|case)\b.*/,
         | 
| 24 | 
            +
                      /.*\s\bdo\b/,
         | 
| 25 25 | 
             
                    ],
         | 
| 26 26 | 
             
                    T::Array[Regexp],
         | 
| 27 27 | 
             
                  )
         | 
| @@ -139,7 +139,6 @@ module RubyLsp | |
| 139 139 | 
             
                  sig { params(spaces: String).void }
         | 
| 140 140 | 
             
                  def handle_comment_line(spaces)
         | 
| 141 141 | 
             
                    add_edit_with_text("##{spaces}")
         | 
| 142 | 
            -
                    move_cursor_to(@position[:line], @indentation + spaces.size + 1)
         | 
| 143 142 | 
             
                  end
         | 
| 144 143 |  | 
| 145 144 | 
             
                  sig { params(text: String, position: Document::PositionShape).void }
         | 
| @@ -107,20 +107,15 @@ module RubyLsp | |
| 107 107 | 
             
                  sig { override.returns(ResponseType) }
         | 
| 108 108 | 
             
                  attr_reader :_response
         | 
| 109 109 |  | 
| 110 | 
            -
                  sig  | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
                      message_queue: Thread::Queue,
         | 
| 114 | 
            -
                      range: T.nilable(T::Range[Integer]),
         | 
| 115 | 
            -
                    ).void
         | 
| 116 | 
            -
                  end
         | 
| 117 | 
            -
                  def initialize(dispatcher, message_queue, range: nil)
         | 
| 118 | 
            -
                    super(dispatcher, message_queue)
         | 
| 110 | 
            +
                  sig { params(dispatcher: Prism::Dispatcher, range: T.nilable(T::Range[Integer])).void }
         | 
| 111 | 
            +
                  def initialize(dispatcher, range: nil)
         | 
| 112 | 
            +
                    super(dispatcher)
         | 
| 119 113 |  | 
| 120 114 | 
             
                    @_response = T.let([], ResponseType)
         | 
| 121 115 | 
             
                    @range = range
         | 
| 122 116 | 
             
                    @special_methods = T.let(nil, T.nilable(T::Array[String]))
         | 
| 123 117 | 
             
                    @current_scope = T.let(ParameterScope.new, ParameterScope)
         | 
| 118 | 
            +
                    @inside_regex_capture = T.let(false, T::Boolean)
         | 
| 124 119 |  | 
| 125 120 | 
             
                    dispatcher.register(
         | 
| 126 121 | 
             
                      self,
         | 
| @@ -152,6 +147,8 @@ module RubyLsp | |
| 152 147 | 
             
                      :on_local_variable_or_write_node_enter,
         | 
| 153 148 | 
             
                      :on_local_variable_target_node_enter,
         | 
| 154 149 | 
             
                      :on_block_local_variable_node_enter,
         | 
| 150 | 
            +
                      :on_match_write_node_enter,
         | 
| 151 | 
            +
                      :on_match_write_node_leave,
         | 
| 155 152 | 
             
                    )
         | 
| 156 153 | 
             
                  end
         | 
| 157 154 |  | 
| @@ -165,14 +162,28 @@ module RubyLsp | |
| 165 162 | 
             
                    # We can't push a semantic token for [] and []= because the argument inside the brackets is a part of
         | 
| 166 163 | 
             
                    # the message_loc
         | 
| 167 164 | 
             
                    return if message.start_with?("[") && (message.end_with?("]") || message.end_with?("]="))
         | 
| 168 | 
            -
             | 
| 169 | 
            -
                    return process_regexp_locals(node) if message == "=~"
         | 
| 165 | 
            +
                    return if message == "=~"
         | 
| 170 166 | 
             
                    return if special_method?(message)
         | 
| 171 167 |  | 
| 172 168 | 
             
                    type = Support::Sorbet.annotation?(node) ? :type : :method
         | 
| 173 169 | 
             
                    add_token(T.must(node.message_loc), type)
         | 
| 174 170 | 
             
                  end
         | 
| 175 171 |  | 
| 172 | 
            +
                  sig { params(node: Prism::MatchWriteNode).void }
         | 
| 173 | 
            +
                  def on_match_write_node_enter(node)
         | 
| 174 | 
            +
                    call = node.call
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                    if call.message == "=~"
         | 
| 177 | 
            +
                      @inside_regex_capture = true
         | 
| 178 | 
            +
                      process_regexp_locals(call)
         | 
| 179 | 
            +
                    end
         | 
| 180 | 
            +
                  end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                  sig { params(node: Prism::MatchWriteNode).void }
         | 
| 183 | 
            +
                  def on_match_write_node_leave(node)
         | 
| 184 | 
            +
                    @inside_regex_capture = true if node.call.message == "=~"
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 176 187 | 
             
                  sig { params(node: Prism::ConstantReadNode).void }
         | 
| 177 188 | 
             
                  def on_constant_read_node_enter(node)
         | 
| 178 189 | 
             
                    return unless visible?(node, @range)
         | 
| @@ -359,6 +370,12 @@ module RubyLsp | |
| 359 370 |  | 
| 360 371 | 
             
                  sig { params(node: Prism::LocalVariableTargetNode).void }
         | 
| 361 372 | 
             
                  def on_local_variable_target_node_enter(node)
         | 
| 373 | 
            +
                    # If we're inside a regex capture, Prism will add LocalVariableTarget nodes for each captured variable.
         | 
| 374 | 
            +
                    # Unfortunately, if the regex contains a backslash, the location will be incorrect and we'll end up highlighting
         | 
| 375 | 
            +
                    # the entire regex as a local variable. We process these captures in process_regexp_locals instead and then
         | 
| 376 | 
            +
                    # prevent pushing local variable target tokens. See https://github.com/ruby/prism/issues/1912
         | 
| 377 | 
            +
                    return if @inside_regex_capture
         | 
| 378 | 
            +
             | 
| 362 379 | 
             
                    return unless visible?(node, @range)
         | 
| 363 380 |  | 
| 364 381 | 
             
                    add_token(node.location, @current_scope.type_for(node.name))
         | 
| @@ -34,15 +34,10 @@ module RubyLsp | |
| 34 34 |  | 
| 35 35 | 
             
                    sig { override.params(uri: URI::Generic, document: Document).returns(T.nilable(String)) }
         | 
| 36 36 | 
             
                    def run(uri, document)
         | 
| 37 | 
            -
                       | 
| 38 | 
            -
             | 
| 39 | 
            -
                      return if @options.ignore_files.any? { |pattern| File.fnmatch(pattern, relative_path) }
         | 
| 37 | 
            +
                      path = uri.to_standardized_path
         | 
| 38 | 
            +
                      return if path && @options.ignore_files.any? { |pattern| File.fnmatch?("*/#{pattern}", path) }
         | 
| 40 39 |  | 
| 41 | 
            -
                      SyntaxTree.format(
         | 
| 42 | 
            -
                        document.source,
         | 
| 43 | 
            -
                        @options.print_width,
         | 
| 44 | 
            -
                        options: @options.formatter_options,
         | 
| 45 | 
            -
                      )
         | 
| 40 | 
            +
                      SyntaxTree.format(document.source, @options.print_width, options: @options.formatter_options)
         | 
| 46 41 | 
             
                    end
         | 
| 47 42 | 
             
                  end
         | 
| 48 43 | 
             
                end
         | 
| @@ -75,6 +75,8 @@ module RubyLsp | |
| 75 75 | 
             
                      Constant::SymbolKind::CONSTANT
         | 
| 76 76 | 
             
                    when RubyIndexer::Entry::Method
         | 
| 77 77 | 
             
                      entry.name == "initialize" ? Constant::SymbolKind::CONSTRUCTOR : Constant::SymbolKind::METHOD
         | 
| 78 | 
            +
                    when RubyIndexer::Entry::Accessor
         | 
| 79 | 
            +
                      Constant::SymbolKind::PROPERTY
         | 
| 78 80 | 
             
                    end
         | 
| 79 81 | 
             
                  end
         | 
| 80 82 | 
             
                end
         | 
    
        data/lib/ruby_lsp/store.rb
    CHANGED
    
    | @@ -17,6 +17,9 @@ module RubyLsp | |
| 17 17 | 
             
                sig { returns(T::Boolean) }
         | 
| 18 18 | 
             
                attr_accessor :experimental_features
         | 
| 19 19 |  | 
| 20 | 
            +
                sig { returns(URI::Generic) }
         | 
| 21 | 
            +
                attr_accessor :workspace_uri
         | 
| 22 | 
            +
             | 
| 20 23 | 
             
                sig { void }
         | 
| 21 24 | 
             
                def initialize
         | 
| 22 25 | 
             
                  @state = T.let({}, T::Hash[String, Document])
         | 
| @@ -24,6 +27,7 @@ module RubyLsp | |
| 24 27 | 
             
                  @formatter = T.let("auto", String)
         | 
| 25 28 | 
             
                  @supports_progress = T.let(true, T::Boolean)
         | 
| 26 29 | 
             
                  @experimental_features = T.let(false, T::Boolean)
         | 
| 30 | 
            +
                  @workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
         | 
| 27 31 | 
             
                end
         | 
| 28 32 |  | 
| 29 33 | 
             
                sig { params(uri: URI::Generic).returns(Document) }
         | 
    
        data/lib/ruby_lsp/utils.rb
    CHANGED
    
    | @@ -4,10 +4,6 @@ | |
| 4 4 | 
             
            module RubyLsp
         | 
| 5 5 | 
             
              # Used to indicate that a request shouldn't return a response
         | 
| 6 6 | 
             
              VOID = T.let(Object.new.freeze, Object)
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              # This freeze is not redundant since the interpolated string is mutable
         | 
| 9 | 
            -
              WORKSPACE_URI = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
         | 
| 10 | 
            -
             | 
| 11 7 | 
             
              BUNDLE_PATH = T.let(
         | 
| 12 8 | 
             
                begin
         | 
| 13 9 | 
             
                  Bundler.bundle_path.to_s
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ruby-lsp
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.13.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Shopify
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023-11- | 
| 11 | 
            +
            date: 2023-11-30 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: language_server-protocol
         | 
| @@ -30,20 +30,20 @@ dependencies: | |
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - ">="
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: 0. | 
| 33 | 
            +
                    version: 0.18.0
         | 
| 34 34 | 
             
                - - "<"
         | 
| 35 35 | 
             
                  - !ruby/object:Gem::Version
         | 
| 36 | 
            -
                    version: '0. | 
| 36 | 
            +
                    version: '0.19'
         | 
| 37 37 | 
             
              type: :runtime
         | 
| 38 38 | 
             
              prerelease: false
         | 
| 39 39 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ">="
         | 
| 42 42 | 
             
                  - !ruby/object:Gem::Version
         | 
| 43 | 
            -
                    version: 0. | 
| 43 | 
            +
                    version: 0.18.0
         | 
| 44 44 | 
             
                - - "<"
         | 
| 45 45 | 
             
                  - !ruby/object:Gem::Version
         | 
| 46 | 
            -
                    version: '0. | 
| 46 | 
            +
                    version: '0.19'
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: sorbet-runtime
         | 
| 49 49 | 
             
              requirement: !ruby/object:Gem::Requirement
         |