ruby-lsp 0.13.3 → 0.14.2

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp-doctor +2 -0
  5. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +4 -8
  6. data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +5 -1
  7. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +4 -2
  8. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +10 -5
  9. data/lib/ruby_indexer/test/classes_and_modules_test.rb +9 -0
  10. data/lib/ruby_indexer/test/index_test.rb +54 -3
  11. data/lib/ruby_lsp/addon.rb +34 -17
  12. data/lib/ruby_lsp/check_docs.rb +8 -8
  13. data/lib/ruby_lsp/executor.rb +28 -10
  14. data/lib/ruby_lsp/internal.rb +8 -6
  15. data/lib/ruby_lsp/listeners/code_lens.rb +54 -55
  16. data/lib/ruby_lsp/listeners/completion.rb +22 -18
  17. data/lib/ruby_lsp/listeners/definition.rb +31 -29
  18. data/lib/ruby_lsp/listeners/document_highlight.rb +6 -11
  19. data/lib/ruby_lsp/listeners/document_link.rb +6 -12
  20. data/lib/ruby_lsp/listeners/document_symbol.rb +194 -55
  21. data/lib/ruby_lsp/listeners/folding_ranges.rb +19 -23
  22. data/lib/ruby_lsp/listeners/hover.rb +36 -34
  23. data/lib/ruby_lsp/listeners/inlay_hints.rb +7 -13
  24. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -124
  25. data/lib/ruby_lsp/listeners/signature_help.rb +15 -14
  26. data/lib/ruby_lsp/requests/code_lens.rb +11 -19
  27. data/lib/ruby_lsp/requests/completion.rb +7 -9
  28. data/lib/ruby_lsp/requests/definition.rb +10 -22
  29. data/lib/ruby_lsp/requests/document_highlight.rb +7 -5
  30. data/lib/ruby_lsp/requests/document_link.rb +7 -6
  31. data/lib/ruby_lsp/requests/document_symbol.rb +5 -11
  32. data/lib/ruby_lsp/requests/folding_ranges.rb +11 -6
  33. data/lib/ruby_lsp/requests/hover.rb +18 -24
  34. data/lib/ruby_lsp/requests/inlay_hints.rb +7 -8
  35. data/lib/ruby_lsp/requests/on_type_formatting.rb +12 -2
  36. data/lib/ruby_lsp/requests/semantic_highlighting.rb +10 -8
  37. data/lib/ruby_lsp/requests/signature_help.rb +53 -18
  38. data/lib/ruby_lsp/requests/support/common.rb +38 -10
  39. data/lib/ruby_lsp/requests/support/dependency_detector.rb +5 -1
  40. data/lib/ruby_lsp/requests.rb +0 -1
  41. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +29 -0
  42. data/lib/ruby_lsp/response_builders/document_symbol.rb +57 -0
  43. data/lib/ruby_lsp/response_builders/hover.rb +49 -0
  44. data/lib/ruby_lsp/response_builders/response_builder.rb +16 -0
  45. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +199 -0
  46. data/lib/ruby_lsp/response_builders/signature_help.rb +28 -0
  47. data/lib/ruby_lsp/response_builders.rb +13 -0
  48. data/lib/ruby_lsp/server.rb +3 -3
  49. data/lib/ruby_lsp/setup_bundler.rb +64 -23
  50. data/lib/ruby_lsp/store.rb +4 -4
  51. metadata +17 -11
  52. data/lib/ruby_lsp/listener.rb +0 -33
  53. data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +0 -73
@@ -3,39 +3,20 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Listeners
6
- class DocumentSymbol < Listener
6
+ class DocumentSymbol
7
7
  extend T::Sig
8
- extend T::Generic
9
-
10
- ResponseType = type_member { { fixed: T::Array[Interface::DocumentSymbol] } }
8
+ include Requests::Support::Common
11
9
 
12
10
  ATTR_ACCESSORS = T.let([:attr_reader, :attr_writer, :attr_accessor].freeze, T::Array[Symbol])
13
11
 
14
- class SymbolHierarchyRoot
15
- extend T::Sig
16
-
17
- sig { returns(T::Array[Interface::DocumentSymbol]) }
18
- attr_reader :children
19
-
20
- sig { void }
21
- def initialize
22
- @children = T.let([], T::Array[Interface::DocumentSymbol])
23
- end
12
+ sig do
13
+ params(
14
+ response_builder: ResponseBuilders::DocumentSymbol,
15
+ dispatcher: Prism::Dispatcher,
16
+ ).void
24
17
  end
