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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +45 -22
- data/exe/ruby-lsp-test-exec +6 -0
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +166 -281
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +25 -57
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
- 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 +49 -9
- 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 +185 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
- data/lib/ruby_indexer/test/method_test.rb +166 -123
- data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
- data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
- 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 +88 -86
- data/lib/ruby_lsp/base_server.rb +59 -54
- data/lib/ruby_lsp/client_capabilities.rb +16 -13
- data/lib/ruby_lsp/document.rb +205 -104
- data/lib/ruby_lsp/erb_document.rb +45 -47
- data/lib/ruby_lsp/global_state.rb +73 -57
- data/lib/ruby_lsp/internal.rb +8 -3
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +81 -76
- 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 +107 -115
- data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
- 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 +214 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +92 -0
- data/lib/ruby_lsp/listeners/test_style.rb +205 -95
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +10 -11
- data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +31 -21
- data/lib/ruby_lsp/requests/completion.rb +8 -21
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +8 -20
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
- data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
- 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 +12 -25
- data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
- 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 +17 -57
- data/lib/ruby_lsp/requests/rename.rb +27 -51
- data/lib/ruby_lsp/requests/request.rb +13 -25
- data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
- 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 +9 -27
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +16 -58
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
- 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 +6 -9
- data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
- data/lib/ruby_lsp/response_builders/hover.rb +12 -18
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
- data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
- data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
- data/lib/ruby_lsp/ruby_document.rb +32 -98
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +303 -196
- data/lib/ruby_lsp/setup_bundler.rb +121 -82
- data/lib/ruby_lsp/static_docs.rb +12 -7
- data/lib/ruby_lsp/store.rb +21 -49
- data/lib/ruby_lsp/test_helper.rb +3 -16
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +138 -93
- data/static_docs/break.md +103 -0
- metadata +14 -20
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -4,7 +4,6 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Listeners
|
6
6
|
class Completion
|
7
|
-
extend T::Sig
|
8
7
|
include Requests::Support::Common
|
9
8
|
|
10
9
|
KEYWORDS = [
|
@@ -51,17 +50,7 @@ module RubyLsp
|
|
51
50
|
"__LINE__",
|
52
51
|
].freeze
|
53
52
|
|
54
|
-
|
55
|
-
params(
|
56
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
57
|
-
global_state: GlobalState,
|
58
|
-
node_context: NodeContext,
|
59
|
-
sorbet_level: RubyDocument::SorbetLevel,
|
60
|
-
dispatcher: Prism::Dispatcher,
|
61
|
-
uri: URI::Generic,
|
62
|
-
trigger_character: T.nilable(String),
|
63
|
-
).void
|
64
|
-
end
|
53
|
+
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem] response_builder, GlobalState global_state, NodeContext node_context, SorbetLevel sorbet_level, Prism::Dispatcher dispatcher, URI::Generic uri, String? trigger_character) -> void
|
65
54
|
def initialize( # rubocop:disable Metrics/ParameterLists
|
66
55
|
response_builder,
|
67
56
|
global_state,
|
@@ -73,8 +62,8 @@ module RubyLsp
|
|
73
62
|
)
|
74
63
|
@response_builder = response_builder
|
75
64
|
@global_state = global_state
|
76
|
-
@index =
|
77
|
-
@type_inferrer =
|
65
|
+
@index = global_state.index #: RubyIndexer::Index
|
66
|
+
@type_inferrer = global_state.type_inferrer #: TypeInferrer
|
78
67
|
@node_context = node_context
|
79
68
|
@sorbet_level = sorbet_level
|
80
69
|
@uri = uri
|
@@ -107,11 +96,11 @@ module RubyLsp
|
|
107
96
|
end
|
108
97
|
|
109
98
|
# Handle completion on regular constant references (e.g. `Bar`)
|
110
|
-
|
99
|
+
#: (Prism::ConstantReadNode node) -> void
|
111
100
|
def on_constant_read_node_enter(node)
|
112
101
|
# The only scenario where Sorbet doesn't provide constant completion is on ignored files. Even if the file has
|
113
102
|
# no sigil, Sorbet will still provide completion for constants
|
114
|
-
return
|
103
|
+
return unless @sorbet_level.ignore?
|
115
104
|
|
116
105
|
name = RubyIndexer::Index.constant_name(node)
|
117
106
|
return if name.nil?
|
@@ -119,7 +108,8 @@ module RubyLsp
|
|
119
108
|
range = range_from_location(node.location)
|
120
109
|
candidates = @index.constant_completion_candidates(name, @node_context.nesting)
|
121
110
|
candidates.each do |entries|
|
122
|
-
complete_name =
|
111
|
+
complete_name = entries.first #: as !nil
|
112
|
+
.name
|
123
113
|
@response_builder << build_entry_completion(
|
124
114
|
complete_name,
|
125
115
|
name,
|
@@ -131,11 +121,11 @@ module RubyLsp
|
|
131
121
|
end
|
132
122
|
|
133
123
|
# Handle completion on namespaced constant references (e.g. `Foo::Bar`)
|
134
|
-
|
124
|
+
#: (Prism::ConstantPathNode node) -> void
|
135
125
|
def on_constant_path_node_enter(node)
|
136
126
|
# The only scenario where Sorbet doesn't provide constant completion is on ignored files. Even if the file has
|
137
127
|
# no sigil, Sorbet will still provide completion for constants
|
138
|
-
return
|
128
|
+
return unless @sorbet_level.ignore?
|
139
129
|
|
140
130
|
name = begin
|
141
131
|
node.full_name
|
@@ -149,11 +139,11 @@ module RubyLsp
|
|
149
139
|
constant_path_completion(name, range_from_location(node.location))
|
150
140
|
end
|
151
141
|
|
152
|
-
|
142
|
+
#: (Prism::CallNode node) -> void
|
153
143
|
def on_call_node_enter(node)
|
154
144
|
# The only scenario where Sorbet doesn't provide constant completion is on ignored files. Even if the file has
|
155
145
|
# no sigil, Sorbet will still provide completion for constants
|
156
|
-
if @sorbet_level
|
146
|
+
if @sorbet_level.ignore?
|
157
147
|
receiver = node.receiver
|
158
148
|
|
159
149
|
# When writing `Foo::`, the AST assigns a method call node (because you can use that syntax to invoke
|
@@ -166,7 +156,7 @@ module RubyLsp
|
|
166
156
|
|
167
157
|
if name
|
168
158
|
start_loc = node.location
|
169
|
-
end_loc =
|
159
|
+
end_loc = node.call_operator_loc #: as !nil
|
170
160
|
|
171
161
|
constant_path_completion(
|
172
162
|
"#{name}::",
|
@@ -193,99 +183,99 @@ module RubyLsp
|
|
193
183
|
end
|
194
184
|
end
|
195
185
|
|
196
|
-
|
186
|
+
#: (Prism::GlobalVariableAndWriteNode node) -> void
|
197
187
|
def on_global_variable_and_write_node_enter(node)
|
198
188
|
handle_global_variable_completion(node.name.to_s, node.name_loc)
|
199
189
|
end
|
200
190
|
|
201
|
-
|
191
|
+
#: (Prism::GlobalVariableOperatorWriteNode node) -> void
|
202
192
|
def on_global_variable_operator_write_node_enter(node)
|
203
193
|
handle_global_variable_completion(node.name.to_s, node.name_loc)
|
204
194
|
end
|
205
195
|
|
206
|
-
|
196
|
+
#: (Prism::GlobalVariableOrWriteNode node) -> void
|
207
197
|
def on_global_variable_or_write_node_enter(node)
|
208
198
|
handle_global_variable_completion(node.name.to_s, node.name_loc)
|
209
199
|
end
|
210
200
|
|
211
|
-
|
201
|
+
#: (Prism::GlobalVariableReadNode node) -> void
|
212
202
|
def on_global_variable_read_node_enter(node)
|
213
203
|
handle_global_variable_completion(node.name.to_s, node.location)
|
214
204
|
end
|
215
205
|
|
216
|
-
|
206
|
+
#: (Prism::GlobalVariableTargetNode node) -> void
|
217
207
|
def on_global_variable_target_node_enter(node)
|
218
208
|
handle_global_variable_completion(node.name.to_s, node.location)
|
219
209
|
end
|
220
210
|
|
221
|
-
|
211
|
+
#: (Prism::GlobalVariableWriteNode node) -> void
|
222
212
|
def on_global_variable_write_node_enter(node)
|
223
213
|
handle_global_variable_completion(node.name.to_s, node.name_loc)
|
224
214
|
end
|
225
215
|
|
226
|
-
|
216
|
+
#: (Prism::InstanceVariableReadNode node) -> void
|
227
217
|
def on_instance_variable_read_node_enter(node)
|
228
218
|
handle_instance_variable_completion(node.name.to_s, node.location)
|
229
219
|
end
|
230
220
|
|
231
|
-
|
221
|
+
#: (Prism::InstanceVariableWriteNode node) -> void
|
232
222
|
def on_instance_variable_write_node_enter(node)
|
233
223
|
handle_instance_variable_completion(node.name.to_s, node.name_loc)
|
234
224
|
end
|
235
225
|
|
236
|
-
|
226
|
+
#: (Prism::InstanceVariableAndWriteNode node) -> void
|
237
227
|
def on_instance_variable_and_write_node_enter(node)
|
238
228
|
handle_instance_variable_completion(node.name.to_s, node.name_loc)
|
239
229
|
end
|
240
230
|
|
241
|
-
|
231
|
+
#: (Prism::InstanceVariableOperatorWriteNode node) -> void
|
242
232
|
def on_instance_variable_operator_write_node_enter(node)
|
243
233
|
handle_instance_variable_completion(node.name.to_s, node.name_loc)
|
244
234
|
end
|
245
235
|
|
246
|
-
|
236
|
+
#: (Prism::InstanceVariableOrWriteNode node) -> void
|
247
237
|
def on_instance_variable_or_write_node_enter(node)
|
248
238
|
handle_instance_variable_completion(node.name.to_s, node.name_loc)
|
249
239
|
end
|
250
240
|
|
251
|
-
|
241
|
+
#: (Prism::InstanceVariableTargetNode node) -> void
|
252
242
|
def on_instance_variable_target_node_enter(node)
|
253
243
|
handle_instance_variable_completion(node.name.to_s, node.location)
|
254
244
|
end
|
255
245
|
|
256
|
-
|
246
|
+
#: (Prism::ClassVariableAndWriteNode node) -> void
|
257
247
|
def on_class_variable_and_write_node_enter(node)
|
258
248
|
handle_class_variable_completion(node.name.to_s, node.name_loc)
|
259
249
|
end
|
260
250
|
|
261
|
-
|
251
|
+
#: (Prism::ClassVariableOperatorWriteNode node) -> void
|
262
252
|
def on_class_variable_operator_write_node_enter(node)
|
263
253
|
handle_class_variable_completion(node.name.to_s, node.name_loc)
|
264
254
|
end
|
265
255
|
|
266
|
-
|
256
|
+
#: (Prism::ClassVariableOrWriteNode node) -> void
|
267
257
|
def on_class_variable_or_write_node_enter(node)
|
268
258
|
handle_class_variable_completion(node.name.to_s, node.name_loc)
|
269
259
|
end
|
270
260
|
|
271
|
-
|
261
|
+
#: (Prism::ClassVariableTargetNode node) -> void
|
272
262
|
def on_class_variable_target_node_enter(node)
|
273
263
|
handle_class_variable_completion(node.name.to_s, node.location)
|
274
264
|
end
|
275
265
|
|
276
|
-
|
266
|
+
#: (Prism::ClassVariableReadNode node) -> void
|
277
267
|
def on_class_variable_read_node_enter(node)
|
278
268
|
handle_class_variable_completion(node.name.to_s, node.location)
|
279
269
|
end
|
280
270
|
|
281
|
-
|
271
|
+
#: (Prism::ClassVariableWriteNode node) -> void
|
282
272
|
def on_class_variable_write_node_enter(node)
|
283
273
|
handle_class_variable_completion(node.name.to_s, node.name_loc)
|
284
274
|
end
|
285
275
|
|
286
276
|
private
|
287
277
|
|
288
|
-
|
278
|
+
#: (String name, Interface::Range range) -> void
|
289
279
|
def constant_path_completion(name, range)
|
290
280
|
top_level_reference = if name.start_with?("::")
|
291
281
|
name = name.delete_prefix("::")
|
@@ -307,7 +297,9 @@ module RubyLsp
|
|
307
297
|
namespace_entries = @index.resolve(aliased_namespace, nesting)
|
308
298
|
return unless namespace_entries
|
309
299
|
|
310
|
-
|
300
|
+
namespace_name = namespace_entries.first #: as !nil
|
301
|
+
.name
|
302
|
+
real_namespace = @index.follow_aliased_namespace(namespace_name)
|
311
303
|
|
312
304
|
candidates = @index.constant_completion_candidates(
|
313
305
|
"#{real_namespace}::#{incomplete_name}",
|
@@ -316,7 +308,7 @@ module RubyLsp
|
|
316
308
|
candidates.each do |entries|
|
317
309
|
# The only time we may have a private constant reference from outside of the namespace is if we're dealing
|
318
310
|
# with ConstantPath and the entry name doesn't start with the current nesting
|
319
|
-
first_entry =
|
311
|
+
first_entry = entries.first #: as !nil
|
320
312
|
next if first_entry.private? && !first_entry.name.start_with?("#{nesting}::")
|
321
313
|
|
322
314
|
entry_name = first_entry.name
|
@@ -335,12 +327,12 @@ module RubyLsp
|
|
335
327
|
name,
|
336
328
|
range,
|
337
329
|
entries,
|
338
|
-
top_level_reference || top_level?(
|
330
|
+
top_level_reference || top_level?(first_entry.name),
|
339
331
|
)
|
340
332
|
end
|
341
333
|
end
|
342
334
|
|
343
|
-
|
335
|
+
#: (String name, Prism::Location location) -> void
|
344
336
|
def handle_global_variable_completion(name, location)
|
345
337
|
candidates = @index.prefix_search(name)
|
346
338
|
|
@@ -363,7 +355,7 @@ module RubyLsp
|
|
363
355
|
end
|
364
356
|
end
|
365
357
|
|
366
|
-
|
358
|
+
#: (String name, Prism::Location location) -> void
|
367
359
|
def handle_class_variable_completion(name, location)
|
368
360
|
type = @type_inferrer.infer_receiver_type(@node_context)
|
369
361
|
return unless type
|
@@ -394,11 +386,11 @@ module RubyLsp
|
|
394
386
|
# If by any chance we haven't indexed the owner, then there's no way to find the right declaration
|
395
387
|
end
|
396
388
|
|
397
|
-
|
389
|
+
#: (String name, Prism::Location location) -> void
|
398
390
|
def handle_instance_variable_completion(name, location)
|
399
391
|
# Sorbet enforces that all instance variables be declared on typed strict or higher, which means it will be able
|
400
392
|
# to provide all features for them
|
401
|
-
return if @sorbet_level
|
393
|
+
return if @sorbet_level.strict?
|
402
394
|
|
403
395
|
type = @type_inferrer.infer_receiver_type(@node_context)
|
404
396
|
return unless type
|
@@ -428,7 +420,7 @@ module RubyLsp
|
|
428
420
|
# If by any chance we haven't indexed the owner, then there's no way to find the right declaration
|
429
421
|
end
|
430
422
|
|
431
|
-
|
423
|
+
#: (Prism::CallNode node) -> void
|
432
424
|
def complete_require(node)
|
433
425
|
arguments_node = node.arguments
|
434
426
|
return unless arguments_node
|
@@ -440,21 +432,27 @@ module RubyLsp
|
|
440
432
|
matched_uris = @index.search_require_paths(path_node_to_complete.content)
|
441
433
|
|
442
434
|
matched_uris.map!(&:require_path).sort!.each do |path|
|
443
|
-
@response_builder << build_completion(
|
435
|
+
@response_builder << build_completion(
|
436
|
+
path, #: as !nil
|
437
|
+
path_node_to_complete,
|
438
|
+
)
|
444
439
|
end
|
445
440
|
end
|
446
441
|
|
447
|
-
|
442
|
+
#: (Prism::CallNode node) -> void
|
448
443
|
def complete_require_relative(node)
|
449
444
|
arguments_node = node.arguments
|
450
445
|
return unless arguments_node
|
451
446
|
|
452
447
|
path_node_to_complete = arguments_node.arguments.first
|
453
|
-
|
454
448
|
return unless path_node_to_complete.is_a?(Prism::StringNode)
|
455
449
|
|
456
|
-
|
450
|
+
# If the file is unsaved (e.g.: untitled:Untitled-1), we can't provide relative completion as we don't know
|
451
|
+
# where the user intends to save it
|
452
|
+
full_path = @uri.to_standardized_path
|
453
|
+
return unless full_path
|
457
454
|
|
455
|
+
origin_dir = Pathname.new(full_path).dirname
|
458
456
|
content = path_node_to_complete.content
|
459
457
|
# if the path is not a directory, glob all possible next characters
|
460
458
|
# for example ../somethi| (where | is the cursor position)
|
@@ -476,17 +474,17 @@ module RubyLsp
|
|
476
474
|
# might fail with EPERM
|
477
475
|
end
|
478
476
|
|
479
|
-
|
477
|
+
#: (Prism::CallNode node, String name) -> void
|
480
478
|
def complete_methods(node, name)
|
481
479
|
# If the node has a receiver, then we don't need to provide local nor keyword completions. Sorbet can provide
|
482
480
|
# local and keyword completion for any file with a Sorbet level of true or higher
|
483
|
-
if
|
481
|
+
if !@sorbet_level.true_or_higher? && !node.receiver
|
484
482
|
add_local_completions(node, name)
|
485
483
|
add_keyword_completions(node, name)
|
486
484
|
end
|
487
485
|
|
488
486
|
# Sorbet can provide completion for methods invoked on self on typed true or higher files
|
489
|
-
return if
|
487
|
+
return if @sorbet_level.true_or_higher? && self_receiver?(node)
|
490
488
|
|
491
489
|
type = @type_inferrer.infer_receiver_type(@node_context)
|
492
490
|
return unless type
|
@@ -497,7 +495,9 @@ module RubyLsp
|
|
497
495
|
method_name = @trigger_character == "." ? nil : name
|
498
496
|
|
499
497
|
range = if method_name
|
500
|
-
range_from_location(
|
498
|
+
range_from_location(
|
499
|
+
node.message_loc, #: as !nil
|
500
|
+
)
|
501
501
|
else
|
502
502
|
loc = node.call_operator_loc
|
503
503
|
|
@@ -515,10 +515,18 @@ module RubyLsp
|
|
515
515
|
external_references = @node_context.fully_qualified_name != type.name
|
516
516
|
|
517
517
|
@index.method_completion_candidates(method_name, type.name).each do |entry|
|
518
|
-
next if entry.visibility !=
|
518
|
+
next if entry.visibility != :public && external_references
|
519
519
|
|
520
520
|
entry_name = entry.name
|
521
521
|
owner_name = entry.owner&.name
|
522
|
+
new_text = entry_name
|
523
|
+
|
524
|
+
if entry_name.end_with?("=")
|
525
|
+
method_name = entry_name.delete_suffix("=")
|
526
|
+
|
527
|
+
# For writer methods, format as assignment and prefix "self." when no receiver is specified
|
528
|
+
new_text = node.receiver.nil? ? "self.#{method_name} = " : "#{method_name} = "
|
529
|
+
end
|
522
530
|
|
523
531
|
label_details = Interface::CompletionItemLabelDetails.new(
|
524
532
|
description: entry.file_name,
|
@@ -528,7 +536,7 @@ module RubyLsp
|
|
528
536
|
label: entry_name,
|
529
537
|
filter_text: entry_name,
|
530
538
|
label_details: label_details,
|
531
|
-
text_edit: Interface::TextEdit.new(range: range, new_text:
|
539
|
+
text_edit: Interface::TextEdit.new(range: range, new_text: new_text),
|
532
540
|
kind: Constant::CompletionItemKind::METHOD,
|
533
541
|
data: {
|
534
542
|
owner_name: owner_name,
|
@@ -540,9 +548,11 @@ module RubyLsp
|
|
540
548
|
# We have not indexed this namespace, so we can't provide any completions
|
541
549
|
end
|
542
550
|
|
543
|
-
|
551
|
+
#: (Prism::CallNode node, String name) -> void
|
544
552
|
def add_local_completions(node, name)
|
545
|
-
range = range_from_location(
|
553
|
+
range = range_from_location(
|
554
|
+
node.message_loc, #: as !nil
|
555
|
+
)
|
546
556
|
|
547
557
|
@node_context.locals_for_scope.each do |local|
|
548
558
|
local_name = local.to_s
|
@@ -560,9 +570,11 @@ module RubyLsp
|
|
560
570
|
end
|
561
571
|
end
|
562
572
|
|
563
|
-
|
573
|
+
#: (Prism::CallNode node, String name) -> void
|
564
574
|
def add_keyword_completions(node, name)
|
565
|
-
range = range_from_location(
|
575
|
+
range = range_from_location(
|
576
|
+
node.message_loc, #: as !nil
|
577
|
+
)
|
566
578
|
|
567
579
|
KEYWORDS.each do |keyword|
|
568
580
|
next unless keyword.start_with?(name)
|
@@ -578,7 +590,7 @@ module RubyLsp
|
|
578
590
|
end
|
579
591
|
end
|
580
592
|
|
581
|
-
|
593
|
+
#: (String label, Prism::StringNode node) -> Interface::CompletionItem
|
582
594
|
def build_completion(label, node)
|
583
595
|
# We should use the content location as we only replace the content and not the delimiters of the string
|
584
596
|
loc = node.content_loc
|
@@ -593,17 +605,9 @@ module RubyLsp
|
|
593
605
|
)
|
594
606
|
end
|
595
607
|
|
596
|
-
|
597
|
-
params(
|
598
|
-
real_name: String,
|
599
|
-
incomplete_name: String,
|
600
|
-
range: Interface::Range,
|
601
|
-
entries: T::Array[RubyIndexer::Entry],
|
602
|
-
top_level: T::Boolean,
|
603
|
-
).returns(Interface::CompletionItem)
|
604
|
-
end
|
608
|
+
#: (String real_name, String incomplete_name, Interface::Range range, Array[RubyIndexer::Entry] entries, bool top_level) -> Interface::CompletionItem
|
605
609
|
def build_entry_completion(real_name, incomplete_name, range, entries, top_level)
|
606
|
-
first_entry =
|
610
|
+
first_entry = entries.first #: as !nil
|
607
611
|
kind = case first_entry
|
608
612
|
when RubyIndexer::Entry::Class
|
609
613
|
Constant::CompletionItemKind::CLASS
|
@@ -690,11 +694,12 @@ module RubyLsp
|
|
690
694
|
# B
|
691
695
|
# end
|
692
696
|
# ```
|
693
|
-
|
697
|
+
#: (String entry_name) -> bool
|
694
698
|
def top_level?(entry_name)
|
695
699
|
nesting = @node_context.nesting
|
696
700
|
nesting.length.downto(0) do |i|
|
697
|
-
prefix =
|
701
|
+
prefix = nesting[0...i] #: as !nil
|
702
|
+
.join("::")
|
698
703
|
full_name = prefix.empty? ? entry_name : "#{prefix}::#{entry_name}"
|
699
704
|
next if full_name == entry_name
|
700
705
|
|