ruby-lsp 0.17.1 → 0.17.3
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 -0
- data/VERSION +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +56 -0
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +28 -0
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +156 -40
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +99 -0
- data/lib/ruby_indexer/ruby_indexer.rb +1 -0
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +3 -2
- data/lib/ruby_indexer/test/configuration_test.rb +1 -1
- data/lib/ruby_indexer/test/constant_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +388 -56
- data/lib/ruby_indexer/test/method_test.rb +20 -0
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +42 -0
- data/lib/ruby_indexer/test/test_case.rb +7 -0
- data/lib/ruby_lsp/document.rb +24 -1
- data/lib/ruby_lsp/global_state.rb +37 -16
- data/lib/ruby_lsp/internal.rb +1 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +2 -2
- data/lib/ruby_lsp/listeners/definition.rb +20 -18
- data/lib/ruby_lsp/listeners/hover.rb +2 -0
- data/lib/ruby_lsp/node_context.rb +15 -4
- data/lib/ruby_lsp/requests/definition.rb +5 -0
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +23 -6
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +5 -1
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +4 -0
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -3
- data/lib/ruby_lsp/server.rb +12 -1
- metadata +27 -5
@@ -107,16 +107,16 @@ module RubyIndexer
|
|
107
107
|
RUBY
|
108
108
|
|
109
109
|
result = @index.fuzzy_search("Bar")
|
110
|
-
assert_equal(
|
111
|
-
assert_equal(
|
110
|
+
assert_equal(3, result.length)
|
111
|
+
assert_equal(["Bar", "Backtrace", "Base"], result.map(&:name))
|
112
112
|
|
113
113
|
result = @index.fuzzy_search("foobarsomeking")
|
114
|
-
assert_equal(
|
115
|
-
assert_equal(["Foo::Baz::Something", "Foo::Bar", "Foo::Baz", "Foo", "Bar"], result.map(&:name))
|
114
|
+
assert_equal(6, result.length)
|
115
|
+
assert_equal(["Foo::Baz::Something", "Foo::Bar", "Foo::Baz", "Foo", "Base", "Bar"], result.map(&:name))
|
116
116
|
|
117
117
|
result = @index.fuzzy_search("FooBaz")
|
118
|
-
assert_equal(
|
119
|
-
assert_equal(["Foo::Baz", "Foo::Bar", "Foo", "Foo::Baz::Something"], result.map(&:name))
|
118
|
+
assert_equal(5, result.length)
|
119
|
+
assert_equal(["Foo::Baz", "Foo::Bar", "Foo", "Foo::Baz::Something", "Float"], result.map(&:name))
|
120
120
|
end
|
121
121
|
|
122
122
|
def test_index_single_ignores_directories
|
@@ -140,6 +140,8 @@ module RubyIndexer
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def test_searching_for_entries_based_on_prefix
|
143
|
+
# For this test, it's easier if we don't include core classes and modules
|
144
|
+
@index = Index.new
|
143
145
|
@index.index_single(IndexablePath.new("/fake", "/fake/path/foo.rb"), <<~RUBY)
|
144
146
|
class Foo::Bar
|
145
147
|
end
|
@@ -181,6 +183,9 @@ module RubyIndexer
|
|
181
183
|
|
182
184
|
def test_resolving_aliases_to_non_existing_constants_with_conflicting_names
|
183
185
|
@index.index_single(IndexablePath.new("/fake", "/fake/path/foo.rb"), <<~RUBY)
|
186
|
+
class Float
|
187
|
+
end
|
188
|
+
|
184
189
|
module Foo
|
185
190
|
class Float < self
|
186
191
|
INFINITY = ::Float::INFINITY
|
@@ -315,7 +320,8 @@ module RubyIndexer
|
|
315
320
|
|
316
321
|
def test_index_single_does_not_fail_for_non_existing_file
|
317
322
|
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"))
|
318
|
-
|
323
|
+
entries_after_indexing = @index.instance_variable_get(:@entries).keys
|
324
|
+
assert_equal(@default_indexed_entries.keys, entries_after_indexing)
|
319
325
|
end
|
320
326
|
|
321
327
|
def test_linearized_ancestors_basic_ordering
|
@@ -339,9 +345,9 @@ module RubyIndexer
|
|
339
345
|
"B",
|
340
346
|
"A",
|
341
347
|
"Foo",
|
342
|
-
|
343
|
-
|
344
|
-
|
348
|
+
"Object",
|
349
|
+
"Kernel",
|
350
|
+
"BasicObject",
|
345
351
|
],
|
346
352
|
@index.linearized_ancestors_of("Foo"),
|
347
353
|
)
|
@@ -351,9 +357,9 @@ module RubyIndexer
|
|
351
357
|
"Bar",
|
352
358
|
"B",
|
353
359
|
"A",
|
354
|
-
|
355
|
-
|
356
|
-
|
360
|
+
"Object",
|
361
|
+
"Kernel",
|
362
|
+
"BasicObject",
|
357
363
|
],
|
358
364
|
@index.linearized_ancestors_of("Bar"),
|
359
365
|
)
|
@@ -401,9 +407,9 @@ module RubyIndexer
|
|
401
407
|
"A",
|
402
408
|
"C",
|
403
409
|
"Bar",
|
404
|
-
|
405
|
-
|
406
|
-
|
410
|
+
"Object",
|
411
|
+
"Kernel",
|
412
|
+
"BasicObject",
|
407
413
|
],
|
408
414
|
@index.linearized_ancestors_of("Foo"),
|
409
415
|
)
|
@@ -432,9 +438,9 @@ module RubyIndexer
|
|
432
438
|
"Foo",
|
433
439
|
"B",
|
434
440
|
"A",
|
435
|
-
|
436
|
-
|
437
|
-
|
441
|
+
"Object",
|
442
|
+
"Kernel",
|
443
|
+
"BasicObject",
|
438
444
|
],
|
439
445
|
@index.linearized_ancestors_of("Foo"),
|
440
446
|
)
|
@@ -444,9 +450,9 @@ module RubyIndexer
|
|
444
450
|
"B",
|
445
451
|
"A",
|
446
452
|
"Bar",
|
447
|
-
|
448
|
-
|
449
|
-
|
453
|
+
"Object",
|
454
|
+
"Kernel",
|
455
|
+
"BasicObject",
|
450
456
|
],
|
451
457
|
@index.linearized_ancestors_of("Bar"),
|
452
458
|
)
|
@@ -493,9 +499,9 @@ module RubyIndexer
|
|
493
499
|
[
|
494
500
|
"A",
|
495
501
|
"Foo",
|
496
|
-
|
497
|
-
|
498
|
-
|
502
|
+
"Object",
|
503
|
+
"Kernel",
|
504
|
+
"BasicObject",
|
499
505
|
],
|
500
506
|
@index.linearized_ancestors_of("Foo"),
|
501
507
|
)
|
@@ -505,9 +511,9 @@ module RubyIndexer
|
|
505
511
|
"A",
|
506
512
|
"Bar",
|
507
513
|
"A",
|
508
|
-
|
509
|
-
|
510
|
-
|
514
|
+
"Object",
|
515
|
+
"Kernel",
|
516
|
+
"BasicObject",
|
511
517
|
],
|
512
518
|
@index.linearized_ancestors_of("Bar"),
|
513
519
|
)
|
@@ -519,15 +525,7 @@ module RubyIndexer
|
|
519
525
|
end
|
520
526
|
RUBY
|
521
527
|
|
522
|
-
assert_equal(
|
523
|
-
[
|
524
|
-
"Foo",
|
525
|
-
# "Object",
|
526
|
-
# "Kernel",
|
527
|
-
# "BasicObject",
|
528
|
-
],
|
529
|
-
@index.linearized_ancestors_of("Foo"),
|
530
|
-
)
|
528
|
+
assert_equal(["Foo"], @index.linearized_ancestors_of("Foo"))
|
531
529
|
end
|
532
530
|
|
533
531
|
def test_ancestors_linearization_complex_prepend_duplication
|
@@ -552,9 +550,9 @@ module RubyIndexer
|
|
552
550
|
"B",
|
553
551
|
"C",
|
554
552
|
"Foo",
|
555
|
-
|
556
|
-
|
557
|
-
|
553
|
+
"Object",
|
554
|
+
"Kernel",
|
555
|
+
"BasicObject",
|
558
556
|
],
|
559
557
|
@index.linearized_ancestors_of("Foo"),
|
560
558
|
)
|
@@ -582,9 +580,9 @@ module RubyIndexer
|
|
582
580
|
"C",
|
583
581
|
"B",
|
584
582
|
"A",
|
585
|
-
|
586
|
-
|
587
|
-
|
583
|
+
"Object",
|
584
|
+
"Kernel",
|
585
|
+
"BasicObject",
|
588
586
|
],
|
589
587
|
@index.linearized_ancestors_of("Foo"),
|
590
588
|
)
|
@@ -613,9 +611,9 @@ module RubyIndexer
|
|
613
611
|
"Foo::Bar",
|
614
612
|
"Foo::Baz",
|
615
613
|
"Foo::Something",
|
616
|
-
|
617
|
-
|
618
|
-
|
614
|
+
"Object",
|
615
|
+
"Kernel",
|
616
|
+
"BasicObject",
|
619
617
|
],
|
620
618
|
@index.linearized_ancestors_of("Foo::Bar"),
|
621
619
|
)
|
@@ -623,9 +621,7 @@ module RubyIndexer
|
|
623
621
|
|
624
622
|
def test_linearizing_ancestors_for_non_existing_namespaces
|
625
623
|
index(<<~RUBY)
|
626
|
-
|
627
|
-
def Array(a); end
|
628
|
-
end
|
624
|
+
def Bar(a); end
|
629
625
|
RUBY
|
630
626
|
|
631
627
|
assert_raises(Index::NonExistingNamespaceError) do
|
@@ -633,7 +629,7 @@ module RubyIndexer
|
|
633
629
|
end
|
634
630
|
|
635
631
|
assert_raises(Index::NonExistingNamespaceError) do
|
636
|
-
@index.linearized_ancestors_of("
|
632
|
+
@index.linearized_ancestors_of("Bar")
|
637
633
|
end
|
638
634
|
end
|
639
635
|
|
@@ -754,7 +750,7 @@ module RubyIndexer
|
|
754
750
|
indexable_path = IndexablePath.new(nil, File.join(dir, "foo.rb"))
|
755
751
|
@index.index_single(indexable_path)
|
756
752
|
|
757
|
-
assert_equal(["Bar", "Foo"], @index.linearized_ancestors_of("Bar"))
|
753
|
+
assert_equal(["Bar", "Foo", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
|
758
754
|
|
759
755
|
# Remove include to invalidate the ancestor tree
|
760
756
|
File.write(File.join(dir, "foo.rb"), <<~RUBY)
|
@@ -767,7 +763,7 @@ module RubyIndexer
|
|
767
763
|
|
768
764
|
@index.handle_change(indexable_path)
|
769
765
|
assert_empty(@index.instance_variable_get(:@ancestors))
|
770
|
-
assert_equal(["Bar"], @index.linearized_ancestors_of("Bar"))
|
766
|
+
assert_equal(["Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
|
771
767
|
end
|
772
768
|
end
|
773
769
|
end
|
@@ -788,7 +784,7 @@ module RubyIndexer
|
|
788
784
|
indexable_path = IndexablePath.new(nil, File.join(dir, "foo.rb"))
|
789
785
|
@index.index_single(indexable_path)
|
790
786
|
|
791
|
-
assert_equal(["Bar", "Foo"], @index.linearized_ancestors_of("Bar"))
|
787
|
+
assert_equal(["Bar", "Foo", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
|
792
788
|
|
793
789
|
# Remove include to invalidate the ancestor tree
|
794
790
|
File.write(File.join(dir, "foo.rb"), <<~RUBY)
|
@@ -804,7 +800,7 @@ module RubyIndexer
|
|
804
800
|
|
805
801
|
@index.handle_change(indexable_path)
|
806
802
|
refute_empty(@index.instance_variable_get(:@ancestors))
|
807
|
-
assert_equal(["Bar", "Foo"], @index.linearized_ancestors_of("Bar"))
|
803
|
+
assert_equal(["Bar", "Foo", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
|
808
804
|
end
|
809
805
|
end
|
810
806
|
end
|
@@ -824,7 +820,7 @@ module RubyIndexer
|
|
824
820
|
indexable_path = IndexablePath.new(nil, File.join(dir, "foo.rb"))
|
825
821
|
@index.index_single(indexable_path)
|
826
822
|
|
827
|
-
assert_equal(["Bar", "Foo"], @index.linearized_ancestors_of("Bar"))
|
823
|
+
assert_equal(["Bar", "Foo", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
|
828
824
|
|
829
825
|
# Remove include to invalidate the ancestor tree
|
830
826
|
File.write(File.join(dir, "foo.rb"), <<~RUBY)
|
@@ -837,9 +833,345 @@ module RubyIndexer
|
|
837
833
|
|
838
834
|
@index.handle_change(indexable_path)
|
839
835
|
assert_empty(@index.instance_variable_get(:@ancestors))
|
840
|
-
assert_equal(["Bar"], @index.linearized_ancestors_of("Bar"))
|
836
|
+
assert_equal(["Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
|
841
837
|
end
|
842
838
|
end
|
843
839
|
end
|
840
|
+
|
841
|
+
def test_resolving_inherited_constants
|
842
|
+
index(<<~RUBY)
|
843
|
+
module Foo
|
844
|
+
CONST = 1
|
845
|
+
end
|
846
|
+
|
847
|
+
module Baz
|
848
|
+
CONST = 2
|
849
|
+
end
|
850
|
+
|
851
|
+
module Qux
|
852
|
+
include Foo
|
853
|
+
end
|
854
|
+
|
855
|
+
module Namespace
|
856
|
+
CONST = 3
|
857
|
+
|
858
|
+
include Baz
|
859
|
+
|
860
|
+
class Bar
|
861
|
+
include Qux
|
862
|
+
end
|
863
|
+
end
|
864
|
+
|
865
|
+
CONST = 4
|
866
|
+
RUBY
|
867
|
+
|
868
|
+
entry = T.must(@index.resolve("CONST", ["Namespace", "Bar"])&.first)
|
869
|
+
assert_equal(14, entry.location.start_line)
|
870
|
+
end
|
871
|
+
|
872
|
+
def test_resolving_inherited_alised_namespace
|
873
|
+
index(<<~RUBY)
|
874
|
+
module Bar
|
875
|
+
TARGET = 123
|
876
|
+
end
|
877
|
+
|
878
|
+
module Foo
|
879
|
+
CONST = Bar
|
880
|
+
end
|
881
|
+
|
882
|
+
module Namespace
|
883
|
+
class Bar
|
884
|
+
include Foo
|
885
|
+
end
|
886
|
+
end
|
887
|
+
RUBY
|
888
|
+
|
889
|
+
entry = T.must(@index.resolve("Foo::CONST::TARGET", [])&.first)
|
890
|
+
assert_equal(2, entry.location.start_line)
|
891
|
+
|
892
|
+
entry = T.must(@index.resolve("Namespace::Bar::CONST::TARGET", [])&.first)
|
893
|
+
assert_equal(2, entry.location.start_line)
|
894
|
+
end
|
895
|
+
|
896
|
+
def test_resolving_same_constant_from_different_scopes
|
897
|
+
index(<<~RUBY)
|
898
|
+
module Namespace
|
899
|
+
CONST = 123
|
900
|
+
|
901
|
+
class Parent
|
902
|
+
CONST = 321
|
903
|
+
end
|
904
|
+
|
905
|
+
class Child < Parent
|
906
|
+
end
|
907
|
+
end
|
908
|
+
RUBY
|
909
|
+
|
910
|
+
entry = T.must(@index.resolve("CONST", ["Namespace", "Child"])&.first)
|
911
|
+
assert_equal(2, entry.location.start_line)
|
912
|
+
|
913
|
+
entry = T.must(@index.resolve("Namespace::Child::CONST", [])&.first)
|
914
|
+
assert_equal(5, entry.location.start_line)
|
915
|
+
end
|
916
|
+
|
917
|
+
def test_resolving_prepended_constants
|
918
|
+
index(<<~RUBY)
|
919
|
+
module Included
|
920
|
+
CONST = 123
|
921
|
+
end
|
922
|
+
|
923
|
+
module Prepended
|
924
|
+
CONST = 321
|
925
|
+
end
|
926
|
+
|
927
|
+
class Foo
|
928
|
+
include Included
|
929
|
+
prepend Prepended
|
930
|
+
end
|
931
|
+
|
932
|
+
class Bar
|
933
|
+
CONST = 456
|
934
|
+
include Included
|
935
|
+
prepend Prepended
|
936
|
+
end
|
937
|
+
RUBY
|
938
|
+
|
939
|
+
entry = T.must(@index.resolve("CONST", ["Foo"])&.first)
|
940
|
+
assert_equal(6, entry.location.start_line)
|
941
|
+
|
942
|
+
entry = T.must(@index.resolve("Foo::CONST", [])&.first)
|
943
|
+
assert_equal(6, entry.location.start_line)
|
944
|
+
|
945
|
+
entry = T.must(@index.resolve("Bar::CONST", [])&.first)
|
946
|
+
assert_equal(15, entry.location.start_line)
|
947
|
+
end
|
948
|
+
|
949
|
+
def test_resolving_constants_favors_ancestors_over_top_level
|
950
|
+
index(<<~RUBY)
|
951
|
+
module Value1
|
952
|
+
CONST = 1
|
953
|
+
end
|
954
|
+
|
955
|
+
module Value2
|
956
|
+
CONST = 2
|
957
|
+
end
|
958
|
+
|
959
|
+
CONST = 3
|
960
|
+
module First
|
961
|
+
include Value1
|
962
|
+
|
963
|
+
module Second
|
964
|
+
include Value2
|
965
|
+
end
|
966
|
+
end
|
967
|
+
RUBY
|
968
|
+
|
969
|
+
entry = T.must(@index.resolve("CONST", ["First", "Second"])&.first)
|
970
|
+
assert_equal(6, entry.location.start_line)
|
971
|
+
end
|
972
|
+
|
973
|
+
def test_resolving_circular_alias
|
974
|
+
index(<<~RUBY)
|
975
|
+
module Namespace
|
976
|
+
FOO = BAR
|
977
|
+
BAR = FOO
|
978
|
+
end
|
979
|
+
RUBY
|
980
|
+
|
981
|
+
foo_entry = T.must(@index.resolve("FOO", ["Namespace"])&.first)
|
982
|
+
assert_equal(2, foo_entry.location.start_line)
|
983
|
+
assert_instance_of(Entry::Alias, foo_entry)
|
984
|
+
|
985
|
+
bar_entry = T.must(@index.resolve("BAR", ["Namespace"])&.first)
|
986
|
+
assert_equal(3, bar_entry.location.start_line)
|
987
|
+
assert_instance_of(Entry::Alias, bar_entry)
|
988
|
+
end
|
989
|
+
|
990
|
+
def test_resolving_circular_alias_three_levels
|
991
|
+
index(<<~RUBY)
|
992
|
+
module Namespace
|
993
|
+
FOO = BAR
|
994
|
+
BAR = BAZ
|
995
|
+
BAZ = FOO
|
996
|
+
end
|
997
|
+
RUBY
|
998
|
+
|
999
|
+
foo_entry = T.must(@index.resolve("FOO", ["Namespace"])&.first)
|
1000
|
+
assert_equal(2, foo_entry.location.start_line)
|
1001
|
+
assert_instance_of(Entry::Alias, foo_entry)
|
1002
|
+
|
1003
|
+
bar_entry = T.must(@index.resolve("BAR", ["Namespace"])&.first)
|
1004
|
+
assert_equal(3, bar_entry.location.start_line)
|
1005
|
+
assert_instance_of(Entry::Alias, bar_entry)
|
1006
|
+
|
1007
|
+
baz_entry = T.must(@index.resolve("BAZ", ["Namespace"])&.first)
|
1008
|
+
assert_equal(4, baz_entry.location.start_line)
|
1009
|
+
assert_instance_of(Entry::Alias, baz_entry)
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
def test_resolving_top_level_compact_reference
|
1013
|
+
index(<<~RUBY)
|
1014
|
+
class Foo::Bar
|
1015
|
+
end
|
1016
|
+
RUBY
|
1017
|
+
|
1018
|
+
foo_entry = T.must(@index.resolve("Foo::Bar", [])&.first)
|
1019
|
+
assert_equal(1, foo_entry.location.start_line)
|
1020
|
+
assert_instance_of(Entry::Class, foo_entry)
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
def test_resolving_references_with_redundant_namespaces
|
1024
|
+
index(<<~RUBY)
|
1025
|
+
module Bar
|
1026
|
+
CONST = 1
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
module A
|
1030
|
+
CONST = 2
|
1031
|
+
|
1032
|
+
module B
|
1033
|
+
CONST = 3
|
1034
|
+
|
1035
|
+
class Foo
|
1036
|
+
include Bar
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
A::B::Foo::CONST
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
RUBY
|
1043
|
+
|
1044
|
+
foo_entry = T.must(@index.resolve("A::B::Foo::CONST", ["A", "B"])&.first)
|
1045
|
+
assert_equal(2, foo_entry.location.start_line)
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
def test_resolving_qualified_references
|
1049
|
+
index(<<~RUBY)
|
1050
|
+
module Namespace
|
1051
|
+
class Entry
|
1052
|
+
CONST = 1
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
module Namespace
|
1057
|
+
class Index
|
1058
|
+
end
|
1059
|
+
end
|
1060
|
+
RUBY
|
1061
|
+
|
1062
|
+
foo_entry = T.must(@index.resolve("Entry::CONST", ["Namespace", "Index"])&.first)
|
1063
|
+
assert_equal(3, foo_entry.location.start_line)
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
def test_resolving_unqualified_references
|
1067
|
+
index(<<~RUBY)
|
1068
|
+
module Foo
|
1069
|
+
CONST = 1
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
module Namespace
|
1073
|
+
CONST = 2
|
1074
|
+
|
1075
|
+
class Index
|
1076
|
+
include Foo
|
1077
|
+
end
|
1078
|
+
end
|
1079
|
+
RUBY
|
1080
|
+
|
1081
|
+
foo_entry = T.must(@index.resolve("CONST", ["Namespace", "Index"])&.first)
|
1082
|
+
assert_equal(6, foo_entry.location.start_line)
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
def test_resolving_references_with_only_top_level_declaration
|
1086
|
+
index(<<~RUBY)
|
1087
|
+
CONST = 1
|
1088
|
+
|
1089
|
+
module Foo; end
|
1090
|
+
|
1091
|
+
module Namespace
|
1092
|
+
class Index
|
1093
|
+
include Foo
|
1094
|
+
end
|
1095
|
+
end
|
1096
|
+
RUBY
|
1097
|
+
|
1098
|
+
foo_entry = T.must(@index.resolve("CONST", ["Namespace", "Index"])&.first)
|
1099
|
+
assert_equal(1, foo_entry.location.start_line)
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
def test_instance_variables_completions_from_different_owners_with_conflicting_names
|
1103
|
+
index(<<~RUBY)
|
1104
|
+
class Foo
|
1105
|
+
def initialize
|
1106
|
+
@bar = 1
|
1107
|
+
end
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
class Bar
|
1111
|
+
def initialize
|
1112
|
+
@bar = 2
|
1113
|
+
end
|
1114
|
+
end
|
1115
|
+
RUBY
|
1116
|
+
|
1117
|
+
entry = T.must(@index.instance_variable_completion_candidates("@", "Bar")&.first)
|
1118
|
+
assert_equal("@bar", entry.name)
|
1119
|
+
assert_equal("Bar", T.must(entry.owner).name)
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
def test_resolving_a_qualified_reference
|
1123
|
+
index(<<~RUBY)
|
1124
|
+
class Base
|
1125
|
+
module Third
|
1126
|
+
CONST = 1
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
class Foo
|
1131
|
+
module Third
|
1132
|
+
CONST = 2
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
class Second < Base
|
1136
|
+
end
|
1137
|
+
end
|
1138
|
+
RUBY
|
1139
|
+
|
1140
|
+
foo_entry = T.must(@index.resolve("Third::CONST", ["Foo"])&.first)
|
1141
|
+
assert_equal(9, foo_entry.location.start_line)
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
def test_resolving_unindexed_constant_with_no_nesting
|
1145
|
+
assert_nil(@index.resolve("RSpec", []))
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
def test_object_superclass_resolution
|
1149
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1150
|
+
module Foo
|
1151
|
+
class Object; end
|
1152
|
+
|
1153
|
+
class Bar; end
|
1154
|
+
class Baz < Object; end
|
1155
|
+
end
|
1156
|
+
RUBY
|
1157
|
+
|
1158
|
+
assert_equal(["Foo::Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Foo::Bar"))
|
1159
|
+
assert_equal(
|
1160
|
+
["Foo::Baz", "Foo::Object", "Object", "Kernel", "BasicObject"],
|
1161
|
+
@index.linearized_ancestors_of("Foo::Baz"),
|
1162
|
+
)
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
def test_top_level_object_superclass_resolution
|
1166
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1167
|
+
module Foo
|
1168
|
+
class Object; end
|
1169
|
+
|
1170
|
+
class Bar < ::Object; end
|
1171
|
+
end
|
1172
|
+
RUBY
|
1173
|
+
|
1174
|
+
assert_equal(["Foo::Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Foo::Bar"))
|
1175
|
+
end
|
844
1176
|
end
|
845
1177
|
end
|
@@ -378,5 +378,25 @@ module RubyIndexer
|
|
378
378
|
entry = T.must(@index["third"]&.first)
|
379
379
|
assert_equal("Foo", T.must(entry.owner).name)
|
380
380
|
end
|
381
|
+
|
382
|
+
def test_keeps_track_of_aliases
|
383
|
+
index(<<~RUBY)
|
384
|
+
class Foo
|
385
|
+
alias whatever to_s
|
386
|
+
alias_method :foo, :to_a
|
387
|
+
alias_method "bar", "to_a"
|
388
|
+
|
389
|
+
# These two are not indexed because they are dynamic or incomplete
|
390
|
+
alias_method baz, :to_a
|
391
|
+
alias_method :baz
|
392
|
+
end
|
393
|
+
RUBY
|
394
|
+
|
395
|
+
assert_entry("whatever", Entry::UnresolvedMethodAlias, "/fake/path/foo.rb:1-8:1-16")
|
396
|
+
assert_entry("foo", Entry::UnresolvedMethodAlias, "/fake/path/foo.rb:2-15:2-19")
|
397
|
+
assert_entry("bar", Entry::UnresolvedMethodAlias, "/fake/path/foo.rb:3-15:3-20")
|
398
|
+
# Foo plus 3 valid aliases
|
399
|
+
assert_equal(4, @index.instance_variable_get(:@entries).length - @default_indexed_entries.length)
|
400
|
+
end
|
381
401
|
end
|
382
402
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "test_case"
|
5
|
+
|
6
|
+
module RubyIndexer
|
7
|
+
class RBSIndexerTest < TestCase
|
8
|
+
def test_index_core_classes
|
9
|
+
entries = @index["Array"]
|
10
|
+
refute_nil(entries)
|
11
|
+
assert_equal(1, entries.length)
|
12
|
+
entry = entries.first
|
13
|
+
assert_match(%r{/gems/rbs-.*/core/array.rbs}, entry.file_path)
|
14
|
+
assert_equal("array.rbs", entry.file_name)
|
15
|
+
assert_equal("Object", entry.parent_class)
|
16
|
+
assert_equal(1, entry.mixin_operations.length)
|
17
|
+
enumerable_include = entry.mixin_operations.first
|
18
|
+
assert_equal("Enumerable", enumerable_include.module_name)
|
19
|
+
|
20
|
+
# Using fixed positions would be fragile, so let's just check some basics.
|
21
|
+
assert_operator(entry.location.start_line, :>, 0)
|
22
|
+
assert_operator(entry.location.end_line, :>, entry.location.start_line)
|
23
|
+
assert_equal(0, entry.location.start_column)
|
24
|
+
assert_operator(entry.location.end_column, :>, 0)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_index_core_modules
|
28
|
+
entries = @index["Kernel"]
|
29
|
+
refute_nil(entries)
|
30
|
+
assert_equal(1, entries.length)
|
31
|
+
entry = entries.first
|
32
|
+
assert_match(%r{/gems/rbs-.*/core/kernel.rbs}, entry.file_path)
|
33
|
+
assert_equal("kernel.rbs", entry.file_name)
|
34
|
+
|
35
|
+
# Using fixed positions would be fragile, so let's just check some basics.
|
36
|
+
assert_operator(entry.location.start_line, :>, 0)
|
37
|
+
assert_operator(entry.location.end_line, :>, entry.location.start_line)
|
38
|
+
assert_equal(0, entry.location.start_column)
|
39
|
+
assert_operator(entry.location.end_column, :>, 0)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -7,6 +7,8 @@ module RubyIndexer
|
|
7
7
|
class TestCase < Minitest::Test
|
8
8
|
def setup
|
9
9
|
@index = Index.new
|
10
|
+
RBSIndexer.new(@index).index_ruby_core
|
11
|
+
@default_indexed_entries = @index.instance_variable_get(:@entries).dup
|
10
12
|
end
|
11
13
|
|
12
14
|
private
|
@@ -17,6 +19,7 @@ module RubyIndexer
|
|
17
19
|
|
18
20
|
def assert_entry(expected_name, type, expected_location, visibility: nil)
|
19
21
|
entries = @index[expected_name]
|
22
|
+
refute_nil(entries, "Expected #{expected_name} to be indexed")
|
20
23
|
refute_empty(entries, "Expected #{expected_name} to be indexed")
|
21
24
|
|
22
25
|
entry = entries.first
|
@@ -41,6 +44,10 @@ module RubyIndexer
|
|
41
44
|
assert_empty(@index.instance_variable_get(:@entries), "Expected nothing to be indexed")
|
42
45
|
end
|
43
46
|
|
47
|
+
def assert_no_indexed_entries
|
48
|
+
assert_equal(@default_indexed_entries, @index.instance_variable_get(:@entries))
|
49
|
+
end
|
50
|
+
|
44
51
|
def assert_no_entry(entry)
|
45
52
|
refute(@index.instance_variable_get(:@entries).key?(entry), "Expected '#{entry}' to not be indexed")
|
46
53
|
end
|