25
-
26
- sig { override.returns(T::Array[Interface::DocumentSymbol]) }
27
- attr_reader :_response
28
-
29
- sig { params(dispatcher: Prism::Dispatcher).void }
30
- def initialize(dispatcher)
31
- @root = T.let(SymbolHierarchyRoot.new, SymbolHierarchyRoot)
32
- @_response = T.let(@root.children, T::Array[Interface::DocumentSymbol])
33
- @stack = T.let(
34
- [@root],
35
- T::Array[T.any(SymbolHierarchyRoot, Interface::DocumentSymbol)],
36
- )
37
-
38
- super
18
+ def initialize(response_builder, dispatcher)
19
+ @response_builder = response_builder
39
20
 
40
21
  dispatcher.register(
41
22
  self,
@@ -44,6 +25,14 @@ module RubyLsp
44
25
  :on_call_node_enter,
45
26
  :on_constant_path_write_node_enter,
46
27
  :on_constant_write_node_enter,
28
+ :on_constant_path_or_write_node_enter,
29
+ :on_constant_path_operator_write_node_enter,
30
+ :on_constant_path_and_write_node_enter,
31
+ :on_constant_or_write_node_enter,
32
+ :on_constant_operator_write_node_enter,
33
+ :on_constant_and_write_node_enter,
34
+ :on_constant_target_node_enter,
35
+ :on_constant_path_target_node_enter,
47
36
  :on_def_node_enter,
48
37
  :on_def_node_leave,
49
38
  :on_module_node_enter,
@@ -52,12 +41,13 @@ module RubyLsp
52
41
  :on_class_variable_write_node_enter,
53
42
  :on_singleton_class_node_enter,
54
43
  :on_singleton_class_node_leave,
44
+ :on_alias_method_node_enter,
55
45
  )
56
46
  end
57
47
 
58
48
  sig { params(node: Prism::ClassNode).void }
59
49
  def on_class_node_enter(node)
