ruby-lsp 0.23.11 → 0.26.6

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 (121) 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 +85 -118
  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_lsp/addon.rb +88 -86
  22. data/lib/ruby_lsp/base_server.rb +79 -65
  23. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  24. data/lib/ruby_lsp/document.rb +205 -104
  25. data/lib/ruby_lsp/erb_document.rb +45 -47
  26. data/lib/ruby_lsp/global_state.rb +134 -86
  27. data/lib/ruby_lsp/internal.rb +8 -3
  28. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  29. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  30. data/lib/ruby_lsp/listeners/definition.rb +78 -72
  31. data/lib/ruby_lsp/listeners/document_highlight.rb +149 -151
  32. data/lib/ruby_lsp/listeners/document_link.rb +93 -86
  33. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  34. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  35. data/lib/ruby_lsp/listeners/hover.rb +109 -117
  36. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  37. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  38. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  39. data/lib/ruby_lsp/listeners/spec_style.rb +231 -0
  40. data/lib/ruby_lsp/listeners/test_discovery.rb +107 -0
  41. data/lib/ruby_lsp/listeners/test_style.rb +207 -95
  42. data/lib/ruby_lsp/node_context.rb +12 -39
  43. data/lib/ruby_lsp/rbs_document.rb +10 -11
  44. data/lib/ruby_lsp/requests/code_action_resolve.rb +92 -66
  45. data/lib/ruby_lsp/requests/code_actions.rb +34 -31
  46. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  47. data/lib/ruby_lsp/requests/completion.rb +8 -21
  48. data/lib/ruby_lsp/requests/completion_resolve.rb +14 -12
  49. data/lib/ruby_lsp/requests/definition.rb +8 -20
  50. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  51. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  52. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  53. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  54. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  55. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  56. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  57. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +139 -0
  58. data/lib/ruby_lsp/requests/hover.rb +12 -25
  59. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  60. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  61. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  62. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  63. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  64. data/lib/ruby_lsp/requests/references.rb +17 -57
  65. data/lib/ruby_lsp/requests/rename.rb +27 -51
  66. data/lib/ruby_lsp/requests/request.rb +13 -25
  67. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  68. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  69. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  70. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  71. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  72. data/lib/ruby_lsp/requests/support/common.rb +23 -61
  73. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  74. data/lib/ruby_lsp/requests/support/package_url.rb +414 -0
  75. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  76. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  77. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  78. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  79. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  80. data/lib/ruby_lsp/requests/support/source_uri.rb +22 -33
  81. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  82. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  83. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  84. data/lib/ruby_lsp/requests/workspace_symbol.rb +24 -16
  85. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  86. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  87. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  88. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  89. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  90. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  91. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  92. data/lib/ruby_lsp/ruby_document.rb +32 -98
  93. data/lib/ruby_lsp/scope.rb +7 -11
  94. data/lib/ruby_lsp/scripts/compose_bundle.rb +7 -5
  95. data/lib/ruby_lsp/server.rb +305 -198
  96. data/lib/ruby_lsp/setup_bundler.rb +160 -97
  97. data/lib/ruby_lsp/static_docs.rb +12 -7
  98. data/lib/ruby_lsp/store.rb +21 -49
  99. data/lib/ruby_lsp/test_helper.rb +3 -16
  100. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +241 -0
  101. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  102. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  103. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  104. data/lib/ruby_lsp/utils.rb +138 -93
  105. data/static_docs/break.md +103 -0
  106. metadata +15 -34
  107. data/lib/ruby_indexer/test/class_variables_test.rb +0 -140
  108. data/lib/ruby_indexer/test/classes_and_modules_test.rb +0 -745
  109. data/lib/ruby_indexer/test/configuration_test.rb +0 -239
  110. data/lib/ruby_indexer/test/constant_test.rb +0 -402
  111. data/lib/ruby_indexer/test/enhancements_test.rb +0 -325
  112. data/lib/ruby_indexer/test/global_variable_test.rb +0 -49
  113. data/lib/ruby_indexer/test/index_test.rb +0 -2186
  114. data/lib/ruby_indexer/test/instance_variables_test.rb +0 -240
  115. data/lib/ruby_indexer/test/method_test.rb +0 -947
  116. data/lib/ruby_indexer/test/prefix_tree_test.rb +0 -150
  117. data/lib/ruby_indexer/test/rbs_indexer_test.rb +0 -386
  118. data/lib/ruby_indexer/test/reference_finder_test.rb +0 -330
  119. data/lib/ruby_indexer/test/test_case.rb +0 -51
  120. data/lib/ruby_indexer/test/uri_test.rb +0 -72
  121. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -1,745 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require_relative "test_case"
