ruby-lsp 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,7 +13,7 @@ module RubyLsp
13
13
  # registering the ruby-lsp as the Ruby formatter.
14
14
  #
15
15
  # The `rubyLsp.formatter` setting specifies which formatter to use.
16
- # If set to `auto`` then it behaves as follows:
16
+ # If set to `auto` then it behaves as follows:
17
17
  # * It will use RuboCop if it is part of the bundle.
18
18
  # * If RuboCop is not available, and `syntax_tree` is a direct dependency, it will use that.
19
19
  # * Otherwise, no formatting will be applied.
@@ -29,6 +29,29 @@ module RubyLsp
29
29
  class Error < StandardError; end
30
30
  class InvalidFormatter < StandardError; end
31
31
 
32
+ @formatters = T.let(
33
+ {
34
+ "syntax_tree" => Support::SyntaxTreeFormattingRunner.instance,
35
+ },
36
+ T::Hash[String, Support::FormatterRunner],
37
+ )
38
+
39
+ class << self
40
+ extend T::Sig
41
+
42
+ sig { returns(T::Hash[String, Support::FormatterRunner]) }
43
+ attr_reader :formatters
44
+
45
+ sig { params(identifier: String, instance: Support::FormatterRunner).void }
46
+ def register_formatter(identifier, instance)
47
+ @formatters[identifier] = instance
48
+ end
49
+ end
50
+
51
+ if defined?(Support::RuboCopFormattingRunner)
52
+ register_formatter("rubocop", Support::RuboCopFormattingRunner.instance)
53
+ end
54
+
32
55
  extend T::Sig
33
56
 
34
57
  sig { params(document: Document, formatter: String).void }
@@ -41,6 +64,8 @@ module RubyLsp
41
64
 
42
65
  sig { override.returns(T.nilable(T.all(T::Array[Interface::TextEdit], Object))) }
43
66
  def run
67
+ return if @formatter == "none"
68
+
44
69
  # Don't try to format files outside the current working directory
45
70
  return unless @uri.sub("file://", "").start_with?(Dir.pwd)
46
71
 
@@ -67,16 +92,10 @@ module RubyLsp
67
92
 
68
93
  sig { returns(T.nilable(String)) }
69
94
  def formatted_file
70
- case @formatter
71
- when "rubocop"
72
- if defined?(Support::RuboCopFormattingRunner)
73
- Support::RuboCopFormattingRunner.instance.run(@uri, @document)
74
- end
75
- when "syntax_tree"
76
- Support::SyntaxTreeFormattingRunner.instance.run(@uri, @document)
77
- else
78
- raise InvalidFormatter, "Unknown formatter: #{@formatter}"
79
- end
95
+ formatter_runner = Formatting.formatters[@formatter]
96
+ raise InvalidFormatter, "Formatter is not available: #{@formatter}" unless formatter_runner
97
+
98
+ formatter_runner.run(@uri, @document)
80
99
  end
81
100
  end
82
101
  end
@@ -18,39 +18,41 @@ module RubyLsp
18
18
  # puts "handle some rescue"
19
19
  # end
20
20
  # ```
21
- class InlayHints < BaseRequest
21
+ class InlayHints < Listener
22
+ extend T::Sig
23
+ extend T::Generic
24
+
25
+ ResponseType = type_member { { fixed: T::Array[Interface::InlayHint] } }
26
+
22
27
  RESCUE_STRING_LENGTH = T.let("rescue".length, Integer)
23
28
 
24
- sig { params(document: Document, range: T::Range[Integer]).void }
25
- def initialize(document, range)
26
- super(document)
29
+ sig { override.returns(ResponseType) }
30
+ attr_reader :response
31
+
32
+ sig { params(range: T::Range[Integer], emitter: EventEmitter, message_queue: Thread::Queue).void }
33
+ def initialize(range, emitter, message_queue)
34
+ super(emitter, message_queue)
27
35
 
28
- @hints = T.let([], T::Array[Interface::InlayHint])
36
+ @response = T.let([], ResponseType)
29
37
  @range = range
30
- end
31
38
 
32
- sig { override.returns(T.all(T::Array[Interface::InlayHint], Object)) }
33
- def run
34
- visit(@document.tree) if @document.parsed?
35
- @hints
39
+ emitter.register(self, :on_rescue)
36
40
  end