60
- @stack << create_document_symbol(
50
+ @response_builder << create_document_symbol(
61
51
  name: node.constant_path.location.slice,
62
52
  kind: Constant::SymbolKind::CLASS,
63
53
  range_location: node.location,
@@ -67,14 +57,14 @@ module RubyLsp
67
57
 
68
58
  sig { params(node: Prism::ClassNode).void }
69
59
  def on_class_node_leave(node)
70
- @stack.pop
60
+ @response_builder.pop
71
61
  end
72
62
 
73
63
  sig { params(node: Prism::SingletonClassNode).void }
74
64
  def on_singleton_class_node_enter(node)
75
65
  expression = node.expression
76
66
 
77
- @stack << create_document_symbol(
67
+ @response_builder << create_document_symbol(
78
68
  name: "<< #{expression.slice}",
79
69
  kind: Constant::SymbolKind::NAMESPACE,
80
70
  range_location: node.location,
@@ -84,28 +74,15 @@ module RubyLsp
84
74
 
85
75
  sig { params(node: Prism::SingletonClassNode).void }
86
76
  def on_singleton_class_node_leave(node)
87
- @stack.pop
77
+ @response_builder.pop
88
78
  end
89
79
 
90
80
  sig { params(node: Prism::CallNode).void }
91
81
  def on_call_node_enter(node)
92
- return unless ATTR_ACCESSORS.include?(node.name) && node.receiver.nil?
93
-
94
- arguments = node.arguments
95
- return unless arguments
96
-
97
- arguments.arguments.each do |argument|
98
- next unless argument.is_a?(Prism::SymbolNode)
99
-
100
- name = argument.value
101
- next unless name
102
-
103
- create_document_symbol(
104
- name: name,
105
- kind: Constant::SymbolKind::FIELD,
106
- range_location: argument.location,
107
- selection_range_location: T.must(argument.value_loc),
108
- )
82
+ if ATTR_ACCESSORS.include?(node.name)
83
+ handle_attr_accessor(node)
84
+ elsif node.name == :alias_method
85
+ handle_alias_method(node)
109
86
  end
110
87
  end
111
88
 
@@ -129,14 +106,94 @@ module RubyLsp
129
106
  )
130
107
  end
131
108
 
109
+ sig { params(node: Prism::ConstantPathAndWriteNode).void }
110
+ def on_constant_path_and_write_node_enter(node)
111
+ create_document_symbol(
112
+ name: node.target.location.slice,
113
+ kind: Constant::SymbolKind::CONSTANT,
114
+ range_location: node.location,
115
+ selection_range_location: node.target.location,
116
+ )
117
+ end
118
+
119
+ sig { params(node: Prism::ConstantPathOrWriteNode).void }
120
+ def on_constant_path_or_write_node_enter(node)
121
+ create_document_symbol(
122
+ name: node.target.location.slice,
123
+ kind: Constant::SymbolKind::CONSTANT,
124
+ range_location: node.location,
125
+ selection_range_location: node.target.location,
126
+ )
127
+ end
128
+
129
+ sig { params(node: Prism::ConstantPathOperatorWriteNode).void }
130
+ def on_constant_path_operator_write_node_enter(node)
131
+ create_document_symbol(
132
+ name: node.target.location.slice,
133
+ kind: Constant::SymbolKind::CONSTANT,
134
+ range_location: node.location,
135
+ selection_range_location: node.target.location,
136
+ )
137
+ end
138
+
139
+ sig { params(node: Prism::ConstantOrWriteNode).void }
140
+ def on_constant_or_write_node_enter(node)
141
+ create_document_symbol(
142
+ name: node.name.to_s,
143
+ kind: Constant::SymbolKind::CONSTANT,
144
+ range_location: node.location,
145
+ selection_range_location: node.name_loc,
146
+ )
147
+ end
148
+
149
+ sig { params(node: Prism::ConstantAndWriteNode).void }
150
+ def on_constant_and_write_node_enter(node)
151
+ create_document_symbol(
152
+ name: node.name.to_s,
153
+ kind: Constant::SymbolKind::CONSTANT,
154
+ range_location: node.location,
155
+ selection_range_location: node.name_loc,
156
+ )
157
+ end
158
+
159
+ sig { params(node: Prism::ConstantOperatorWriteNode).void }
160
+ def on_constant_operator_write_node_enter(node)
161
+ create_document_symbol(
162
+ name: node.name.to_s,
163
+ kind: Constant::SymbolKind::CONSTANT,
164
+ range_location: node.location,
165
+ selection_range_location: node.name_loc,
166
+ )
167
+ end
168
+
169
+ sig { params(node: Prism::ConstantTargetNode).void }
170
+ def on_constant_target_node_enter(node)
171
+ create_document_symbol(
172
+ name: node.name.to_s,
173
+ kind: Constant::SymbolKind::CONSTANT,
174
+ range_location: node.location,
175
+ selection_range_location: node.location,
176
+ )
177
+ end
178
+
179
+ sig { params(node: Prism::ConstantPathTargetNode).void }
180
+ def on_constant_path_target_node_enter(node)
181
+ create_document_symbol(
182
+ name: node.slice,
183
+ kind: Constant::SymbolKind::CONSTANT,
184
+ range_location: node.location,
185
+ selection_range_location: node.location,
186
+ )
187
+ end
188
+
132
189
  sig { params(node: Prism::DefNode).void }
133
190
  def on_def_node_leave(node)
134
- @stack.pop
191
+ @response_builder.pop
135
192
  end
136
193
 
137
194
  sig { params(node: Prism::ModuleNode).void }
138
195
  def on_module_node_enter(node)
139
- @stack << create_document_symbol(
196
+ @response_builder << create_document_symbol(
140
197
  name: node.constant_path.location.slice,
141
198
  kind: Constant::SymbolKind::MODULE,
142
199
  range_location: node.location,
@@ -147,7 +204,7 @@ module RubyLsp
147
204
  sig { params(node: Prism::DefNode).void }
148
205
  def on_def_node_enter(node)
149
206
  receiver = node.receiver
150
- previous_symbol = @stack.last
207
+ previous_symbol = @response_builder.last
151
208
 
152
209
  if receiver.is_a?(Prism::SelfNode)
153
210
  name = "self.#{node.name}"
@@ -167,12 +224,12 @@ module RubyLsp
167
224
  selection_range_location: node.name_loc,
168
225
  )
169
226
 
170
- @stack << symbol
227
+ @response_builder << symbol
171
228
  end
172
229
 
173
230
  sig { params(node: Prism::ModuleNode).void }
174
231
  def on_module_node_leave(node)
175
- @stack.pop
232
+ @response_builder.pop
176
233
  end
177
234
 
178
235
  sig { params(node: Prism::InstanceVariableWriteNode).void }
@@ -195,6 +252,22 @@ module RubyLsp
195
252
  )
196
253
  end
197
254
 
255
+ sig { params(node: Prism::AliasMethodNode).void }
256
+ def on_alias_method_node_enter(node)
257
+ new_name_node = node.new_name
258
+ return unless new_name_node.is_a?(Prism::SymbolNode)
259
+
260
+ name = new_name_node.value
261
+ return unless name
262
+
263
+ create_document_symbol(
264
+ name: name,
265
+ kind: Constant::SymbolKind::METHOD,
266
+ range_location: new_name_node.location,
267
+ selection_range_location: T.must(new_name_node.value_loc),
268
+ )
269
+ end
270
+
198
271
  private
199
272
 
200
273
  sig do
@@ -214,10 +287,76 @@ module RubyLsp
214
287
  children: [],
215
288
  )
216
289
 
217
- T.must(@stack.last).children << symbol
290
+ @response_builder.last.children << symbol
218
291
 
219
292
  symbol
220
293
  end
294
+
295
+ sig { params(node: Prism::CallNode).void }
296
+ def handle_attr_accessor(node)
297
+ receiver = node.receiver
298
+ return if receiver && !receiver.is_a?(Prism::SelfNode)
299
+
300
+ arguments = node.arguments
301
+ return unless arguments
302
+
303
+ arguments.arguments.each do |argument|
304
+ if argument.is_a?(Prism::SymbolNode)
305
+ name = argument.value
306
+ next unless name
307
+
308
+ create_document_symbol(
309
+ name: name,
310
+ kind: Constant::SymbolKind::FIELD,
311
+ range_location: argument.location,
312
+ selection_range_location: T.must(argument.value_loc),
313
+ )
314
+ elsif argument.is_a?(Prism::StringNode)
315
+ name = argument.content
316
+ next if name.empty?
317
+
318
+ create_document_symbol(
319
+ name: name,
320
+ kind: Constant::SymbolKind::FIELD,
321
+ range_location: argument.location,
322
+ selection_range_location: argument.content_loc,
323
+ )
324
+ end
325
+ end
326
+ end
327
+
328
+ sig { params(node: Prism::CallNode).void }
329
+ def handle_alias_method(node)
330
+ receiver = node.receiver
331
+ return if receiver && !receiver.is_a?(Prism::SelfNode)
332
+
333
+ arguments = node.arguments
334
+ return unless arguments
335
+
336
+ new_name_argument = arguments.arguments.first
337
+
338
+ if new_name_argument.is_a?(Prism::SymbolNode)
339
+ name = new_name_argument.value
340
+ return unless name
341
+
342
+ create_document_symbol(
343
+ name: name,
344
+ kind: Constant::SymbolKind::METHOD,
345
+ range_location: new_name_argument.location,
346
+ selection_range_location: T.must(new_name_argument.value_loc),
347
+ )
348
+ elsif new_name_argument.is_a?(Prism::StringNode)
349
+ name = new_name_argument.content
350
+ return if name.empty?
351
+
352
+ create_document_symbol(
353
+ name: name,
354
+ kind: Constant::SymbolKind::METHOD,
355
+ range_location: new_name_argument.location,
356
+ selection_range_location: new_name_argument.content_loc,
357
+ )
358
+ end
359
+ end
221
360
  end
222
361
  end
223
362
  end
@@ -3,19 +3,20 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Listeners
6
- class FoldingRanges < Listener
6
+ class FoldingRanges
7
7
  extend T::Sig
8
- extend T::Generic
9
-
10
- ResponseType = type_member { { fixed: T::Array[Interface::FoldingRange] } }
11
-
12
- sig { params(comments: T::Array[Prism::Comment], dispatcher: Prism::Dispatcher).void }
13
- def initialize(comments, dispatcher)
14
- super(dispatcher)
15
-
16
- @_response = T.let([], ResponseType)
8
+ include Requests::Support::Common
9
+
10
+ sig do
11
+ params(
12
+ response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::FoldingRange],
13
+ comments: T::Array[Prism::Comment],
14
+ dispatcher: Prism::Dispatcher,
15
+ ).void
16
+ end
17
+ def initialize(response_builder, comments, dispatcher)
18
+ @response_builder = response_builder
17
19
  @requires = T.let([], T::Array[Prism::CallNode])
18
- @finalized_response = T.let(false, T::Boolean)
19
20
  @comments = comments
20
21
 
21
22
  dispatcher.register(
@@ -46,15 +47,10 @@ module RubyLsp
46
47
  )
47
48
  end
48
49
 
49
- sig { override.returns(ResponseType) }
50
- def _response
51
- unless @finalized_response
52
- push_comment_ranges
53
- emit_requires_range
54
- @finalized_response = true
55
- end
56
-
57
- @_response
50
+ sig { void }
51
+ def finalize_response!
52
+ push_comment_ranges
53
+ emit_requires_range
58
54
  end
59
55
 
60
56
  sig { params(node: Prism::IfNode).void }
@@ -203,7 +199,7 @@ module RubyLsp
203
199
  end.each do |chunk|
204
200
  next if chunk.length == 1
205
201
 
206
- @_response << Interface::FoldingRange.new(
202
+ @response_builder << Interface::FoldingRange.new(
207
203
  start_line: T.must(chunk.first).location.start_line - 1,
208
204
  end_line: T.must(chunk.last).location.end_line - 1,
209
205
  kind: "comment",
@@ -214,7 +210,7 @@ module RubyLsp
214
210
  sig { void }
215
211
  def emit_requires_range
216
212
  if @requires.length > 1
217
- @_response << Interface::FoldingRange.new(
213
+ @response_builder << Interface::FoldingRange.new(
218
214
  start_line: T.must(@requires.first).location.start_line - 1,
219
215
  end_line: T.must(@requires.last).location.end_line - 1,
220
216
  kind: "imports",
@@ -260,7 +256,7 @@ module RubyLsp
260
256
  emit_requires_range
261
257
  return if start_line >= end_line
262
258
 
263
- @_response << Interface::FoldingRange.new(
259
+ @response_builder << Interface::FoldingRange.new(
264
260
  start_line: start_line - 1,
265
261
  end_line: end_line - 1,
266
262
  kind: "region",
@@ -3,11 +3,9 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Listeners
6
- class Hover < Listener
6
+ class Hover
7
7
  extend T::Sig
8
- extend T::Generic
9
-
10
- ResponseType = type_member { { fixed: T.nilable(Interface::Hover) } }
8
+ include Requests::Support::Common
11
9
 
12
10
  ALLOWED_TARGETS = T.let(
13
11
  [
@@ -19,11 +17,17 @@ module RubyLsp
19
17
  T::Array[T.class_of(Prism::Node)],
20
18
  )
21
19
 
22
- sig { override.returns(ResponseType) }
23
- attr_reader :_response
20
+ ALLOWED_REMOTE_PROVIDERS = T.let(
21
+ [
22
+ "https://github.com",
23
+ "https://gitlab.com",
24
+ ].freeze,
25
+ T::Array[String],
26
+ )
24
27
 
25
28
  sig do
26
29
  params(
30
+ response_builder: ResponseBuilders::Hover,
27
31
  uri: URI::Generic,
28
32
  nesting: T::Array[String],
29
33
  index: RubyIndexer::Index,
@@ -31,14 +35,13 @@ module RubyLsp
31
35
  typechecker_enabled: T::Boolean,
32
36
  ).void
33
37
  end
34
- def initialize(uri, nesting, index, dispatcher, typechecker_enabled)
38
+ def initialize(response_builder, uri, nesting, index, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
39
+ @response_builder = response_builder
35
40
  @path = T.let(uri.to_standardized_path, T.nilable(String))
36
41
  @nesting = nesting
37
42
  @index = index
38
43
  @typechecker_enabled = typechecker_enabled
39
- @_response = T.let(nil, ResponseType)
40
44
 
41
- super(dispatcher)
42
45
  dispatcher.register(
43
46
  self,
44
47
  :on_constant_read_node_enter,
@@ -52,7 +55,10 @@ module RubyLsp
52
55
  def on_constant_read_node_enter(node)
53
56
  return if @typechecker_enabled
54
57
 
55
- generate_hover(node.slice, node.location)
58
+ name = constant_name(node)
59
+ return if name.nil?
60
+
61
+ generate_hover(name, node.location)
56
62
  end
57
63
 
58
64
  sig { params(node: Prism::ConstantWriteNode).void }
@@ -66,7 +72,10 @@ module RubyLsp
66
72
  def on_constant_path_node_enter(node)
67
73
  return if DependencyDetector.instance.typechecker
68
74
 
69
- generate_hover(node.slice, node.location)
75
+ name = constant_name(node)
76
+ return if name.nil?
77
+
78
+ generate_hover(name, node.location)
70
79
  end
71
80
 
72
81
  sig { params(node: Prism::CallNode).void }
@@ -83,15 +92,12 @@ module RubyLsp
83
92
  message = node.message
84
93
  return unless message
85
94
 
86
- target_method = @index.resolve_method(message, @nesting.join("::"))
87
- return unless target_method
88
-
89
- location = target_method.location
95
+ methods = @index.resolve_method(message, @nesting.join("::"))
96
+ return unless methods
90
97
 
91
- @_response = Interface::Hover.new(
92
- range: range_from_location(location),
93
- contents: markdown_from_index_entries(message, target_method),
94
- )
98
+ categorized_markdown_from_index_entries(message, methods).each do |category, content|
99
+ @response_builder.push(content, category: category)
100
+ end
95
101
  end
96
102
 
97
103
  private
@@ -106,10 +112,9 @@ module RubyLsp
106
112
  first_entry = T.must(entries.first)
107
113
  return if first_entry.visibility == :private && first_entry.name != "#{@nesting.join("::")}::#{name}"
108
114
 
109
- @_response = Interface::Hover.new(
110
- range: range_from_location(location),
111
- contents: markdown_from_index_entries(name, entries),
112
- )
115
+ categorized_markdown_from_index_entries(name, entries).each do |category, content|
116
+ @response_builder.push(content, category: category)
117
+ end
113
118
  end
114
119
 
115
120
  sig { params(node: Prism::CallNode).void }
@@ -132,18 +137,15 @@ module RubyLsp
132
137
  # Remove leading whitespace if a heredoc was used for the summary or description
133
138
  info = info.gsub(/^ +/, "")
134
139
 
135
- markdown = <<~MARKDOWN
136
- **#{spec.name}** (#{spec.version})
137
- #{info}
138
- MARKDOWN
139
-
140
- @_response = Interface::Hover.new(
141
- range: range_from_location(node.location),
142
- contents: Interface::MarkupContent.new(
143
- kind: Constant::MarkupKind::MARKDOWN,
144
- value: markdown,
145
- ),
140
+ remote_url = [spec.homepage, spec.metadata["source_code_uri"]].compact.find do |page|
141
+ page.start_with?(*ALLOWED_REMOTE_PROVIDERS)
142
+ end
143
+
144
+ @response_builder.push(
145
+ "**#{spec.name}** (#{spec.version}) #{remote_url && " - [open remote](#{remote_url})"}",
146
+ category: :title,
146
147
  )
148
+ @response_builder.push(info, category: :documentation)
147
149
  rescue Gem::MissingSpecError
148
150
  # Do nothing if the spec cannot be found
149
151
  end
@@ -3,28 +3,22 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Listeners
6
- class InlayHints < Listener
6
+ class InlayHints
7
7
  extend T::Sig
8
- extend T::Generic
9
-
10
- ResponseType = type_member { { fixed: T::Array[Interface::InlayHint] } }
8
+ include Requests::Support::Common
11
9
 
12
10
  RESCUE_STRING_LENGTH = T.let("rescue".length, Integer)
13
11
 
14
- sig { override.returns(ResponseType) }
15
- attr_reader :_response
16
-
17
12
  sig do
18
13
  params(
14
+ response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::InlayHint],
19
15
  range: T::Range[Integer],
20
16
  hints_configuration: RequestConfig,
21
17
  dispatcher: Prism::Dispatcher,
22
18
  ).void
23
19
  end
24
- def initialize(range, hints_configuration, dispatcher)
25
- super(dispatcher)
26
-
27
- @_response = T.let([], ResponseType)
20
+ def initialize(response_builder, range, hints_configuration, dispatcher)
21
+ @response_builder = response_builder
28
22
  @range = range
29
23
  @hints_configuration = hints_configuration
30
24
 
@@ -39,7 +33,7 @@ module RubyLsp
39
33
  loc = node.location
40
34
  return unless visible?(node, @range)
41
35
 
42
- @_response << Interface::InlayHint.new(
36
+ @response_builder << Interface::InlayHint.new(
43
37
  position: { line: loc.start_line - 1, character: loc.start_column + RESCUE_STRING_LENGTH },
44
38
  label: "StandardError",
45
39
  padding_left: true,
@@ -68,7 +62,7 @@ module RubyLsp
68
62
  tooltip = "This is a local variable: #{node_name}"
69
63
  end
70
64
 
71
- @_response << Interface::InlayHint.new(
65
+ @response_builder << Interface::InlayHint.new(
72
66
  position: { line: loc.start_line - 1, character: loc.start_column + node_name.length + 1 },
73
67
  label: node_name,
74
68
  padding_left: true,