ruby-lsp 0.17.4 → 0.17.13
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 +11 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp +26 -1
- data/exe/ruby-lsp-check +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +74 -43
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +26 -0
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +147 -29
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +383 -79
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +195 -61
- data/lib/ruby_indexer/ruby_indexer.rb +1 -8
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +71 -3
- data/lib/ruby_indexer/test/configuration_test.rb +1 -1
- data/lib/ruby_indexer/test/constant_test.rb +17 -17
- data/lib/ruby_indexer/test/enhancements_test.rb +197 -0
- data/lib/ruby_indexer/test/index_test.rb +367 -17
- data/lib/ruby_indexer/test/method_test.rb +58 -25
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +297 -0
- data/lib/ruby_indexer/test/test_case.rb +1 -5
- data/lib/ruby_lsp/addon.rb +22 -5
- data/lib/ruby_lsp/base_server.rb +8 -3
- data/lib/ruby_lsp/document.rb +27 -46
- data/lib/ruby_lsp/erb_document.rb +125 -0
- data/lib/ruby_lsp/global_state.rb +47 -19
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/completion.rb +161 -57
- data/lib/ruby_lsp/listeners/definition.rb +91 -27
- data/lib/ruby_lsp/listeners/document_highlight.rb +5 -1
- data/lib/ruby_lsp/listeners/hover.rb +61 -19
- data/lib/ruby_lsp/listeners/signature_help.rb +13 -6
- data/lib/ruby_lsp/node_context.rb +65 -5
- data/lib/ruby_lsp/requests/code_action_resolve.rb +107 -9
- data/lib/ruby_lsp/requests/code_actions.rb +11 -2
- data/lib/ruby_lsp/requests/completion.rb +4 -4
- data/lib/ruby_lsp/requests/completion_resolve.rb +14 -9
- data/lib/ruby_lsp/requests/definition.rb +18 -8
- data/lib/ruby_lsp/requests/diagnostics.rb +6 -5
- data/lib/ruby_lsp/requests/document_symbol.rb +2 -7
- data/lib/ruby_lsp/requests/folding_ranges.rb +6 -2
- data/lib/ruby_lsp/requests/formatting.rb +15 -0
- data/lib/ruby_lsp/requests/hover.rb +5 -5
- data/lib/ruby_lsp/requests/on_type_formatting.rb +6 -4
- data/lib/ruby_lsp/requests/selection_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +3 -2
- data/lib/ruby_lsp/requests/signature_help.rb +3 -3
- data/lib/ruby_lsp/requests/support/common.rb +11 -2
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +2 -6
- data/lib/ruby_lsp/ruby_document.rb +74 -0
- data/lib/ruby_lsp/server.rb +129 -54
- data/lib/ruby_lsp/store.rb +33 -9
- data/lib/ruby_lsp/test_helper.rb +3 -1
- data/lib/ruby_lsp/type_inferrer.rb +61 -25
- data/lib/ruby_lsp/utils.rb +13 -0
- metadata +9 -8
- data/exe/ruby-lsp-doctor +0 -23
@@ -22,6 +22,8 @@ module RubyIndexer
|
|
22
22
|
sig { returns(RubyIndexer::Location) }
|
23
23
|
attr_reader :location
|
24
24
|
|
25
|
+
alias_method :name_location, :location
|
26
|
+
|
25
27
|
sig { returns(T::Array[String]) }
|
26
28
|
attr_reader :comments
|
27
29
|
|
@@ -57,6 +59,16 @@ module RubyIndexer
|
|
57
59
|
)
|
58
60
|
end
|
59
61
|
|
62
|
+
sig { returns(T::Boolean) }
|
63
|
+
def public?
|
64
|
+
visibility == Visibility::PUBLIC
|
65
|
+
end
|
66
|
+
|
67
|
+
sig { returns(T::Boolean) }
|
68
|
+
def protected?
|
69
|
+
visibility == Visibility::PROTECTED
|
70
|
+
end
|
71
|
+
|
60
72
|
sig { returns(T::Boolean) }
|
61
73
|
def private?
|
62
74
|
visibility == Visibility::PRIVATE
|
@@ -84,7 +96,6 @@ module RubyIndexer
|
|
84
96
|
|
85
97
|
class Include < ModuleOperation; end
|
86
98
|
class Prepend < ModuleOperation; end
|
87
|
-
class Extend < ModuleOperation; end
|
88
99
|
|
89
100
|
class Namespace < Entry
|
90
101
|
extend T::Sig
|
@@ -95,20 +106,39 @@ module RubyIndexer
|
|
95
106
|
sig { returns(T::Array[String]) }
|
96
107
|
attr_reader :nesting
|
97
108
|
|
109
|
+
# Returns the location of the constant name, excluding the parent class or the body
|
110
|
+
sig { returns(Location) }
|
111
|
+
attr_reader :name_location
|
112
|
+
|
98
113
|
sig do
|
99
114
|
params(
|
100
115
|
nesting: T::Array[String],
|
101
116
|
file_path: String,
|
102
117
|
location: T.any(Prism::Location, RubyIndexer::Location),
|
118
|
+
name_location: T.any(Prism::Location, Location),
|
103
119
|
comments: T::Array[String],
|
104
120
|
).void
|
105
121
|
end
|
106
|
-
def initialize(nesting, file_path, location, comments)
|
122
|
+
def initialize(nesting, file_path, location, name_location, comments)
|
107
123
|
@name = T.let(nesting.join("::"), String)
|
108
124
|
# The original nesting where this namespace was discovered
|
109
125
|
@nesting = nesting
|
110
126
|
|
111
127
|
super(@name, file_path, location, comments)
|
128
|
+
|
129
|
+
@name_location = T.let(
|
130
|
+
if name_location.is_a?(Prism::Location)
|
131
|
+
Location.new(
|
132
|
+
name_location.start_line,
|
133
|
+
name_location.end_line,
|
134
|
+
name_location.start_column,
|
135
|
+
name_location.end_column,
|
136
|
+
)
|
137
|
+
else
|
138
|
+
name_location
|
139
|
+
end,
|
140
|
+
RubyIndexer::Location,
|
141
|
+
)
|
112
142
|
end
|
113
143
|
|
114
144
|
sig { returns(T::Array[String]) }
|
@@ -146,12 +176,13 @@ module RubyIndexer
|
|
146
176
|
nesting: T::Array[String],
|
147
177
|
file_path: String,
|
148
178
|
location: T.any(Prism::Location, RubyIndexer::Location),
|
179
|
+
name_location: T.any(Prism::Location, Location),
|
149
180
|
comments: T::Array[String],
|
150
181
|
parent_class: T.nilable(String),
|
151
182
|
).void
|
152
183
|
end
|
153
|
-
def initialize(nesting, file_path, location, comments, parent_class)
|
154
|
-
super(nesting, file_path, location, comments)
|
184
|
+
def initialize(nesting, file_path, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
|
185
|
+
super(nesting, file_path, location, name_location, comments)
|
155
186
|
@parent_class = parent_class
|
156
187
|
end
|
157
188
|
|
@@ -164,8 +195,8 @@ module RubyIndexer
|
|
164
195
|
class SingletonClass < Class
|
165
196
|
extend T::Sig
|
166
197
|
|
167
|
-
sig { params(location: Prism::Location, comments: T::Array[String]).void }
|
168
|
-
def update_singleton_information(location, comments)
|
198
|
+
sig { params(location: Prism::Location, name_location: Prism::Location, comments: T::Array[String]).void }
|
199
|
+
def update_singleton_information(location, name_location, comments)
|
169
200
|
# Create a new RubyIndexer::Location object from the Prism location
|
170
201
|
@location = Location.new(
|
171
202
|
location.start_line,
|
@@ -173,6 +204,12 @@ module RubyIndexer
|
|
173
204
|
location.start_column,
|
174
205
|
location.end_column,
|
175
206
|
)
|
207
|
+
@name_location = Location.new(
|
208
|
+
name_location.start_line,
|
209
|
+
name_location.end_line,
|
210
|
+
name_location.start_column,
|
211
|
+
name_location.end_column,
|
212
|
+
)
|
176
213
|
@comments.concat(comments)
|
177
214
|
end
|
178
215
|
end
|
@@ -251,6 +288,14 @@ module RubyIndexer
|
|
251
288
|
class BlockParameter < Parameter
|
252
289
|
DEFAULT_NAME = T.let(:"<anonymous block>", Symbol)
|
253
290
|
|
291
|
+
class << self
|
292
|
+
extend T::Sig
|
293
|
+
sig { returns(BlockParameter) }
|
294
|
+
def anonymous
|
295
|
+
new(name: DEFAULT_NAME)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
254
299
|
sig { override.returns(Symbol) }
|
255
300
|
def decorated_name
|
256
301
|
:"&#{@name}"
|
@@ -266,6 +311,11 @@ module RubyIndexer
|
|
266
311
|
sig { returns(T.nilable(Entry::Namespace)) }
|
267
312
|
attr_reader :owner
|
268
313
|
|
314
|
+
sig { returns(T::Array[RubyIndexer::Entry::Parameter]) }
|
315
|
+
def parameters
|
316
|
+
T.must(signatures.first).parameters
|
317
|
+
end
|
318
|
+
|
269
319
|
sig do
|
270
320
|
params(
|
271
321
|
name: String,
|
@@ -282,47 +332,85 @@ module RubyIndexer
|
|
282
332
|
@owner = owner
|
283
333
|
end
|
284
334
|
|
285
|
-
sig { abstract.returns(T::Array[
|
286
|
-
def
|
335
|
+
sig { abstract.returns(T::Array[Entry::Signature]) }
|
336
|
+
def signatures; end
|
287
337
|
|
288
|
-
# Returns a string with the decorated names of the parameters of this member. E.g.: `(a, b = 1, c: 2)`
|
289
338
|
sig { returns(String) }
|
290
339
|
def decorated_parameters
|
291
|
-
|
340
|
+
first_signature = signatures.first
|
341
|
+
return "()" unless first_signature
|
342
|
+
|
343
|
+
"(#{first_signature.format})"
|
344
|
+
end
|
345
|
+
|
346
|
+
sig { returns(String) }
|
347
|
+
def formatted_signatures
|
348
|
+
overloads_count = signatures.size
|
349
|
+
case overloads_count
|
350
|
+
when 1
|
351
|
+
""
|
352
|
+
when 2
|
353
|
+
"\n(+1 overload)"
|
354
|
+
else
|
355
|
+
"\n(+#{overloads_count - 1} overloads)"
|
356
|
+
end
|
292
357
|
end
|
293
358
|
end
|
294
359
|
|
295
360
|
class Accessor < Member
|
296
361
|
extend T::Sig
|
297
362
|
|
298
|
-
sig { override.returns(T::Array[
|
299
|
-
def
|
300
|
-
|
301
|
-
|
302
|
-
|
363
|
+
sig { override.returns(T::Array[Signature]) }
|
364
|
+
def signatures
|
365
|
+
@signatures ||= T.let(
|
366
|
+
begin
|
367
|
+
params = []
|
368
|
+
params << RequiredParameter.new(name: name.delete_suffix("=").to_sym) if name.end_with?("=")
|
369
|
+
[Entry::Signature.new(params)]
|
370
|
+
end,
|
371
|
+
T.nilable(T::Array[Signature]),
|
372
|
+
)
|
303
373
|
end
|
304
374
|
end
|
305
375
|
|
306
376
|
class Method < Member
|
307
377
|
extend T::Sig
|
308
378
|
|
309
|
-
sig { override.returns(T::Array[
|
310
|
-
attr_reader :
|
379
|
+
sig { override.returns(T::Array[Signature]) }
|
380
|
+
attr_reader :signatures
|
381
|
+
|
382
|
+
# Returns the location of the method name, excluding parameters or the body
|
383
|
+
sig { returns(Location) }
|
384
|
+
attr_reader :name_location
|
311
385
|
|
312
386
|
sig do
|
313
387
|
params(
|
314
388
|
name: String,
|
315
389
|
file_path: String,
|
316
390
|
location: T.any(Prism::Location, RubyIndexer::Location),
|
391
|
+
name_location: T.any(Prism::Location, Location),
|
317
392
|
comments: T::Array[String],
|
318
|
-
|
393
|
+
signatures: T::Array[Signature],
|
319
394
|
visibility: Visibility,
|
320
395
|
owner: T.nilable(Entry::Namespace),
|
321
396
|
).void
|
322
397
|
end
|
323
|
-
def initialize(name, file_path, location, comments,
|
398
|
+
def initialize(name, file_path, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
324
399
|
super(name, file_path, location, comments, visibility, owner)
|
325
|
-
@
|
400
|
+
@signatures = signatures
|
401
|
+
@name_location = T.let(
|
402
|
+
if name_location.is_a?(Prism::Location)
|
403
|
+
Location.new(
|
404
|
+
name_location.start_line,
|
405
|
+
name_location.end_line,
|
406
|
+
name_location.start_column,
|
407
|
+
name_location.end_column,
|
408
|
+
)
|
409
|
+
else
|
410
|
+
name_location
|
411
|
+
end,
|
412
|
+
RubyIndexer::Location,
|
413
|
+
)
|
326
414
|
end
|
327
415
|
end
|
328
416
|
|
@@ -336,7 +424,7 @@ module RubyIndexer
|
|
336
424
|
# All aliases are inserted as UnresolvedAlias in the index first and then we lazily resolve them to the correct
|
337
425
|
# target in [rdoc-ref:Index#resolve]. If the right hand side contains a constant that doesn't exist, then it's not
|
338
426
|
# possible to resolve the alias and it will remain an UnresolvedAlias until the right hand side constant exists
|
339
|
-
class
|
427
|
+
class UnresolvedConstantAlias < Entry
|
340
428
|
extend T::Sig
|
341
429
|
|
342
430
|
sig { returns(String) }
|
@@ -364,13 +452,13 @@ module RubyIndexer
|
|
364
452
|
end
|
365
453
|
|
366
454
|
# Alias represents a resolved alias, which points to an existing constant target
|
367
|
-
class
|
455
|
+
class ConstantAlias < Entry
|
368
456
|
extend T::Sig
|
369
457
|
|
370
458
|
sig { returns(String) }
|
371
459
|
attr_reader :target
|
372
460
|
|
373
|
-
sig { params(target: String, unresolved_alias:
|
461
|
+
sig { params(target: String, unresolved_alias: UnresolvedConstantAlias).void }
|
374
462
|
def initialize(target, unresolved_alias)
|
375
463
|
super(unresolved_alias.name, unresolved_alias.file_path, unresolved_alias.location, unresolved_alias.comments)
|
376
464
|
|
@@ -417,7 +505,7 @@ module RubyIndexer
|
|
417
505
|
old_name: String,
|
418
506
|
owner: T.nilable(Entry::Namespace),
|
419
507
|
file_path: String,
|
420
|
-
location: Prism::Location,
|
508
|
+
location: T.any(Prism::Location, RubyIndexer::Location),
|
421
509
|
comments: T::Array[String],
|
422
510
|
).void
|
423
511
|
end
|
@@ -437,6 +525,9 @@ module RubyIndexer
|
|
437
525
|
sig { returns(T.any(Member, MethodAlias)) }
|
438
526
|
attr_reader :target
|
439
527
|
|
528
|
+
sig { returns(T.nilable(Entry::Namespace)) }
|
529
|
+
attr_reader :owner
|
530
|
+
|
440
531
|
sig { params(target: T.any(Member, MethodAlias), unresolved_alias: UnresolvedMethodAlias).void }
|
441
532
|
def initialize(target, unresolved_alias)
|
442
533
|
full_comments = ["Alias for #{target.name}\n"]
|
@@ -452,11 +543,7 @@ module RubyIndexer
|
|
452
543
|
)
|
453
544
|
|
454
545
|
@target = target
|
455
|
-
|
456
|
-
|
457
|
-
sig { returns(T.nilable(Entry::Namespace)) }
|
458
|
-
def owner
|
459
|
-
@target.owner
|
546
|
+
@owner = T.let(unresolved_alias.owner, T.nilable(Entry::Namespace))
|
460
547
|
end
|
461
548
|
|
462
549
|
sig { returns(T::Array[Parameter]) }
|
@@ -468,6 +555,37 @@ module RubyIndexer
|
|
468
555
|
def decorated_parameters
|
469
556
|
@target.decorated_parameters
|
470
557
|
end
|
558
|
+
|
559
|
+
sig { returns(String) }
|
560
|
+
def formatted_signatures
|
561
|
+
@target.formatted_signatures
|
562
|
+
end
|
563
|
+
|
564
|
+
sig { returns(T::Array[Signature]) }
|
565
|
+
def signatures
|
566
|
+
@target.signatures
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
# Ruby doesn't support method overloading, so a method will have only one signature.
|
571
|
+
# However RBS can represent the concept of method overloading, with different return types based on the arguments
|
572
|
+
# passed, so we need to store all the signatures.
|
573
|
+
class Signature
|
574
|
+
extend T::Sig
|
575
|
+
|
576
|
+
sig { returns(T::Array[Parameter]) }
|
577
|
+
attr_reader :parameters
|
578
|
+
|
579
|
+
sig { params(parameters: T::Array[Parameter]).void }
|
580
|
+
def initialize(parameters)
|
581
|
+
@parameters = parameters
|
582
|
+
end
|
583
|
+
|
584
|
+
# Returns a string with the decorated names of the parameters of this member. E.g.: `(a, b = 1, c: 2)`
|
585
|
+
sig { returns(String) }
|
586
|
+
def format
|
587
|
+
@parameters.map(&:decorated_name).join(", ")
|
588
|
+
end
|
471
589
|
end
|
472
590
|
end
|
473
591
|
end
|