ruby-lsp 0.23.11 → 0.26.1

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 (119) 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 +45 -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 +140 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +166 -281
  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 +25 -57
  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 +65 -40
  23. data/lib/ruby_indexer/test/configuration_test.rb +49 -9
  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 +185 -135
  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 +70 -75
  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 +59 -54
  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 +73 -57
  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 +44 -58
  44. data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
  45. data/lib/ruby_lsp/listeners/document_link.rb +50 -70
  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 +107 -115
  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 +214 -0
  53. data/lib/ruby_lsp/listeners/test_discovery.rb +92 -0
  54. data/lib/ruby_lsp/listeners/test_style.rb +205 -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 +65 -61
  58. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  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 +6 -6
  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 +85 -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 +16 -58
  86. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  87. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  88. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  89. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  90. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  91. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  92. data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
  93. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  94. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  95. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  96. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  97. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  98. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  99. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  100. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  101. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  102. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  103. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  104. data/lib/ruby_lsp/ruby_document.rb +32 -98
  105. data/lib/ruby_lsp/scope.rb +7 -11
  106. data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
  107. data/lib/ruby_lsp/server.rb +303 -196
  108. data/lib/ruby_lsp/setup_bundler.rb +121 -82
  109. data/lib/ruby_lsp/static_docs.rb +12 -7
  110. data/lib/ruby_lsp/store.rb +21 -49
  111. data/lib/ruby_lsp/test_helper.rb +3 -16
  112. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
  113. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  114. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  115. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  116. data/lib/ruby_lsp/utils.rb +138 -93
  117. data/static_docs/break.md +103 -0
  118. metadata +14 -20
  119. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -3,48 +3,34 @@
3
3
 
4
4
  module RubyIndexer
5
5
  class DeclarationListener
6
- extend T::Sig
6
+ OBJECT_NESTING = ["Object"].freeze #: Array[String]
7
+ BASIC_OBJECT_NESTING = ["BasicObject"].freeze #: Array[String]
7
8
 
8
- OBJECT_NESTING = T.let(["Object"].freeze, T::Array[String])
9
- BASIC_OBJECT_NESTING = T.let(["BasicObject"].freeze, T::Array[String])
10
-
11
- sig { returns(T::Array[String]) }
9
+ #: Array[String]
12
10
  attr_reader :indexing_errors
13
11
 
14
- sig do
15
- params(
16
- index: Index,
17
- dispatcher: Prism::Dispatcher,
18
- parse_result: Prism::ParseResult,
19
- uri: URI::Generic,
20
- collect_comments: T::Boolean,
21
- ).void
22
- end
12
+ #: (Index index, Prism::Dispatcher dispatcher, Prism::ParseLexResult | Prism::ParseResult parse_result, URI::Generic uri, ?collect_comments: bool) -> void
23
13
  def initialize(index, dispatcher, parse_result, uri, collect_comments: false)
24
14
  @index = index
25
15
  @uri = uri
26
- @enhancements = T.let(Enhancement.all(self), T::Array[Enhancement])
27
- @visibility_stack = T.let([VisibilityScope.public_scope], T::Array[VisibilityScope])
28
- @comments_by_line = T.let(
29
- parse_result.comments.to_h do |c|
30
- [c.location.start_line, c]
31
- end,
32
- T::Hash[Integer, Prism::Comment],
33
- )
34
- @inside_def = T.let(false, T::Boolean)
35
- @code_units_cache = T.let(
36
- parse_result.code_units_cache(@index.configuration.encoding),
37
- T.any(T.proc.params(arg0: Integer).returns(Integer), Prism::CodeUnitsCache),
38
- )
39
- @source_lines = T.let(parse_result.source.lines, T::Array[String])
16
+ @enhancements = Enhancement.all(self) #: Array[Enhancement]
17
+ @visibility_stack = [VisibilityScope.public_scope] #: Array[VisibilityScope]
18
+ @comments_by_line = parse_result.comments.to_h do |c|
19
+ [c.location.start_line, c]
20
+ end #: Hash[Integer, Prism::Comment]
21
+ @inside_def = false #: bool
22
+ @code_units_cache = parse_result
23
+ .code_units_cache(@index.configuration.encoding) #: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
24
+
25
+ @source_lines = parse_result.source.lines #: Array[String]
40
26
 
41
27
  # The nesting stack we're currently inside. Used to determine the fully qualified name of constants, but only
42
28
  # stored by unresolved aliases which need the original nesting to be lazily resolved
43
- @stack = T.let([], T::Array[String])
29
+ @stack = [] #: Array[String]
44
30
 
