ruby-lsp 0.23.11 → 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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +10 -4
  5. data/exe/ruby-lsp-check +0 -4
  6. data/exe/ruby-lsp-launcher +46 -22
  7. data/exe/ruby-lsp-test-exec +6 -0
  8. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
  9. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
  10. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
  11. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +159 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +130 -253
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +189 -285
  15. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  16. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
  17. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +31 -59
  18. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
  19. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
  20. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
  21. data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
  22. data/lib/ruby_indexer/test/classes_and_modules_test.rb +85 -40
  23. data/lib/ruby_indexer/test/configuration_test.rb +52 -14
  24. data/lib/ruby_indexer/test/constant_test.rb +34 -34
  25. data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
  26. data/lib/ruby_indexer/test/index_test.rb +226 -139
  27. data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
  28. data/lib/ruby_indexer/test/method_test.rb +166 -123
  29. data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
  30. data/lib/ruby_indexer/test/rbs_indexer_test.rb +71 -76
  31. data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
  32. data/lib/ruby_indexer/test/test_case.rb +9 -3
  33. data/lib/ruby_indexer/test/uri_test.rb +15 -2
  34. data/lib/ruby_lsp/addon.rb +88 -86
  35. data/lib/ruby_lsp/base_server.rb +79 -65
  36. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  37. data/lib/ruby_lsp/document.rb +205 -104
  38. data/lib/ruby_lsp/erb_document.rb +45 -47
  39. data/lib/ruby_lsp/global_state.rb +134 -86
  40. data/lib/ruby_lsp/internal.rb +8 -3
  41. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  42. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  43. data/lib/ruby_lsp/listeners/definition.rb +78 -72
  44. data/lib/ruby_lsp/listeners/document_highlight.rb +149 -151
  45. data/lib/ruby_lsp/listeners/document_link.rb +93 -86
  46. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  47. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  48. data/lib/ruby_lsp/listeners/hover.rb +109 -117
  49. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  50. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  51. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  52. data/lib/ruby_lsp/listeners/spec_style.rb +231 -0
  53. data/lib/ruby_lsp/listeners/test_discovery.rb +107 -0
  54. data/lib/ruby_lsp/listeners/test_style.rb +207 -95
  55. data/lib/ruby_lsp/node_context.rb +12 -39
  56. data/lib/ruby_lsp/rbs_document.rb +10 -11
  57. data/lib/ruby_lsp/requests/code_action_resolve.rb +92 -66
  58. data/lib/ruby_lsp/requests/code_actions.rb +34 -31
  59. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  60. data/lib/ruby_lsp/requests/completion.rb +8 -21
  61. data/lib/ruby_lsp/requests/completion_resolve.rb +14 -12
  62. data/lib/ruby_lsp/requests/definition.rb +8 -20
  63. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  64. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  65. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  66. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  67. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  68. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  69. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  70. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +139 -0
  71. data/lib/ruby_lsp/requests/hover.rb +12 -25
  72. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  73. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  74. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  75. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  76. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  77. data/lib/ruby_lsp/requests/references.rb +17 -57
  78. data/lib/ruby_lsp/requests/rename.rb +27 -51
  79. data/lib/ruby_lsp/requests/request.rb +13 -25
  80. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  81. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  82. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  83. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  84. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  85. data/lib/ruby_lsp/requests/support/common.rb +23 -61
  86. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  87. data/lib/ruby_lsp/requests/support/package_url.rb +414 -0
  88. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  89. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  90. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  91. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  92. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  93. data/lib/ruby_lsp/requests/support/source_uri.rb +22 -33
  94. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  95. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  96. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  97. data/lib/ruby_lsp/requests/workspace_symbol.rb +24 -16
  98. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  99. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  100. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  101. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  102. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  103. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  104. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  105. data/lib/ruby_lsp/ruby_document.rb +32 -98
  106. data/lib/ruby_lsp/scope.rb +7 -11
  107. data/lib/ruby_lsp/scripts/compose_bundle.rb +7 -5
  108. data/lib/ruby_lsp/server.rb +305 -198
  109. data/lib/ruby_lsp/setup_bundler.rb +146 -86
  110. data/lib/ruby_lsp/static_docs.rb +12 -7
  111. data/lib/ruby_lsp/store.rb +21 -49
  112. data/lib/ruby_lsp/test_helper.rb +3 -16
  113. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +241 -0
  114. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  115. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  116. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  117. data/lib/ruby_lsp/utils.rb +138 -93
  118. data/static_docs/break.md +103 -0
  119. metadata +15 -20
  120. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -15,11 +15,11 @@ module RubyIndexer
15
15
  end
16
16
  RUBY
17
17
 
18
- entries = @index["Foo"]
18
+ entries = @index["Foo"] #: as !nil
19
19
  assert_equal(2, entries.length)
20
20
 
21
21
  @index.delete(URI::Generic.from_path(path: "/fake/path/other_foo.rb"))
22
- entries = @index["Foo"]
22
+ entries = @index["Foo"] #: as !nil
23
23
  assert_equal(1, entries.length)
24
24
  end
25
25
 
@@ -29,7 +29,7 @@ module RubyIndexer
29
29
  end
30
30
  RUBY
31
31
 
32
- entries = @index["Foo"]
32
+ entries = @index["Foo"] #: as !nil
33
33
  assert_equal(1, entries.length)
34
34
 
35
35
  @index.delete(URI::Generic.from_path(path: "/fake/path/foo.rb"))
@@ -52,21 +52,21 @@ module RubyIndexer
52
52
  end
53
53
  RUBY
54
54
 
55
- entries = @index.resolve("Something", ["Foo", "Baz"])
55
+ entries = @index.resolve("Something", ["Foo", "Baz"]) #: as !nil
56
56
  refute_empty(entries)
57
- assert_equal("Foo::Baz::Something", entries.first.name)
57
+ assert_equal("Foo::Baz::Something", entries.first&.name)
58
58
 
59
- entries = @index.resolve("Bar", ["Foo"])
59
+ entries = @index.resolve("Bar", ["Foo"]) #: as !nil
60
60
  refute_empty(entries)
61
- assert_equal("Foo::Bar", entries.first.name)
61
+ assert_equal("Foo::Bar", entries.first&.name)
62
62
 