5
-
6
- module RubyIndexer
7
- class ClassesAndModulesTest < TestCase
8
- def test_empty_statements_class
9
- index(<<~RUBY)
10
- class Foo
11
- end
12
- RUBY
13
-
14
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:0-0:1-3")
15
- end
16
-
17
- def test_conditional_class
18
- index(<<~RUBY)
19
- class Foo
20
- end if condition
21
- RUBY
22
-
23
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:0-0:1-3")
24
- end
25
-
26
- def test_class_with_statements
27
- index(<<~RUBY)
28
- class Foo
29
- def something; end
30
- end
31
- RUBY
32
-
33
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:0-0:2-3")
34
- end
35
-
36
- def test_colon_colon_class
37
- index(<<~RUBY)
38
- class ::Foo
39
- end
40
- RUBY
41
-
42
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:0-0:1-3")
43
- end
44
-
45
- def test_colon_colon_class_inside_class
46
- index(<<~RUBY)
47
- class Bar
48
- class ::Foo
49
- end
50
- end
51
- RUBY
52
-
53
- assert_entry("Bar", Entry::Class, "/fake/path/foo.rb:0-0:3-3")
54
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:1-2:2-5")
55
- end
56
-
57
- def test_namespaced_class
58
- index(<<~RUBY)
59
- class Foo::Bar
60
- end
61
- RUBY
62
-
63
- assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:0-0:1-3")
64
- end
65
-
66
- def test_dynamically_namespaced_class
67
- index(<<~RUBY)
68
- class self::Bar
69
- end
70
- RUBY
71
-
72
- assert_entry("self::Bar", Entry::Class, "/fake/path/foo.rb:0-0:1-3")
73
- end
74
-
75
- def test_dynamically_namespaced_class_does_not_affect_other_classes
76
- index(<<~RUBY)
77
- class Foo
78
- class self::Bar
79
- end
80
-
81
- class Bar
82
- end
83
- end
84
- RUBY
85
-
86
- refute_entry("self::Bar")
87
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:0-0:6-3")
88
- assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:4-2:5-5")
89
- end
90
-
91
- def test_empty_statements_module
92
- index(<<~RUBY)
93
- module Foo
94
- end
95
- RUBY
96
-
97
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:1-3")
98
- end
99
-
100
- def test_conditional_module
101
- index(<<~RUBY)
102
- module Foo
103
- end if condition
104
- RUBY
105
-
106
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:1-3")
107
- end
108
-
109
- def test_module_with_statements
110
- index(<<~RUBY)
111
- module Foo
112
- def something; end
113
- end
114
- RUBY
115
-
116
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:2-3")
117
- end
118
-
119
- def test_colon_colon_module
120
- index(<<~RUBY)
121
- module ::Foo
122
- end
123
- RUBY
124
-
125
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:1-3")
126
- end
127
-
128
- def test_namespaced_module
129
- index(<<~RUBY)
130
- module Foo::Bar
131
- end
132
- RUBY
133
-
134
- assert_entry("Foo::Bar", Entry::Module, "/fake/path/foo.rb:0-0:1-3")
135
- end
136
-
137
- def test_dynamically_namespaced_module
138
- index(<<~RUBY)
139
- module self::Bar
140
- end
141
- RUBY
142
-
143
- assert_entry("self::Bar", Entry::Module, "/fake/path/foo.rb:0-0:1-3")
144
- end
145
-
146
- def test_dynamically_namespaced_module_does_not_affect_other_modules
147
- index(<<~RUBY)
148
- module Foo
149
- class self::Bar
150
- end
151
-
152
- module Bar
153
- end
154
- end
155
- RUBY
156
-
157
- assert_entry("Foo::self::Bar", Entry::Class, "/fake/path/foo.rb:1-2:2-5")
158
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:6-3")
159
- assert_entry("Foo::Bar", Entry::Module, "/fake/path/foo.rb:4-2:5-5")
160
- end
161
-
162
- def test_nested_modules_and_classes_with_multibyte_characters
163
- index(<<~RUBY)
164
- module A動物
165
- class Bねこ; end
166
- end
167
- RUBY
168
-
169
- assert_entry("A動物", Entry::Module, "/fake/path/foo.rb:0-0:2-3")
170
- assert_entry("A動物::Bねこ", Entry::Class, "/fake/path/foo.rb:1-2:1-16")
171
- end
172
-
173
- def test_nested_modules_and_classes
174
- index(<<~RUBY)
175
- module Foo
176
- class Bar
177
- end
178
-
179
- module Baz
180
- class Qux
181
- class Something
182
- end
183
- end
184
- end
185
- end
186
- RUBY
187
-
188
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:10-3")
189
- assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:1-2:2-5")
190
- assert_entry("Foo::Baz", Entry::Module, "/fake/path/foo.rb:4-2:9-5")
191
- assert_entry("Foo::Baz::Qux", Entry::Class, "/fake/path/foo.rb:5-4:8-7")
192
- assert_entry("Foo::Baz::Qux::Something", Entry::Class, "/fake/path/foo.rb:6-6:7-9")
193
- end
194
-
195
- def test_deleting_from_index_based_on_file_path
196
- index(<<~RUBY)
197
- class Foo
198
- end
199
- RUBY
200
-
201
- assert_entry("Foo", Entry::Class, "/fake/path/foo.rb:0-0:1-3")
202
-
203
- @index.delete(URI::Generic.from_path(path: "/fake/path/foo.rb"))
204
- refute_entry("Foo")
205
-
206
- assert_no_indexed_entries
207
- end
208
-
209
- def test_comments_can_be_attached_to_a_class
210
- index(<<~RUBY)
211
- # This is method comment
212
- def foo; end
213
- # This is a Foo comment
214
- # This is another Foo comment
215
- class Foo
216
- # This should not be attached
217
- end
218
-
219
- # Ignore me
220
-
221
- # This Bar comment has 1 line padding
222
-
223
- class Bar; end
224
- RUBY
225
-
226
- foo_entry = @index["Foo"].first
227
- assert_equal("This is a Foo comment\nThis is another Foo comment", foo_entry.comments)
228
-
229
- bar_entry = @index["Bar"].first
230
- assert_equal("This Bar comment has 1 line padding", bar_entry.comments)
231
- end
232
-
233
- def test_skips_comments_containing_invalid_encodings
234
- index(<<~RUBY)
235
- # comment \xBA
236
- class Foo
237
- end
238
- RUBY
239
- assert(@index["Foo"].first)
240
- end
241
-
242
- def test_comments_can_be_attached_to_a_namespaced_class
243
- index(<<~RUBY)
244
- # This is a Foo comment
245
- # This is another Foo comment
246
- class Foo
247
- # This is a Bar comment
248
- class Bar; end
249
- end
250
- RUBY
251
-
252
- foo_entry = @index["Foo"].first
253
- assert_equal("This is a Foo comment\nThis is another Foo comment", foo_entry.comments)
254
-
255
- bar_entry = @index["Foo::Bar"].first
256
- assert_equal("This is a Bar comment", bar_entry.comments)
257
- end
258
-
259
- def test_comments_can_be_attached_to_a_reopened_class
260
- index(<<~RUBY)
261
- # This is a Foo comment
262
- class Foo; end
263
-
264
- # This is another Foo comment
265
- class Foo; end
266
- RUBY
267
-
268
- first_foo_entry = @index["Foo"][0]
269
- assert_equal("This is a Foo comment", first_foo_entry.comments)
270
-
271
- second_foo_entry = @index["Foo"][1]
272
- assert_equal("This is another Foo comment", second_foo_entry.comments)
273
- end
274
-
275
- def test_comments_removes_the_leading_pound_and_space
276
- index(<<~RUBY)
277
- # This is a Foo comment
278
- class Foo; end
279
-
280
- #This is a Bar comment
281
- class Bar; end
282
- RUBY
283
-
284
- first_foo_entry = @index["Foo"][0]
285
- assert_equal("This is a Foo comment", first_foo_entry.comments)
286
-
287
- second_foo_entry = @index["Bar"][0]
288
- assert_equal("This is a Bar comment", second_foo_entry.comments)
289
- end
290
-
291
- def test_private_class_and_module_indexing
292
- index(<<~RUBY)
293
- class A
294
- class B; end
295
- private_constant(:B)
296
-
297
- module C; end
298
- private_constant("C")
299
-
300
- class D; end
301
- end
302
- RUBY
303
-
304
- b_const = @index["A::B"].first
305
- assert_predicate(b_const, :private?)
306
-
307
- c_const = @index["A::C"].first
308
- assert_predicate(c_const, :private?)
309
-
310
- d_const = @index["A::D"].first
311
- assert_equal(Entry::Visibility::PUBLIC, d_const.visibility)
312
- end
313
-
314
- def test_keeping_track_of_super_classes
315
- index(<<~RUBY)
316
- class Foo < Bar
317
- end
318
-
319
- class Baz
320
- end
321
-
322
- module Something
323
- class Baz
324
- end
325
-
326
- class Qux < ::Baz
327
- end
328
- end
329
-
330
- class FinalThing < Something::Baz
331
- end
332
- RUBY
333
-
334
- foo = T.must(@index["Foo"].first)
335
- assert_equal("Bar", foo.parent_class)
336
-
337
- baz = T.must(@index["Baz"].first)
338
- assert_equal("::Object", baz.parent_class)
339
-
340
- qux = T.must(@index["Something::Qux"].first)
341
- assert_equal("::Baz", qux.parent_class)
342
-
343
- final_thing = T.must(@index["FinalThing"].first)
344
- assert_equal("Something::Baz", final_thing.parent_class)
345
- end
346
-
347
- def test_keeping_track_of_included_modules
348
- index(<<~RUBY)
349
- class Foo
350
- # valid syntaxes that we can index
351
- include A1
352
- self.include A2
353
- include A3, A4
354
- self.include A5, A6
355
-
356
- # valid syntaxes that we cannot index because of their dynamic nature
357
- include some_variable_or_method_call
358
- self.include some_variable_or_method_call
359
-
360
- def something
361
- include A7 # We should not index this because of this dynamic nature
362
- end
363
-
364
- # Valid inner class syntax definition with its own modules included
365
- class Qux
366
- include Corge
367
- self.include Corge
368
- include Baz
369
-
370
- include some_variable_or_method_call
371
- end
372
- end
373
-
374
- class ConstantPathReferences
375
- include Foo::Bar
376
- self.include Foo::Bar2
377
-
378
- include dynamic::Bar
379
- include Foo::
380
- end
381
- RUBY
382
-
383
- foo = T.must(@index["Foo"][0])
384
- assert_equal(["A1", "A2", "A3", "A4", "A5", "A6"], foo.mixin_operation_module_names)
385
-
386
- qux = T.must(@index["Foo::Qux"][0])
387
- assert_equal(["Corge", "Corge", "Baz"], qux.mixin_operation_module_names)
388
-
389
- constant_path_references = T.must(@index["ConstantPathReferences"][0])
390
- assert_equal(["Foo::Bar", "Foo::Bar2"], constant_path_references.mixin_operation_module_names)
391
- end
392
-
393
- def test_keeping_track_of_prepended_modules
394
- index(<<~RUBY)
395
- class Foo
396
- # valid syntaxes that we can index
397
- prepend A1
398
- self.prepend A2
399
- prepend A3, A4
400
- self.prepend A5, A6
401
-
402
- # valid syntaxes that we cannot index because of their dynamic nature
403
- prepend some_variable_or_method_call
404
- self.prepend some_variable_or_method_call
405
-
406
- def something
407
- prepend A7 # We should not index this because of this dynamic nature
408
- end
409
-
410
- # Valid inner class syntax definition with its own modules prepended
411
- class Qux
412
- prepend Corge
413
- self.prepend Corge
414
- prepend Baz
415
-
416
- prepend some_variable_or_method_call
417
- end
418
- end
419
-
420
- class ConstantPathReferences
421
- prepend Foo::Bar
422
- self.prepend Foo::Bar2
423
-
424
- prepend dynamic::Bar
425
- prepend Foo::
426
- end
427
- RUBY
428
-
429
- foo = T.must(@index["Foo"][0])
430
- assert_equal(["A1", "A2", "A3", "A4", "A5", "A6"], foo.mixin_operation_module_names)
431
-
432
- qux = T.must(@index["Foo::Qux"][0])
433
- assert_equal(["Corge", "Corge", "Baz"], qux.mixin_operation_module_names)
434
-
435
- constant_path_references = T.must(@index["ConstantPathReferences"][0])
436
- assert_equal(["Foo::Bar", "Foo::Bar2"], constant_path_references.mixin_operation_module_names)
437
- end
438
-
439
- def test_keeping_track_of_extended_modules
440
- index(<<~RUBY)
441
- class Foo
442
- # valid syntaxes that we can index
443
- extend A1
444
- self.extend A2
445
- extend A3, A4
446
- self.extend A5, A6
447
-
448
- # valid syntaxes that we cannot index because of their dynamic nature
449
- extend some_variable_or_method_call
450
- self.extend some_variable_or_method_call
451
-
452
- def something
453
- extend A7 # We should not index this because of this dynamic nature
454
- end
455
-
456
- # Valid inner class syntax definition with its own modules prepended
457
- class Qux
458
- extend Corge
459
- self.extend Corge
460
- extend Baz
461
-
462
- extend some_variable_or_method_call
463
- end
464
- end
465
-
466
- class ConstantPathReferences
467
- extend Foo::Bar
468
- self.extend Foo::Bar2
469
-
470
- extend dynamic::Bar
471
- extend Foo::
472
- end
473
- RUBY
474
-
475
- foo = T.must(@index["Foo::<Class:Foo>"][0])
476
- assert_equal(["A1", "A2", "A3", "A4", "A5", "A6"], foo.mixin_operation_module_names)
477
-
478
- qux = T.must(@index["Foo::Qux::<Class:Qux>"][0])
479
- assert_equal(["Corge", "Corge", "Baz"], qux.mixin_operation_module_names)
480
-
481
- constant_path_references = T.must(@index["ConstantPathReferences::<Class:ConstantPathReferences>"][0])
482
- assert_equal(["Foo::Bar", "Foo::Bar2"], constant_path_references.mixin_operation_module_names)
483
- end
484
-
485
- def test_tracking_singleton_classes
486
- index(<<~RUBY)
487
- class Foo; end
488
- class Foo
489
- # Some extra comments
490
- class << self
491
- end
492
- end
493
- RUBY
494
-
495
- foo = T.must(@index["Foo::<Class:Foo>"].first)
496
- assert_equal(4, foo.location.start_line)
497
- assert_equal("Some extra comments", foo.comments)
498
- end
499
-
500
- def test_dynamic_singleton_class_blocks
501
- index(<<~RUBY)
502
- class Foo
503
- # Some extra comments
504
- class << bar
505
- end
506
- end
507
- RUBY
508
-
509
- singleton = T.must(@index["Foo::<Class:bar>"].first)
510
-
511
- # Even though this is not correct, we consider any dynamic singleton class block as a regular singleton class.
512
- # That pattern cannot be properly analyzed statically and assuming that it's always a regular singleton simplifies
513
- # the implementation considerably.
514
- assert_equal(3, singleton.location.start_line)
515
- assert_equal("Some extra comments", singleton.comments)
516
- end
517
-
518
- def test_namespaces_inside_singleton_blocks
519
- index(<<~RUBY)
520
- class Foo
521
- class << self
522
- class Bar
523
- end
524
- end
525
- end
526
- RUBY
527
-
528
- assert_entry("Foo::<Class:Foo>::Bar", Entry::Class, "/fake/path/foo.rb:2-4:3-7")
529
- end
530
-
531
- def test_name_location_points_to_constant_path_location
532
- index(<<~RUBY)
533
- class Foo
534
- def foo; end
535
- end
536
-
537
- module Bar
538
- def bar; end
539
- end
540
- RUBY
541
-
542
- foo = T.must(@index["Foo"].first)
543
- refute_equal(foo.location, foo.name_location)
544
-
545
- name_location = foo.name_location
546
- assert_equal(1, name_location.start_line)
547
- assert_equal(1, name_location.end_line)
548
- assert_equal(6, name_location.start_column)
549
- assert_equal(9, name_location.end_column)
550
-
551
- bar = T.must(@index["Bar"].first)
552
- refute_equal(bar.location, bar.name_location)
553
-
554
- name_location = bar.name_location
555
- assert_equal(5, name_location.start_line)
556
- assert_equal(5, name_location.end_line)
557
- assert_equal(7, name_location.start_column)
558
- assert_equal(10, name_location.end_column)
559
- end
560
-
561
- def test_indexing_namespaces_inside_top_level_references
562
- index(<<~RUBY)
563
- module ::Foo
564
- class Bar
565
- end
566
- end
567
- RUBY
568
-
569
- # We want to explicitly verify that we didn't introduce the leading `::` by accident, but `Index#[]` deletes the
570
- # prefix when we use `refute_entry`
571
- entries = @index.instance_variable_get(:@entries)
572
- refute(entries.key?("::Foo"))
573
- refute(entries.key?("::Foo::Bar"))
574
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:3-3")
575
- assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:1-2:2-5")
576
- end
577
-
578
- def test_indexing_singletons_inside_top_level_references
579
- index(<<~RUBY)
580
- module ::Foo
581
- class Bar
582
- class << self
583
- end
584
- end
585
- end
586
- RUBY
587
-
588
- # We want to explicitly verify that we didn't introduce the leading `::` by accident, but `Index#[]` deletes the
589
- # prefix when we use `refute_entry`
590
- entries = @index.instance_variable_get(:@entries)
591
- refute(entries.key?("::Foo"))
592
- refute(entries.key?("::Foo::Bar"))
593
- refute(entries.key?("::Foo::Bar::<Class:Bar>"))
594
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:0-0:5-3")
595
- assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:1-2:4-5")
596
- assert_entry("Foo::Bar::<Class:Bar>", Entry::SingletonClass, "/fake/path/foo.rb:2-4:3-7")
597
- end
598
-
599
- def test_indexing_namespaces_inside_nested_top_level_references
600
- index(<<~RUBY)
601
- class Baz
602
- module ::Foo
603
- class Bar
604
- end
605
-
606
- class ::Qux
607
- end
608
- end
609
- end
610
- RUBY
611
-
612
- refute_entry("Baz::Foo")
613
- refute_entry("Baz::Foo::Bar")
614
- assert_entry("Baz", Entry::Class, "/fake/path/foo.rb:0-0:8-3")
615
- assert_entry("Foo", Entry::Module, "/fake/path/foo.rb:1-2:7-5")
616
- assert_entry("Foo::Bar", Entry::Class, "/fake/path/foo.rb:2-4:3-7")
617
- assert_entry("Qux", Entry::Class, "/fake/path/foo.rb:5-4:6-7")
618
- end
619
-
620
- def test_lazy_comment_fetching_uses_correct_line_breaks_for_rendering
621
- uri = URI::Generic.from_path(
622
- load_path_entry: "#{Dir.pwd}/lib",
623
- path: "#{Dir.pwd}/lib/ruby_lsp/node_context.rb",
624
- )
625
-
626
- @index.index_file(uri, collect_comments: false)
627
-
628
- entry = @index["RubyLsp::NodeContext"].first
629
-
630
- assert_equal(<<~COMMENTS.chomp, entry.comments)
631
- This class allows listeners to access contextual information about a node in the AST, such as its parent,
632
- its namespace nesting, and the surrounding CallNode (e.g. a method call).
633
- COMMENTS
634
- end
635
-
636
- def test_lazy_comment_fetching_does_not_fail_if_file_gets_deleted
637
- uri = URI::Generic.from_path(
638
- load_path_entry: "#{Dir.pwd}/lib",
639
- path: "#{Dir.pwd}/lib/ruby_lsp/does_not_exist.rb",
640
- )
641
-
642
- @index.index_single(uri, <<~RUBY, collect_comments: false)
643
- class Foo
644
- end
645
- RUBY
646
-
647
- entry = @index["Foo"].first
648
- assert_empty(entry.comments)
649
- end
650
-
651
- def test_singleton_inside_compact_namespace
652
- index(<<~RUBY)
653
- module Foo::Bar
654
- class << self
655
- def baz; end
656
- end
657
- end
658
- RUBY
659
-
660
- # Verify we didn't index the incorrect name
661
- assert_nil(@index["Foo::Bar::<Class:Foo::Bar>"])
662
-
663
- # Verify we indexed the correct name
664
- assert_entry("Foo::Bar::<Class:Bar>", Entry::SingletonClass, "/fake/path/foo.rb:1-2:3-5")
665
-
666
- method = @index["baz"]&.first
667
- assert_equal("Foo::Bar::<Class:Bar>", method.owner.name)
668
- end
669
-
670
- def test_lazy_comments_with_spaces_are_properly_attributed
671
- path = File.join(Dir.pwd, "lib", "foo.rb")
672
- source = <<~RUBY
673
- require "whatever"
674
-
675
- # These comments belong to the declaration below
676
- # They have to be associated with it
677
-
678
- class Foo
679
- end
680
- RUBY
681
- File.write(path, source)
682
- @index.index_single(URI::Generic.from_path(path: path), source, collect_comments: false)
683
-
684
- entry = @index["Foo"].first
685
-
686
- begin
687
- assert_equal(<<~COMMENTS.chomp, entry.comments)
688
- These comments belong to the declaration below
689
- They have to be associated with it
690
- COMMENTS
691
- ensure
692
- FileUtils.rm(path)
693
- end
694
- end
695
-
696
- def test_lazy_comments_with_no_spaces_are_properly_attributed
697
- path = File.join(Dir.pwd, "lib", "foo.rb")
698
- source = <<~RUBY
699
- require "whatever"
700
-
701
- # These comments belong to the declaration below
702
- # They have to be associated with it
703
- class Foo
704
- end
705
- RUBY
706
- File.write(path, source)
707
- @index.index_single(URI::Generic.from_path(path: path), source, collect_comments: false)
708
-
709
- entry = @index["Foo"].first
710
-
711
- begin
712
- assert_equal(<<~COMMENTS.chomp, entry.comments)
713
- These comments belong to the declaration below
714
- They have to be associated with it
715
- COMMENTS
716
- ensure
717
- FileUtils.rm(path)
718
- end
719
- end
720
-
721
- def test_lazy_comments_with_two_extra_spaces_are_properly_ignored
722
- path = File.join(Dir.pwd, "lib", "foo.rb")
723
- source = <<~RUBY
724
- require "whatever"
725
-
726
- # These comments don't belong to the declaration below
727
- # They will not be associated with it
728
-
729
-
730
- class Foo
731
- end
732
- RUBY
733
- File.write(path, source)
734
- @index.index_single(URI::Generic.from_path(path: path), source, collect_comments: false)
735
-
736
- entry = @index["Foo"].first
737
-
738
- begin
739
- assert_empty(entry.comments)
740
- ensure
741
- FileUtils.rm(path)
742
- end
743
- end
744
- end
745
- end