45
31
  # A stack of namespace entries that represent where we currently are. Used to properly assign methods to an owner
46
- @owner_stack = T.let([], T::Array[Entry::Namespace])
47
- @indexing_errors = T.let([], T::Array[String])
32
+ @owner_stack = [] #: Array[Entry::Namespace]
33
+ @indexing_errors = [] #: Array[String]
48
34
  @collect_comments = collect_comments
49
35
 
50
36
  dispatcher.register(
@@ -87,7 +73,7 @@ module RubyIndexer
87
73
  )
88
74
  end
89
75
 
90
- sig { params(node: Prism::ClassNode).void }
76
+ #: (Prism::ClassNode node) -> void
91
77
  def on_class_node_enter(node)
92
78
  constant_path = node.constant_path
93
79
  superclass = node.superclass
@@ -119,23 +105,23 @@ module RubyIndexer
119
105
  )
120
106
  end
121
107
 
122
- sig { params(node: Prism::ClassNode).void }
108
+ #: (Prism::ClassNode node) -> void
123
109
  def on_class_node_leave(node)
124
110
  pop_namespace_stack
125
111
  end
126
112
 
127
- sig { params(node: Prism::ModuleNode).void }
113
+ #: (Prism::ModuleNode node) -> void
128
114
  def on_module_node_enter(node)
129
115
  constant_path = node.constant_path
130
116
  add_module(constant_path.slice, node.location, constant_path.location, comments: collect_comments(node))
131
117
  end
132
118
 
133
- sig { params(node: Prism::ModuleNode).void }
119
+ #: (Prism::ModuleNode node) -> void
134
120
  def on_module_node_leave(node)
135
121
  pop_namespace_stack
136
122
  end
137
123
 
138
- sig { params(node: Prism::SingletonClassNode).void }
124
+ #: (Prism::SingletonClassNode node) -> void
139
125
  def on_singleton_class_node_enter(node)
140
126
  @visibility_stack.push(VisibilityScope.public_scope)
141
127
 
@@ -146,10 +132,10 @@ module RubyIndexer
146
132
  name = (expression.is_a?(Prism::SelfNode) ? "<Class:#{last_name_in_stack}>" : "<Class:#{expression.slice}>")
147
133
  real_nesting = Index.actual_nesting(@stack, name)
148
134
 
149
- existing_entries = T.cast(@index[real_nesting.join("::")], T.nilable(T::Array[Entry::SingletonClass]))
135
+ existing_entries = @index[real_nesting.join("::")] #: as Array[Entry::SingletonClass]?
150
136
 
151
137
  if existing_entries
