ruby-lsp 0.26.4 → 0.26.5
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/VERSION +1 -1
- data/exe/ruby-lsp-launcher +4 -3
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +19 -0
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +33 -27
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +1 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +6 -2
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +20 -0
- data/lib/ruby_indexer/test/configuration_test.rb +3 -5
- data/lib/ruby_indexer/test/index_test.rb +1 -4
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
- data/lib/ruby_lsp/global_state.rb +65 -33
- data/lib/ruby_lsp/listeners/definition.rb +34 -14
- data/lib/ruby_lsp/listeners/document_link.rb +1 -6
- data/lib/ruby_lsp/listeners/hover.rb +2 -2
- data/lib/ruby_lsp/requests/code_action_resolve.rb +33 -11
- data/lib/ruby_lsp/requests/code_actions.rb +20 -5
- data/lib/ruby_lsp/requests/completion_resolve.rb +8 -6
- data/lib/ruby_lsp/requests/support/source_uri.rb +7 -6
- data/lib/ruby_lsp/scripts/compose_bundle.rb +1 -1
- data/lib/ruby_lsp/setup_bundler.rb +25 -14
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c0285974bdf15d052431c1401f320645f57d8bd186ce9899dafc53f11da269a
|
|
4
|
+
data.tar.gz: d17e63e0b0db476033d2dfcaec8e40b4131f97cde55c7ade2cd2977ead23dc15
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26f63dc15bacf617c683dbb7b55fbf1eee1d2f8051b207a27cead0479b475c16d9cb31fbee3fc180f3c054cfd6754c2e5427ec1fa7d4330a17ff3a0ccd9c5f92
|
|
7
|
+
data.tar.gz: 1717199121bee0e9e72dc7bac4ba1779cbed7d4480f7f58bf046b9a3ac8c752c34fe4584eadcf45f98437bbdfb5a3ebcad36cf6951318cf4c63ae6fb84e5b41e
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.26.
|
|
1
|
+
0.26.5
|
data/exe/ruby-lsp-launcher
CHANGED
|
@@ -108,10 +108,11 @@ rescue Bundler::GemNotFound, Bundler::GitError
|
|
|
108
108
|
unless install_error || ARGV.include?("--retry")
|
|
109
109
|
$stderr.puts("Initial bundle compose succeeded, but Bundler.setup failed. Trying to restart from scratch...")
|
|
110
110
|
File.write(raw_initialize_path, raw_initialize)
|
|
111
|
-
exec(Gem.ruby, __FILE__, *ARGV, "--retry")
|
|
112
|
-
end
|
|
113
111
|
|
|
114
|
-
|
|
112
|
+
Bundler.with_unbundled_env do
|
|
113
|
+
exec(Gem.ruby, __FILE__, *ARGV, "--retry")
|
|
114
|
+
end
|
|
115
|
+
end
|
|
115
116
|
rescue StandardError => e
|
|
116
117
|
setup_error = e
|
|
117
118
|
$stderr.puts("Failed to set up composed Bundle\n#{e.full_message}")
|
|
@@ -143,6 +143,7 @@ module RubyIndexer
|
|
|
143
143
|
)
|
|
144
144
|
else
|
|
145
145
|
entry = Entry::SingletonClass.new(
|
|
146
|
+
@index.configuration,
|
|
146
147
|
real_nesting,
|
|
147
148
|
@uri,
|
|
148
149
|
Location.from_prism_location(node.location, @code_units_cache),
|
|
@@ -326,6 +327,7 @@ module RubyIndexer
|
|
|
326
327
|
signatures = [Entry::Signature.new(list_params(node.parameters))]
|
|
327
328
|
|
|
328
329
|
@index.add(Entry::Method.new(
|
|
330
|
+
@index.configuration,
|
|
329
331
|
method_name,
|
|
330
332
|
@uri,
|
|
331
333
|
location,
|
|
@@ -340,6 +342,7 @@ module RubyIndexer
|
|
|
340
342
|
singleton = @index.existing_or_new_singleton_class(owner.name)
|
|
341
343
|
|
|
342
344
|
@index.add(Entry::Method.new(
|
|
345
|
+
@index.configuration,
|
|
343
346
|
method_name,
|
|
344
347
|
@uri,
|
|
345
348
|
location,
|
|
@@ -354,6 +357,7 @@ module RubyIndexer
|
|
|
354
357
|
singleton = @index.existing_or_new_singleton_class(owner.name)
|
|
355
358
|
|
|
356
359
|
@index.add(Entry::Method.new(
|
|
360
|
+
@index.configuration,
|
|
357
361
|
method_name,
|
|
358
362
|
@uri,
|
|
359
363
|
Location.from_prism_location(node.location, @code_units_cache),
|
|
@@ -433,6 +437,7 @@ module RubyIndexer
|
|
|
433
437
|
comments = collect_comments(node)
|
|
434
438
|
@index.add(
|
|
435
439
|
Entry::UnresolvedMethodAlias.new(
|
|
440
|
+
@index.configuration,
|
|
436
441
|
method_name,
|
|
437
442
|
node.old_name.slice,
|
|
438
443
|
@owner_stack.last,
|
|
@@ -473,6 +478,7 @@ module RubyIndexer
|
|
|
473
478
|
location = Location.from_prism_location(node_location, @code_units_cache)
|
|
474
479
|
|
|
475
480
|
@index.add(Entry::Method.new(
|
|
481
|
+
@index.configuration,
|
|
476
482
|
name,
|
|
477
483
|
@uri,
|
|
478
484
|
location,
|
|
@@ -490,6 +496,7 @@ module RubyIndexer
|
|
|
490
496
|
name_loc = Location.from_prism_location(name_location, @code_units_cache)
|
|
491
497
|
|
|
492
498
|
entry = Entry::Module.new(
|
|
499
|
+
@index.configuration,
|
|
493
500
|
Index.actual_nesting(@stack, name),
|
|
494
501
|
@uri,
|
|
495
502
|
location,
|
|
@@ -504,6 +511,7 @@ module RubyIndexer
|
|
|
504
511
|
def add_class(name_or_nesting, full_location, name_location, parent_class_name: nil, comments: nil)
|
|
505
512
|
nesting = name_or_nesting.is_a?(Array) ? name_or_nesting : Index.actual_nesting(@stack, name_or_nesting)
|
|
506
513
|
entry = Entry::Class.new(
|
|
514
|
+
@index.configuration,
|
|
507
515
|
nesting,
|
|
508
516
|
@uri,
|
|
509
517
|
Location.from_prism_location(full_location, @code_units_cache),
|
|
@@ -548,6 +556,7 @@ module RubyIndexer
|
|
|
548
556
|
comments = collect_comments(node)
|
|
549
557
|
|
|
550
558
|
@index.add(Entry::GlobalVariable.new(
|
|
559
|
+
@index.configuration,
|
|
551
560
|
name,
|
|
552
561
|
@uri,
|
|
553
562
|
Location.from_prism_location(loc, @code_units_cache),
|
|
@@ -572,6 +581,7 @@ module RubyIndexer
|
|
|
572
581
|
end
|
|
573
582
|
|
|
574
583
|
@index.add(Entry::ClassVariable.new(
|
|
584
|
+
@index.configuration,
|
|
575
585
|
name,
|
|
576
586
|
@uri,
|
|
577
587
|
Location.from_prism_location(loc, @code_units_cache),
|
|
@@ -594,6 +604,7 @@ module RubyIndexer
|
|
|
594
604
|
end
|
|
595
605
|
|
|
596
606
|
@index.add(Entry::InstanceVariable.new(
|
|
607
|
+
@index.configuration,
|
|
597
608
|
name,
|
|
598
609
|
@uri,
|
|
599
610
|
Location.from_prism_location(loc, @code_units_cache),
|
|
@@ -656,6 +667,7 @@ module RubyIndexer
|
|
|
656
667
|
comments = collect_comments(node)
|
|
657
668
|
@index.add(
|
|
658
669
|
Entry::UnresolvedMethodAlias.new(
|
|
670
|
+
@index.configuration,
|
|
659
671
|
new_name_value,
|
|
660
672
|
old_name_value,
|
|
661
673
|
@owner_stack.last,
|
|
@@ -675,6 +687,7 @@ module RubyIndexer
|
|
|
675
687
|
case value
|
|
676
688
|
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
|
677
689
|
Entry::UnresolvedConstantAlias.new(
|
|
690
|
+
@index.configuration,
|
|
678
691
|
value.slice,
|
|
679
692
|
@stack.dup,
|
|
680
693
|
name,
|
|
@@ -688,6 +701,7 @@ module RubyIndexer
|
|
|
688
701
|
# If the right hand side is another constant assignment, we need to visit it because that constant has to be
|
|
689
702
|
# indexed too
|
|
690
703
|
Entry::UnresolvedConstantAlias.new(
|
|
704
|
+
@index.configuration,
|
|
691
705
|
value.name.to_s,
|
|
692
706
|
@stack.dup,
|
|
693
707
|
name,
|
|
@@ -699,6 +713,7 @@ module RubyIndexer
|
|
|
699
713
|
Prism::ConstantPathAndWriteNode
|
|
700
714
|
|
|
701
715
|
Entry::UnresolvedConstantAlias.new(
|
|
716
|
+
@index.configuration,
|
|
702
717
|
value.target.slice,
|
|
703
718
|
@stack.dup,
|
|
704
719
|
name,
|
|
@@ -708,6 +723,7 @@ module RubyIndexer
|
|
|
708
723
|
)
|
|
709
724
|
else
|
|
710
725
|
Entry::Constant.new(
|
|
726
|
+
@index.configuration,
|
|
711
727
|
name,
|
|
712
728
|
@uri,
|
|
713
729
|
Location.from_prism_location(node.location, @code_units_cache),
|
|
@@ -785,6 +801,7 @@ module RubyIndexer
|
|
|
785
801
|
|
|
786
802
|
if reader
|
|
787
803
|
@index.add(Entry::Accessor.new(
|
|
804
|
+
@index.configuration,
|
|
788
805
|
name,
|
|
789
806
|
@uri,
|
|
790
807
|
Location.from_prism_location(loc, @code_units_cache),
|
|
@@ -797,6 +814,7 @@ module RubyIndexer
|
|
|
797
814
|
next unless writer
|
|
798
815
|
|
|
799
816
|
@index.add(Entry::Accessor.new(
|
|
817
|
+
@index.configuration,
|
|
800
818
|
"#{name}=",
|
|
801
819
|
@uri,
|
|
802
820
|
Location.from_prism_location(loc, @code_units_cache),
|
|
@@ -879,6 +897,7 @@ module RubyIndexer
|
|
|
879
897
|
singleton = @index.existing_or_new_singleton_class(entry_owner_name)
|
|
880
898
|
location = Location.from_prism_location(argument.location, @code_units_cache)
|
|
881
899
|
@index.add(Entry::Method.new(
|
|
900
|
+
@index.configuration,
|
|
882
901
|
method_name,
|
|
883
902
|
@uri,
|
|
884
903
|
location,
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
module RubyIndexer
|
|
5
5
|
class Entry
|
|
6
|
+
#: Configuration
|
|
7
|
+
attr_reader :configuration
|
|
8
|
+
|
|
6
9
|
#: String
|
|
7
10
|
attr_reader :name
|
|
8
11
|
|
|
@@ -17,8 +20,9 @@ module RubyIndexer
|
|
|
17
20
|
#: Symbol
|
|
18
21
|
attr_accessor :visibility
|
|
19
22
|
|
|
20
|
-
#: (String name, URI::Generic uri, Location location, String? comments) -> void
|
|
21
|
-
def initialize(name, uri, location, comments)
|
|
23
|
+
#: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments) -> void
|
|
24
|
+
def initialize(configuration, name, uri, location, comments)
|
|
25
|
+
@configuration = configuration
|
|
22
26
|
@name = name
|
|
23
27
|
@uri = uri
|
|
24
28
|
@comments = comments
|
|
@@ -82,7 +86,7 @@ module RubyIndexer
|
|
|
82
86
|
correct_group.filter_map do |comment|
|
|
83
87
|
content = comment.slice.chomp
|
|
84
88
|
|
|
85
|
-
if content.valid_encoding?
|
|
89
|
+
if content.valid_encoding? && !content.match?(@configuration.magic_comment_regex)
|
|
86
90
|
content.delete_prefix!("#")
|
|
87
91
|
content.delete_prefix!(" ")
|
|
88
92
|
content
|
|
@@ -121,13 +125,13 @@ module RubyIndexer
|
|
|
121
125
|
#: Location
|
|
122
126
|
attr_reader :name_location
|
|
123
127
|
|
|
124
|
-
#: (Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments) -> void
|
|
125
|
-
def initialize(nesting, uri, location, name_location, comments)
|
|
128
|
+
#: (Configuration configuration, Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments) -> void
|
|
129
|
+
def initialize(configuration, nesting, uri, location, name_location, comments) # rubocop:disable Metrics/ParameterLists
|
|
126
130
|
@name = nesting.join("::") #: String
|
|
127
131
|
# The original nesting where this namespace was discovered
|
|
128
132
|
@nesting = nesting
|
|
129
133
|
|
|
130
|
-
super(@name, uri, location, comments)
|
|
134
|
+
super(configuration, @name, uri, location, comments)
|
|
131
135
|
|
|
132
136
|
@name_location = name_location
|
|
133
137
|
end
|
|
@@ -160,9 +164,9 @@ module RubyIndexer
|
|
|
160
164
|
#: String?
|
|
161
165
|
attr_reader :parent_class
|
|
162
166
|
|
|
163
|
-
#: (Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments, String? parent_class) -> void
|
|
164
|
-
def initialize(nesting, uri, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
|
|
165
|
-
super(nesting, uri, location, name_location, comments)
|
|
167
|
+
#: (Configuration configuration, Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments, String? parent_class) -> void
|
|
168
|
+
def initialize(configuration, nesting, uri, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
|
|
169
|
+
super(configuration, nesting, uri, location, name_location, comments)
|
|
166
170
|
@parent_class = parent_class
|
|
167
171
|
end
|
|
168
172
|
|
|
@@ -285,9 +289,9 @@ module RubyIndexer
|
|
|
285
289
|
#: Entry::Namespace?
|
|
286
290
|
attr_reader :owner
|
|
287
291
|
|
|
288
|
-
#: (String name, URI::Generic uri, Location location, String? comments, Symbol visibility, Entry::Namespace? owner) -> void
|
|
289
|
-
def initialize(name, uri, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
|
290
|
-
super(name, uri, location, comments)
|
|
292
|
+
#: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments, Symbol visibility, Entry::Namespace? owner) -> void
|
|
293
|
+
def initialize(configuration, name, uri, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
|
294
|
+
super(configuration, name, uri, location, comments)
|
|
291
295
|
@visibility = visibility
|
|
292
296
|
@owner = owner
|
|
293
297
|
end
|
|
@@ -341,9 +345,9 @@ module RubyIndexer
|
|
|
341
345
|
#: Location
|
|
342
346
|
attr_reader :name_location
|
|
343
347
|
|
|
344
|
-
#: (String name, URI::Generic uri, Location location, Location name_location, String? comments, Array[Signature] signatures, Symbol visibility, Entry::Namespace? owner) -> void
|
|
345
|
-
def initialize(name, uri, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
|
346
|
-
super(name, uri, location, comments, visibility, owner)
|
|
348
|
+
#: (Configuration configuration, String name, URI::Generic uri, Location location, Location name_location, String? comments, Array[Signature] signatures, Symbol visibility, Entry::Namespace? owner) -> void
|
|
349
|
+
def initialize(configuration, name, uri, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
|
|
350
|
+
super(configuration, name, uri, location, comments, visibility, owner)
|
|
347
351
|
@signatures = signatures
|
|
348
352
|
@name_location = name_location
|
|
349
353
|
end
|
|
@@ -366,9 +370,9 @@ module RubyIndexer
|
|
|
366
370
|
#: Array[String]
|
|
367
371
|
attr_reader :nesting
|
|
368
372
|
|
|
369
|
-
#: (String target, Array[String] nesting, String name, URI::Generic uri, Location location, String? comments) -> void
|
|
370
|
-
def initialize(target, nesting, name, uri, location, comments) # rubocop:disable Metrics/ParameterLists
|
|
371
|
-
super(name, uri, location, comments)
|
|
373
|
+
#: (Configuration configuration, String target, Array[String] nesting, String name, URI::Generic uri, Location location, String? comments) -> void
|
|
374
|
+
def initialize(configuration, target, nesting, name, uri, location, comments) # rubocop:disable Metrics/ParameterLists
|
|
375
|
+
super(configuration, name, uri, location, comments)
|
|
372
376
|
|
|
373
377
|
@target = target
|
|
374
378
|
@nesting = nesting
|
|
@@ -383,6 +387,7 @@ module RubyIndexer
|
|
|
383
387
|
#: (String target, UnresolvedConstantAlias unresolved_alias) -> void
|
|
384
388
|
def initialize(target, unresolved_alias)
|
|
385
389
|
super(
|
|
390
|
+
unresolved_alias.configuration,
|
|
386
391
|
unresolved_alias.name,
|
|
387
392
|
unresolved_alias.uri,
|
|
388
393
|
unresolved_alias.location,
|
|
@@ -402,9 +407,9 @@ module RubyIndexer
|
|
|
402
407
|
#: Entry::Namespace?
|
|
403
408
|
attr_reader :owner
|
|
404
409
|
|
|
405
|
-
#: (String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void
|
|
406
|
-
def initialize(name, uri, location, comments, owner)
|
|
407
|
-
super(name, uri, location, comments)
|
|
410
|
+
#: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void
|
|
411
|
+
def initialize(configuration, name, uri, location, comments, owner) # rubocop:disable Metrics/ParameterLists
|
|
412
|
+
super(configuration, name, uri, location, comments)
|
|
408
413
|
@owner = owner
|
|
409
414
|
end
|
|
410
415
|
end
|
|
@@ -414,9 +419,9 @@ module RubyIndexer
|
|
|
414
419
|
#: Entry::Namespace?
|
|
415
420
|
attr_reader :owner
|
|
416
421
|
|
|
417
|
-
#: (String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void
|
|
418
|
-
def initialize(name, uri, location, comments, owner)
|
|
419
|
-
super(name, uri, location, comments)
|
|
422
|
+
#: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void
|
|
423
|
+
def initialize(configuration, name, uri, location, comments, owner) # rubocop:disable Metrics/ParameterLists
|
|
424
|
+
super(configuration, name, uri, location, comments)
|
|
420
425
|
@owner = owner
|
|
421
426
|
end
|
|
422
427
|
end
|
|
@@ -431,9 +436,9 @@ module RubyIndexer
|
|
|
431
436
|
#: Entry::Namespace?
|
|
432
437
|
attr_reader :owner
|
|
433
438
|
|
|
434
|
-
#: (String new_name, String old_name, Entry::Namespace? owner, URI::Generic uri, Location location, String? comments) -> void
|
|
435
|
-
def initialize(new_name, old_name, owner, uri, location, comments) # rubocop:disable Metrics/ParameterLists
|
|
436
|
-
super(new_name, uri, location, comments)
|
|
439
|
+
#: (Configuration configuration, String new_name, String old_name, Entry::Namespace? owner, URI::Generic uri, Location location, String? comments) -> void
|
|
440
|
+
def initialize(configuration, new_name, old_name, owner, uri, location, comments) # rubocop:disable Metrics/ParameterLists
|
|
441
|
+
super(configuration, new_name, uri, location, comments)
|
|
437
442
|
|
|
438
443
|
@new_name = new_name
|
|
439
444
|
@old_name = old_name
|
|
@@ -456,6 +461,7 @@ module RubyIndexer
|
|
|
456
461
|
full_comments << target.comments
|
|
457
462
|
|
|
458
463
|
super(
|
|
464
|
+
unresolved_alias.configuration,
|
|
459
465
|
unresolved_alias.new_name,
|
|
460
466
|
unresolved_alias.uri,
|
|
461
467
|
unresolved_alias.location,
|
|
@@ -52,9 +52,9 @@ module RubyIndexer
|
|
|
52
52
|
comments = comments_to_string(declaration)
|
|
53
53
|
entry = if declaration.is_a?(RBS::AST::Declarations::Class)
|
|
54
54
|
parent_class = declaration.super_class&.name&.name&.to_s
|
|
55
|
-
Entry::Class.new(nesting, uri, location, location, comments, parent_class)
|
|
55
|
+
Entry::Class.new(@index.configuration, nesting, uri, location, location, comments, parent_class)
|
|
56
56
|
else
|
|
57
|
-
Entry::Module.new(nesting, uri, location, location, comments)
|
|
57
|
+
Entry::Module.new(@index.configuration, nesting, uri, location, location, comments)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
add_declaration_mixins_to_entry(declaration, entry)
|
|
@@ -110,6 +110,7 @@ module RubyIndexer
|
|
|
110
110
|
real_owner = member.singleton? ? @index.existing_or_new_singleton_class(owner.name) : owner
|
|
111
111
|
signatures = signatures(member)
|
|
112
112
|
@index.add(Entry::Method.new(
|
|
113
|
+
@index.configuration,
|
|
113
114
|
name,
|
|
114
115
|
uri,
|
|
115
116
|
location,
|
|
@@ -243,6 +244,7 @@ module RubyIndexer
|
|
|
243
244
|
def handle_constant(declaration, nesting, uri)
|
|
244
245
|
fully_qualified_name = [*nesting, declaration.name.name.to_s].join("::")
|
|
245
246
|
@index.add(Entry::Constant.new(
|
|
247
|
+
@index.configuration,
|
|
246
248
|
fully_qualified_name,
|
|
247
249
|
uri,
|
|
248
250
|
to_ruby_indexer_location(declaration.location),
|
|
@@ -258,6 +260,7 @@ module RubyIndexer
|
|
|
258
260
|
comments = comments_to_string(declaration)
|
|
259
261
|
|
|
260
262
|
@index.add(Entry::GlobalVariable.new(
|
|
263
|
+
@index.configuration,
|
|
261
264
|
name,
|
|
262
265
|
uri,
|
|
263
266
|
location,
|
|
@@ -271,6 +274,7 @@ module RubyIndexer
|
|
|
271
274
|
comments = comments_to_string(member)
|
|
272
275
|
|
|
273
276
|
entry = Entry::UnresolvedMethodAlias.new(
|
|
277
|
+
@index.configuration,
|
|
274
278
|
member.new_name.to_s,
|
|
275
279
|
member.old_name.to_s,
|
|
276
280
|
owner_entry,
|
|
@@ -766,5 +766,25 @@ module RubyIndexer
|
|
|
766
766
|
FileUtils.rm(path)
|
|
767
767
|
end
|
|
768
768
|
end
|
|
769
|
+
|
|
770
|
+
def test_lazy_comments_ignores_magic_comments
|
|
771
|
+
path = File.join(Dir.pwd, "lib", "foo.rb")
|
|
772
|
+
source = <<~RUBY
|
|
773
|
+
# frozen_string_literal: true
|
|
774
|
+
|
|
775
|
+
class Foo
|
|
776
|
+
end
|
|
777
|
+
RUBY
|
|
778
|
+
File.write(path, source)
|
|
779
|
+
@index.index_single(URI::Generic.from_path(path: path), source, collect_comments: false)
|
|
780
|
+
|
|
781
|
+
entry = @index["Foo"]&.first #: as !nil
|
|
782
|
+
|
|
783
|
+
begin
|
|
784
|
+
assert_empty(entry.comments)
|
|
785
|
+
ensure
|
|
786
|
+
FileUtils.rm(path)
|
|
787
|
+
end
|
|
788
|
+
end
|
|
769
789
|
end
|
|
770
790
|
end
|
|
@@ -233,18 +233,16 @@ module RubyIndexer
|
|
|
233
233
|
RUBY
|
|
234
234
|
|
|
235
235
|
Bundler.with_unbundled_env do
|
|
236
|
-
capture_subprocess_io
|
|
236
|
+
capture_subprocess_io do
|
|
237
|
+
system("bundle install")
|
|
237
238
|
|
|
238
|
-
_stdout, stderr = capture_subprocess_io do
|
|
239
239
|
script = [
|
|
240
240
|
"require \"ruby_lsp/internal\"",
|
|
241
241
|
"RubyIndexer::Configuration.new.indexable_uris",
|
|
242
242
|
].join(";")
|
|
243
243
|
|
|
244
|
-
system("bundle exec ruby -e '#{script}'")
|
|
244
|
+
assert(system("bundle exec ruby -e '#{script}'"))
|
|
245
245
|
end
|
|
246
|
-
|
|
247
|
-
assert_empty(stderr)
|
|
248
246
|
end
|
|
249
247
|
end
|
|
250
248
|
end
|
|
@@ -107,15 +107,12 @@ module RubyIndexer
|
|
|
107
107
|
RUBY
|
|
108
108
|
|
|
109
109
|
result = @index.fuzzy_search("Zws")
|
|
110
|
-
assert_equal(2, result.length)
|
|
111
110
|
assert_equal(["Zws", "Qtl::Zwo::Something"], result.map(&:name))
|
|
112
111
|
|
|
113
112
|
result = @index.fuzzy_search("qtlzwssomeking")
|
|
114
|
-
assert_equal(
|
|
115
|
-
assert_equal(["Qtl::Zwo::Something", "Qtl::Zws", "Qtl::Zwo", "Qtl", "Zws"], result.map(&:name))
|
|
113
|
+
assert_equal(["Qtl::Zwo::Something", "Qtl::Zws", "Qtl::Zwo", "Qtl", "Zws", "blocking"], result.map(&:name))
|
|
116
114
|
|
|
117
115
|
result = @index.fuzzy_search("QltZwo")
|
|
118
|
-
assert_equal(4, result.length)
|
|
119
116
|
assert_equal(["Qtl::Zwo", "Qtl::Zws", "Qtl::Zwo::Something", "Qtl"], result.map(&:name))
|
|
120
117
|
end
|
|
121
118
|
|
|
@@ -28,7 +28,7 @@ module RubyIndexer
|
|
|
28
28
|
def test_index_core_modules
|
|
29
29
|
entries = @index["Kernel"] #: as !nil
|
|
30
30
|
refute_nil(entries)
|
|
31
|
-
assert_equal(
|
|
31
|
+
assert_equal(2, entries.length)
|
|
32
32
|
entry = entries.first #: as Entry::Module
|
|
33
33
|
assert_match(%r{/gems/rbs-.*/core/kernel.rbs}, entry.file_path)
|
|
34
34
|
assert_equal("kernel.rbs", entry.file_name)
|
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module RubyLsp
|
|
5
|
+
# Holds the detected value and the reason for detection
|
|
6
|
+
class DetectionResult
|
|
7
|
+
#: String
|
|
8
|
+
attr_reader :value
|
|
9
|
+
|
|
10
|
+
#: String
|
|
11
|
+
attr_reader :reason
|
|
12
|
+
|
|
13
|
+
#: (String value, String reason) -> void
|
|
14
|
+
def initialize(value, reason)
|
|
15
|
+
@value = value
|
|
16
|
+
@reason = reason
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
5
20
|
class GlobalState
|
|
6
21
|
#: String
|
|
7
22
|
attr_reader :test_library
|
|
@@ -122,8 +137,11 @@ module RubyLsp
|
|
|
122
137
|
end
|
|
123
138
|
|
|
124
139
|
if @formatter == "auto"
|
|
125
|
-
|
|
126
|
-
|
|
140
|
+
formatter_result = detect_formatter(direct_dependencies, all_dependencies)
|
|
141
|
+
@formatter = formatter_result.value
|
|
142
|
+
notifications << Notification.window_log_message(
|
|
143
|
+
"Auto detected formatter: #{@formatter} (#{formatter_result.reason})",
|
|
144
|
+
)
|
|
127
145
|
end
|
|
128
146
|
|
|
129
147
|
specified_linters = options.dig(:initializationOptions, :linters)
|
|
@@ -144,21 +162,28 @@ module RubyLsp
|
|
|
144
162
|
specified_linters << "rubocop_internal"
|
|
145
163
|
end
|
|
146
164
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
Notification.window_log_message("Using linters specified by user: #{@linters.join(", ")}")
|
|
165
|
+
if specified_linters
|
|
166
|
+
@linters = specified_linters
|
|
167
|
+
notifications << Notification.window_log_message("Using linters specified by user: #{@linters.join(", ")}")
|
|
151
168
|
else
|
|
152
|
-
|
|
169
|
+
linter_results = detect_linters(direct_dependencies, all_dependencies)
|
|
170
|
+
@linters = linter_results.map(&:value)
|
|
171
|
+
linter_messages = linter_results.map { |r| "#{r.value} (#{r.reason})" }
|
|
172
|
+
notifications << Notification.window_log_message("Auto detected linters: #{linter_messages.join(", ")}")
|
|
153
173
|
end
|
|
154
174
|
|
|
155
|
-
|
|
156
|
-
|
|
175
|
+
test_library_result = detect_test_library(direct_dependencies)
|
|
176
|
+
@test_library = test_library_result.value
|
|
177
|
+
notifications << Notification.window_log_message(
|
|
178
|
+
"Detected test library: #{@test_library} (#{test_library_result.reason})",
|
|
179
|
+
)
|
|
157
180
|
|
|
158
|
-
|
|
159
|
-
|
|
181
|
+
typechecker_result = detect_typechecker(all_dependencies)
|
|
182
|
+
@has_type_checker = !typechecker_result.nil?
|
|
183
|
+
if typechecker_result
|
|
160
184
|
notifications << Notification.window_log_message(
|
|
161
|
-
"Ruby LSP detected this is a Sorbet project and will defer to the
|
|
185
|
+
"Ruby LSP detected this is a Sorbet project (#{typechecker_result.reason}) and will defer to the " \
|
|
186
|
+
"Sorbet LSP for some functionality",
|
|
162
187
|
)
|
|
163
188
|
end
|
|
164
189
|
|
|
@@ -228,60 +253,67 @@ module RubyLsp
|
|
|
228
253
|
|
|
229
254
|
private
|
|
230
255
|
|
|
231
|
-
#: (Array[String] direct_dependencies, Array[String] all_dependencies) ->
|
|
256
|
+
#: (Array[String] direct_dependencies, Array[String] all_dependencies) -> DetectionResult
|
|
232
257
|
def detect_formatter(direct_dependencies, all_dependencies)
|
|
233
258
|
# NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.
|
|
234
|
-
|
|
259
|
+
if direct_dependencies.any?(/^rubocop/)
|
|
260
|
+
return DetectionResult.new("rubocop_internal", "direct dependency matching /^rubocop/")
|
|
261
|
+
end
|
|
235
262
|
|
|
236
|
-
|
|
237
|
-
|
|
263
|
+
if direct_dependencies.include?("syntax_tree")
|
|
264
|
+
return DetectionResult.new("syntax_tree", "direct dependency")
|
|
265
|
+
end
|
|
238
266
|
|
|
239
|
-
|
|
240
|
-
|
|
267
|
+
if all_dependencies.include?("rubocop") && dot_rubocop_yml_present
|
|
268
|
+
return DetectionResult.new("rubocop_internal", "transitive dependency with .rubocop.yml present")
|
|
269
|
+
end
|
|
241
270
|
|
|
242
|
-
"none"
|
|
271
|
+
DetectionResult.new("none", "no formatter detected")
|
|
243
272
|
end
|
|
244
273
|
|
|
245
274
|
# Try to detect if there are linters in the project's dependencies. For auto-detection, we always only consider a
|
|
246
275
|
# single linter. To have multiple linters running, the user must configure them manually
|
|
247
|
-
#: (Array[String] dependencies, Array[String] all_dependencies) -> Array[
|
|
276
|
+
#: (Array[String] dependencies, Array[String] all_dependencies) -> Array[DetectionResult]
|
|
248
277
|
def detect_linters(dependencies, all_dependencies)
|
|
249
|
-
linters = []
|
|
278
|
+
linters = [] #: Array[DetectionResult]
|
|
250
279
|
|
|
251
|
-
if dependencies.any?(/^rubocop/)
|
|
252
|
-
linters << "rubocop_internal"
|
|
280
|
+
if dependencies.any?(/^rubocop/)
|
|
281
|
+
linters << DetectionResult.new("rubocop_internal", "direct dependency matching /^rubocop/")
|
|
282
|
+
elsif all_dependencies.include?("rubocop") && dot_rubocop_yml_present
|
|
283
|
+
linters << DetectionResult.new("rubocop_internal", "transitive dependency with .rubocop.yml present")
|
|
253
284
|
end
|
|
254
285
|
|
|
255
286
|
linters
|
|
256
287
|
end
|
|
257
288
|
|
|
258
|
-
#: (Array[String] dependencies) ->
|
|
289
|
+
#: (Array[String] dependencies) -> DetectionResult
|
|
259
290
|
def detect_test_library(dependencies)
|
|
260
291
|
if dependencies.any?(/^rspec/)
|
|
261
|
-
"rspec"
|
|
292
|
+
DetectionResult.new("rspec", "direct dependency matching /^rspec/")
|
|
262
293
|
# A Rails app may have a dependency on minitest, but we would instead want to use the Rails test runner provided
|
|
263
294
|
# by ruby-lsp-rails. A Rails app doesn't need to depend on the rails gem itself, individual components like
|
|
264
295
|
# activestorage may be added to the gemfile so that other components aren't downloaded. Check for the presence
|
|
265
296
|
# of bin/rails to support these cases.
|
|
266
297
|
elsif bin_rails_present
|
|
267
|
-
"rails"
|
|
298
|
+
DetectionResult.new("rails", "bin/rails present")
|
|
268
299
|
# NOTE: Intentionally ends with $ to avoid mis-matching minitest-reporters, etc. in a Rails app.
|
|
269
300
|
elsif dependencies.any?(/^minitest$/)
|
|
270
|
-
"minitest"
|
|
301
|
+
DetectionResult.new("minitest", "direct dependency matching /^minitest$/")
|
|
271
302
|
elsif dependencies.any?(/^test-unit/)
|
|
272
|
-
"test-unit"
|
|
303
|
+
DetectionResult.new("test-unit", "direct dependency matching /^test-unit/")
|
|
273
304
|
else
|
|
274
|
-
"unknown"
|
|
305
|
+
DetectionResult.new("unknown", "no test library detected")
|
|
275
306
|
end
|
|
276
307
|
end
|
|
277
308
|
|
|
278
|
-
#: (Array[String] dependencies) ->
|
|
309
|
+
#: (Array[String] dependencies) -> DetectionResult?
|
|
279
310
|
def detect_typechecker(dependencies)
|
|
280
|
-
return
|
|
311
|
+
return if ENV["RUBY_LSP_BYPASS_TYPECHECKER"]
|
|
312
|
+
return if dependencies.none?(/^sorbet-static/)
|
|
281
313
|
|
|
282
|
-
|
|
314
|
+
DetectionResult.new("sorbet", "sorbet-static in dependencies")
|
|
283
315
|
rescue Bundler::GemfileNotFound
|
|
284
|
-
|
|
316
|
+
nil
|
|
285
317
|
end
|
|
286
318
|
|
|
287
319
|
#: -> bool
|
|
@@ -71,24 +71,26 @@ module RubyLsp
|
|
|
71
71
|
|
|
72
72
|
#: (Prism::StringNode node) -> void
|
|
73
73
|
def on_string_node_enter(node)
|
|
74
|
-
enclosing_call
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
with_enclosing_call(node) do |enclosing_call, name|
|
|
75
|
+
case name
|
|
76
|
+
when :require, :require_relative
|
|
77
|
+
handle_require_definition(node, name)
|
|
78
|
+
when :send, :public_send
|
|
79
|
+
handle_send_or_public_send_definition(enclosing_call, node) { node.content }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
81
82
|
end
|
|
82
83
|
|
|
83
84
|
#: (Prism::SymbolNode node) -> void
|
|
84
85
|
def on_symbol_node_enter(node)
|
|
85
|
-
enclosing_call
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
with_enclosing_call(node) do |enclosing_call, name|
|
|
87
|
+
case name
|
|
88
|
+
when :autoload
|
|
89
|
+
handle_autoload_definition(enclosing_call)
|
|
90
|
+
when :send, :public_send
|
|
91
|
+
handle_send_or_public_send_definition(enclosing_call, node) { node.unescaped }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
#: (Prism::BlockArgumentNode node) -> void
|
|
@@ -220,6 +222,24 @@ module RubyLsp
|
|
|
220
222
|
|
|
221
223
|
private
|
|
222
224
|
|
|
225
|
+
#: (Prism::Node node) { (Prism::CallNode, Symbol) -> void } -> void
|
|
226
|
+
def with_enclosing_call(node, &block)
|
|
227
|
+
enclosing_call = @node_context.call_node
|
|
228
|
+
return unless enclosing_call
|
|
229
|
+
|
|
230
|
+
block.call(enclosing_call, enclosing_call.name)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
#: (Prism::CallNode enclosing_call, Prism::Node node) { -> String } -> void
|
|
234
|
+
def handle_send_or_public_send_definition(enclosing_call, node, &block)
|
|
235
|
+
first_argument = enclosing_call.arguments&.arguments&.first
|
|
236
|
+
return unless first_argument.eql?(node)
|
|
237
|
+
|
|
238
|
+
method_name = block.call
|
|
239
|
+
|
|
240
|
+
handle_method_definition(method_name, nil)
|
|
241
|
+
end
|
|
242
|
+
|
|
223
243
|
#: -> void
|
|
224
244
|
def handle_super_node_definition
|
|
225
245
|
# Sorbet can handle super hover on typed true or higher
|
|
@@ -135,8 +135,6 @@ module RubyLsp
|
|
|
135
135
|
return unless path
|
|
136
136
|
|
|
137
137
|
gem_name = purl.name
|
|
138
|
-
return unless gem_name
|
|
139
|
-
|
|
140
138
|
file_path = self.class.gem_paths.dig(gem_name, gem_version, CGI.unescape(path))
|
|
141
139
|
return if file_path.nil?
|
|
142
140
|
|
|
@@ -160,10 +158,7 @@ module RubyLsp
|
|
|
160
158
|
path = uri.path
|
|
161
159
|
return unless path
|
|
162
160
|
|
|
163
|
-
|
|
164
|
-
return unless gem_name
|
|
165
|
-
|
|
166
|
-
file_path = self.class.gem_paths.dig(gem_name, gem_version, CGI.unescape(path))
|
|
161
|
+
file_path = self.class.gem_paths.dig(uri.gem_name, gem_version, CGI.unescape(path))
|
|
167
162
|
return if file_path.nil?
|
|
168
163
|
|
|
169
164
|
[file_path, uri.line_number || "0"]
|
|
@@ -283,10 +283,10 @@ module RubyLsp
|
|
|
283
283
|
content = KEYWORD_DOCS[keyword]
|
|
284
284
|
return unless content
|
|
285
285
|
|
|
286
|
-
|
|
286
|
+
doc_uri = URI::Generic.from_path(path: File.join(STATIC_DOCS_PATH, "#{keyword}.md"))
|
|
287
287
|
|
|
288
288
|
@response_builder.push("```ruby\n#{keyword}\n```", category: :title)
|
|
289
|
-
@response_builder.push("[Read more](#{
|
|
289
|
+
@response_builder.push("[Read more](#{doc_uri})", category: :links)
|
|
290
290
|
@response_builder.push(content, category: :documentation)
|
|
291
291
|
end
|
|
292
292
|
|
|
@@ -51,20 +51,42 @@ module RubyLsp
|
|
|
51
51
|
#: -> (Interface::CodeAction)
|
|
52
52
|
def switch_block_style
|
|
53
53
|
source_range = @code_action.dig(:data, :range)
|
|
54
|
-
|
|
54
|
+
if source_range[:start] == source_range[:end]
|
|
55
|
+
block_context = @document.locate_node(
|
|
56
|
+
source_range[:start],
|
|
57
|
+
node_types: [Prism::BlockNode],
|
|
58
|
+
)
|
|
59
|
+
node = block_context.node
|
|
60
|
+
unless node.is_a?(Prism::BlockNode)
|
|
61
|
+
raise InvalidTargetRangeError, "Cursor is not inside a block"
|
|
62
|
+
end
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
# Find the call node at the block node's start position.
|
|
65
|
+
# This should be the call node whose block the cursor is inside of.
|
|
66
|
+
call_context = RubyDocument.locate(
|
|
67
|
+
@document.ast,
|
|
68
|
+
node.location.cached_start_code_units_offset(@document.code_units_cache),
|
|
69
|
+
node_types: [Prism::CallNode],
|
|
70
|
+
code_units_cache: @document.code_units_cache,
|
|
71
|
+
)
|
|
72
|
+
target = call_context.node
|
|
73
|
+
unless target.is_a?(Prism::CallNode) && target.block == node
|
|
74
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
target = @document.locate_first_within_range(
|
|
78
|
+
@code_action.dig(:data, :range),
|
|
79
|
+
node_types: [Prism::CallNode],
|
|
80
|
+
)
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
unless target.is_a?(Prism::CallNode)
|
|
83
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
|
84
|
+
end
|
|
64
85
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
node = target.block
|
|
87
|
+
unless node.is_a?(Prism::BlockNode)
|
|
88
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
|
89
|
+
end
|
|
68
90
|
end
|
|
69
91
|
|
|
70
92
|
indentation = " " * target.location.start_column unless node.opening_loc.slice == "do"
|
|
@@ -63,12 +63,8 @@ module RubyLsp
|
|
|
63
63
|
kind: Constant::CodeActionKind::REFACTOR_EXTRACT,
|
|
64
64
|
data: { range: @range, uri: @uri.to_s },
|
|
65
65
|
)
|
|
66
|
-
code_actions << Interface::CodeAction.new(
|
|
67
|
-
title: TOGGLE_BLOCK_STYLE_TITLE,
|
|
68
|
-
kind: Constant::CodeActionKind::REFACTOR_REWRITE,
|
|
69
|
-
data: { range: @range, uri: @uri.to_s },
|
|
70
|
-
)
|
|
71
66
|
end
|
|
67
|
+
code_actions.concat(toggle_block_style_action)
|
|
72
68
|
code_actions.concat(attribute_actions)
|
|
73
69
|
|
|
74
70
|
code_actions
|
|
@@ -113,6 +109,25 @@ module RubyLsp
|
|
|
113
109
|
),
|
|
114
110
|
]
|
|
115
111
|
end
|
|
112
|
+
|
|
113
|
+
#: -> Array[Interface::CodeAction]
|
|
114
|
+
def toggle_block_style_action
|
|
115
|
+
if @range[:start] == @range[:end]
|
|
116
|
+
block_context = @document.locate_node(
|
|
117
|
+
@range[:start],
|
|
118
|
+
node_types: [Prism::BlockNode],
|
|
119
|
+
)
|
|
120
|
+
return [] unless block_context.node.is_a?(Prism::BlockNode)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
[
|
|
124
|
+
Interface::CodeAction.new(
|
|
125
|
+
title: TOGGLE_BLOCK_STYLE_TITLE,
|
|
126
|
+
kind: Constant::CodeActionKind::REFACTOR_REWRITE,
|
|
127
|
+
data: { range: @range, uri: @uri.to_s },
|
|
128
|
+
),
|
|
129
|
+
]
|
|
130
|
+
end
|
|
116
131
|
end
|
|
117
132
|
end
|
|
118
133
|
end
|
|
@@ -68,10 +68,12 @@ module RubyLsp
|
|
|
68
68
|
"[Learn more about guessed types](#{GUESSED_TYPES_URL})"
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
@item[:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
unless @item[:kind] == Constant::CompletionItemKind::FILE
|
|
72
|
+
@item[:documentation] = Interface::MarkupContent.new(
|
|
73
|
+
kind: "markdown",
|
|
74
|
+
value: markdown_from_index_entries(label, entries, MAX_DOCUMENTATION_ENTRIES, extra_links: extra_links),
|
|
75
|
+
)
|
|
76
|
+
end
|
|
75
77
|
|
|
76
78
|
@item
|
|
77
79
|
end
|
|
@@ -84,7 +86,7 @@ module RubyLsp
|
|
|
84
86
|
content = KEYWORD_DOCS[keyword]
|
|
85
87
|
|
|
86
88
|
if content
|
|
87
|
-
|
|
89
|
+
doc_uri = URI::Generic.from_path(path: File.join(STATIC_DOCS_PATH, "#{keyword}.md"))
|
|
88
90
|
|
|
89
91
|
@item[:documentation] = Interface::MarkupContent.new(
|
|
90
92
|
kind: "markdown",
|
|
@@ -93,7 +95,7 @@ module RubyLsp
|
|
|
93
95
|
#{keyword}
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
[Read more](#{
|
|
98
|
+
[Read more](#{doc_uri})
|
|
97
99
|
|
|
98
100
|
#{content}
|
|
99
101
|
MARKDOWN
|
|
@@ -5,6 +5,7 @@ require "uri/file"
|
|
|
5
5
|
|
|
6
6
|
module URI
|
|
7
7
|
# Must be kept in sync with the one in Tapioca
|
|
8
|
+
# https://github.com/Shopify/tapioca/blob/main/lib/tapioca/helpers/source_uri.rb
|
|
8
9
|
class Source < URI::File
|
|
9
10
|
COMPONENT = [
|
|
10
11
|
:scheme,
|
|
@@ -21,16 +22,14 @@ module URI
|
|
|
21
22
|
# have the uri gem in their own bundle and thus not use a compatible version.
|
|
22
23
|
PARSER = const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER #: RFC2396_Parser
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
self #: as untyped # rubocop:disable Style/RedundantSelf
|
|
27
|
-
.alias_method(:line_number, :fragment)
|
|
25
|
+
alias_method(:gem_name, :host)
|
|
26
|
+
alias_method(:line_number, :fragment)
|
|
28
27
|
|
|
29
28
|
#: String?
|
|
30
29
|
attr_reader :gem_version
|
|
31
30
|
|
|
32
31
|
class << self
|
|
33
|
-
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) ->
|
|
32
|
+
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) -> instance
|
|
34
33
|
def build(gem_name:, gem_version:, path:, line_number:)
|
|
35
34
|
super(
|
|
36
35
|
{
|
|
@@ -67,12 +66,14 @@ module URI
|
|
|
67
66
|
|
|
68
67
|
#: -> String
|
|
69
68
|
def to_s
|
|
70
|
-
"source://#{gem_name}/#{gem_version}
|
|
69
|
+
"source://#{gem_name}/#{gem_version}/#{path}##{line_number}"
|
|
71
70
|
end
|
|
72
71
|
|
|
73
72
|
if URI.respond_to?(:register_scheme)
|
|
73
|
+
# Handle URI 0.11.0 and newer https://github.com/ruby/uri/pull/26
|
|
74
74
|
URI.register_scheme("SOURCE", self)
|
|
75
75
|
else
|
|
76
|
+
# Fallback for URI <0.11.0
|
|
76
77
|
@@schemes = @@schemes #: Hash[String, untyped] # rubocop:disable Style/ClassVars
|
|
77
78
|
@@schemes["SOURCE"] = self
|
|
78
79
|
end
|
|
@@ -5,7 +5,7 @@ def compose(raw_initialize)
|
|
|
5
5
|
require_relative "../setup_bundler"
|
|
6
6
|
require "json"
|
|
7
7
|
require "uri"
|
|
8
|
-
|
|
8
|
+
require_relative "../../ruby_indexer/lib/ruby_indexer/uri"
|
|
9
9
|
|
|
10
10
|
initialize_request = JSON.parse(raw_initialize, symbolize_names: true)
|
|
11
11
|
workspace_uri = initialize_request.dig(:params, :workspaceFolders, 0, :uri)
|
|
@@ -36,7 +36,7 @@ module RubyLsp
|
|
|
36
36
|
@project_path = project_path
|
|
37
37
|
@branch = options[:branch] #: String?
|
|
38
38
|
@launcher = options[:launcher] #: bool?
|
|
39
|
-
|
|
39
|
+
force_output_to_stderr! if @launcher
|
|
40
40
|
|
|
41
41
|
# Regular bundle paths
|
|
42
42
|
@gemfile = begin
|
|
@@ -282,14 +282,25 @@ module RubyLsp
|
|
|
282
282
|
|
|
283
283
|
return update(env) if @needs_update_path.exist?
|
|
284
284
|
|
|
285
|
-
# The ENV can only be merged after checking if an update is required because we depend on the original value of
|
|
286
|
-
# ENV["BUNDLE_GEMFILE"], which gets overridden after the merge
|
|
287
285
|
FileUtils.touch(@needs_update_path) if needs_update
|
|
288
286
|
|
|
289
287
|
$stderr.puts("Ruby LSP> Checking if the composed bundle is satisfied...")
|
|
290
|
-
missing_gems = bundle_check
|
|
291
288
|
|
|
292
|
-
|
|
289
|
+
begin
|
|
290
|
+
missing_gems = bundle_check
|
|
291
|
+
rescue Errno::EPIPE, Bundler::HTTPError
|
|
292
|
+
# These are errors cases where we cannot recover
|
|
293
|
+
raise
|
|
294
|
+
rescue => e
|
|
295
|
+
# If anything fails with bundle check, try to bundle install
|
|
296
|
+
$stderr.puts("Ruby LSP> Running bundle install because #{e.message}")
|
|
297
|
+
bundle_install
|
|
298
|
+
return env
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
if missing_gems.empty?
|
|
302
|
+
$stderr.puts("Ruby LSP> Bundle already satisfied")
|
|
303
|
+
else
|
|
293
304
|
$stderr.puts(<<~MESSAGE)
|
|
294
305
|
Ruby LSP> Running bundle install because the following gems are not installed:
|
|
295
306
|
#{missing_gems.map { |g| "#{g.name}: #{g.version}" }.join("\n")}
|
|
@@ -298,11 +309,6 @@ module RubyLsp
|
|
|
298
309
|
bundle_install
|
|
299
310
|
end
|
|
300
311
|
|
|
301
|
-
$stderr.puts("Ruby LSP> Bundle already satisfied")
|
|
302
|
-
env
|
|
303
|
-
rescue => e
|
|
304
|
-
$stderr.puts("Ruby LSP> Running bundle install because #{e.message}")
|
|
305
|
-
bundle_install
|
|
306
312
|
env
|
|
307
313
|
end
|
|
308
314
|
|
|
@@ -489,11 +495,16 @@ module RubyLsp
|
|
|
489
495
|
end
|
|
490
496
|
|
|
491
497
|
#: -> void
|
|
492
|
-
def
|
|
493
|
-
|
|
498
|
+
def force_output_to_stderr!
|
|
499
|
+
# Bundler and RubyGems have different UI objects used for printing. We need to ensure that both are configured to
|
|
500
|
+
# print only to stderr or else they'll break the connection with the editor
|
|
501
|
+
Gem::DefaultUserInteraction.ui = Gem::StreamUI.new($stdin, $stderr, $stderr, false)
|
|
502
|
+
|
|
503
|
+
ui = Bundler.ui
|
|
504
|
+
ui.output_stream = :stderr if ui.respond_to?(:output_stream=)
|
|
505
|
+
ui.level = :info
|
|
494
506
|
|
|
495
|
-
Bundler::Thor::Shell::Basic.prepend(ThorPatch)
|
|
496
|
-
Bundler.ui.level = :info
|
|
507
|
+
Bundler::Thor::Shell::Basic.prepend(ThorPatch) if defined?(Bundler::Thor::Shell::Basic)
|
|
497
508
|
end
|
|
498
509
|
end
|
|
499
510
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-lsp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.26.
|
|
4
|
+
version: 0.26.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
@@ -217,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
217
217
|
- !ruby/object:Gem::Version
|
|
218
218
|
version: '0'
|
|
219
219
|
requirements: []
|
|
220
|
-
rubygems_version:
|
|
220
|
+
rubygems_version: 4.0.3
|
|
221
221
|
specification_version: 4
|
|
222
222
|
summary: An opinionated language server for Ruby
|
|
223
223
|
test_files: []
|