63
- entries = @index.resolve("Bar", ["Foo", "Baz"])
63
+ entries = @index.resolve("Bar", ["Foo", "Baz"]) #: as !nil
64
64
  refute_empty(entries)
65
- assert_equal("Foo::Bar", entries.first.name)
65
+ assert_equal("Foo::Bar", entries.first&.name)
66
66
 
67
- entries = @index.resolve("Foo::Bar", ["Foo", "Baz"])
67
+ entries = @index.resolve("Foo::Bar", ["Foo", "Baz"]) #: as !nil
68
68
  refute_empty(entries)
69
- assert_equal("Foo::Bar", entries.first.name)
69
+ assert_equal("Foo::Bar", entries.first&.name)
70
70
 
71
71
  assert_nil(@index.resolve("DoesNotExist", ["Foo"]))
72
72
  end
@@ -86,9 +86,9 @@ module RubyIndexer
86
86
  end
87
87
  RUBY
88
88
 
89
- entries = @index["::Foo::Baz::Something"]
89
+ entries = @index["::Foo::Baz::Something"] #: as !nil
90
90
  refute_empty(entries)
91
- assert_equal("Foo::Baz::Something", entries.first.name)
91
+ assert_equal("Foo::Baz::Something", entries.first&.name)
92
92
  end
93
93
 
94
94
  def test_fuzzy_search
@@ -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(5, result.length)
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
 
@@ -140,7 +137,7 @@ module RubyIndexer
140
137
  end
141
138
  RUBY
142
139
 
143
- assert_equal(["path/foo", "path/other_foo"], @index.search_require_paths("path").map(&:require_path))
140
+ assert_equal(["path/other_foo", "path/foo"], @index.search_require_paths("path").map(&:require_path))
144
141
  end
145
142
 
146
143
  def test_searching_for_entries_based_on_prefix
@@ -157,10 +154,10 @@ module RubyIndexer
157
154
  RUBY
158
155
 
159
156
  results = @index.prefix_search("Foo", []).map { |entries| entries.map(&:name) }
160
- assert_equal([["Foo::Bizw", "Foo::Bizw"], ["Foo::Bizt"]], results)
157
+ assert_equal([["Foo::Bizt"], ["Foo::Bizw", "Foo::Bizw"]], results)
161
158
 
162
159
  results = @index.prefix_search("Biz", ["Foo"]).map { |entries| entries.map(&:name) }
163
- assert_equal([["Foo::Bizw", "Foo::Bizw"], ["Foo::Bizt"]], results)
160
+ assert_equal([["Foo::Bizt"], ["Foo::Bizw", "Foo::Bizw"]], results)
164
161
  end
165
162
 
166
163
  def test_resolve_normalizes_top_level_names
@@ -172,15 +169,15 @@ module RubyIndexer
172
169
  end
173
170
  RUBY
174
171
 
175
- entries = @index.resolve("::Foo::Bar", [])
172
+ entries = @index.resolve("::Foo::Bar", []) #: as !nil
176
173
  refute_nil(entries)
177
174
 
178
- assert_equal("Foo::Bar", entries.first.name)
175
+ assert_equal("Foo::Bar", entries.first&.name)
179
176
 
180
- entries = @index.resolve("::Bar", ["Foo"])
177
+ entries = @index.resolve("::Bar", ["Foo"]) #: as !nil
181
178
  refute_nil(entries)
182
179
 
183
- assert_equal("Bar", entries.first.name)
180
+ assert_equal("Bar", entries.first&.name)
184
181
  end
185
182
 
186
183
  def test_resolving_aliases_to_non_existing_constants_with_conflicting_names
@@ -195,7 +192,7 @@ module RubyIndexer
195
192
  end
196
193
  RUBY
197
194
 
198
- entry = @index.resolve("BAZ", ["Foo", "Bar"]).first
195
+ entry = @index.resolve("BAZ", ["Foo", "Bar"])&.first
199
196
  refute_nil(entry)
200
197
 
201
198
  assert_instance_of(Entry::UnresolvedConstantAlias, entry)
@@ -233,9 +230,10 @@ module RubyIndexer
233
230
  end
234
231
  RUBY
235
232
 
236
- entries = T.must(@index.resolve_method("baz", "Foo::Bar"))
237
- assert_equal("baz", entries.first.name)
238
- assert_equal("Foo::Bar", T.must(entries.first.owner).name)
233
+ entries = @index.resolve_method("baz", "Foo::Bar") #: as !nil
234
+ assert_equal("baz", entries.first&.name)
235
+ owner = entries.first&.owner #: as !nil
236
+ assert_equal("Foo::Bar", owner.name)
239
237
  end
240
238
 
241
239
  def test_resolve_method_with_class_name_conflict
@@ -248,9 +246,10 @@ module RubyIndexer
248
246
  end
249
247
  RUBY
250
248
 
251
- entries = T.must(@index.resolve_method("Array", "Foo"))
252
- assert_equal("Array", entries.first.name)
253
- assert_equal("Foo", T.must(entries.first.owner).name)
249
+ entries = @index.resolve_method("Array", "Foo") #: as !nil
250
+ assert_equal("Array", entries.first&.name)
251
+ owner = entries.first&.owner #: as !nil
252
+ assert_equal("Foo", owner.name)
254
253
  end
255
254
 
256
255
  def test_resolve_method_attribute
@@ -260,9 +259,10 @@ module RubyIndexer
260
259
  end
261
260
  RUBY
262
261
 
263
- entries = T.must(@index.resolve_method("bar", "Foo"))
264
- assert_equal("bar", entries.first.name)
265
- assert_equal("Foo", T.must(entries.first.owner).name)
262
+ entries = @index.resolve_method("bar", "Foo") #: as !nil
263
+ assert_equal("bar", entries.first&.name)
264
+ owner = entries.first&.owner #: as !nil
265
+ assert_equal("Foo", owner.name)
266
266
  end
267
267
 
268
268
  def test_resolve_method_with_two_definitions
@@ -278,15 +278,17 @@ module RubyIndexer
278
278
  end
279
279
  RUBY
280
280
 
281
- first_entry, second_entry = T.must(@index.resolve_method("bar", "Foo"))
281
+ first_entry, second_entry = @index.resolve_method("bar", "Foo") #: as !nil
282
282
 