152
- entry = T.must(existing_entries.first)
138
+ entry = existing_entries.first #: as !nil
153
139
  entry.update_singleton_information(
154
140
  Location.from_prism_location(node.location, @code_units_cache),
155
141
  Location.from_prism_location(expression.location, @code_units_cache),
@@ -172,12 +158,12 @@ module RubyIndexer
172
158
  end
173
159
  end
174
160
 
175
- sig { params(node: Prism::SingletonClassNode).void }
161
+ #: (Prism::SingletonClassNode node) -> void
176
162
  def on_singleton_class_node_leave(node)
177
163
  pop_namespace_stack
178
164
  end
179
165
 
180
- sig { params(node: Prism::MultiWriteNode).void }
166
+ #: (Prism::MultiWriteNode node) -> void
181
167
  def on_multi_write_node_enter(node)
182
168
  value = node.value
183
169
  values = value.is_a?(Prism::ArrayNode) && value.opening_loc ? value.elements : []
@@ -197,7 +183,7 @@ module RubyIndexer
197
183
  end
198
184
  end
199
185
 
200
- sig { params(node: Prism::ConstantPathWriteNode).void }
186
+ #: (Prism::ConstantPathWriteNode node) -> void
201
187
  def on_constant_path_write_node_enter(node)
202
188
  # ignore variable constants like `var::FOO` or `self.class::FOO`
203
189
  target = node.target
@@ -207,7 +193,7 @@ module RubyIndexer
207
193
  add_constant(node, name)
208
194
  end
209
195
 
210
- sig { params(node: Prism::ConstantPathOrWriteNode).void }
196
+ #: (Prism::ConstantPathOrWriteNode node) -> void
211
197
  def on_constant_path_or_write_node_enter(node)
212
198
  # ignore variable constants like `var::FOO` or `self.class::FOO`
213
199
  target = node.target
@@ -217,7 +203,7 @@ module RubyIndexer
217
203
  add_constant(node, name)
218
204
  end
219
205
 
220
- sig { params(node: Prism::ConstantPathOperatorWriteNode).void }
206
+ #: (Prism::ConstantPathOperatorWriteNode node) -> void
221
207
  def on_constant_path_operator_write_node_enter(node)
222
208
  # ignore variable constants like `var::FOO` or `self.class::FOO`
223
209
  target = node.target
@@ -227,7 +213,7 @@ module RubyIndexer
227
213
  add_constant(node, name)
228
214
  end
229
215
 
230
- sig { params(node: Prism::ConstantPathAndWriteNode).void }
216
+ #: (Prism::ConstantPathAndWriteNode node) -> void
231
217
  def on_constant_path_and_write_node_enter(node)
232
218
  # ignore variable constants like `var::FOO` or `self.class::FOO`
233
219
  target = node.target
@@ -237,31 +223,31 @@ module RubyIndexer
237
223
  add_constant(node, name)
238
224
  end
239
225
 
240
- sig { params(node: Prism::ConstantWriteNode).void }
226
+ #: (Prism::ConstantWriteNode node) -> void
241
227
  def on_constant_write_node_enter(node)
242
228
  name = fully_qualify_name(node.name.to_s)
243
229
  add_constant(node, name)
244
230
  end
245
231
 
246
- sig { params(node: Prism::ConstantOrWriteNode).void }
232
+ #: (Prism::ConstantOrWriteNode node) -> void
247
233
  def on_constant_or_write_node_enter(node)
248
234
  name = fully_qualify_name(node.name.to_s)
249
235
  add_constant(node, name)
250
236
  end
251
237
 
252
- sig { params(node: Prism::ConstantAndWriteNode).void }
238
+ #: (Prism::ConstantAndWriteNode node) -> void
253
239
  def on_constant_and_write_node_enter(node)
254
240
  name = fully_qualify_name(node.name.to_s)
255
241
  add_constant(node, name)
256
242
  end
257
243
 
258
- sig { params(node: Prism::ConstantOperatorWriteNode).void }
244
+ #: (Prism::ConstantOperatorWriteNode node) -> void
259
245
  def on_constant_operator_write_node_enter(node)
260
246
  name = fully_qualify_name(node.name.to_s)
261
247
  add_constant(node, name)
262
248
  end
263
249
 
264
- sig { params(node: Prism::CallNode).void }
250
+ #: (Prism::CallNode node) -> void
265
251
  def on_call_node_enter(node)
266
252
  message = node.name
267
253
 
@@ -274,16 +260,19 @@ module RubyIndexer
274
260
  handle_attribute(node, reader: false, writer: true)
275
261
  when :attr_accessor
276
262
  handle_attribute(node, reader: true, writer: true)
263
+ when :attr
264
+ has_writer = node.arguments&.arguments&.last&.is_a?(Prism::TrueNode) || false
265
+ handle_attribute(node, reader: true, writer: has_writer)
277
266
  when :alias_method
278
267
  handle_alias_method(node)
279
268
  when :include, :prepend, :extend
280
269
  handle_module_operation(node, message)
281
270
  when :public
282
- @visibility_stack.push(VisibilityScope.public_scope)
271
+ handle_visibility_change(node, :public)
283
272
  when :protected
284
- @visibility_stack.push(VisibilityScope.new(visibility: Entry::Visibility::PROTECTED))
273
+ handle_visibility_change(node, :protected)
285
274
  when :private
286
- @visibility_stack.push(VisibilityScope.new(visibility: Entry::Visibility::PRIVATE))
275
+ handle_visibility_change(node, :private)
287
276
  when :module_function
288
277
  handle_module_function(node)
289
278
  when :private_class_method
@@ -299,7 +288,7 @@ module RubyIndexer
299
288
  end
300
289
  end
301
290
 
302
- sig { params(node: Prism::CallNode).void }
291
+ #: (Prism::CallNode node) -> void
303
292
  def on_call_node_leave(node)
304
293
  message = node.name
305
294
  case message
@@ -320,7 +309,7 @@ module RubyIndexer
320
309
  end
321
310
  end
322
311
 
323
- sig { params(node: Prism::DefNode).void }
312
+ #: (Prism::DefNode node) -> void
324
313
  def on_def_node_enter(node)
325
314
  owner = @owner_stack.last
326
315
  return unless owner
@@ -357,7 +346,7 @@ module RubyIndexer
357
346
  name_location,
358
347
  comments,
359
348
  signatures,
360
- Entry::Visibility::PUBLIC,
349
+ :public,
361
350
  singleton,
362
351
  ))
