ruby-lsp 0.23.11 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +10 -4
  5. data/exe/ruby-lsp-check +0 -4
  6. data/exe/ruby-lsp-launcher +45 -22
  7. data/exe/ruby-lsp-test-exec +6 -0
  8. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
  9. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
  10. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
  11. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +166 -281
  15. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  16. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
  17. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +25 -57
  18. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
  19. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
  20. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
  21. data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
  22. data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
  23. data/lib/ruby_indexer/test/configuration_test.rb +49 -9
  24. data/lib/ruby_indexer/test/constant_test.rb +34 -34
  25. data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
  26. data/lib/ruby_indexer/test/index_test.rb +185 -135
  27. data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
  28. data/lib/ruby_indexer/test/method_test.rb +166 -123
  29. data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
  30. data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
  31. data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
  32. data/lib/ruby_indexer/test/test_case.rb +9 -3
  33. data/lib/ruby_indexer/test/uri_test.rb +15 -2
  34. data/lib/ruby_lsp/addon.rb +88 -86
  35. data/lib/ruby_lsp/base_server.rb +59 -54
  36. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  37. data/lib/ruby_lsp/document.rb +205 -104
  38. data/lib/ruby_lsp/erb_document.rb +45 -47
  39. data/lib/ruby_lsp/global_state.rb +73 -57
  40. data/lib/ruby_lsp/internal.rb +8 -3
  41. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  42. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  43. data/lib/ruby_lsp/listeners/definition.rb +44 -58
  44. data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
  45. data/lib/ruby_lsp/listeners/document_link.rb +50 -70
  46. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  47. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  48. data/lib/ruby_lsp/listeners/hover.rb +107 -115
  49. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  50. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  51. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  52. data/lib/ruby_lsp/listeners/spec_style.rb +214 -0
  53. data/lib/ruby_lsp/listeners/test_discovery.rb +92 -0
  54. data/lib/ruby_lsp/listeners/test_style.rb +205 -95
  55. data/lib/ruby_lsp/node_context.rb +12 -39
  56. data/lib/ruby_lsp/rbs_document.rb +10 -11
  57. data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
  58. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  59. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  60. data/lib/ruby_lsp/requests/completion.rb +8 -21
  61. data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
  62. data/lib/ruby_lsp/requests/definition.rb +8 -20
  63. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  64. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  65. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  66. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  67. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  68. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  69. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  70. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +85 -0
  71. data/lib/ruby_lsp/requests/hover.rb +12 -25
  72. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  73. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  74. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  75. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  76. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  77. data/lib/ruby_lsp/requests/references.rb +17 -57
  78. data/lib/ruby_lsp/requests/rename.rb +27 -51
  79. data/lib/ruby_lsp/requests/request.rb +13 -25
  80. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  81. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  82. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  83. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  84. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  85. data/lib/ruby_lsp/requests/support/common.rb +16 -58
  86. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  87. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  88. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  89. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  90. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  91. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  92. data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
  93. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  94. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  95. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  96. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  97. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  98. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  99. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  100. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  101. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  102. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  103. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  104. data/lib/ruby_lsp/ruby_document.rb +32 -98
  105. data/lib/ruby_lsp/scope.rb +7 -11
  106. data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
  107. data/lib/ruby_lsp/server.rb +303 -196
  108. data/lib/ruby_lsp/setup_bundler.rb +121 -82
  109. data/lib/ruby_lsp/static_docs.rb +12 -7
  110. data/lib/ruby_lsp/store.rb +21 -49
  111. data/lib/ruby_lsp/test_helper.rb +3 -16
  112. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
  113. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  114. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  115. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  116. data/lib/ruby_lsp/utils.rb +138 -93
  117. data/static_docs/break.md +103 -0
  118. metadata +14 -20
  119. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -7,23 +7,17 @@ module RubyLsp
7
7
  # request is used to to resolve the edit field for a given code action, if it is not already provided in the
8
8
  # textDocument/codeAction response. We can use it for scenarios that require more computation such as refactoring.
9
9
  class CodeActionResolve < Request
10
- extend T::Sig
11
10
  include Support::Common