283
- assert_equal("bar", first_entry.name)
284
- assert_equal("Foo", T.must(first_entry.owner).name)
285
- assert_includes(first_entry.comments, "Hello from first `bar`")
283
+ assert_equal("bar", first_entry&.name)
284
+ owner = first_entry&.owner #: as !nil
285
+ assert_equal("Foo", owner.name)
286
+ assert_includes(first_entry&.comments, "Hello from first `bar`")
286
287
 
287
- assert_equal("bar", second_entry.name)
288
- assert_equal("Foo", T.must(second_entry.owner).name)
289
- assert_includes(second_entry.comments, "Hello from second `bar`")
288
+ assert_equal("bar", second_entry&.name)
289
+ owner = second_entry&.owner #: as !nil
290
+ assert_equal("Foo", owner.name)
291
+ assert_includes(second_entry&.comments, "Hello from second `bar`")
290
292
  end
291
293
 
292
294
  def test_resolve_method_inherited_only
@@ -300,9 +302,8 @@ module RubyIndexer
300
302
  end
301
303
  RUBY
302
304
 
303
- entry = T.must(@index.resolve_method("baz", "Foo", inherited_only: true).first)
304
-
305
- assert_equal("Bar", T.must(entry.owner).name)
305
+ entry = @index.resolve_method("baz", "Foo", inherited_only: true)&.first #: as !nil
306
+ assert_equal("Bar", entry.owner&.name)
306
307
  end
307
308
 
308
309
  def test_resolve_method_inherited_only_for_prepended_module
@@ -338,7 +339,7 @@ module RubyIndexer
338
339
  entries = @index.prefix_search("qz")
339
340
  refute_empty(entries)
340
341
 
341
- entry = T.must(T.must(entries.first).first)
342
+ entry = entries.first&.first #: as !nil
342
343
  assert_equal("qzx", entry.name)
343
344
  end
344
345
 
@@ -724,6 +725,30 @@ module RubyIndexer
724
725
  assert_equal(["A", "ALIAS"], @index.linearized_ancestors_of("A"))
725
726
  end
726
727
 
728
+ def test_linearizing_ancestors_for_classes_with_overridden_parents
729
+ index(<<~RUBY)
730
+ # Find the re-open of a class first, without specifying a parent
731
+ class Child
732
+ end
733
+
734
+ # Now, find the actual definition of the class, which includes a parent
735
+ class Parent; end
736
+ class Child < Parent
737
+ end
738
+ RUBY
739
+
740
+ assert_equal(
741
+ [
742
+ "Child",
743
+ "Parent",
744
+ "Object",
745
+ "Kernel",
746
+ "BasicObject",
747
+ ],
748
+ @index.linearized_ancestors_of("Child"),
749
+ )
750
+ end
751
+
727
752
  def test_resolving_an_inherited_method
728
753
  index(<<~RUBY)
729
754
  module Foo
@@ -739,13 +764,13 @@ module RubyIndexer
739
764
  end
740
765
  RUBY
741
766
 
742
- entry = T.must(@index.resolve_method("baz", "Wow")&.first)
767
+ entry = @index.resolve_method("baz", "Wow")&.first #: as !nil
743
768
  assert_equal("baz", entry.name)
744
- assert_equal("Foo", T.must(entry.owner).name)
769
+ assert_equal("Foo", entry.owner&.name)
745
770
 
746
- entry = T.must(@index.resolve_method("qux", "Wow")&.first)
771
+ entry = @index.resolve_method("qux", "Wow")&.first #: as !nil
747
772
  assert_equal("qux", entry.name)
748
- assert_equal("Bar", T.must(entry.owner).name)
773
+ assert_equal("Bar", entry.owner&.name)
749
774
  end
750
775
 
751
776
  def test_resolving_an_inherited_method_lands_on_first_match
@@ -765,12 +790,12 @@ module RubyIndexer
765
790
  end
766
791
  RUBY
767
792
 
768
- entries = T.must(@index.resolve_method("qux", "Wow"))
793
+ entries = @index.resolve_method("qux", "Wow") #: as !nil
769
794
  assert_equal(1, entries.length)
770
795
 
771
- entry = T.must(entries.first)
796
+ entry = entries.first #: as !nil
772
797
  assert_equal("qux", entry.name)
773
- assert_equal("Foo", T.must(entry.owner).name)
798
+ assert_equal("Foo", entry.owner&.name)
774
799
  end
775
800
 
776
801
  def test_handle_change_clears_ancestor_cache_if_tree_changed
@@ -800,7 +825,8 @@ module RubyIndexer
800
825
  end
801
826
  RUBY
802
827
 
803
- @index.handle_change(uri, File.read(T.must(uri.full_path)))
828
+ path = uri.full_path #: as !nil
829
+ @index.handle_change(uri, File.read(path))
804
830
  assert_empty(@index.instance_variable_get(:@ancestors))