363
352
  end
@@ -379,7 +368,7 @@ module RubyIndexer
379
368
  end
380
369
  end
381
370
 
382
- sig { params(node: Prism::DefNode).void }
371
+ #: (Prism::DefNode node) -> void
383
372
  def on_def_node_leave(node)
384
373
  @inside_def = false
385
374
 
@@ -388,57 +377,57 @@ module RubyIndexer
388
377
  end
389
378
  end
390
379
 
391
- sig { params(node: Prism::GlobalVariableAndWriteNode).void }
380
+ #: (Prism::GlobalVariableAndWriteNode node) -> void
392
381
  def on_global_variable_and_write_node_enter(node)
393
382
  handle_global_variable(node, node.name_loc)
394
383
  end
395
384
 
396
- sig { params(node: Prism::GlobalVariableOperatorWriteNode).void }
385
+ #: (Prism::GlobalVariableOperatorWriteNode node) -> void
397
386
  def on_global_variable_operator_write_node_enter(node)
398
387
  handle_global_variable(node, node.name_loc)
399
388
  end
400
389
 
401
- sig { params(node: Prism::GlobalVariableOrWriteNode).void }
390
+ #: (Prism::GlobalVariableOrWriteNode node) -> void
402
391
  def on_global_variable_or_write_node_enter(node)
403
392
  handle_global_variable(node, node.name_loc)
404
393
  end
405
394
 
406
- sig { params(node: Prism::GlobalVariableTargetNode).void }
395
+ #: (Prism::GlobalVariableTargetNode node) -> void
407
396
  def on_global_variable_target_node_enter(node)
408
397
  handle_global_variable(node, node.location)
409
398
  end
410
399
 
411
- sig { params(node: Prism::GlobalVariableWriteNode).void }
400
+ #: (Prism::GlobalVariableWriteNode node) -> void
412
401
  def on_global_variable_write_node_enter(node)
413
402
  handle_global_variable(node, node.name_loc)
414
403
  end
415
404
 
416
- sig { params(node: Prism::InstanceVariableWriteNode).void }
405
+ #: (Prism::InstanceVariableWriteNode node) -> void
417
406
  def on_instance_variable_write_node_enter(node)
418
407
  handle_instance_variable(node, node.name_loc)
419
408
  end
420
409
 
421
- sig { params(node: Prism::InstanceVariableAndWriteNode).void }
410
+ #: (Prism::InstanceVariableAndWriteNode node) -> void
422
411
  def on_instance_variable_and_write_node_enter(node)
423
412
  handle_instance_variable(node, node.name_loc)
424
413
  end
425
414
 
426
- sig { params(node: Prism::InstanceVariableOperatorWriteNode).void }
415
+ #: (Prism::InstanceVariableOperatorWriteNode node) -> void
427
416
  def on_instance_variable_operator_write_node_enter(node)
428
417
  handle_instance_variable(node, node.name_loc)
429
418
  end
430
419
 
431
- sig { params(node: Prism::InstanceVariableOrWriteNode).void }
420
+ #: (Prism::InstanceVariableOrWriteNode node) -> void
432
421
  def on_instance_variable_or_write_node_enter(node)
433
422
  handle_instance_variable(node, node.name_loc)
434
423
  end
435
424
 
436
- sig { params(node: Prism::InstanceVariableTargetNode).void }
425
+ #: (Prism::InstanceVariableTargetNode node) -> void
437
426
  def on_instance_variable_target_node_enter(node)
438
427
  handle_instance_variable(node, node.location)
439
428
  end
440
429
 
441
- sig { params(node: Prism::AliasMethodNode).void }
430
+ #: (Prism::AliasMethodNode node) -> void
442
431
  def on_alias_method_node_enter(node)
443
432
  method_name = node.new_name.slice
444
433
  comments = collect_comments(node)
@@ -454,41 +443,33 @@ module RubyIndexer
454
443
  )
455
444
  end
456
445
 
457
- sig { params(node: Prism::ClassVariableAndWriteNode).void }
446
+ #: (Prism::ClassVariableAndWriteNode node) -> void
458
447
  def on_class_variable_and_write_node_enter(node)
459
448
  handle_class_variable(node, node.name_loc)
460
449
  end
461
450
 
462
- sig { params(node: Prism::ClassVariableOperatorWriteNode).void }
451
+ #: (Prism::ClassVariableOperatorWriteNode node) -> void
463
452
  def on_class_variable_operator_write_node_enter(node)
464
453
  handle_class_variable(node, node.name_loc)