37
41
 
38
- sig { override.params(node: SyntaxTree::Rescue).void }
39
- def visit_rescue(node)
42
+ sig { params(node: SyntaxTree::Rescue).void }
43
+ def on_rescue(node)
40
44
  exception = node.exception
41
45
  return unless exception.nil? || exception.exceptions.nil?
42
46
 
43
47
  loc = node.location
44
48
  return unless visible?(node, @range)
45
49
 
46
- @hints << Interface::InlayHint.new(
50
+ @response << Interface::InlayHint.new(
47
51
  position: { line: loc.start_line - 1, character: loc.start_column + RESCUE_STRING_LENGTH },
48
52
  label: "StandardError",
49
53
  padding_left: true,
50
54
  tooltip: "StandardError is implied in a bare rescue",
51
55
  )
52
-
53
- super
54
56
  end
55
57
  end
56
58
  end
@@ -18,9 +18,11 @@ module RubyLsp
18
18
  # var # --> semantic highlighting: local variable
19
19
  # end
20
20
  # ```
21
- class SemanticHighlighting < BaseRequest
21
+ class SemanticHighlighting < Listener
22
22
  extend T::Sig
23
- include SyntaxTree::WithScope
23
+ extend T::Generic
24
+
25
+ ResponseType = type_member { { fixed: T::Array[SemanticToken] } }
24
26
 
25
27
  TOKEN_TYPES = T.let(
26
28
  {
@@ -102,99 +104,91 @@ module RubyLsp
102
104
  end
103
105
  end
104
106
 
107
+ sig { override.returns(ResponseType) }
108
+ attr_reader :response
109
+
105
110
  sig do
106
111
  params(
107
- document: Document,
112
+ emitter: EventEmitter,
113
+ message_queue: Thread::Queue,
108
114
  range: T.nilable(T::Range[Integer]),
109
- encoder: T.nilable(Support::SemanticTokenEncoder),
110
115
  ).void
111
116
  end
112
- def initialize(document, range: nil, encoder: nil)
113
- super(document)
117
+ def initialize(emitter, message_queue, range: nil)
118
+ super(emitter, message_queue)
114
119
 
115
- @encoder = encoder
116
- @tokens = T.let([], T::Array[SemanticToken])
117
- @tree = T.let(T.must(document.tree), SyntaxTree::Node)
120
+ @response = T.let([], ResponseType)
118
121
  @range = range
119
122
  @special_methods = T.let(nil, T.nilable(T::Array[String]))
120
- end
121
123
 
122
- sig do
123
- override.returns(
124
- T.any(
125
- Interface::SemanticTokens,
126
- T.all(T::Array[SemanticToken], Object),
127
- ),
124
+ emitter.register(
125
+ self,
126
+ :after_binary,
127
+ :on_block_var,
128
+ :on_call,
129
+ :on_class,
130
+ :on_command,
131
+ :on_command_call,
132
+ :on_const,
133
+ :on_def,
134
+ :on_field,
135
+ :on_kw,
136
+ :on_lambda_var,
137
+ :on_module,
138
+ :on_params,
139
+ :on_var_field,
140
+ :on_var_ref,
141
+ :on_vcall,
128
142
  )
129
143
  end
130
- def run
131
- return @tokens unless @document.parsed?
132
144
 
133
- visit(@tree)
134
- return @tokens unless @encoder
135
-
136
- @encoder.encode(@tokens)
137
- end
138
-
139
- sig { override.params(node: SyntaxTree::CallNode).void }
140
- def visit_call(node)
141
- return super unless visible?(node, @range)
142
-
143
- visit(node.receiver)
145
+ sig { params(node: SyntaxTree::CallNode).void }
146
+ def on_call(node)
147
+ return unless visible?(node, @range)
144
148
 
145
149
  message = node.message
146
150
  if !message.is_a?(Symbol) && !special_method?(message.value)
147
151
  type = Support::Sorbet.annotation?(node) ? :type : :method
148
-
149
152
  add_token(message.location, type)
150
153
  end
151
-
152
- visit(node.arguments)
153
154
  end
154
155
 
155
- sig { override.params(node: SyntaxTree::Command).void }
156
- def visit_command(node)
157
- return super unless visible?(node, @range)
156
+ sig { params(node: SyntaxTree::Command).void }
157
+ def on_command(node)
158
+ return unless visible?(node, @range)
158
159
 
159
- unless special_method?(node.message.value)
160
- add_token(node.message.location, :method)
161
- end
162
- visit(node.arguments)
163
- visit(node.block)
160
+ add_token(node.message.location, :method) unless special_method?(node.message.value)
164
161
  end
165
162
 
166
- sig { override.params(node: SyntaxTree::CommandCall).void }
167
- def visit_command_call(node)
168
- return super unless visible?(node, @range)
163
+ sig { params(node: SyntaxTree::CommandCall).void }
164
+ def on_command_call(node)
165
+ return unless visible?(node, @range)
169
166
 
170
- visit(node.receiver)
171
167
  message = node.message
172
168
  add_token(message.location, :method) unless message.is_a?(Symbol)
173
- visit(node.arguments)
174
- visit(node.block)
175
169
  end
176
170
 
177
- sig { override.params(node: SyntaxTree::Const).void }
178
- def visit_const(node)
179
- return super unless visible?(node, @range)
171
+ sig { params(node: SyntaxTree::Const).void }
172
+ def on_const(node)
173
+ return unless visible?(node, @range)
174
+ # When finding a module or class definition, we will have already pushed a token related to this constant. We
175
+ # need to look at the previous two tokens and if they match this locatione exactly, avoid pushing another token
176
+ # on top of the previous one
177
+ return if @response.last(2).any? { |token| token.location == node.location }
180
178
 
181
179
  add_token(node.location, :namespace)
182
180
  end
183
181
 
184
- sig { override.params(node: SyntaxTree::DefNode).void }
185
- def visit_def(node)
186
- return super unless visible?(node, @range)
182
+ sig { params(node: SyntaxTree::DefNode).void }
183
+ def on_def(node)
184
+ return unless visible?(node, @range)
187
185
 
188
186
  add_token(node.name.location, :method, [:declaration])
189
- visit(node.params)
190
- visit(node.bodystmt)
191
- visit(node.target) if node.target
192
- visit(node.operator) if node.operator
193
187
  end
194
188
 
195
- sig { override.params(node: SyntaxTree::Kw).void }
196
- def visit_kw(node)
197
- return super unless visible?(node, @range)
189
+ sig { params(node: SyntaxTree::Kw).void }
190
+ def on_kw(node)
191
+ return unless visible?(node, @range)
198
192
 
199
193
  case node.value
200
194
  when "self"
@@ -202,9 +196,9 @@ module RubyLsp
202
196
  end
203
197
  end
204
198
 
205
- sig { override.params(node: SyntaxTree::Params).void }
206
- def visit_params(node)
207
- return super unless visible?(node, @range)
199
+ sig { params(node: SyntaxTree::Params).void }
200
+ def on_params(node)
201
+ return unless visible?(node, @range)
208
202
 
209
203
  node.keywords.each do |keyword, *|
210
204
  location = keyword.location
@@ -220,22 +214,18 @@ module RubyLsp
220
214
  name = rest.name
221
215
  add_token(name.location, :parameter) if name
222
216
  end
223
-
224
- super
225
217
  end
226
218
 
227
- sig { override.params(node: SyntaxTree::Field).void }
228
- def visit_field(node)
229
- return super unless visible?(node, @range)
219
+ sig { params(node: SyntaxTree::Field).void }
220
+ def on_field(node)
221
+ return unless visible?(node, @range)
230
222
 
231
223
  add_token(node.name.location, :method)
232
-
233
- super
234
224
  end
235
225
 
236
- sig { override.params(node: SyntaxTree::VarField).void }
237
- def visit_var_field(node)
238
- return super unless visible?(node, @range)
226
+ sig { params(node: SyntaxTree::VarField).void }
227
+ def on_var_field(node)
228
+ return unless visible?(node, @range)
239
229
 
240
230
  value = node.value
241
231
 
@@ -243,18 +233,12 @@ module RubyLsp
243
233
  when SyntaxTree::Ident
244
234
  type = type_for_local(value)
245
235
  add_token(value.location, type)
246
- when Symbol
247
- # do nothing
248
- else
249
- visit(value)
250
236
  end
251
-
252
- super
253
237
  end
254
238
 
255
- sig { override.params(node: SyntaxTree::VarRef).void }
256
- def visit_var_ref(node)
257
- return super unless visible?(node, @range)
239
+ sig { params(node: SyntaxTree::VarRef).void }
240
+ def on_var_ref(node)
241
+ return unless visible?(node, @range)
258
242
 
259
243
  value = node.value
260
244
 
@@ -262,35 +246,29 @@ module RubyLsp
262
246
  when SyntaxTree::Ident
263
247
  type = type_for_local(value)
264
248
  add_token(value.location, type)
265
- when Symbol
266
- # do nothing
267
- else
268
- visit(value)
269
249
  end
270
250
  end
271
251
 
272
252
  # All block locals are variables. E.g.: [].each do |x; block_local|
273
- sig { override.params(node: SyntaxTree::BlockVar).void }
274
- def visit_block_var(node)
253
+ sig { params(node: SyntaxTree::BlockVar).void }
254
+ def on_block_var(node)
275
255
  node.locals.each { |local| add_token(local.location, :variable) }
276
- super
277
256
  end
278
257
 
279
258
  # All lambda locals are variables. E.g.: ->(x; lambda_local) {}
280
- sig { override.params(node: SyntaxTree::LambdaVar).void }
281
- def visit_lambda_var(node)
259
+ sig { params(node: SyntaxTree::LambdaVar).void }
260
+ def on_lambda_var(node)
282
261
  node.locals.each { |local| add_token(local.location, :variable) }
283
- super
284
262
  end
285
263
 
286
- sig { override.params(node: SyntaxTree::VCall).void }
287
- def visit_vcall(node)
288
- return super unless visible?(node, @range)
264
+ sig { params(node: SyntaxTree::VCall).void }
265
+ def on_vcall(node)
266
+ return unless visible?(node, @range)
289
267
 
290
268
  # A VCall may exist as a local in the current_scope. This happens when used named capture groups in a regexp
291
269
  ident = node.value
292
270
  value = ident.value
293
- local = current_scope.find_local(value)
271
+ local = @emitter.current_scope.find_local(value)
294
272
  return if local.nil? && special_method?(value)
295
273
 
296
274
  type = if local
@@ -304,11 +282,8 @@ module RubyLsp
304
282
  add_token(node.value.location, type)
305
283
  end
306
284
 
307
- sig { override.params(node: SyntaxTree::Binary).void }
308
- def visit_binary(node)
309
- # It's important to visit the regexp first in the WithScope module
310
- super
311
-
285
+ sig { params(node: SyntaxTree::Binary).void }
286
+ def after_binary(node)
312
287
  # You can only capture local variables with regexp by using the =~ operator
313
288
  return unless node.operator == :=~
314
289
 
@@ -324,38 +299,35 @@ module RubyLsp
324
299
 
325
300
  # For each capture name we find in the regexp, look for a local in the current_scope
326
301
  Regexp.new(content.value, Regexp::FIXEDENCODING).names.each do |name|
327
- local = current_scope.find_local(name)
302
+ local = @emitter.current_scope.find_local(name)
328
303
  next unless local
329
304
 
330
305
  local.definitions.each { |definition| add_token(definition, :variable) }
331
306
  end
332
307
  end
333
308
 
334
- sig { override.params(node: SyntaxTree::ClassDeclaration).void }
335
- def visit_class(node)
336
- return super unless visible?(node, @range)
309
+ sig { params(node: SyntaxTree::ClassDeclaration).void }
310
+ def on_class(node)
311
+ return unless visible?(node, @range)
337
312
 
338
313
  add_token(node.constant.location, :class, [:declaration])
339
314
 
340
315
  superclass = node.superclass
341
316
  add_token(superclass.location, :class) if superclass
342
-
343
- visit(node.bodystmt)
344
317
  end
345
318
 
346
- sig { override.params(node: SyntaxTree::ModuleDeclaration).void }
347
- def visit_module(node)
348
- return super unless visible?(node, @range)
319
+ sig { params(node: SyntaxTree::ModuleDeclaration).void }
320
+ def on_module(node)
321
+ return unless visible?(node, @range)
349
322
 
350
- add_token(node.constant.location, :class, [:declaration])
351
- visit(node.bodystmt)
323
+ add_token(node.constant.location, :namespace, [:declaration])
352
324
  end
353
325
 
354
326
  sig { params(location: SyntaxTree::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
355
327
  def add_token(location, type, modifiers = [])
356
328
  length = location.end_char - location.start_char
357
329
  modifiers_indices = modifiers.filter_map { |modifier| TOKEN_MODIFIERS[modifier] }
358
- @tokens.push(
330
+ @response.push(
359
331
  SemanticToken.new(
360
332
  location: location,
361
333
  length: length,
@@ -393,7 +365,7 @@ module RubyLsp
393
365
 
394
366
  sig { params(value: SyntaxTree::Ident).returns(Symbol) }
395
367
  def type_for_local(value)
396
- local = current_scope.find_local(value.value)
368
+ local = @emitter.current_scope.find_local(value.value)
397
369
 
398
370
  if local.nil? || local.type == :variable
399
371
  :variable
@@ -5,6 +5,8 @@ module RubyLsp
5
5
  module Requests
6
6
  module Support
7
7
  module Common
8
+ # WARNING: Methods in this class may be used by Ruby LSP extensions such as https://github.com/Shopify/ruby-lsp-rails,
9
+ # or extensions by created by developers outside of Shopify, so be cautious of changing anything.
8
10
  extend T::Sig
9
11
 
10
12
  sig { params(node: SyntaxTree::Node).returns(Interface::Range) }
@@ -55,25 +57,12 @@ module RubyLsp
55
57
  node: SyntaxTree::Node,
56
58
  title: String,
57
59
  command_name: String,
58
- path: String,
59
- name: String,
60
- test_command: String,
61
- type: String,
60
+ arguments: T.nilable(T::Array[T.untyped]),
61
+ data: T.nilable(T::Hash[T.untyped, T.untyped]),
62
62
  ).returns(Interface::CodeLens)
63
63
  end
64
- def create_code_lens(node, title:, command_name:, path:, name:, test_command:, type:)
64
+ def create_code_lens(node, title:, command_name:, arguments:, data:)
65
65
  range = range_from_syntax_tree_node(node)
66
- arguments = [
67
- path,
68
- name,
69
- test_command,
70
- {
71
- start_line: node.location.start_line - 1,
72
- start_column: node.location.start_column,
73
- end_line: node.location.end_line - 1,
74
- end_column: node.location.end_column,
75
- },
76
- ]
77
66
 
78
67
  Interface::CodeLens.new(
79
68
  range: range,
@@ -82,7 +71,7 @@ module RubyLsp
82
71
  command: command_name,
83
72
  arguments: arguments,
84
73
  ),
85
- data: { type: type },
74
+ data: data,
86
75
  )
87
76
  end
88
77
  end
@@ -0,0 +1,41 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module DependencyDetector
6
+ class << self
7
+ extend T::Sig
8
+
9
+ sig { returns(String) }
10
+ def detected_formatter
11
+ # NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.
12
+ if direct_dependency?(/^rubocop/)
13
+ "rubocop"
14
+ elsif direct_dependency?(/^syntax_tree$/)
15
+ "syntax_tree"
16
+ else
17
+ "none"
18
+ end
19
+ end
20
+
21
+ sig { returns(String) }
22
+ def detected_test_library
23
+ if direct_dependency?(/^minitest/)
24
+ "minitest"
25
+ elsif direct_dependency?(/^test-unit/)
26
+ "test-unit"
27
+ elsif direct_dependency?(/^rspec/)
28
+ "rspec"
29
+ else
30
+ warn("WARNING: No test library detected. Assuming minitest.")
31
+ "minitest"
32
+ end
33
+ end
34
+
35
+ sig { params(gem_pattern: Regexp).returns(T::Boolean) }
36
+ def direct_dependency?(gem_pattern)
37
+ Bundler.locked_gems.dependencies.keys.grep(gem_pattern).any?
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module Requests
6
+ module Support
7
+ module FormatterRunner
8
+ extend T::Sig
9
+ extend T::Helpers
10
+
11
+ interface!
12
+
13
+ sig { abstract.params(uri: String, document: Document).returns(T.nilable(String)) }
14
+ def run(uri, document); end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -13,6 +13,7 @@ module RubyLsp
13
13
  class RuboCopFormattingRunner
14
14
  extend T::Sig
15
15
  include Singleton
16
+ include Support::FormatterRunner
16
17
 
17
18
  sig { void }
18
19
  def initialize
@@ -20,7 +21,7 @@ module RubyLsp
20
21
  @runner = T.let(RuboCopRunner.new("-a"), RuboCopRunner)
21
22
  end
22
23
 
23
- sig { params(uri: String, document: Document).returns(String) }
24
+ sig { override.params(uri: String, document: Document).returns(String) }
24
25
  def run(uri, document)
25
26
  filename = CGI.unescape(URI.parse(uri).path)
26
27
 
@@ -78,7 +78,7 @@ module URI
78
78
  if URI.respond_to?(:register_scheme)
79
79
  URI.register_scheme("SOURCE", self)
80
80
  else
81
- @@schemes = T.let(@@schemes, T::Hash[String, Class]) # rubocop:disable Style/ClassVars
81
+ @@schemes = T.let(@@schemes, T::Hash[String, T::Class[T.anything]]) # rubocop:disable Style/ClassVars
82
82
  @@schemes["SOURCE"] = self
83
83
  end
84
84
  end
@@ -11,6 +11,7 @@ module RubyLsp
11
11
  class SyntaxTreeFormattingRunner
12
12
  extend T::Sig
13
13
  include Singleton
14
+ include Support::FormatterRunner
14
15
 
15
16
  sig { void }
16
17
  def initialize
@@ -25,7 +26,7 @@ module RubyLsp
25
26
  )
26
27
  end
27
28
 
28
- sig { params(uri: String, document: Document).returns(T.nilable(String)) }
29
+ sig { override.params(uri: String, document: Document).returns(T.nilable(String)) }
29
30
  def run(uri, document)
30
31
  relative_path = Pathname.new(URI(uri).path).relative_path_from(T.must(WORKSPACE_URI.path))
31
32
  return if @options.ignore_files.any? { |pattern| File.fnmatch(pattern, relative_path) }
@@ -49,6 +49,7 @@ module RubyLsp
49
49
  autoload :RailsDocumentClient, "ruby_lsp/requests/support/rails_document_client"
50
50
  autoload :PrefixTree, "ruby_lsp/requests/support/prefix_tree"
51
51
  autoload :Common, "ruby_lsp/requests/support/common"
52
+ autoload :FormatterRunner, "ruby_lsp/requests/support/formatter_runner"
52
53
  end
53
54
  end
54
55
  end
@@ -27,6 +27,9 @@ module RubyLsp
27
27
  # The messages queue includes requests and notifications to be sent to the client
28
28
  @message_queue = T.let(Thread::Queue.new, Thread::Queue)
29
29
 
30
+ # The executor is responsible for executing requests
31
+ @executor = T.let(Executor.new(@store, @message_queue), Executor)
32
+
30
33
  # Create a thread to watch the messages queue and send them to the client
31
34
  @message_dispatcher = T.let(
32
35
  Thread.new do
@@ -62,7 +65,7 @@ module RubyLsp
62
65
  @reader.read do |request|
63
66
  case request[:method]
64
67
  when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange"
65
- result = Executor.new(@store, @message_queue).execute(request)
68
+ result = @executor.execute(request)
66
69
  finalize_request(result, request)
67
70
  when "$/cancelRequest"
68
71
  # Cancel the job if it's still in the queue
@@ -126,7 +129,7 @@ module RubyLsp
126
129
  # We need to return nil to the client even if the request was cancelled
127
130
  Result.new(response: nil)
128
131
  else
129
- Executor.new(@store, @message_queue).execute(request)
132
+ @executor.execute(request)
130
133
  end
131
134
 
132
135
  finalize_request(result, request)
@@ -6,7 +6,7 @@ module RubyLsp
6
6
  VOID = T.let(Object.new.freeze, Object)
7
7
 
8
8
  # This freeze is not redundant since the interpolated string is mutable
9
- WORKSPACE_URI = T.let(URI("file://#{Dir.pwd}".freeze), URI::Generic) # rubocop:disable Style/RedundantFreeze
9
+ WORKSPACE_URI = T.let(URI("file://#{Dir.pwd}".freeze), URI::Generic)
10
10
 
11
11
  # A notification to be sent to the client
12
12
  class Message