12
11
 
13
12
  NEW_VARIABLE_NAME = "new_variable"
14
13
  NEW_METHOD_NAME = "new_method"
15
14
 
16
15
  class CodeActionError < StandardError; end
16
+ class EmptySelectionError < CodeActionError; end
17
+ class InvalidTargetRangeError < CodeActionError; end
18
+ class UnknownCodeActionError < CodeActionError; end
17
19
 
18
- class Error < ::T::Enum
19
- enums do
20
- EmptySelection = new
21
- InvalidTargetRange = new
22
- UnknownCodeAction = new
23
- end
24
- end
25
-
26
- sig { params(document: RubyDocument, global_state: GlobalState, code_action: T::Hash[Symbol, T.untyped]).void }
20
+ #: (RubyDocument document, GlobalState global_state, Hash[Symbol, untyped] code_action) -> void
27
21
  def initialize(document, global_state, code_action)
28
22
  super()
29
23
  @document = document
@@ -31,9 +25,10 @@ module RubyLsp
31
25
  @code_action = code_action
32
26
  end
33
27
 
34
- sig { override.returns(T.any(Interface::CodeAction, Error)) }
28
+ # @override
29
+ #: -> (Interface::CodeAction)
35
30
  def perform
36
- return Error::EmptySelection if @document.source.empty?
31
+ raise EmptySelectionError, "Invalid selection for refactor" if @document.source.empty?
37
32
 
38
33
  case @code_action[:title]
39
34
  when CodeActions::EXTRACT_TO_VARIABLE_TITLE
@@ -47,26 +42,30 @@ module RubyLsp
47
42
  CodeActions::CREATE_ATTRIBUTE_ACCESSOR
48
43
  create_attribute_accessor
49
44
  else
50
- Error::UnknownCodeAction
45
+ raise UnknownCodeActionError, "Unknown code action: #{@code_action[:title]}"
51
46
  end
52
47
  end
53
48
 
54
49
  private
55
50
 
56
- sig { returns(T.any(Interface::CodeAction, Error)) }
51
+ #: -> (Interface::CodeAction)
57
52
  def switch_block_style
58
53
  source_range = @code_action.dig(:data, :range)
59
- return Error::EmptySelection if source_range[:start] == source_range[:end]
54
+ raise EmptySelectionError, "Invalid selection for refactor" if source_range[:start] == source_range[:end]
60
55
 
61
56
  target = @document.locate_first_within_range(
62
57
  @code_action.dig(:data, :range),
63
58
  node_types: [Prism::CallNode],
64
59
  )
65
60
 
66
- return Error::InvalidTargetRange unless target.is_a?(Prism::CallNode)
61
+ unless target.is_a?(Prism::CallNode)
62
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
63
+ end
67
64
 
68
65
  node = target.block
69
- return Error::InvalidTargetRange unless node.is_a?(Prism::BlockNode)
66
+ unless node.is_a?(Prism::BlockNode)
67
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
68
+ end
70
69
 
71
70
  indentation = " " * target.location.start_column unless node.opening_loc.slice == "do"
72
71
 
@@ -91,17 +90,17 @@ module RubyLsp
91
90
  )
92
91
  end
93
92
 
94
- sig { returns(T.any(Interface::CodeAction, Error)) }
93
+ #: -> (Interface::CodeAction)
95
94
  def refactor_variable
96
95
  source_range = @code_action.dig(:data, :range)
97
- return Error::EmptySelection if source_range[:start] == source_range[:end]
96
+ raise EmptySelectionError, "Invalid selection for refactor" if source_range[:start] == source_range[:end]
98
97
 
99
98
  start_index, end_index = @document.find_index_by_position(source_range[:start], source_range[:end])
100
- extracted_source = T.must(@document.source[start_index...end_index])
99
+ extracted_source = @document.source[start_index...end_index] #: as !nil
101
100
 
102
101
  # Find the closest statements node, so that we place the refactor in a valid position
103
102
  node_context = RubyDocument