465
454
  end
466
455
 
467
- sig { params(node: Prism::ClassVariableOrWriteNode).void }
456
+ #: (Prism::ClassVariableOrWriteNode node) -> void
468
457
  def on_class_variable_or_write_node_enter(node)
469
458
  handle_class_variable(node, node.name_loc)
470
459
  end
471
460
 
472
- sig { params(node: Prism::ClassVariableTargetNode).void }
461
+ #: (Prism::ClassVariableTargetNode node) -> void
473
462
  def on_class_variable_target_node_enter(node)
474
463
  handle_class_variable(node, node.location)
475
464
  end
476
465
 
477
- sig { params(node: Prism::ClassVariableWriteNode).void }
466
+ #: (Prism::ClassVariableWriteNode node) -> void
478
467
  def on_class_variable_write_node_enter(node)
479
468
  handle_class_variable(node, node.name_loc)
480
469
  end
481
470
 
482
- sig do
483
- params(
484
- name: String,
485
- node_location: Prism::Location,
486
- signatures: T::Array[Entry::Signature],
487
- visibility: Entry::Visibility,
488
- comments: T.nilable(String),
489
- ).void
490
- end
491
- def add_method(name, node_location, signatures, visibility: Entry::Visibility::PUBLIC, comments: nil)
471
+ #: (String name, Prism::Location node_location, Array[Entry::Signature] signatures, ?visibility: Symbol, ?comments: String?) -> void
472
+ def add_method(name, node_location, signatures, visibility: :public, comments: nil)
492
473
  location = Location.from_prism_location(node_location, @code_units_cache)
493
474
 
494
475
  @index.add(Entry::Method.new(
@@ -503,14 +484,7 @@ module RubyIndexer
503
484
  ))
504
485
  end
505
486
 
506
- sig do
507
- params(
508
- name: String,
509
- full_location: Prism::Location,
510
- name_location: Prism::Location,
511
- comments: T.nilable(String),
512
- ).void
513
- end
487
+ #: (String name, Prism::Location full_location, Prism::Location name_location, ?comments: String?) -> void
514
488
  def add_module(name, full_location, name_location, comments: nil)
515
489
  location = Location.from_prism_location(full_location, @code_units_cache)
516
490
  name_loc = Location.from_prism_location(name_location, @code_units_cache)
@@ -526,15 +500,7 @@ module RubyIndexer
526
500
  advance_namespace_stack(name, entry)
527
501
  end
528
502
 
529
- sig do
530
- params(
531
- name_or_nesting: T.any(String, T::Array[String]),
532
- full_location: Prism::Location,
533
- name_location: Prism::Location,
534
- parent_class_name: T.nilable(String),
535
- comments: T.nilable(String),
536
- ).void
537
- end
503
+ #: ((String | Array[String]) name_or_nesting, Prism::Location full_location, Prism::Location name_location, ?parent_class_name: String?, ?comments: String?) -> void
538
504
  def add_class(name_or_nesting, full_location, name_location, parent_class_name: nil, comments: nil)
539
505
  nesting = name_or_nesting.is_a?(Array) ? name_or_nesting : Index.actual_nesting(@stack, name_or_nesting)
540
506
  entry = Entry::Class.new(
@@ -546,10 +512,13 @@ module RubyIndexer
546
512
  parent_class_name,
547
513
  )
548
514
 
549
- advance_namespace_stack(T.must(nesting.last), entry)
515
+ advance_namespace_stack(
516
+ nesting.last, #: as !nil
517
+ entry,
518
+ )
550
519
  end
551
520
 
552
- sig { params(block: T.proc.params(index: Index, base: Entry::Namespace).void).void }
521
+ #: { (Index index, Entry::Namespace base) -> void } -> void
553
522
  def register_included_hook(&block)
554
523
  owner = @owner_stack.last
555
524
  return unless owner
@@ -559,32 +528,21 @@ module RubyIndexer
559
528
  end
560
529
  end
561
530
 
562
- sig { void }
531
+ #: -> void
563
532
  def pop_namespace_stack
564
533
  @stack.pop
565
534
  @owner_stack.pop
566
535
  @visibility_stack.pop
567
536
  end
568
537
 
569
- sig { returns(T.nilable(Entry::Namespace)) }
538
+ #: -> Entry::Namespace?
570
539
  def current_owner
571
540
  @owner_stack.last
572
541
  end
573
542
 
574
543
  private
575
544
 
