ruby-lsp 0.19.1 → 0.20.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp +7 -1
- data/lib/core_ext/uri.rb +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +63 -12
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +85 -36
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +5 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +39 -98
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +12 -19
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +22 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -7
- data/lib/ruby_indexer/test/enhancements_test.rb +5 -7
- data/lib/ruby_indexer/test/global_variable_test.rb +49 -0
- data/lib/ruby_indexer/test/index_test.rb +89 -0
- data/lib/ruby_lsp/erb_document.rb +15 -2
- data/lib/ruby_lsp/listeners/definition.rb +20 -0
- data/lib/ruby_lsp/listeners/folding_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/code_action_resolve.rb +8 -2
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +2 -1
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/range_formatting.rb +4 -2
- data/lib/ruby_lsp/requests/references.rb +3 -1
- data/lib/ruby_lsp/requests/rename.rb +3 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +1 -1
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +6 -6
- data/lib/ruby_lsp/response_builders/document_symbol.rb +2 -2
- data/lib/ruby_lsp/response_builders/hover.rb +2 -2
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +14 -8
- data/lib/ruby_lsp/response_builders/signature_help.rb +2 -2
- data/lib/ruby_lsp/ruby_document.rb +33 -12
- data/lib/ruby_lsp/setup_bundler.rb +30 -8
- data/lib/ruby_lsp/type_inferrer.rb +1 -1
- metadata +6 -5
@@ -31,30 +31,16 @@ module RubyIndexer
|
|
31
31
|
params(
|
32
32
|
name: String,
|
33
33
|
file_path: String,
|
34
|
-
location:
|
34
|
+
location: Location,
|
35
35
|
comments: T.nilable(String),
|
36
|
-
encoding: Encoding,
|
37
36
|
).void
|
38
37
|
end
|
39
|
-
def initialize(name, file_path, location, comments
|
38
|
+
def initialize(name, file_path, location, comments)
|
40
39
|
@name = name
|
41
40
|
@file_path = file_path
|
42
41
|
@comments = comments
|
43
42
|
@visibility = T.let(Visibility::PUBLIC, Visibility)
|
44
|
-
|
45
|
-
@location = T.let(
|
46
|
-
if location.is_a?(Prism::Location)
|
47
|
-
Location.new(
|
48
|
-
location.start_line,
|
49
|
-
location.end_line,
|
50
|
-
location.start_code_units_column(encoding),
|
51
|
-
location.end_code_units_column(encoding),
|
52
|
-
)
|
53
|
-
else
|
54
|
-
location
|
55
|
-
end,
|
56
|
-
RubyIndexer::Location,
|
57
|
-
)
|
43
|
+
@location = location
|
58
44
|
end
|
59
45
|
|
60
46
|
sig { returns(T::Boolean) }
|
@@ -152,32 +138,19 @@ module RubyIndexer
|
|
152
138
|
params(
|
153
139
|
nesting: T::Array[String],
|
154
140
|
file_path: String,
|
155
|
-
location:
|
156
|
-
name_location:
|
141
|
+
location: Location,
|
142
|
+
name_location: Location,
|
157
143
|
comments: T.nilable(String),
|
158
|
-
encoding: Encoding,
|
159
144
|
).void
|
160
145
|
end
|
161
|
-
def initialize(nesting, file_path, location, name_location, comments
|
146
|
+
def initialize(nesting, file_path, location, name_location, comments)
|
162
147
|
@name = T.let(nesting.join("::"), String)
|
163
148
|
# The original nesting where this namespace was discovered
|
164
149
|
@nesting = nesting
|
165
150
|
|
166
|
-
super(@name, file_path, location, comments
|
167
|
-
|
168
|
-
@name_location =
|
169
|
-
if name_location.is_a?(Prism::Location)
|
170
|
-
Location.new(
|
171
|
-
name_location.start_line,
|
172
|
-
name_location.end_line,
|
173
|
-
name_location.start_code_units_column(encoding),
|
174
|
-
name_location.end_code_units_column(encoding),
|
175
|
-
)
|
176
|
-
else
|
177
|
-
name_location
|
178
|
-
end,
|
179
|
-
RubyIndexer::Location,
|
180
|
-
)
|
151
|
+
super(@name, file_path, location, comments)
|
152
|
+
|
153
|
+
@name_location = name_location
|
181
154
|
end
|
182
155
|
|
183
156
|
sig { returns(T::Array[String]) }
|
@@ -214,15 +187,14 @@ module RubyIndexer
|
|
214
187
|
params(
|
215
188
|
nesting: T::Array[String],
|
216
189
|
file_path: String,
|
217
|
-
location:
|
218
|
-
name_location:
|
190
|
+
location: Location,
|
191
|
+
name_location: Location,
|
219
192
|
comments: T.nilable(String),
|
220
|
-
encoding: Encoding,
|
221
193
|
parent_class: T.nilable(String),
|
222
194
|
).void
|
223
195
|
end
|
224
|
-
def initialize(nesting, file_path, location, name_location, comments,
|
225
|
-
super(nesting, file_path, location, name_location, comments
|
196
|
+
def initialize(nesting, file_path, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
|
197
|
+
super(nesting, file_path, location, name_location, comments)
|
226
198
|
@parent_class = parent_class
|
227
199
|
end
|
228
200
|
|
@@ -237,26 +209,14 @@ module RubyIndexer
|
|
237
209
|
|
238
210
|
sig do
|
239
211
|
params(
|
240
|
-
location:
|
241
|
-
name_location:
|
212
|
+
location: Location,
|
213
|
+
name_location: Location,
|
242
214
|
comments: T.nilable(String),
|
243
|
-
encoding: Encoding,
|
244
215
|
).void
|
245
216
|
end
|
246
|
-
def update_singleton_information(location, name_location, comments
|
247
|
-
|
248
|
-
@
|
249
|
-
location.start_line,
|
250
|
-
location.end_line,
|
251
|
-
location.start_code_units_column(encoding),
|
252
|
-
location.end_code_units_column(encoding),
|
253
|
-
)
|
254
|
-
@name_location = Location.new(
|
255
|
-
name_location.start_line,
|
256
|
-
name_location.end_line,
|
257
|
-
name_location.start_code_units_column(encoding),
|
258
|
-
name_location.end_code_units_column(encoding),
|
259
|
-
)
|
217
|
+
def update_singleton_information(location, name_location, comments)
|
218
|
+
@location = location
|
219
|
+
@name_location = name_location
|
260
220
|
(@comments ||= +"") << comments if comments
|
261
221
|
end
|
262
222
|
end
|
@@ -373,15 +333,14 @@ module RubyIndexer
|
|
373
333
|
params(
|
374
334
|
name: String,
|
375
335
|
file_path: String,
|
376
|
-
location:
|
336
|
+
location: Location,
|
377
337
|
comments: T.nilable(String),
|
378
|
-
encoding: Encoding,
|
379
338
|
visibility: Visibility,
|
380
339
|
owner: T.nilable(Entry::Namespace),
|
381
340
|
).void
|
382
341
|
end
|
383
|
-
def initialize(name, file_path, location, comments,
|
384
|
-
super(name, file_path, location, comments
|
342
|
+
def initialize(name, file_path, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
343
|
+
super(name, file_path, location, comments)
|
385
344
|
@visibility = visibility
|
386
345
|
@owner = owner
|
387
346
|
end
|
@@ -441,31 +400,18 @@ module RubyIndexer
|
|
441
400
|
params(
|
442
401
|
name: String,
|
443
402
|
file_path: String,
|
444
|
-
location:
|
445
|
-
name_location:
|
403
|
+
location: Location,
|
404
|
+
name_location: Location,
|
446
405
|
comments: T.nilable(String),
|
447
|
-
encoding: Encoding,
|
448
406
|
signatures: T::Array[Signature],
|
449
407
|
visibility: Visibility,
|
450
408
|
owner: T.nilable(Entry::Namespace),
|
451
409
|
).void
|
452
410
|
end
|
453
|
-
def initialize(name, file_path, location, name_location, comments,
|
454
|
-
super(name, file_path, location, comments,
|
411
|
+
def initialize(name, file_path, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
412
|
+
super(name, file_path, location, comments, visibility, owner)
|
455
413
|
@signatures = signatures
|
456
|
-
@name_location =
|
457
|
-
if name_location.is_a?(Prism::Location)
|
458
|
-
Location.new(
|
459
|
-
name_location.start_line,
|
460
|
-
name_location.end_line,
|
461
|
-
name_location.start_code_units_column(encoding),
|
462
|
-
name_location.end_code_units_column(encoding),
|
463
|
-
)
|
464
|
-
else
|
465
|
-
name_location
|
466
|
-
end,
|
467
|
-
RubyIndexer::Location,
|
468
|
-
)
|
414
|
+
@name_location = name_location
|
469
415
|
end
|
470
416
|
end
|
471
417
|
|
@@ -494,13 +440,12 @@ module RubyIndexer
|
|
494
440
|
nesting: T::Array[String],
|
495
441
|
name: String,
|
496
442
|
file_path: String,
|
497
|
-
location:
|
443
|
+
location: Location,
|
498
444
|
comments: T.nilable(String),
|
499
|
-
encoding: Encoding,
|
500
445
|
).void
|
501
446
|
end
|
502
|
-
def initialize(target, nesting, name, file_path, location, comments
|
503
|
-
super(name, file_path, location, comments
|
447
|
+
def initialize(target, nesting, name, file_path, location, comments) # rubocop:disable Metrics/ParameterLists
|
448
|
+
super(name, file_path, location, comments)
|
504
449
|
|
505
450
|
@target = target
|
506
451
|
@nesting = nesting
|
@@ -514,14 +459,13 @@ module RubyIndexer
|
|
514
459
|
sig { returns(String) }
|
515
460
|
attr_reader :target
|
516
461
|
|
517
|
-
sig { params(target: String, unresolved_alias: UnresolvedConstantAlias
|
518
|
-
def initialize(target, unresolved_alias
|
462
|
+
sig { params(target: String, unresolved_alias: UnresolvedConstantAlias).void }
|
463
|
+
def initialize(target, unresolved_alias)
|
519
464
|
super(
|
520
465
|
unresolved_alias.name,
|
521
466
|
unresolved_alias.file_path,
|
522
467
|
unresolved_alias.location,
|
523
468
|
unresolved_alias.comments,
|
524
|
-
encoding
|
525
469
|
)
|
526
470
|
|
527
471
|
@visibility = unresolved_alias.visibility
|
@@ -541,14 +485,13 @@ module RubyIndexer
|
|
541
485
|
params(
|
542
486
|
name: String,
|
543
487
|
file_path: String,
|
544
|
-
location:
|
488
|
+
location: Location,
|
545
489
|
comments: T.nilable(String),
|
546
|
-
encoding: Encoding,
|
547
490
|
owner: T.nilable(Entry::Namespace),
|
548
491
|
).void
|
549
492
|
end
|
550
|
-
def initialize(name, file_path, location, comments,
|
551
|
-
super(name, file_path, location, comments
|
493
|
+
def initialize(name, file_path, location, comments, owner)
|
494
|
+
super(name, file_path, location, comments)
|
552
495
|
@owner = owner
|
553
496
|
end
|
554
497
|
end
|
@@ -571,13 +514,12 @@ module RubyIndexer
|
|
571
514
|
old_name: String,
|
572
515
|
owner: T.nilable(Entry::Namespace),
|
573
516
|
file_path: String,
|
574
|
-
location:
|
517
|
+
location: Location,
|
575
518
|
comments: T.nilable(String),
|
576
|
-
encoding: Encoding,
|
577
519
|
).void
|
578
520
|
end
|
579
|
-
def initialize(new_name, old_name, owner, file_path, location, comments
|
580
|
-
super(new_name, file_path, location, comments
|
521
|
+
def initialize(new_name, old_name, owner, file_path, location, comments) # rubocop:disable Metrics/ParameterLists
|
522
|
+
super(new_name, file_path, location, comments)
|
581
523
|
|
582
524
|
@new_name = new_name
|
583
525
|
@old_name = old_name
|
@@ -596,9 +538,9 @@ module RubyIndexer
|
|
596
538
|
attr_reader :owner
|
597
539
|
|
598
540
|
sig do
|
599
|
-
params(target: T.any(Member, MethodAlias), unresolved_alias: UnresolvedMethodAlias
|
541
|
+
params(target: T.any(Member, MethodAlias), unresolved_alias: UnresolvedMethodAlias).void
|
600
542
|
end
|
601
|
-
def initialize(target, unresolved_alias
|
543
|
+
def initialize(target, unresolved_alias)
|
602
544
|
full_comments = +"Alias for #{target.name}\n"
|
603
545
|
full_comments << "#{unresolved_alias.comments}\n"
|
604
546
|
full_comments << target.comments
|
@@ -608,7 +550,6 @@ module RubyIndexer
|
|
608
550
|
unresolved_alias.file_path,
|
609
551
|
unresolved_alias.location,
|
610
552
|
full_comments,
|
611
|
-
encoding
|
612
553
|
)
|
613
554
|
|
614
555
|
@target = target
|
@@ -665,7 +665,6 @@ module RubyIndexer
|
|
665
665
|
attached_ancestor.location,
|
666
666
|
attached_ancestor.name_location,
|
667
667
|
nil,
|
668
|
-
@configuration.encoding,
|
669
668
|
nil,
|
670
669
|
)
|
671
670
|
add(singleton, skip_prefix_tree: true)
|
@@ -859,7 +858,7 @@ module RubyIndexer
|
|
859
858
|
return entry unless target
|
860
859
|
|
861
860
|
target_name = T.must(target.first).name
|
862
|
-
resolved_alias = Entry::ConstantAlias.new(target_name, entry
|
861
|
+
resolved_alias = Entry::ConstantAlias.new(target_name, entry)
|
863
862
|
|
864
863
|
# Replace the UnresolvedAlias by a resolved one so that we don't have to do this again later
|
865
864
|
original_entries = T.must(@entries[alias_name])
|
@@ -981,29 +980,23 @@ module RubyIndexer
|
|
981
980
|
# nesting
|
982
981
|
sig { params(name: String, nesting: T::Array[String]).returns(String) }
|
983
982
|
def build_non_redundant_full_name(name, nesting)
|
983
|
+
# If there's no nesting, then we can just return the name as is
|
984
984
|
return name if nesting.empty?
|
985
985
|
|
986
|
-
namespace = nesting.join("::")
|
987
|
-
|
988
986
|
# If the name is not qualified, we can just concatenate the nesting and the name
|
989
|
-
return "#{
|
987
|
+
return "#{nesting.join("::")}::#{name}" unless name.include?("::")
|
990
988
|
|
991
989
|
name_parts = name.split("::")
|
990
|
+
first_redundant_part = nesting.index(name_parts[0])
|
992
991
|
|
993
|
-
#
|
994
|
-
|
992
|
+
# If there are no redundant parts between the name and the nesting, then the full name is both combined
|
993
|
+
return "#{nesting.join("::")}::#{name}" unless first_redundant_part
|
995
994
|
|
996
|
-
if
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
# No parts of the nesting are in the name, we can concatenate the namespace and the name
|
1002
|
-
"#{namespace}::#{name}"
|
1003
|
-
else
|
1004
|
-
# The name includes some parts of the nesting. We need to remove the redundant parts
|
1005
|
-
"#{namespace}::#{T.must(name_parts[index..-1]).join("::")}"
|
1006
|
-
end
|
995
|
+
# Otherwise, push all of the leading parts of the nesting that aren't redundant into the name. For example, if we
|
996
|
+
# have a reference to `Foo::Bar` inside the `[Namespace, Foo]` nesting, then only the `Foo` part is redundant, but
|
997
|
+
# we still need to include the `Namespace` part
|
998
|
+
T.unsafe(name_parts).unshift(*nesting[0...first_redundant_part])
|
999
|
+
name_parts.join("::")
|
1007
1000
|
end
|
1008
1001
|
|
1009
1002
|
sig do
|
@@ -1050,7 +1043,7 @@ module RubyIndexer
|
|
1050
1043
|
target_method_entries = resolve_method(entry.old_name, receiver_name, seen_names)
|
1051
1044
|
return entry unless target_method_entries
|
1052
1045
|
|
1053
|
-
resolved_alias = Entry::MethodAlias.new(T.must(target_method_entries.first), entry
|
1046
|
+
resolved_alias = Entry::MethodAlias.new(T.must(target_method_entries.first), entry)
|
1054
1047
|
original_entries = T.must(@entries[new_name])
|
1055
1048
|
original_entries.delete(entry)
|
1056
1049
|
original_entries << resolved_alias
|
@@ -5,6 +5,28 @@ module RubyIndexer
|
|
5
5
|
class Location
|
6
6
|
extend T::Sig
|
7
7
|
|
8
|
+
class << self
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig do
|
12
|
+
params(
|
13
|
+
prism_location: Prism::Location,
|
14
|
+
code_units_cache: T.any(
|
15
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
16
|
+
Prism::CodeUnitsCache,
|
17
|
+
),
|
18
|
+
).returns(T.attached_class)
|
19
|
+
end
|
20
|
+
def from_prism_location(prism_location, code_units_cache)
|
21
|
+
new(
|
22
|
+
prism_location.start_line,
|
23
|
+
prism_location.end_line,
|
24
|
+
prism_location.cached_start_code_units_column(code_units_cache),
|
25
|
+
prism_location.cached_end_code_units_column(code_units_cache),
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
8
30
|
sig { returns(Integer) }
|
9
31
|
attr_reader :start_line, :end_line, :start_column, :end_column
|
10
32
|
|
@@ -61,9 +61,9 @@ module RubyIndexer
|
|
61
61
|
comments = comments_to_string(declaration)
|
62
62
|
entry = if declaration.is_a?(RBS::AST::Declarations::Class)
|
63
63
|
parent_class = declaration.super_class&.name&.name&.to_s
|
64
|
-
Entry::Class.new(nesting, file_path, location, location, comments,
|
64
|
+
Entry::Class.new(nesting, file_path, location, location, comments, parent_class)
|
65
65
|
else
|
66
|
-
Entry::Module.new(nesting, file_path, location, location, comments
|
66
|
+
Entry::Module.new(nesting, file_path, location, location, comments)
|
67
67
|
end
|
68
68
|
add_declaration_mixins_to_entry(declaration, entry)
|
69
69
|
@index.add(entry)
|
@@ -136,7 +136,6 @@ module RubyIndexer
|
|
136
136
|
location,
|
137
137
|
location,
|
138
138
|
comments,
|
139
|
-
@index.configuration.encoding,
|
140
139
|
signatures,
|
141
140
|
visibility,
|
142
141
|
real_owner,
|
@@ -269,7 +268,6 @@ module RubyIndexer
|
|
269
268
|
file_path,
|
270
269
|
to_ruby_indexer_location(declaration.location),
|
271
270
|
comments_to_string(declaration),
|
272
|
-
@index.configuration.encoding,
|
273
271
|
))
|
274
272
|
end
|
275
273
|
|
@@ -279,14 +277,12 @@ module RubyIndexer
|
|
279
277
|
file_path = pathname.to_s
|
280
278
|
location = to_ruby_indexer_location(declaration.location)
|
281
279
|
comments = comments_to_string(declaration)
|
282
|
-
encoding = @index.configuration.encoding
|
283
280
|
|
284
281
|
@index.add(Entry::GlobalVariable.new(
|
285
282
|
name,
|
286
283
|
file_path,
|
287
284
|
location,
|
288
285
|
comments,
|
289
|
-
encoding,
|
290
286
|
))
|
291
287
|
end
|
292
288
|
|
@@ -302,7 +298,6 @@ module RubyIndexer
|
|
302
298
|
file_path,
|
303
299
|
to_ruby_indexer_location(member.location),
|
304
300
|
comments,
|
305
|
-
@index.configuration.encoding,
|
306
301
|
)
|
307
302
|
|
308
303
|
@index.add(entry)
|
@@ -9,14 +9,14 @@ module RubyIndexer
|
|
9
9
|
enhancement_class = Class.new do
|
10
10
|
include Enhancement
|
11
11
|
|
12
|
-
def on_call_node(index, owner, node, file_path)
|
12
|
+
def on_call_node(index, owner, node, file_path, code_units_cache)
|
13
13
|
return unless owner
|
14
14
|
return unless node.name == :extend
|
15
15
|
|
16
16
|
arguments = node.arguments&.arguments
|
17
17
|
return unless arguments
|
18
18
|
|
19
|
-
location = node.location
|
19
|
+
location = Location.from_prism_location(node.location, code_units_cache)
|
20
20
|
|
21
21
|
arguments.each do |node|
|
22
22
|
next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
|
@@ -39,7 +39,6 @@ module RubyIndexer
|
|
39
39
|
location,
|
40
40
|
location,
|
41
41
|
nil,
|
42
|
-
index.configuration.encoding,
|
43
42
|
[Entry::Signature.new([Entry::RequiredParameter.new(name: :a)])],
|
44
43
|
Entry::Visibility::PUBLIC,
|
45
44
|
owner,
|
@@ -102,7 +101,7 @@ module RubyIndexer
|
|
102
101
|
enhancement_class = Class.new do
|
103
102
|
include Enhancement
|
104
103
|
|
105
|
-
def on_call_node(index, owner, node, file_path)
|
104
|
+
def on_call_node(index, owner, node, file_path, code_units_cache)
|
106
105
|
return unless owner
|
107
106
|
|
108
107
|
name = node.name
|
@@ -114,7 +113,7 @@ module RubyIndexer
|
|
114
113
|
association_name = arguments.first
|
115
114
|
return unless association_name.is_a?(Prism::SymbolNode)
|
116
115
|
|
117
|
-
location = association_name.location
|
116
|
+
location = Location.from_prism_location(association_name.location, code_units_cache)
|
118
117
|
|
119
118
|
index.add(Entry::Method.new(
|
120
119
|
T.must(association_name.value),
|
@@ -122,7 +121,6 @@ module RubyIndexer
|
|
122
121
|
location,
|
123
122
|
location,
|
124
123
|
nil,
|
125
|
-
index.configuration.encoding,
|
126
124
|
[],
|
127
125
|
Entry::Visibility::PUBLIC,
|
128
126
|
owner,
|
@@ -166,7 +164,7 @@ module RubyIndexer
|
|
166
164
|
enhancement_class = Class.new do
|
167
165
|
include Enhancement
|
168
166
|
|
169
|
-
def on_call_node(index, owner, node, file_path)
|
167
|
+
def on_call_node(index, owner, node, file_path, code_units_cache)
|
170
168
|
raise "Error"
|
171
169
|
end
|
172
170
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "test_case"
|
5
|
+
|
6
|
+
module RubyIndexer
|
7
|
+
class GlobalVariableTest < TestCase
|
8
|
+
def test_global_variable_and_write
|
9
|
+
index(<<~RUBY)
|
10
|
+
$foo &&= 1
|
11
|
+
RUBY
|
12
|
+
|
13
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_global_variable_operator_write
|
17
|
+
index(<<~RUBY)
|
18
|
+
$foo += 1
|
19
|
+
RUBY
|
20
|
+
|
21
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_global_variable_or_write
|
25
|
+
index(<<~RUBY)
|
26
|
+
$foo ||= 1
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_global_variable_target_node
|
33
|
+
index(<<~RUBY)
|
34
|
+
$foo, $bar = 1
|
35
|
+
RUBY
|
36
|
+
|
37
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
38
|
+
assert_entry("$bar", Entry::GlobalVariable, "/fake/path/foo.rb:0-6:0-10")
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_global_variable_write
|
42
|
+
index(<<~RUBY)
|
43
|
+
$foo = 1
|
44
|
+
RUBY
|
45
|
+
|
46
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1934,5 +1934,94 @@ module RubyIndexer
|
|
1934
1934
|
real_namespace = @index.follow_aliased_namespace("Namespace::Second")
|
1935
1935
|
assert_equal("First::Second", real_namespace)
|
1936
1936
|
end
|
1937
|
+
|
1938
|
+
def test_resolving_alias_to_non_existing_namespace
|
1939
|
+
index(<<~RUBY)
|
1940
|
+
module Namespace
|
1941
|
+
class Foo
|
1942
|
+
module InnerNamespace
|
1943
|
+
Constants = Namespace::Foo::Constants
|
1944
|
+
end
|
1945
|
+
end
|
1946
|
+
end
|
1947
|
+
RUBY
|
1948
|
+
|
1949
|
+
entry = @index.resolve("Constants", ["Namespace", "Foo", "InnerNamespace"])&.first
|
1950
|
+
assert_instance_of(Entry::UnresolvedConstantAlias, entry)
|
1951
|
+
|
1952
|
+
entry = @index.resolve("Namespace::Foo::Constants", ["Namespace", "Foo", "InnerNamespace"])&.first
|
1953
|
+
assert_nil(entry)
|
1954
|
+
end
|
1955
|
+
|
1956
|
+
def test_resolving_alias_to_existing_constant_from_inner_namespace
|
1957
|
+
index(<<~RUBY)
|
1958
|
+
module Parent
|
1959
|
+
CONST = 123
|
1960
|
+
end
|
1961
|
+
|
1962
|
+
module First
|
1963
|
+
module Namespace
|
1964
|
+
class Foo
|
1965
|
+
include Parent
|
1966
|
+
|
1967
|
+
module InnerNamespace
|
1968
|
+
Constants = Namespace::Foo::CONST
|
1969
|
+
end
|
1970
|
+
end
|
1971
|
+
end
|
1972
|
+
end
|
1973
|
+
RUBY
|
1974
|
+
|
1975
|
+
entry = @index.resolve("Namespace::Foo::CONST", ["First", "Namespace", "Foo", "InnerNamespace"])&.first
|
1976
|
+
assert_equal("Parent::CONST", entry.name)
|
1977
|
+
assert_instance_of(Entry::Constant, entry)
|
1978
|
+
end
|
1979
|
+
|
1980
|
+
def test_build_non_redundant_name
|
1981
|
+
assert_equal(
|
1982
|
+
"Namespace::Foo::Constants",
|
1983
|
+
@index.send(
|
1984
|
+
:build_non_redundant_full_name,
|
1985
|
+
"Namespace::Foo::Constants",
|
1986
|
+
["Namespace", "Foo", "InnerNamespace"],
|
1987
|
+
),
|
1988
|
+
)
|
1989
|
+
|
1990
|
+
assert_equal(
|
1991
|
+
"Namespace::Foo::Constants",
|
1992
|
+
@index.send(
|
1993
|
+
:build_non_redundant_full_name,
|
1994
|
+
"Namespace::Foo::Constants",
|
1995
|
+
["Namespace", "Foo"],
|
1996
|
+
),
|
1997
|
+
)
|
1998
|
+
|
1999
|
+
assert_equal(
|
2000
|
+
"Namespace::Foo::Constants",
|
2001
|
+
@index.send(
|
2002
|
+
:build_non_redundant_full_name,
|
2003
|
+
"Foo::Constants",
|
2004
|
+
["Namespace", "Foo"],
|
2005
|
+
),
|
2006
|
+
)
|
2007
|
+
|
2008
|
+
assert_equal(
|
2009
|
+
"Bar::Namespace::Foo::Constants",
|
2010
|
+
@index.send(
|
2011
|
+
:build_non_redundant_full_name,
|
2012
|
+
"Namespace::Foo::Constants",
|
2013
|
+
["Bar"],
|
2014
|
+
),
|
2015
|
+
)
|
2016
|
+
|
2017
|
+
assert_equal(
|
2018
|
+
"First::Namespace::Foo::Constants",
|
2019
|
+
@index.send(
|
2020
|
+
:build_non_redundant_full_name,
|
2021
|
+
"Namespace::Foo::Constants",
|
2022
|
+
["First", "Namespace", "Foo", "InnerNamespace"],
|
2023
|
+
),
|
2024
|
+
)
|
2025
|
+
end
|
1937
2026
|
end
|
1938
2027
|
end
|
@@ -6,10 +6,18 @@ module RubyLsp
|
|
6
6
|
extend T::Sig
|
7
7
|
extend T::Generic
|
8
8
|
|
9
|
+
ParseResultType = type_member { { fixed: Prism::ParseResult } }
|
10
|
+
|
9
11
|
sig { returns(String) }
|
10
12
|
attr_reader :host_language_source
|
11
13
|
|
12
|
-
|
14
|
+
sig do
|
15
|
+
returns(T.any(
|
16
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
17
|
+
Prism::CodeUnitsCache,
|
18
|
+
))
|
19
|
+
end
|
20
|
+
attr_reader :code_units_cache
|
13
21
|
|
14
22
|
sig { params(source: String, version: Integer, uri: URI::Generic, encoding: Encoding).void }
|
15
23
|
def initialize(source:, version:, uri:, encoding: Encoding::UTF_8)
|
@@ -17,6 +25,10 @@ module RubyLsp
|
|
17
25
|
# overrides this with the proper virtual host language source
|
18
26
|
@host_language_source = T.let("", String)
|
19
27
|
super
|
28
|
+
@code_units_cache = T.let(@parse_result.code_units_cache(@encoding), T.any(
|
29
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
30
|
+
Prism::CodeUnitsCache,
|
31
|
+
))
|
20
32
|
end
|
21
33
|
|
22
34
|
sig { override.returns(T::Boolean) }
|
@@ -30,6 +42,7 @@ module RubyLsp
|
|
30
42
|
# Use partial script to avoid syntax errors in ERB files where keywords may be used without the full context in
|
31
43
|
# which they will be evaluated
|
32
44
|
@parse_result = Prism.parse(scanner.ruby, partial_script: true)
|
45
|
+
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
33
46
|
true
|
34
47
|
end
|
35
48
|
|
@@ -53,8 +66,8 @@ module RubyLsp
|
|
53
66
|
RubyDocument.locate(
|
54
67
|
@parse_result.value,
|
55
68
|
create_scanner.find_char_position(position),
|
69
|
+
code_units_cache: @code_units_cache,
|
56
70
|
node_types: node_types,
|
57
|
-
encoding: @encoding,
|
58
71
|
)
|
59
72
|
end
|
60
73
|
|