104
- .locate(@document.parse_result.value,
103
+ .locate(@document.ast,
105
104
  start_index,
106
105
  node_types: [
107
106
  Prism::StatementsNode,
@@ -111,16 +110,20 @@ module RubyLsp
111
110
 
112
111
  closest_statements = node_context.node
113
112
  parent_statements = node_context.parent
114
- return Error::InvalidTargetRange if closest_statements.nil? || closest_statements.child_nodes.compact.empty?
113
+ if closest_statements.nil? || closest_statements.child_nodes.compact.empty?
114
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
115
+ end
115
116
 
116
117
  # Find the node with the end line closest to the requested position, so that we can place the refactor
117
118
  # immediately after that closest node
118
- closest_node = T.must(closest_statements.child_nodes.compact.min_by do |node|
119
+ closest_node = closest_statements.child_nodes.compact.min_by do |node|
119
120
  distance = source_range.dig(:start, :line) - (node.location.end_line - 1)
120
121
  distance <= 0 ? Float::INFINITY : distance
121
- end)
122
+ end #: as !nil
122
123
 
123
- return Error::InvalidTargetRange if closest_node.is_a?(Prism::MissingNode)
124
+ if closest_node.is_a?(Prism::MissingNode)
125
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
126
+ end
124
127
 
125
128
  closest_node_loc = closest_node.location
126
129
  # If the parent expression is a single line block, then we have to extract it inside of the one-line block
@@ -151,9 +154,12 @@ module RubyLsp
151
154
  lines = @document.source.lines
152
155
 
153
156
  indentation_line = lines[indentation_line_number]
154
- return Error::InvalidTargetRange unless indentation_line
157
+ unless indentation_line
158
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
159
+ end
155
160
 
156
- indentation = T.must(indentation_line[/\A */]).size
161
+ indentation = indentation_line[/\A */] #: as !nil
162
+ .size
157
163
 
158
164
  target_range = {
159
165
  start: { line: target_line, character: indentation },
@@ -161,7 +167,9 @@ module RubyLsp
161
167
  }
162
168
 
163
169
  line = lines[target_line]
164
- return Error::InvalidTargetRange unless line
170
+ unless line
171
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
172
+ end
165
173
 
166
174
  variable_source = if line.strip.empty?
167
175
  "\n#{" " * indentation}#{NEW_VARIABLE_NAME} = #{extracted_source}"
@@ -189,27 +197,31 @@ module RubyLsp
189
197
  )
190
198
  end
191
199
 
192
- sig { returns(T.any(Interface::CodeAction, Error)) }
200
+ #: -> (Interface::CodeAction)
193
201
  def refactor_method
194
202
  source_range = @code_action.dig(:data, :range)
195
- return Error::EmptySelection if source_range[:start] == source_range[:end]
203
+ raise EmptySelectionError, "Invalid selection for refactor" if source_range[:start] == source_range[:end]
196
204
 
197
205
  start_index, end_index = @document.find_index_by_position(source_range[:start], source_range[:end])
198
- extracted_source = T.must(@document.source[start_index...end_index])
206
+ extracted_source = @document.source[start_index...end_index] #: as !nil
199
207
 
200
208
  # Find the closest method declaration node, so that we place the refactor in a valid position
201
209
  node_context = RubyDocument.locate(
202
- @document.parse_result.value,
210
+ @document.ast,
203
211
  start_index,
204
212
  node_types: [Prism::DefNode],
205
213
  code_units_cache: @document.code_units_cache,
206
214
  )
207
215
  closest_node = node_context.node
208
- return Error::InvalidTargetRange unless closest_node
216
+ unless closest_node
217
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
218
+ end
209
219
 
210
220
  target_range = if closest_node.is_a?(Prism::DefNode)
211
221
  end_keyword_loc = closest_node.end_keyword_loc
212
- return Error::InvalidTargetRange unless end_keyword_loc
222
+ unless end_keyword_loc
223
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
224
+ end
213
225
 
214
226
  end_line = end_keyword_loc.end_line - 1
215
227
  character = end_keyword_loc.end_column
@@ -261,7 +273,7 @@ module RubyLsp
261
273
  )
262
274
  end
263
275
 
264
- sig { params(range: T::Hash[Symbol, T.untyped], new_text: String).returns(Interface::TextEdit) }
276
+ #: (Hash[Symbol, untyped] range, String new_text) -> Interface::TextEdit
265
277
  def create_text_edit(range, new_text)
266
278
  Interface::TextEdit.new(
267
279
  range: Interface::Range.new(
@@ -272,7 +284,7 @@ module RubyLsp
272
284
  )
273
285
  end
274
286
 
275
- sig { params(node: Prism::BlockNode, indentation: T.nilable(String)).returns(String) }
287
+ #: (Prism::BlockNode node, String? indentation) -> String
276
288
  def recursively_switch_nested_block_styles(node, indentation)
277
289
  parameters = node.parameters
278
290
  body = node.body
@@ -301,7 +313,7 @@ module RubyLsp
301
313
  source
302
314
  end
303
315
 
304
- sig { params(body: Prism::Node, indentation: T.nilable(String)).returns(String) }
316
+ #: (Prism::Node body, String? indentation) -> String
305
317
  def switch_block_body(body, indentation)
306
318
  # Check if there are any nested blocks inside of the current block
307
319
  body_loc = body.location
@@ -330,7 +342,7 @@ module RubyLsp
330
342
  indentation ? body_content.gsub(";", "\n") : "#{body_content.gsub("\n", ";")} "
331
343
  end
332
344
 
333
- sig { returns(T.any(Interface::CodeAction, Error)) }
345
+ #: -> (Interface::CodeAction)
334
346
  def create_attribute_accessor
335
347
  source_range = @code_action.dig(:data, :range)
336
348
 
@@ -348,20 +360,12 @@ module RubyLsp
348
360
  )
349
361
  node = node_context.node
350
362
 
351
- return Error::EmptySelection unless CodeActions::INSTANCE_VARIABLE_NODES.include?(node.class)
363
+ unless CodeActions::INSTANCE_VARIABLE_NODES.include?(node.class)
364
+ raise EmptySelectionError, "Invalid selection for refactor"
365
+ end
352
366
  end
353
367
 
354
- node = T.cast(
355
- node,
356
- T.any(
357
- Prism::InstanceVariableAndWriteNode,
358
- Prism::InstanceVariableOperatorWriteNode,
359
- Prism::InstanceVariableOrWriteNode,
360
- Prism::InstanceVariableReadNode,
361
- Prism::InstanceVariableTargetNode,
362
- Prism::InstanceVariableWriteNode,
363
- ),
364
- )
368
+ node = node #: as Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableReadNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode
365
369
 
366
370
  node_context = @document.locate_node(
367
371
  {
@@ -375,20 +379,20 @@ module RubyLsp
375
379
  ],
376
380
  )
377
381
  closest_node = node_context.node
378
- return Error::InvalidTargetRange if closest_node.nil?
382
+ if closest_node.nil?
383
+ raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
384
+ end
379
385
 
380
386
  attribute_name = node.name[1..]
381
387
  indentation = " " * (closest_node.location.start_column + 2)
382
- attribute_accessor_source = T.must(
383
- case @code_action[:title]
384
- when CodeActions::CREATE_ATTRIBUTE_READER
385
- "#{indentation}attr_reader :#{attribute_name}\n\n"
386
- when CodeActions::CREATE_ATTRIBUTE_WRITER
387
- "#{indentation}attr_writer :#{attribute_name}\n\n"
388
- when CodeActions::CREATE_ATTRIBUTE_ACCESSOR
389
- "#{indentation}attr_accessor :#{attribute_name}\n\n"
390
- end,
391
- )
388
+ attribute_accessor_source = case @code_action[:title]
389
+ when CodeActions::CREATE_ATTRIBUTE_READER
390
+ "#{indentation}attr_reader :#{attribute_name}\n\n"
391
+ when CodeActions::CREATE_ATTRIBUTE_WRITER
392
+ "#{indentation}attr_writer :#{attribute_name}\n\n"
393
+ when CodeActions::CREATE_ATTRIBUTE_ACCESSOR
394
+ "#{indentation}attr_accessor :#{attribute_name}\n\n"
395
+ end #: as !nil
392
396
 
393
397
  target_start_line = closest_node.location.start_line
394
398
  target_range = {
@@ -7,8 +7,6 @@ module RubyLsp
7
7
  # request informs the editor of RuboCop quick fixes that can be applied. These are accessible by hovering over a
8
8
  # specific diagnostic.
9
9
  class CodeActions < Request
10
- extend T::Sig
11
-
12
10
  EXTRACT_TO_VARIABLE_TITLE = "Refactor: Extract Variable"
13
11
  EXTRACT_TO_METHOD_TITLE = "Refactor: Extract Method"
14
12
  TOGGLE_BLOCK_STYLE_TITLE = "Refactor: Toggle block style"
@@ -16,22 +14,17 @@ module RubyLsp
16
14
  CREATE_ATTRIBUTE_WRITER = "Create Attribute Writer"
17
15
  CREATE_ATTRIBUTE_ACCESSOR = "Create Attribute Accessor"
18
16
 
19
- INSTANCE_VARIABLE_NODES = T.let(
20
- [
21
- Prism::InstanceVariableAndWriteNode,
22
- Prism::InstanceVariableOperatorWriteNode,
23
- Prism::InstanceVariableOrWriteNode,
24
- Prism::InstanceVariableReadNode,
25
- Prism::InstanceVariableTargetNode,
26
- Prism::InstanceVariableWriteNode,
27
- ],
28
- T::Array[T.class_of(Prism::Node)],
29
- )
17
+ INSTANCE_VARIABLE_NODES = [
18
+ Prism::InstanceVariableAndWriteNode,
19
+ Prism::InstanceVariableOperatorWriteNode,
20
+ Prism::InstanceVariableOrWriteNode,
21
+ Prism::InstanceVariableReadNode,
22
+ Prism::InstanceVariableTargetNode,
23
+ Prism::InstanceVariableWriteNode,
24
+ ] #: Array[singleton(Prism::Node)]
30
25
 
31
26
  class << self
32
- extend T::Sig
33
-
34
- sig { returns(Interface::CodeActionRegistrationOptions) }
27
+ #: -> Interface::CodeActionRegistrationOptions
35
28
  def provider
36
29
  Interface::CodeActionRegistrationOptions.new(
37
30
  document_selector: nil,
@@ -40,22 +33,17 @@ module RubyLsp
40
33
  end
41
34
  end
42
35
 
43
- sig do
44
- params(
45
- document: T.any(RubyDocument, ERBDocument),
46
- range: T::Hash[Symbol, T.untyped],
47
- context: T::Hash[Symbol, T.untyped],
48
- ).void
49
- end
36
+ #: ((RubyDocument | ERBDocument) document, Hash[Symbol, untyped] range, Hash[Symbol, untyped] context) -> void
50
37
  def initialize(document, range, context)
51
38
  super()
52
39
  @document = document
53
- @uri = T.let(document.uri, URI::Generic)
40
+ @uri = document.uri #: URI::Generic
54
41
  @range = range
55
42
  @context = context
56
43
  end
57
44
 
58
- sig { override.returns(T.nilable(T.all(T::Array[Interface::CodeAction], Object))) }
45
+ # @override
46
+ #: -> (Array[Interface::CodeAction] & Object)?
59
47
  def perform
60
48
  diagnostics = @context[:diagnostics]
61
49
 
@@ -88,7 +76,7 @@ module RubyLsp
88
76
 
89
77
  private
90
78
 
91
- sig { returns(T::Array[Interface::CodeAction]) }
79
+ #: -> Array[Interface::CodeAction]
92
80
  def attribute_actions
93
81
  return [] unless @document.is_a?(RubyDocument)
94
82
 
@@ -11,40 +11,50 @@ module RubyLsp
11
11
  # [code lens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens)
12
12
  # request informs the editor of runnable commands such as testing and debugging.
13
13
  class CodeLens < Request
14
- extend T::Sig
15
-
16
14
  class << self
17
- extend T::Sig
18
-
19
- sig { returns(Interface::CodeLensOptions) }
15
+ #: -> Interface::CodeLensOptions
20
16
  def provider
21
- Interface::CodeLensOptions.new(resolve_provider: false)
17
+ Interface::CodeLensOptions.new(resolve_provider: true)
22
18
  end
23
19
  end
24
20
 
25
- sig do
26
- params(
27
- global_state: GlobalState,
28
- uri: URI::Generic,
29
- dispatcher: Prism::Dispatcher,
30
- ).void
31
- end
32
- def initialize(global_state, uri, dispatcher)
33
- @response_builder = T.let(
34
- ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens].new,
35
- ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
36
- )
21
+ #: (GlobalState, RubyDocument | ERBDocument, Prism::Dispatcher) -> void
22
+ def initialize(global_state, document, dispatcher)
23
+ @response_builder = ResponseBuilders::CollectionResponseBuilder
24
+ .new #: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
37
25
  super()
38
- Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
26
+
27
+ @document = document
28
+ @test_builder = ResponseBuilders::TestCollection.new #: ResponseBuilders::TestCollection
29
+ uri = document.uri
30
+ file_path = uri.full_path
31
+ code_lens_config = global_state.feature_configuration(:codeLens)
32
+ test_lenses_enabled = (!code_lens_config || code_lens_config.enabled?(:enableTestCodeLens)) &&
33
+ file_path && File.fnmatch?(TEST_PATH_PATTERN, file_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
34
+
35
+ if global_state.enabled_feature?(:fullTestDiscovery)
36
+ if test_lenses_enabled
37
+ Listeners::TestStyle.new(@test_builder, global_state, dispatcher, uri)
38
+ Listeners::SpecStyle.new(@test_builder, global_state, dispatcher, uri)
39
+ end
40
+ else
41
+ Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
42
+ end
39
43
 
40
44
  Addon.addons.each do |addon|
41
45
  addon.create_code_lens_listener(@response_builder, uri, dispatcher)
46
+
47
+ if global_state.enabled_feature?(:fullTestDiscovery) && test_lenses_enabled
48
+ addon.create_discover_tests_listener(@test_builder, dispatcher, uri)
49
+ end
42
50
  end
43
51
  end
44
52
 
45
- sig { override.returns(T::Array[Interface::CodeLens]) }
53
+ # @override
54
+ #: -> Array[Interface::CodeLens]
46
55
  def perform
47
- @response_builder.response
56
+ @document.cache_set("rubyLsp/discoverTests", @test_builder.response)
57
+ @response_builder.response + @test_builder.code_lens
48
58
  end
49
59
  end
50
60
  end
@@ -8,12 +8,8 @@ module RubyLsp
8
8
  # The [completion](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
9
9
  # suggests possible completions according to what the developer is typing.
10
10
  class Completion < Request
11
- extend T::Sig
12
-
13
11
  class << self
14
- extend T::Sig
15
-
16
- sig { returns(Interface::CompletionOptions) }
12
+ #: -> Interface::CompletionOptions
17
13
  def provider
18
14
  Interface::CompletionOptions.new(
19
15
  resolve_provider: true,
@@ -25,18 +21,10 @@ module RubyLsp
25
21
  end
26
22
  end
27
23
 
28
- sig do
29
- params(
30
- document: T.any(RubyDocument, ERBDocument),
31
- global_state: GlobalState,
32
- params: T::Hash[Symbol, T.untyped],
33
- sorbet_level: RubyDocument::SorbetLevel,
34
- dispatcher: Prism::Dispatcher,
35
- ).void
36
- end
24
+ #: ((RubyDocument | ERBDocument) document, GlobalState global_state, Hash[Symbol, untyped] params, SorbetLevel sorbet_level, Prism::Dispatcher dispatcher) -> void
37
25
  def initialize(document, global_state, params, sorbet_level, dispatcher)
38
26
  super()
39
- @target = T.let(nil, T.nilable(Prism::Node))
27
+ @target = nil #: Prism::Node?
40
28
  @dispatcher = dispatcher
41
29
  # Completion always receives the position immediately after the character that was just typed. Here we adjust it
42
30
  # back by 1, so that we find the right node
@@ -45,7 +33,7 @@ module RubyLsp
45
33
  delegate_request_if_needed!(global_state, document, char_position)
46
34
 
47
35
  node_context = RubyDocument.locate(
48
- document.parse_result.value,
36
+ document.ast,
49
37
  char_position,
50
38
  node_types: [
51
39
  Prism::CallNode,
@@ -72,10 +60,8 @@ module RubyLsp
72
60
  ],
73
61
  code_units_cache: document.code_units_cache,
74
62
  )
75
- @response_builder = T.let(
76
- ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem].new,
77
- ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
78
- )
63
+ @response_builder = ResponseBuilders::CollectionResponseBuilder
64
+ .new #: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem]
79
65
 
80
66
  Listeners::Completion.new(
81
67
  @response_builder,
@@ -102,7 +88,8 @@ module RubyLsp
102
88
  end
103
89
  end
104
90
 
105
- sig { override.returns(T::Array[Interface::CompletionItem]) }
91
+ # @override
92
+ #: -> Array[Interface::CompletionItem]
106
93
  def perform
107
94
  return [] unless @target
108
95
 
@@ -14,21 +14,21 @@ module RubyLsp
14
14
  # At most 10 definitions are included, to ensure low latency during request processing and rendering the completion
15
15
  # item.
16
16
  class CompletionResolve < Request
17
- extend T::Sig
18
17
  include Requests::Support::Common
19
18
 
20
19
  # set a limit on the number of documentation entries returned, to avoid rendering performance issues
21
20
  # https://github.com/Shopify/ruby-lsp/pull/1798
22
21
  MAX_DOCUMENTATION_ENTRIES = 10
23
22
 
24
- sig { params(global_state: GlobalState, item: T::Hash[Symbol, T.untyped]).void }
23
+ #: (GlobalState global_state, Hash[Symbol, untyped] item) -> void
25
24
  def initialize(global_state, item)
26
25
  super()
27
- @index = T.let(global_state.index, RubyIndexer::Index)
26
+ @index = global_state.index #: RubyIndexer::Index
28
27
  @item = item
29
28
  end
30
29
 
31
- sig { override.returns(T::Hash[Symbol, T.untyped]) }
30
+ # @override
31
+ #: -> Hash[Symbol, untyped]
32
32
  def perform
33
33
  return @item if @item.dig(:data, :skip_resolve)
34
34
 
@@ -54,7 +54,7 @@ module RubyLsp
54
54
  end
55
55
  end
56
56
 
57
- first_entry = T.must(entries.first)
57
+ first_entry = entries.first #: as !nil
58
58
 
59
59
  if first_entry.is_a?(RubyIndexer::Entry::Member)
60
60
  label = +"#{label}#{first_entry.decorated_parameters}"
@@ -78,7 +78,7 @@ module RubyLsp
78
78
 
79
79
  private
80
80
 
81
- sig { params(item: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
81
+ #: (Hash[Symbol, untyped] item) -> Hash[Symbol, untyped]
82
82
  def keyword_resolve(item)
83
83
  keyword = item[:label]
84
84
  content = KEYWORD_DOCS[keyword]
@@ -9,31 +9,18 @@ module RubyLsp
9
9
  # request](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) jumps to the
10
10
  # definition of the symbol under the cursor.
11
11
  class Definition < Request
12
- extend T::Sig
13
- extend T::Generic
14
-
15
- sig do
16
- params(
17
- document: T.any(RubyDocument, ERBDocument),
18
- global_state: GlobalState,
19
- position: T::Hash[Symbol, T.untyped],
20
- dispatcher: Prism::Dispatcher,
21
- sorbet_level: RubyDocument::SorbetLevel,
22
- ).void
23
- end
12
+ #: ((RubyDocument | ERBDocument) document, GlobalState global_state, Hash[Symbol, untyped] position, Prism::Dispatcher dispatcher, SorbetLevel sorbet_level) -> void
24
13
  def initialize(document, global_state, position, dispatcher, sorbet_level)
25
14
  super()
26
- @response_builder = T.let(
27
- ResponseBuilders::CollectionResponseBuilder[T.any(Interface::Location, Interface::LocationLink)].new,
28
- ResponseBuilders::CollectionResponseBuilder[T.any(Interface::Location, Interface::LocationLink)],
29
- )
15
+ @response_builder = ResponseBuilders::CollectionResponseBuilder
16
+ .new #: ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)]
30
17
  @dispatcher = dispatcher
31
18
 
32
19
  char_position, _ = document.find_index_by_position(position)
33
20
  delegate_request_if_needed!(global_state, document, char_position)
34
21
 
35
22
  node_context = RubyDocument.locate(
36
- document.parse_result.value,
23
+ document.ast,
37
24
  char_position,
38
25
  node_types: [
39
26
  Prism::CallNode,
@@ -100,10 +87,11 @@ module RubyLsp
100
87
  end
101
88
  end
102
89
 
103
- @target = T.let(target, T.nilable(Prism::Node))
90
+ @target = target #: Prism::Node?
104
91
  end
105
92
 
106
- sig { override.returns(T::Array[T.any(Interface::Location, Interface::LocationLink)]) }
93
+ # @override
94
+ #: -> Array[(Interface::Location | Interface::LocationLink)]
107
95
  def perform
108
96
  @dispatcher.dispatch_once(@target) if @target
109
97
  @response_builder.response
@@ -111,7 +99,7 @@ module RubyLsp
111
99
 
112
100
  private
113
101
 
114
- sig { params(position: T::Hash[Symbol, T.untyped], target: T.nilable(Prism::Node)).returns(T::Boolean) }
102
+ #: (Hash[Symbol, untyped] position, Prism::Node? target) -> bool
115
103
  def position_outside_target?(position, target)
116
104
  case target
117
105
  when Prism::GlobalVariableAndWriteNode,
@@ -7,12 +7,8 @@ module RubyLsp
7
7
  # [diagnostics](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics)
8
8
  # request informs the editor of RuboCop offenses for a given file.
9
9
  class Diagnostics < Request
10
- extend T::Sig
11
-
12
10
  class << self
13
- extend T::Sig
14
-
15
- sig { returns(Interface::DiagnosticRegistrationOptions) }
11
+ #: -> Interface::DiagnosticRegistrationOptions
16
12
  def provider
17
13
  Interface::DiagnosticRegistrationOptions.new(
18
14
  document_selector: nil,
@@ -22,15 +18,16 @@ module RubyLsp
22
18
  end
23
19
  end
24
20
 
25
- sig { params(global_state: GlobalState, document: RubyDocument).void }
21
+ #: (GlobalState global_state, RubyDocument document) -> void
26
22
  def initialize(global_state, document)
27
23
  super()
28
- @active_linters = T.let(global_state.active_linters, T::Array[Support::Formatter])
24
+ @active_linters = global_state.active_linters #: Array[Support::Formatter]
29
25
  @document = document
30
- @uri = T.let(document.uri, URI::Generic)
26
+ @uri = document.uri #: URI::Generic
31
27
  end
32
28
 
33
- sig { override.returns(T.nilable(T.all(T::Array[Interface::Diagnostic], Object))) }
29
+ # @override
30
+ #: -> (Array[Interface::Diagnostic] & Object)?
34
31
  def perform
35
32
  diagnostics = []
36
33
  diagnostics.concat(syntax_error_diagnostics, syntax_warning_diagnostics)
@@ -50,7 +47,7 @@ module RubyLsp
50
47
 
51
48
  private
52
49
 
53
- sig { returns(T::Array[Interface::Diagnostic]) }
50
+ #: -> Array[Interface::Diagnostic]
54
51
  def syntax_warning_diagnostics
55
52
  @document.parse_result.warnings.map do |warning|
56
53
  location = warning.location
@@ -73,7 +70,7 @@ module RubyLsp
73
70
  end
74
71
  end
75
72
 
76
- sig { returns(T::Array[Interface::Diagnostic]) }
73
+ #: -> Array[Interface::Diagnostic]
77
74
  def syntax_error_diagnostics
78
75
  @document.parse_result.errors.map do |error|
79
76
  location = error.location