576
- sig do
577
- params(
578
- node: T.any(
579
- Prism::GlobalVariableAndWriteNode,
580
- Prism::GlobalVariableOperatorWriteNode,
581
- Prism::GlobalVariableOrWriteNode,
582
- Prism::GlobalVariableTargetNode,
583
- Prism::GlobalVariableWriteNode,
584
- ),
585
- loc: Prism::Location,
586
- ).void
587
- end
545
+ #: ((Prism::GlobalVariableAndWriteNode | Prism::GlobalVariableOperatorWriteNode | Prism::GlobalVariableOrWriteNode | Prism::GlobalVariableTargetNode | Prism::GlobalVariableWriteNode) node, Prism::Location loc) -> void
588
546
  def handle_global_variable(node, loc)
589
547
  name = node.name.to_s
590
548
  comments = collect_comments(node)
@@ -597,18 +555,7 @@ module RubyIndexer
597
555
  ))
598
556
  end
599
557
 
600
- sig do
601
- params(
602
- node: T.any(
603
- Prism::ClassVariableAndWriteNode,
604
- Prism::ClassVariableOperatorWriteNode,
605
- Prism::ClassVariableOrWriteNode,
606
- Prism::ClassVariableTargetNode,
607
- Prism::ClassVariableWriteNode,
608
- ),
609
- loc: Prism::Location,
610
- ).void
611
- end
558
+ #: ((Prism::ClassVariableAndWriteNode | Prism::ClassVariableOperatorWriteNode | Prism::ClassVariableOrWriteNode | Prism::ClassVariableTargetNode | Prism::ClassVariableWriteNode) node, Prism::Location loc) -> void
612
559
  def handle_class_variable(node, loc)
613
560
  name = node.name.to_s
614
561
  # Ignore incomplete class variable names, which aren't valid Ruby syntax.
@@ -633,18 +580,7 @@ module RubyIndexer
633
580
  ))
634
581
  end
635
582
 
636
- sig do
637
- params(
638
- node: T.any(
639
- Prism::InstanceVariableAndWriteNode,
640
- Prism::InstanceVariableOperatorWriteNode,
641
- Prism::InstanceVariableOrWriteNode,
642
- Prism::InstanceVariableTargetNode,
643
- Prism::InstanceVariableWriteNode,
644
- ),
645
- loc: Prism::Location,
646
- ).void
647
- end
583
+ #: ((Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode) node, Prism::Location loc) -> void
648
584
  def handle_instance_variable(node, loc)
649
585
  name = node.name.to_s
650
586
  return if name == "@"
@@ -666,7 +602,7 @@ module RubyIndexer
666
602
  ))
667
603
  end
668
604
 
669
- sig { params(node: Prism::CallNode).void }
605
+ #: (Prism::CallNode node) -> void
670
606
  def handle_private_constant(node)
671
607
  arguments = node.arguments&.arguments
672
608
  return unless arguments
@@ -688,10 +624,10 @@ module RubyIndexer
688
624
  # The private_constant method does not resolve the constant name. It always points to a constant that needs to
689
625
  # exist in the current namespace
690
626
  entries = @index[fully_qualify_name(name)]
691
- entries&.each { |entry| entry.visibility = Entry::Visibility::PRIVATE }
627
+ entries&.each { |entry| entry.visibility = :private }
692
628
  end
693
629
 
694
- sig { params(node: Prism::CallNode).void }
630
+ #: (Prism::CallNode node) -> void
695
631
  def handle_alias_method(node)
696
632
  arguments = node.arguments&.arguments
697
633
  return unless arguments
@@ -730,24 +666,7 @@ module RubyIndexer
730
666
  )
731
667
  end
732
668
 
733
- sig do
734
- params(
735
- node: T.any(
736
- Prism::ConstantWriteNode,
737
- Prism::ConstantOrWriteNode,
738
- Prism::ConstantAndWriteNode,
739
- Prism::ConstantOperatorWriteNode,
740
- Prism::ConstantPathWriteNode,
741
- Prism::ConstantPathOrWriteNode,
742
- Prism::ConstantPathOperatorWriteNode,
743
- Prism::ConstantPathAndWriteNode,
744
- Prism::ConstantTargetNode,
745
- Prism::ConstantPathTargetNode,
746
- ),
747
- name: String,
748
- value: T.nilable(Prism::Node),
749
- ).void
750
- end
669
+ #: ((Prism::ConstantWriteNode | Prism::ConstantOrWriteNode | Prism::ConstantAndWriteNode | Prism::ConstantOperatorWriteNode | Prism::ConstantPathWriteNode | Prism::ConstantPathOrWriteNode | Prism::ConstantPathOperatorWriteNode | Prism::ConstantPathAndWriteNode | Prism::ConstantTargetNode | Prism::ConstantPathTargetNode) node, String name, ?Prism::Node? value) -> void
751
670
  def add_constant(node, name, value = nil)
