ruby-lsp 0.17.1 → 0.17.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|