805
831
  assert_equal(["Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
806
832
  end
@@ -837,7 +863,8 @@ module RubyIndexer
837
863
  end
838
864
  RUBY
839
865
 
840
- @index.handle_change(uri, File.read(T.must(uri.full_path)))
866
+ path = uri.full_path #: as !nil
867
+ @index.handle_change(uri, File.read(path))
841
868
  refute_empty(@index.instance_variable_get(:@ancestors))
842
869
  assert_equal(["Bar", "Foo", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
843
870
  end
@@ -870,7 +897,8 @@ module RubyIndexer
870
897
  end
871
898
  RUBY
872
899
 
873
- @index.handle_change(uri, File.read(T.must(uri.full_path)))
900
+ path = uri.full_path #: as !nil
901
+ @index.handle_change(uri, File.read(path))
874
902
  assert_empty(@index.instance_variable_get(:@ancestors))
875
903
  assert_equal(["Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Bar"))
876
904
  end
@@ -904,7 +932,7 @@ module RubyIndexer
904
932
  CONST = 4
905
933
  RUBY
906
934
 
907
- entry = T.must(@index.resolve("CONST", ["Namespace", "Bar"])&.first)
935
+ entry = @index.resolve("CONST", ["Namespace", "Bar"])&.first #: as !nil
908
936
  assert_equal(14, entry.location.start_line)
909
937
  end
910
938
 
@@ -925,10 +953,10 @@ module RubyIndexer
925
953
  end
926
954
  RUBY
927
955
 
928
- entry = T.must(@index.resolve("Foo::CONST::TARGET", [])&.first)
956
+ entry = @index.resolve("Foo::CONST::TARGET", [])&.first #: as !nil
929
957
  assert_equal(2, entry.location.start_line)
930
958
 
931
- entry = T.must(@index.resolve("Namespace::Bar::CONST::TARGET", [])&.first)
959
+ entry = @index.resolve("Namespace::Bar::CONST::TARGET", [])&.first #: as !nil
932
960
  assert_equal(2, entry.location.start_line)
933
961
  end
934
962
 
@@ -946,10 +974,10 @@ module RubyIndexer
946
974
  end
947
975
  RUBY
948
976
 
949
- entry = T.must(@index.resolve("CONST", ["Namespace", "Child"])&.first)
977
+ entry = @index.resolve("CONST", ["Namespace", "Child"])&.first #: as !nil
950
978
  assert_equal(2, entry.location.start_line)
951
979
 
952
- entry = T.must(@index.resolve("Namespace::Child::CONST", [])&.first)
980
+ entry = @index.resolve("Namespace::Child::CONST", [])&.first #: as !nil
953
981
  assert_equal(5, entry.location.start_line)
954
982
  end
955
983
 
@@ -975,13 +1003,13 @@ module RubyIndexer
975
1003
  end
976
1004
  RUBY
977
1005
 
978
- entry = T.must(@index.resolve("CONST", ["Foo"])&.first)
1006
+ entry = @index.resolve("CONST", ["Foo"])&.first #: as !nil
979
1007
  assert_equal(6, entry.location.start_line)
980
1008
 
981
- entry = T.must(@index.resolve("Foo::CONST", [])&.first)
1009
+ entry = @index.resolve("Foo::CONST", [])&.first #: as !nil
982
1010
  assert_equal(6, entry.location.start_line)
983
1011
 
984
- entry = T.must(@index.resolve("Bar::CONST", [])&.first)
1012
+ entry = @index.resolve("Bar::CONST", [])&.first #: as !nil
985
1013
  assert_equal(15, entry.location.start_line)
986
1014
  end
987
1015
 
@@ -1005,7 +1033,7 @@ module RubyIndexer
1005
1033
  end
1006
1034
  RUBY
1007
1035
 
1008
- entry = T.must(@index.resolve("CONST", ["First", "Second"])&.first)
1036
+ entry = @index.resolve("CONST", ["First", "Second"])&.first #: as !nil
1009
1037
  assert_equal(6, entry.location.start_line)
1010
1038
  end
1011
1039
 
@@ -1017,11 +1045,11 @@ module RubyIndexer
1017
1045
  end
1018
1046
  RUBY
1019
1047
 
1020
- foo_entry = T.must(@index.resolve("FOO", ["Namespace"])&.first)
1048
+ foo_entry = @index.resolve("FOO", ["Namespace"])&.first #: as !nil
1021
1049
  assert_equal(2, foo_entry.location.start_line)
1022
1050
  assert_instance_of(Entry::ConstantAlias, foo_entry)
1023
1051
 
1024
- bar_entry = T.must(@index.resolve("BAR", ["Namespace"])&.first)
1052
+ bar_entry = @index.resolve("BAR", ["Namespace"])&.first #: as !nil
1025
1053
  assert_equal(3, bar_entry.location.start_line)
1026
1054
  assert_instance_of(Entry::ConstantAlias, bar_entry)
1027
1055
  end
@@ -1035,15 +1063,15 @@ module RubyIndexer
1035
1063
  end
1036
1064
  RUBY
1037
1065
 
1038
- foo_entry = T.must(@index.resolve("FOO", ["Namespace"])&.first)
1066
+ foo_entry = @index.resolve("FOO", ["Namespace"])&.first #: as !nil
1039
1067
  assert_equal(2, foo_entry.location.start_line)
1040
1068
  assert_instance_of(Entry::ConstantAlias, foo_entry)
1041
1069
 
1042
- bar_entry = T.must(@index.resolve("BAR", ["Namespace"])&.first)
1070
+ bar_entry = @index.resolve("BAR", ["Namespace"])&.first #: as !nil
1043
1071
  assert_equal(3, bar_entry.location.start_line)
1044
1072
  assert_instance_of(Entry::ConstantAlias, bar_entry)
1045
1073
 
1046
- baz_entry = T.must(@index.resolve("BAZ", ["Namespace"])&.first)
1074
+ baz_entry = @index.resolve("BAZ", ["Namespace"])&.first #: as !nil
1047
1075
  assert_equal(4, baz_entry.location.start_line)
1048
1076
  assert_instance_of(Entry::ConstantAlias, baz_entry)
1049
1077
  end
@@ -1065,7 +1093,7 @@ module RubyIndexer
1065
1093
  end
1066
1094
  RUBY
1067
1095
 
1068
- entry = T.must(@index.resolve("Other::ALIAS::CONST", ["Third"])&.first)
1096
+ entry = @index.resolve("Other::ALIAS::CONST", ["Third"])&.first #: as !nil
1069
1097
  assert_kind_of(Entry::Constant, entry)
1070
1098
  assert_equal("Original::Something::CONST", entry.name)
1071
1099
  end
@@ -1080,7 +1108,7 @@ module RubyIndexer
1080
1108
  FOO::CONST
1081
1109
  RUBY
1082
1110
 
1083
- entry = T.must(@index.resolve("FOO::CONST", [])&.first)
1111
+ entry = @index.resolve("FOO::CONST", [])&.first #: as !nil
1084
1112
  assert_kind_of(Entry::Constant, entry)
1085
1113
  assert_equal("Foo::CONST", entry.name)
1086
1114
  end
@@ -1091,7 +1119,7 @@ module RubyIndexer
1091
1119
  end
1092
1120
  RUBY
1093
1121
 
1094
- foo_entry = T.must(@index.resolve("Foo::Bar", [])&.first)
1122
+ foo_entry = @index.resolve("Foo::Bar", [])&.first #: as !nil
1095
1123
  assert_equal(1, foo_entry.location.start_line)
1096
1124
  assert_instance_of(Entry::Class, foo_entry)
1097
1125
  end
@@ -1117,10 +1145,50 @@ module RubyIndexer
1117
1145
  end
1118
1146
  RUBY
1119
1147
 
1120
- foo_entry = T.must(@index.resolve("A::B::Foo::CONST", ["A", "B"])&.first)
1148
+ foo_entry = @index.resolve("A::B::Foo::CONST", ["A", "B"])&.first #: as !nil
1121
1149
  assert_equal(2, foo_entry.location.start_line)
1122
1150
  end
1123
1151
 
1152
+ def test_resolving_self_referential_constant_alias
1153
+ index(<<~RUBY)
1154
+ module A
1155
+ module B
1156
+ class C
1157
+ end
1158
+ end
1159
+ end
1160
+
1161
+ module A
1162
+ module D
1163
+ B = B::C
1164
+ end
1165
+ end
1166
+ RUBY
1167
+
1168
+ entry = @index.resolve("A::D::B", [])&.first #: as Entry::ConstantAlias
1169
+
1170
+ assert_kind_of(RubyIndexer::Entry::ConstantAlias, entry)
1171
+ assert_equal(10, entry.location.start_line)
1172
+ assert_equal("A::B::C", entry.target)
1173
+ end
1174
+
1175
+ def test_resolving_non_existing_self_referential_constant_alias
1176
+ index(<<~RUBY)
1177
+ module Foo
1178
+ SomeClass = ::SomeClass
1179
+ UNRESOLVED = SomeClass::CONSTANT
1180
+ end
1181
+ RUBY
1182
+
1183
+ entry = @index.resolve("Foo::UNRESOLVED", [])&.first #: as Entry::UnresolvedConstantAlias
1184
+ assert_kind_of(Entry::UnresolvedConstantAlias, entry)
1185
+ assert_equal(3, entry.location.start_line)
1186
+ assert_equal("SomeClass::CONSTANT", entry.target)
1187
+
1188
+ entry = @index.resolve("SomeClass::CONSTANT", ["Foo"])
1189
+ refute(entry)
1190
+ end
1191
+
1124
1192
  def test_resolving_qualified_references
1125
1193
  index(<<~RUBY)
1126
1194
  module Namespace
@@ -1135,7 +1203,7 @@ module RubyIndexer
1135
1203
  end
1136
1204
  RUBY
1137
1205
 
1138
- foo_entry = T.must(@index.resolve("Entry::CONST", ["Namespace", "Index"])&.first)
1206
+ foo_entry = @index.resolve("Entry::CONST", ["Namespace", "Index"])&.first #: as !nil
1139
1207
  assert_equal(3, foo_entry.location.start_line)
1140
1208
  end
1141
1209
 
@@ -1154,7 +1222,7 @@ module RubyIndexer
1154
1222
  end
1155
1223
  RUBY
1156
1224
 
1157
- foo_entry = T.must(@index.resolve("CONST", ["Namespace", "Index"])&.first)
1225
+ foo_entry = @index.resolve("CONST", ["Namespace", "Index"])&.first #: as !nil
1158
1226
  assert_equal(6, foo_entry.location.start_line)
1159
1227
  end
1160
1228
 
@@ -1171,7 +1239,7 @@ module RubyIndexer
1171
1239
  end
1172
1240
  RUBY
1173
1241
 
1174
- foo_entry = T.must(@index.resolve("CONST", ["Namespace", "Index"])&.first)
1242
+ foo_entry = @index.resolve("CONST", ["Namespace", "Index"])&.first #: as !nil
1175
1243
  assert_equal(1, foo_entry.location.start_line)
1176
1244
  end
1177
1245
 
@@ -1190,9 +1258,9 @@ module RubyIndexer
1190
1258
  end
1191
1259
  RUBY
1192
1260
 
1193
- entry = T.must(@index.instance_variable_completion_candidates("@", "Bar")&.first)
1261
+ entry = @index.instance_variable_completion_candidates("@", "Bar").first #: as !nil
1194
1262
  assert_equal("@bar", entry.name)
1195
- assert_equal("Bar", T.must(entry.owner).name)
1263
+ assert_equal("Bar", entry.owner&.name)
1196
1264
  end
1197
1265
 
1198
1266
  def test_resolving_a_qualified_reference
@@ -1213,7 +1281,7 @@ module RubyIndexer
1213
1281
  end
1214
1282
  RUBY
1215
1283
 
1216
- foo_entry = T.must(@index.resolve("Third::CONST", ["Foo"])&.first)
1284
+ foo_entry = @index.resolve("Third::CONST", ["Foo"])&.first #: as !nil
1217
1285
  assert_equal(9, foo_entry.location.start_line)
1218
1286
  end
1219
1287
 
@@ -1226,9 +1294,9 @@ module RubyIndexer
1226
1294
  class Object; end
1227
1295
  RUBY
1228
1296
 
1229
- entries = @index["Object"]
1297
+ entries = @index["Object"] #: as !nil
1230
1298
  assert_equal(2, entries.length)
1231
- reopened_entry = entries.last
1299
+ reopened_entry = entries.last #: as Entry::Class
1232
1300
  assert_equal("::BasicObject", reopened_entry.parent_class)
1233
1301
  assert_equal(["Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Object"))
1234
1302
  end
@@ -1238,9 +1306,9 @@ module RubyIndexer
1238
1306
  class BasicObject; end
1239
1307
  RUBY
1240
1308
 
1241
- entries = @index["BasicObject"]
1309
+ entries = @index["BasicObject"] #: as !nil
1242
1310
  assert_equal(2, entries.length)
1243
- reopened_entry = entries.last
1311
+ reopened_entry = entries.last #: as Entry::Class
1244
1312
  assert_nil(reopened_entry.parent_class)
1245
1313
  assert_equal(["BasicObject"], @index.linearized_ancestors_of("BasicObject"))
1246
1314
  end
@@ -1318,10 +1386,9 @@ module RubyIndexer
1318
1386
  end
1319
1387
  RUBY
1320
1388
 
1321
- entry = @index.resolve_method("found_me!", "Foo::Bar::<Class:Bar>::Baz::<Class:Baz>")&.first
1389
+ entry = @index.resolve_method("found_me!", "Foo::Bar::<Class:Bar>::Baz::<Class:Baz>")&.first #: as !nil
1322
1390
  refute_nil(entry)
1323
-
1324
- assert_equal("found_me!", T.must(entry).name)
1391
+ assert_equal("found_me!", entry.name)
1325
1392
  end
1326
1393
 
1327
1394
  def test_resolving_constants_in_singleton_contexts
@@ -1344,9 +1411,9 @@ module RubyIndexer
1344
1411
  end
1345
1412
  RUBY
1346
1413
 
1347
- entry = @index.resolve("CONST", ["Foo", "Bar", "<Class:Bar>", "Baz", "<Class:Baz>"])&.first
1414
+ entry = @index.resolve("CONST", ["Foo", "Bar", "<Class:Bar>", "Baz", "<Class:Baz>"])&.first #: as !nil
1348
1415
  refute_nil(entry)
1349
- assert_equal(9, T.must(entry).location.start_line)
1416
+ assert_equal(9, entry.location.start_line)
1350
1417
  end
1351
1418
 
1352
1419
  def test_resolving_instance_variables_in_singleton_contexts
@@ -1366,17 +1433,17 @@ module RubyIndexer
1366
1433
  end
1367
1434
  RUBY
1368
1435
 
1369
- entry = @index.resolve_instance_variable("@a", "Foo::Bar::<Class:Bar>")&.first
1436
+ entry = @index.resolve_instance_variable("@a", "Foo::Bar::<Class:Bar>")&.first #: as !nil
1370
1437
  refute_nil(entry)
1371
- assert_equal("@a", T.must(entry).name)
1438
+ assert_equal("@a", entry.name)
1372
1439
 
1373
- entry = @index.resolve_instance_variable("@b", "Foo::Bar::<Class:Bar>")&.first
1440
+ entry = @index.resolve_instance_variable("@b", "Foo::Bar::<Class:Bar>")&.first #: as !nil
1374
1441
  refute_nil(entry)
1375
- assert_equal("@b", T.must(entry).name)
1442
+ assert_equal("@b", entry.name)
1376
1443
 
1377
- entry = @index.resolve_instance_variable("@c", "Foo::Bar::<Class:Bar>::<Class:<Class:Bar>>")&.first
1444
+ entry = @index.resolve_instance_variable("@c", "Foo::Bar::<Class:Bar>::<Class:<Class:Bar>>")&.first #: as !nil
1378
1445
  refute_nil(entry)
1379
- assert_equal("@c", T.must(entry).name)
1446
+ assert_equal("@c", entry.name)
1380
1447
  end
1381
1448
 
1382
1449
  def test_instance_variable_completion_in_singleton_contexts
@@ -1422,7 +1489,7 @@ module RubyIndexer
1422
1489
 
1423
1490
  results = @index.fuzzy_search("Zwq")
1424
1491
  assert_equal(1, results.length)
1425
- assert_equal("Zwq", results.first.name)
1492
+ assert_equal("Zwq", results.first&.name)
1426
1493
  end
1427
1494
 
1428
1495
  def test_resolving_method_aliases
@@ -1444,39 +1511,39 @@ module RubyIndexer
1444
1511
  RUBY
1445
1512
 
1446
1513
  # baz
1447
- methods = @index.resolve_method("baz", "Bar")
1514
+ methods = @index.resolve_method("baz", "Bar") #: as !nil
1448
1515
  refute_nil(methods)
1449
1516
 
1450
- entry = T.must(methods.first)
1517
+ entry = methods.first #: as Entry::MethodAlias
1451
1518
  assert_kind_of(Entry::MethodAlias, entry)
1452
1519
  assert_equal("bar", entry.target.name)
1453
- assert_equal("Foo", T.must(entry.target.owner).name)
1520
+ assert_equal("Foo", entry.target.owner&.name)
1454
1521
 
1455
1522
  # qux
1456
- methods = @index.resolve_method("qux", "Bar")
1523
+ methods = @index.resolve_method("qux", "Bar") #: as !nil
1457
1524
  refute_nil(methods)
1458
1525
 
1459
- entry = T.must(methods.first)
1526
+ entry = methods.first #: as Entry::MethodAlias
1460
1527
  assert_kind_of(Entry::MethodAlias, entry)
1461
1528
  assert_equal("hello", entry.target.name)
1462
- assert_equal("Bar", T.must(entry.target.owner).name)
1529
+ assert_equal("Bar", entry.target.owner&.name)
1463
1530
 
1464
1531
  # double
1465
- methods = @index.resolve_method("double", "Bar")
1532
+ methods = @index.resolve_method("double", "Bar") #: as !nil
1466
1533
  refute_nil(methods)
1467
1534
 
1468
- entry = T.must(methods.first)
1535
+ entry = methods.first #: as Entry::MethodAlias
1469
1536
  assert_kind_of(Entry::MethodAlias, entry)
1470
1537
 
1471
- target = entry.target
1538
+ target = entry.target #: as Entry::MethodAlias
1472
1539
  assert_equal("double_alias", target.name)
1473
1540
  assert_kind_of(Entry::MethodAlias, target)
1474
- assert_equal("Foo", T.must(target.owner).name)
1541
+ assert_equal("Foo", target.owner&.name)
1475
1542
 
1476
1543
  final_target = target.target
1477
1544
  assert_equal("bar", final_target.name)
1478
1545
  assert_kind_of(Entry::Method, final_target)
1479
- assert_equal("Foo", T.must(final_target.owner).name)
1546
+ assert_equal("Foo", final_target.owner&.name)
1480
1547
  end
1481
1548
 
1482
1549
  def test_resolving_circular_method_aliases
@@ -1490,7 +1557,7 @@ module RubyIndexer
1490
1557
  methods = @index.resolve_method("bar", "Foo")
1491
1558
  assert_nil(methods)
1492
1559
 
1493
- entry = T.must(@index["bar"].first)
1560
+ entry = @index["bar"]&.first
1494
1561
  assert_kind_of(Entry::UnresolvedMethodAlias, entry)
1495
1562
  end
1496
1563
 
@@ -1505,7 +1572,7 @@ module RubyIndexer
1505
1572
  methods = @index.resolve_method("bar", "Foo")
1506
1573
  assert_nil(methods)
1507
1574
 
1508
- entry = T.must(@index["bar"].first)
1575
+ entry = @index["bar"]&.first
1509
1576
  assert_kind_of(Entry::UnresolvedMethodAlias, entry)
1510
1577
  end
1511
1578
 
@@ -1521,18 +1588,18 @@ module RubyIndexer
1521
1588
  end
1522
1589
  RUBY
1523
1590
 
1524
- methods = @index.resolve_method("decorated_name", "Foo")
1591
+ methods = @index.resolve_method("decorated_name", "Foo") #: as !nil
1525
1592
  refute_nil(methods)
1526
1593
 
1527
- entry = T.must(methods.first)
1594
+ entry = methods.first #: as Entry::MethodAlias
1528
1595
  assert_kind_of(Entry::MethodAlias, entry)
1529
1596
 
1530
1597
  target = entry.target
1531
1598
  assert_equal("name", target.name)
1532
1599
  assert_kind_of(Entry::Accessor, target)
1533
- assert_equal("Foo", T.must(target.owner).name)
1600
+ assert_equal("Foo", target.owner&.name)
1534
1601
 
1535
- other_decorated_name = T.must(@index["decorated_name"].find { |e| e.is_a?(Entry::UnresolvedMethodAlias) })
1602
+ other_decorated_name = @index["decorated_name"]&.find { |e| e.is_a?(Entry::UnresolvedMethodAlias) }
1536
1603
  assert_kind_of(Entry::UnresolvedMethodAlias, other_decorated_name)
1537
1604
  end
1538
1605
 
@@ -1557,7 +1624,7 @@ module RubyIndexer
1557
1624
  end
1558
1625
  RUBY
1559
1626
 
1560
- entry = T.must(@index.first_unqualified_const("Bar")&.first)
1627
+ entry = @index.first_unqualified_const("Bar")&.first #: as !nil
1561
1628
  assert_equal("Foo::Bar", entry.name)
1562
1629
  end
1563
1630
 
@@ -1574,7 +1641,7 @@ module RubyIndexer
1574
1641
  end
1575
1642
  RUBY
1576
1643
 
1577
- entry = T.must(@index.first_unqualified_const("Type")&.first)
1644
+ entry = @index.first_unqualified_const("Type")&.first #: as !nil
1578
1645
  assert_equal("Namespace::Type", entry.name)
1579
1646
  end
1580
1647
 
@@ -1591,7 +1658,7 @@ module RubyIndexer
1591
1658
 
1592
1659
  entries = @index.method_completion_candidates("bar", "Baz")
1593
1660
  assert_equal(["bar"], entries.map(&:name))
1594
- assert_equal("Baz", T.must(entries.first.owner).name)
1661
+ assert_equal("Baz", entries.first&.owner&.name)
1595
1662
  end
1596
1663
 
1597
1664
  def test_completion_does_not_duplicate_methods_overridden_by_aliases
@@ -1607,7 +1674,7 @@ module RubyIndexer
1607
1674
 
1608
1675
  entries = @index.method_completion_candidates("bar", "Baz")
1609
1676
  assert_equal(["bar"], entries.map(&:name))
1610
- assert_equal("Baz", T.must(entries.first.owner).name)
1677
+ assert_equal("Baz", entries.first&.owner&.name)
1611
1678
  end
1612
1679
 
1613
1680
  def test_decorated_parameters
@@ -1618,11 +1685,10 @@ module RubyIndexer
1618
1685
  end
1619
1686
  RUBY
1620
1687
 
1621
- methods = @index.resolve_method("bar", "Foo")
1688
+ methods = @index.resolve_method("bar", "Foo") #: as !nil
1622
1689
  refute_nil(methods)
1623
1690
 
1624
- entry = T.must(methods.first)
1625
-
1691
+ entry = methods.first #: as Entry::Method
1626
1692
  assert_equal("(a, b = <default>, c: <default>)", entry.decorated_parameters)
1627
1693
  end
1628
1694
 
@@ -1634,11 +1700,10 @@ module RubyIndexer
1634
1700
  end
1635
1701
  RUBY
1636
1702
 
1637
- methods = @index.resolve_method("bar", "Foo")
1703
+ methods = @index.resolve_method("bar", "Foo") #: as !nil
1638
1704
  refute_nil(methods)
1639
1705
 
1640
- entry = T.must(methods.first)
1641
-
1706
+ entry = methods.first #: as Entry::Method
1642
1707
  assert_equal("()", entry.decorated_parameters)
1643
1708
  end
1644
1709
 
@@ -1707,9 +1772,9 @@ module RubyIndexer
1707
1772
  RUBY
1708
1773
 
1709
1774
  ["bar", "baz"].product(["Foo", "Foo::<Class:Foo>"]).each do |method, receiver|
1710
- entry = @index.resolve_method(method, receiver)&.first
1775
+ entry = @index.resolve_method(method, receiver)&.first #: as !nil
1711
1776
  refute_nil(entry)
1712
- assert_equal(method, T.must(entry).name)
1777
+ assert_equal(method, entry.name)
1713
1778
  end
1714
1779
 
1715
1780
  assert_equal(
@@ -1888,7 +1953,7 @@ module RubyIndexer
1888
1953
  end
1889
1954
  RUBY
1890
1955
 
1891
- method = @index.resolve_method("==", "Foo").first
1956
+ method = @index.resolve_method("==", "Foo")&.first #: as Entry::Method
1892
1957
  assert_kind_of(Entry::Method, method)
1893
1958
  assert_equal("==", method.name)
1894
1959
 
@@ -1906,13 +1971,13 @@ module RubyIndexer
1906
1971
  end
1907
1972
  RUBY
1908
1973
 
1909
- entries = @index.entries_for("file:///fake/path/foo.rb", Entry)
1974
+ entries = @index.entries_for("file:///fake/path/foo.rb", Entry) #: as !nil
1910
1975
  assert_equal(["Foo", "Bar", "my_def", "Bar::<Class:Bar>", "my_singleton_def"], entries.map(&:name))
1911
1976
 
1912
- entries = @index.entries_for("file:///fake/path/foo.rb", RubyIndexer::Entry::Namespace)
1977
+ entries = @index.entries_for("file:///fake/path/foo.rb", RubyIndexer::Entry::Namespace) #: as !nil
1913
1978
  assert_equal(["Foo", "Bar", "Bar::<Class:Bar>"], entries.map(&:name))
1914
1979
 
1915
- entries = @index.entries_for("file:///fake/path/foo.rb")
1980
+ entries = @index.entries_for("file:///fake/path/foo.rb") #: as !nil
1916
1981
  assert_equal(["Foo", "Bar", "my_def", "Bar::<Class:Bar>", "my_singleton_def"], entries.map(&:name))
1917
1982
  end
1918
1983
 
@@ -1945,14 +2010,29 @@ module RubyIndexer
1945
2010
  result = @index.constant_completion_candidates("X", ["Namespace", "Baz"])
1946
2011
 
1947
2012
  result.each do |entries|
1948
- name = entries.first.name
2013
+ name = entries.first&.name
1949
2014
  assert(entries.all? { |e| e.name == name })
1950
2015
  end
1951
2016
 
1952
- assert_equal(["Namespace::XQRK", "Bar::XQRK", "XQRK"], result.map { |entries| entries.first.name })
2017
+ assert_equal(["Namespace::XQRK", "Bar::XQRK", "XQRK"], result.map { |entries| entries.first&.name })
1953
2018
 
1954
2019
  result = @index.constant_completion_candidates("::X", ["Namespace", "Baz"])
1955
- assert_equal(["XQRK"], result.map { |entries| entries.first.name })
2020
+ assert_equal(["XQRK"], result.map { |entries| entries.first&.name })
2021
+ end
2022
+
2023
+ def test_constant_completion_does_not_confuse_uppercase_methods
2024
+ index(<<~RUBY)
2025
+ class Foo
2026
+ def Qux
2027
+ end
2028
+ end
2029
+ RUBY
2030
+
2031
+ candidates = @index.constant_completion_candidates("Q", [])
2032
+ refute_includes(candidates.flat_map { |entries| entries.map(&:name) }, "Qux")
2033
+
2034
+ candidates = @index.constant_completion_candidates("Qux", [])
2035
+ assert_equal(0, candidates.length)
1956
2036
  end
1957
2037
 
1958
2038
  def test_constant_completion_candidates_for_empty_name
@@ -1967,7 +2047,7 @@ module RubyIndexer
1967
2047
  RUBY
1968
2048
 
1969
2049
  result = @index.constant_completion_candidates("Baz::", [])
1970
- assert_includes(result.map { |entries| entries.first.name }, "Foo::Bar")
2050
+ assert_includes(result.map { |entries| entries.first&.name }, "Foo::Bar")
1971
2051
  end
1972
2052
 
1973
2053
  def test_follow_alias_namespace
@@ -2025,7 +2105,7 @@ module RubyIndexer
2025
2105
  end
2026
2106
  RUBY
2027
2107
 
2028
- entry = @index.resolve("Namespace::Foo::CONST", ["First", "Namespace", "Foo", "InnerNamespace"])&.first
2108
+ entry = @index.resolve("Namespace::Foo::CONST", ["First", "Namespace", "Foo", "InnerNamespace"])&.first #: as !nil
2029
2109
  assert_equal("Parent::CONST", entry.name)
2030
2110
  assert_instance_of(Entry::Constant, entry)
2031
2111
  end
@@ -2093,7 +2173,7 @@ module RubyIndexer
2093
2173
  end
2094
2174
  RUBY
2095
2175
 
2096
- entry = @index["Foo"]&.first
2176
+ entry = @index["Foo"]&.first #: as !nil
2097
2177
  refute_nil(entry, "Expected indexer to be able to handle unsaved URIs")
2098
2178
  assert_equal("untitled:Untitled-1", entry.uri.to_s)
2099
2179
  assert_equal("Untitled-1", entry.file_name)
@@ -2105,7 +2185,7 @@ module RubyIndexer
2105
2185
  end
2106
2186
  RUBY
2107
2187
 
2108
- entry = @index["Foo"]&.first
2188
+ entry = @index["Foo"]&.first #: as !nil
2109
2189
  refute_nil(entry, "Expected indexer to be able to handle unsaved URIs")
2110
2190
  assert_equal("I added this comment!", entry.comments)
2111
2191
  end
@@ -2124,13 +2204,13 @@ module RubyIndexer
2124
2204
  end
2125
2205
  RUBY
2126
2206
 
2127
- abc, adf = @index.instance_variable_completion_candidates("@", "Child::<Class:Child>")
2207
+ adf, abc = @index.instance_variable_completion_candidates("@", "Child::<Class:Child>")
2128
2208
 
2129
2209
  refute_nil(abc)
2130
2210
  refute_nil(adf)
2131
2211
 
2132
- assert_equal("@@abc", abc.name)
2133
- assert_equal("@@adf", adf.name)
2212
+ assert_equal("@@abc", abc&.name)
2213
+ assert_equal("@@adf", adf&.name)
2134
2214
  end
2135
2215
 
2136
2216
  def test_class_variable_completion_from_singleton_context
@@ -2156,7 +2236,7 @@ module RubyIndexer
2156
2236
  end
2157
2237
  RUBY
2158
2238
 
2159
- candidates = @index.resolve_class_variable("@@hello", "Foo::<Class:Foo>")
2239
+ candidates = @index.resolve_class_variable("@@hello", "Foo::<Class:Foo>") #: as !nil
2160
2240
  refute_empty(candidates)
2161
2241
 
2162
2242
  assert_equal("@@hello", candidates.first&.name)
@@ -2181,6 +2261,13 @@ module RubyIndexer
2181
2261
 
2182
2262
  node = Prism.parse("class Foo; end").value.statements.body.first.constant_path
2183
2263
  assert_equal("Foo", Index.constant_name(node))
2264
+
2265
+ node = Prism.parse(<<~RUBY).value.statements.body.first.constant_path
2266
+ class class Foo
2267
+ end
2268
+ end
2269
+ RUBY
2270
+ assert_nil(Index.constant_name(node))
2184
2271
  end
2185
2272
  end
2186
2273
  end