752
671
  value = node.value unless node.is_a?(Prism::ConstantTargetNode) || node.is_a?(Prism::ConstantPathTargetNode)
753
672
  comments = collect_comments(node)
@@ -798,7 +717,7 @@ module RubyIndexer
798
717
  )
799
718
  end
800
719
 
801
- sig { params(node: Prism::Node).returns(T.nilable(String)) }
720
+ #: (Prism::Node node) -> String?
802
721
  def collect_comments(node)
803
722
  return unless @collect_comments
804
723
 
@@ -810,6 +729,9 @@ module RubyIndexer
810
729
  comment = @comments_by_line[line]
811
730
  break unless comment
812
731
 
732
+ # a trailing comment from a previous line is not a comment for this node
733
+ break if comment.trailing?
734
+
813
735
  comment_content = comment.location.slice
814
736
 
815
737
  # invalid encodings would raise an "invalid byte sequence" exception
@@ -826,12 +748,12 @@ module RubyIndexer
826
748
  comments
827
749
  end
828
750
 
829
- sig { params(line: Integer).returns(T::Boolean) }
751
+ #: (Integer line) -> bool
830
752
  def comment_exists_at?(line)
831
753
  @comments_by_line.key?(line) || !@source_lines[line - 1].to_s.strip.empty?
832
754
  end
833
755
 
834
- sig { params(name: String).returns(String) }
756
+ #: (String name) -> String
835
757
  def fully_qualify_name(name)
836
758
  if @stack.empty? || name.start_with?("::")
837
759
  name
@@ -840,7 +762,7 @@ module RubyIndexer
840
762
  end.delete_prefix("::")
841
763
  end
842
764
 
843
- sig { params(node: Prism::CallNode, reader: T::Boolean, writer: T::Boolean).void }
765
+ #: (Prism::CallNode node, reader: bool, writer: bool) -> void
844
766
  def handle_attribute(node, reader:, writer:)
845
767
  arguments = node.arguments&.arguments
846
768
  return unless arguments
@@ -885,7 +807,7 @@ module RubyIndexer
885
807
  end
886
808
  end
887
809
 
888
- sig { params(node: Prism::CallNode, operation: Symbol).void }
810
+ #: (Prism::CallNode node, Symbol operation) -> void
889
811
  def handle_module_operation(node, operation)
890
812
  return if @inside_def
891
813
 
@@ -919,7 +841,7 @@ module RubyIndexer
919
841
  end
920
842
  end
921
843
 
922
- sig { params(node: Prism::CallNode).void }
844
+ #: (Prism::CallNode node) -> void
923
845
  def handle_module_function(node)
924
846
  # Invoking `module_function` in a class raises
925
847
  owner = @owner_stack.last
@@ -952,7 +874,7 @@ module RubyIndexer
952
874
  entry_owner_name = entry.owner&.name
953
875
  next unless entry_owner_name
954
876
 
955
- entry.visibility = Entry::Visibility::PRIVATE
877
+ entry.visibility = :private
956
878
 
957
879
  singleton = @index.existing_or_new_singleton_class(entry_owner_name)
958
880
  location = Location.from_prism_location(argument.location, @code_units_cache)
@@ -963,14 +885,14 @@ module RubyIndexer
963
885
  location,
964
886
  collect_comments(node)&.concat(entry.comments),
965
887
  entry.signatures,
966
- Entry::Visibility::PUBLIC,
888
+ :public,
967
889
  singleton,
968
890
  ))
969
891
  end
970
892
  end
971
893
  end
972
894
 
973
- sig { params(node: Prism::CallNode).void }
895
+ #: (Prism::CallNode node) -> void
974
896
  def handle_private_class_method(node)
975
897
  arguments = node.arguments&.arguments
976
898
  return unless arguments
@@ -978,7 +900,7 @@ module RubyIndexer
978
900
  # If we're passing a method definition directly to `private_class_method`, push a new private scope. That will be
979
901
  # applied when the indexer finds the method definition and then popped on `call_node_leave`
980
902
  if arguments.first.is_a?(Prism::DefNode)
981
- @visibility_stack.push(VisibilityScope.new(visibility: Entry::Visibility::PRIVATE))
903
+ @visibility_stack.push(VisibilityScope.new(visibility: :private))
982
904
  return
983
905
  end
984
906
 
