ruby-lsp 0.23.11 → 0.23.17
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/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp-launcher +20 -11
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +134 -183
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -10
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +97 -217
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +139 -281
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +18 -19
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +23 -55
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +47 -61
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
- data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
- data/lib/ruby_indexer/test/configuration_test.rb +48 -7
- data/lib/ruby_indexer/test/constant_test.rb +34 -34
- data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +146 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +37 -37
- data/lib/ruby_indexer/test/method_test.rb +149 -123
- data/lib/ruby_indexer/test/prefix_tree_test.rb +13 -13
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +68 -73
- data/lib/ruby_indexer/test/test_case.rb +9 -3
- data/lib/ruby_indexer/test/uri_test.rb +15 -2
- data/lib/ruby_lsp/addon.rb +44 -71
- data/lib/ruby_lsp/base_server.rb +29 -32
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +40 -54
- data/lib/ruby_lsp/erb_document.rb +37 -41
- data/lib/ruby_lsp/global_state.rb +52 -57
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +67 -73
- data/lib/ruby_lsp/listeners/definition.rb +44 -58
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +50 -70
- data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
- data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
- data/lib/ruby_lsp/listeners/hover.rb +92 -110
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
- data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
- data/lib/ruby_lsp/listeners/test_style.rb +167 -90
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +9 -7
- data/lib/ruby_lsp/requests/code_action_resolve.rb +63 -59
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +20 -19
- data/lib/ruby_lsp/requests/completion.rb +7 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +7 -17
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
- data/lib/ruby_lsp/requests/document_link.rb +6 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
- data/lib/ruby_lsp/requests/formatting.rb +6 -9
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +85 -0
- data/lib/ruby_lsp/requests/hover.rb +10 -20
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +9 -53
- data/lib/ruby_lsp/requests/rename.rb +20 -46
- data/lib/ruby_lsp/requests/request.rb +8 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +6 -6
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
- data/lib/ruby_lsp/requests/signature_help.rb +8 -26
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +15 -55
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +11 -14
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
- data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
- data/lib/ruby_lsp/response_builders/document_symbol.rb +14 -19
- data/lib/ruby_lsp/response_builders/hover.rb +11 -14
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +60 -88
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +43 -10
- data/lib/ruby_lsp/ruby_document.rb +24 -92
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +182 -99
- data/lib/ruby_lsp/setup_bundler.rb +65 -60
- data/lib/ruby_lsp/static_docs.rb +11 -7
- data/lib/ruby_lsp/store.rb +29 -47
- data/lib/ruby_lsp/test_helper.rb +2 -12
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +191 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +105 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +94 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +92 -83
- metadata +9 -3
@@ -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
|
-
|
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
|
-
|
28
|
+
# @override
|
29
|
+
#: -> (Interface::CodeAction)
|
35
30
|
def perform
|
36
|
-
|
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
|
-
|
45
|
+
raise UnknownCodeActionError, "Unknown code action: #{@code_action[:title]}"
|
51
46
|
end
|
52
47
|
end
|
53
48
|
|
54
49
|
private
|
55
50
|
|
56
|
-
|
51
|
+
#: -> (Interface::CodeAction)
|
57
52
|
def switch_block_style
|
58
53
|
source_range = @code_action.dig(:data, :range)
|
59
|
-
|
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
|
-
|
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
|
-
|
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,13 +90,13 @@ module RubyLsp
|
|
91
90
|
)
|
92
91
|
end
|
93
92
|
|
94
|
-
|
93
|
+
#: -> (Interface::CodeAction)
|
95
94
|
def refactor_variable
|
96
95
|
source_range = @code_action.dig(:data, :range)
|
97
|
-
|
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 =
|
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
|
@@ -111,16 +110,20 @@ module RubyLsp
|
|
111
110
|
|
112
111
|
closest_statements = node_context.node
|
113
112
|
parent_statements = node_context.parent
|
114
|
-
|
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 =
|
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
|
-
|
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
|
-
|
157
|
+
unless indentation_line
|
158
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
159
|
+
end
|
155
160
|
|
156
|
-
indentation =
|
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
|
-
|
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,13 +197,13 @@ module RubyLsp
|
|
189
197
|
)
|
190
198
|
end
|
191
199
|
|
192
|
-
|
200
|
+
#: -> (Interface::CodeAction)
|
193
201
|
def refactor_method
|
194
202
|
source_range = @code_action.dig(:data, :range)
|
195
|
-
|
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 =
|
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(
|
@@ -205,11 +213,15 @@ module RubyLsp
|
|
205
213
|
code_units_cache: @document.code_units_cache,
|
206
214
|
)
|
207
215
|
closest_node = node_context.node
|
208
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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 # rubocop:disable Layout/LineLength
|
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
|
-
|
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 =
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
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 =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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
|
-
|
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 =
|
40
|
+
@uri = document.uri #: URI::Generic
|
54
41
|
@range = range
|
55
42
|
@context = context
|
56
43
|
end
|
57
44
|
|
58
|
-
|
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
|
-
|
79
|
+
#: -> Array[Interface::CodeAction]
|
92
80
|
def attribute_actions
|
93
81
|
return [] unless @document.is_a?(RubyDocument)
|
94
82
|
|
@@ -11,40 +11,41 @@ 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
|
-
|
18
|
-
|
19
|
-
sig { returns(Interface::CodeLensOptions) }
|
15
|
+
#: -> Interface::CodeLensOptions
|
20
16
|
def provider
|
21
17
|
Interface::CodeLensOptions.new(resolve_provider: false)
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
25
|
-
|
26
|
-
params(
|
27
|
-
global_state: GlobalState,
|
28
|
-
uri: URI::Generic,
|
29
|
-
dispatcher: Prism::Dispatcher,
|
30
|
-
).void
|
31
|
-
end
|
21
|
+
#: (GlobalState global_state, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
|
32
22
|
def initialize(global_state, uri, dispatcher)
|
33
|
-
@response_builder =
|
34
|
-
ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
|
35
|
-
ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
|
36
|
-
)
|
23
|
+
@response_builder = ResponseBuilders::CollectionResponseBuilder
|
24
|
+
.new #: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
|
37
25
|
super()
|
38
|
-
|
26
|
+
|
27
|
+
@test_builder = ResponseBuilders::TestCollection.new #: ResponseBuilders::TestCollection
|
28
|
+
|
29
|
+
if global_state.enabled_feature?(:fullTestDiscovery)
|
30
|
+
Listeners::TestStyle.new(@test_builder, global_state, dispatcher, uri)
|
31
|
+
Listeners::SpecStyle.new(@test_builder, global_state, dispatcher, uri)
|
32
|
+
else
|
33
|
+
Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
|
34
|
+
end
|
39
35
|
|
40
36
|
Addon.addons.each do |addon|
|
41
37
|
addon.create_code_lens_listener(@response_builder, uri, dispatcher)
|
38
|
+
|
39
|
+
if global_state.enabled_feature?(:fullTestDiscovery)
|
40
|
+
addon.create_discover_tests_listener(@test_builder, dispatcher, uri)
|
41
|
+
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
# @override
|
46
|
+
#: -> Array[Interface::CodeLens]
|
46
47
|
def perform
|
47
|
-
@response_builder.response
|
48
|
+
@response_builder.response + @test_builder.code_lens
|
48
49
|
end
|
49
50
|
end
|
50
51
|
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
|
-
|
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
|
-
|
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 =
|
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
|
@@ -72,10 +60,8 @@ module RubyLsp
|
|
72
60
|
],
|
73
61
|
code_units_cache: document.code_units_cache,
|
74
62
|
)
|
75
|
-
@response_builder =
|
76
|
-
ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem]
|
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
|
-
|
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
|
-
|
23
|
+
#: (GlobalState global_state, Hash[Symbol, untyped] item) -> void
|
25
24
|
def initialize(global_state, item)
|
26
25
|
super()
|
27
|
-
@index =
|
26
|
+
@index = global_state.index #: RubyIndexer::Index
|
28
27
|
@item = item
|
29
28
|
end
|
30
29
|
|
31
|
-
|
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 =
|
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
|
-
|
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,24 +9,13 @@ 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
12
|
extend T::Generic
|
14
13
|
|
15
|
-
|
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
|
14
|
+
#: ((RubyDocument | ERBDocument) document, GlobalState global_state, Hash[Symbol, untyped] position, Prism::Dispatcher dispatcher, SorbetLevel sorbet_level) -> void
|
24
15
|
def initialize(document, global_state, position, dispatcher, sorbet_level)
|
25
16
|
super()
|
26
|
-
@response_builder =
|
27
|
-
ResponseBuilders::CollectionResponseBuilder[
|
28
|
-
ResponseBuilders::CollectionResponseBuilder[T.any(Interface::Location, Interface::LocationLink)],
|
29
|
-
)
|
17
|
+
@response_builder = ResponseBuilders::CollectionResponseBuilder
|
18
|
+
.new #: ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)]
|
30
19
|
@dispatcher = dispatcher
|
31
20
|
|
32
21
|
char_position, _ = document.find_index_by_position(position)
|
@@ -100,10 +89,11 @@ module RubyLsp
|
|
100
89
|
end
|
101
90
|
end
|
102
91
|
|
103
|
-
@target =
|
92
|
+
@target = target #: Prism::Node?
|
104
93
|
end
|
105
94
|
|
106
|
-
|
95
|
+
# @override
|
96
|
+
#: -> Array[(Interface::Location | Interface::LocationLink)]
|
107
97
|
def perform
|
108
98
|
@dispatcher.dispatch_once(@target) if @target
|
109
99
|
@response_builder.response
|
@@ -111,7 +101,7 @@ module RubyLsp
|
|
111
101
|
|
112
102
|
private
|
113
103
|
|
114
|
-
|
104
|
+
#: (Hash[Symbol, untyped] position, Prism::Node? target) -> bool
|
115
105
|
def position_outside_target?(position, target)
|
116
106
|
case target
|
117
107
|
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
|
-
|
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
|
-
|
21
|
+
#: (GlobalState global_state, RubyDocument document) -> void
|
26
22
|
def initialize(global_state, document)
|
27
23
|
super()
|
28
|
-
@active_linters =
|
24
|
+
@active_linters = global_state.active_linters #: Array[Support::Formatter]
|
29
25
|
@document = document
|
30
|
-
@uri =
|
26
|
+
@uri = document.uri #: URI::Generic
|
31
27
|
end
|
32
28
|
|
33
|
-
|
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
|
-
|
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
|
-
|
73
|
+
#: -> Array[Interface::Diagnostic]
|
77
74
|
def syntax_error_diagnostics
|
78
75
|
@document.parse_result.errors.map do |error|
|
79
76
|
location = error.location
|
@@ -1,27 +1,29 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "ruby_lsp/listeners/test_discovery"
|
4
5
|
require "ruby_lsp/listeners/test_style"
|
6
|
+
require "ruby_lsp/listeners/spec_style"
|
5
7
|
|
6
8
|
module RubyLsp
|
7
9
|
module Requests
|
8
10
|
# This is a custom request to ask the server to parse a test file and discover all available examples in it. Add-ons
|
9
11
|
# can augment the behavior through listeners, allowing them to handle discovery for different frameworks
|
10
12
|
class DiscoverTests < Request
|
11
|
-
extend T::Sig
|
12
13
|
include Support::Common
|
13
14
|
|
14
|
-
|
15
|
+
#: (GlobalState global_state, RubyDocument document, Prism::Dispatcher dispatcher) -> void
|
15
16
|
def initialize(global_state, document, dispatcher)
|
16
17
|
super()
|
17
18
|
@global_state = global_state
|
18
19
|
@document = document
|
19
20
|
@dispatcher = dispatcher
|
20
|
-
@response_builder =
|
21
|
-
@index =
|
21
|
+
@response_builder = ResponseBuilders::TestCollection.new #: ResponseBuilders::TestCollection
|
22
|
+
@index = global_state.index #: RubyIndexer::Index
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
+
# @override
|
26
|
+
#: -> Array[Support::TestItem]
|
25
27
|
def perform
|
26
28
|
uri = @document.uri
|
27
29
|
|
@@ -35,6 +37,12 @@ module RubyLsp
|
|
35
37
|
# in the index first and then discover the tests, all in the same traversal.
|
36
38
|
if @index.entries_for(uri.to_s)
|
37
39
|
Listeners::TestStyle.new(@response_builder, @global_state, @dispatcher, @document.uri)
|
40
|
+
Listeners::SpecStyle.new(@response_builder, @global_state, @dispatcher, @document.uri)
|
41
|
+
|
42
|
+
Addon.addons.each do |addon|
|
43
|
+
addon.create_discover_tests_listener(@response_builder, @dispatcher, @document.uri)
|
44
|
+
end
|
45
|
+
|
38
46
|
@dispatcher.visit(@document.parse_result.value)
|
39
47
|
else
|
40
48
|
@global_state.synchronize do
|
@@ -47,6 +55,11 @@ module RubyLsp
|
|
47
55
|
)
|
48
56
|
|
49
57
|
Listeners::TestStyle.new(@response_builder, @global_state, @dispatcher, @document.uri)
|
58
|
+
Listeners::SpecStyle.new(@response_builder, @global_state, @dispatcher, @document.uri)
|
59
|
+
|
60
|
+
Addon.addons.each do |addon|
|
61
|
+
addon.create_discover_tests_listener(@response_builder, @dispatcher, @document.uri)
|
62
|
+
end
|
50
63
|
|
51
64
|
# Dispatch the events both for indexing the test file and discovering the tests. The order here is
|
52
65
|
# important because we need the index to be aware of the existing classes/modules/methods before the test
|