@@ -987,10 +909,9 @@ module RubyIndexer
987
909
 
988
910
  # private_class_method accepts strings, symbols or arrays of strings and symbols as arguments. Here we build a
989
911
  # single list of all of the method names that have to be made private
990
- arrays, others = T.cast(
991
- arguments.partition { |argument| argument.is_a?(Prism::ArrayNode) },
992
- [T::Array[Prism::ArrayNode], T::Array[Prism::Node]],
993
- )
912
+ arrays, others = arguments.partition do |argument|
913
+ argument.is_a?(Prism::ArrayNode)
914
+ end #: as [Array[Prism::ArrayNode], Array[Prism::Node]]
994
915
  arrays.each { |array| others.concat(array.elements) }
995
916
 
996
917
  names = others.filter_map do |argument|
@@ -1006,18 +927,16 @@ module RubyIndexer
1006
927
  entries = @index.resolve_method(name, @index.existing_or_new_singleton_class(owner_name).name)
1007
928
  next unless entries
1008
929
 
1009
- entries.each do |entry|
1010
- entry.visibility = Entry::Visibility::PRIVATE
1011
- end
930
+ entries.each { |entry| entry.visibility = :private }
1012
931
  end
1013
932
  end
1014
933
 
1015
- sig { returns(VisibilityScope) }
934
+ #: -> VisibilityScope
1016
935
  def current_visibility_scope
1017
- T.must(@visibility_stack.last)
936
+ @visibility_stack.last #: as !nil
1018
937
  end
1019
938
 
1020
- sig { params(parameters_node: T.nilable(Prism::ParametersNode)).returns(T::Array[Entry::Parameter]) }
939
+ #: (Prism::ParametersNode? parameters_node) -> Array[Entry::Parameter]
1021
940
  def list_params(parameters_node)
1022
941
  return [] unless parameters_node
1023
942
 
@@ -1079,7 +998,7 @@ module RubyIndexer
1079
998
  parameters
1080
999
  end
1081
1000
 
1082
- sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Symbol)) }
1001
+ #: (Prism::Node? node) -> Symbol?
1083
1002
  def parameter_name(node)
1084
1003
  case node
1085
1004
  when Prism::RequiredParameterNode, Prism::OptionalParameterNode,
@@ -1104,7 +1023,7 @@ module RubyIndexer
1104
1023
  end
1105
1024
  end
1106
1025
 
1107
- sig { params(short_name: String, entry: Entry::Namespace).void }
1026
+ #: (String short_name, Entry::Namespace entry) -> void
1108
1027
  def advance_namespace_stack(short_name, entry)
1109
1028
  @visibility_stack.push(VisibilityScope.public_scope)
1110
1029
  @owner_stack << entry
@@ -1114,12 +1033,50 @@ module RubyIndexer
1114
1033
 
1115
1034
  # Returns the last name in the stack not as we found it, but in terms of declared constants. For example, if the
1116
1035
  # last entry in the stack is a compact namespace like `Foo::Bar`, then the last name is `Bar`
1117
- sig { returns(T.nilable(String)) }
1036
+ #: -> String?
1118
1037
  def last_name_in_stack
1119
1038
  name = @stack.last
1120
1039
  return unless name
1121
1040
 
1122
1041
  name.split("::").last
1123
1042
  end
1043
+
1044
+ #: (Prism::CallNode, Symbol) -> void
1045
+ def handle_visibility_change(node, visibility)
1046
+ owner = @owner_stack.last
1047
+ return unless owner
1048
+
1049
+ owner_name = owner.name
1050
+ method_names = string_or_symbol_argument_values(node)
1051
+
1052
+ if method_names.empty?
1053
+ @visibility_stack.push(VisibilityScope.new(visibility: visibility))
1054
+ return
1055
+ end
1056
+
1057
+ method_names.each do |method_name|
1058
+ entries = @index.resolve_method(method_name, owner_name)
1059
+ next unless entries
1060
+
1061
+ entries.each do |entry|
1062
+ entry.visibility = visibility
1063
+ end
1064
+ end
1065
+ end
1066
+
1067
+ #: (Prism::CallNode) -> Array[String]
1068
+ def string_or_symbol_argument_values(node)
1069
+ arguments = node.arguments&.arguments
1070
+ return [] unless arguments
1071
+
1072
+ arguments.filter_map do |argument|
1073
+ case argument
1074
+ when Prism::StringNode
1075
+ argument.content
1076
+ when Prism::SymbolNode
1077
+ argument.value
1078
+ end
1079
+ end
1080
+ end
1124
1081
  end
1125
1082
  end