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
@@ -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),
@@ -157,6 +143,7 @@ module RubyIndexer
157
143
  )
158
144
  else
159
145
  entry = Entry::SingletonClass.new(
146
+ @index.configuration,
160
147
  real_nesting,
161
148
  @uri,
162
149
  Location.from_prism_location(node.location, @code_units_cache),
@@ -172,12 +159,12 @@ module RubyIndexer
172
159
  end
173
160
  end
174
161
 
175
- sig { params(node: Prism::SingletonClassNode).void }
162
+ #: (Prism::SingletonClassNode node) -> void
176
163
  def on_singleton_class_node_leave(node)
177
164
  pop_namespace_stack
178
165
  end
179
166
 
180
- sig { params(node: Prism::MultiWriteNode).void }
167
+ #: (Prism::MultiWriteNode node) -> void
181
168
  def on_multi_write_node_enter(node)
182
169
  value = node.value
183
170
  values = value.is_a?(Prism::ArrayNode) && value.opening_loc ? value.elements : []
@@ -197,7 +184,7 @@ module RubyIndexer
197
184
  end
198
185
  end
199
186
 
200
- sig { params(node: Prism::ConstantPathWriteNode).void }
187
+ #: (Prism::ConstantPathWriteNode node) -> void
201
188
  def on_constant_path_write_node_enter(node)
202
189
  # ignore variable constants like `var::FOO` or `self.class::FOO`
203
190
  target = node.target
@@ -207,7 +194,7 @@ module RubyIndexer
207
194
  add_constant(node, name)
208
195
  end
209
196
 
210
- sig { params(node: Prism::ConstantPathOrWriteNode).void }
197
+ #: (Prism::ConstantPathOrWriteNode node) -> void
211
198
  def on_constant_path_or_write_node_enter(node)
212
199
  # ignore variable constants like `var::FOO` or `self.class::FOO`
213
200
  target = node.target
@@ -217,7 +204,7 @@ module RubyIndexer
217
204
  add_constant(node, name)
218
205
  end
219
206
 
220
- sig { params(node: Prism::ConstantPathOperatorWriteNode).void }
207
+ #: (Prism::ConstantPathOperatorWriteNode node) -> void
221
208
  def on_constant_path_operator_write_node_enter(node)
222
209
  # ignore variable constants like `var::FOO` or `self.class::FOO`
223
210
  target = node.target
@@ -227,7 +214,7 @@ module RubyIndexer
227
214
  add_constant(node, name)
228
215
  end
229
216
 
230
- sig { params(node: Prism::ConstantPathAndWriteNode).void }
217
+ #: (Prism::ConstantPathAndWriteNode node) -> void
231
218
  def on_constant_path_and_write_node_enter(node)
232
219
  # ignore variable constants like `var::FOO` or `self.class::FOO`
233
220
  target = node.target
@@ -237,31 +224,31 @@ module RubyIndexer
237
224
  add_constant(node, name)
238
225
  end
239
226
 
240
- sig { params(node: Prism::ConstantWriteNode).void }
227
+ #: (Prism::ConstantWriteNode node) -> void
241
228
  def on_constant_write_node_enter(node)
242
229
  name = fully_qualify_name(node.name.to_s)
243
230
  add_constant(node, name)
244
231
  end
245
232
 
246
- sig { params(node: Prism::ConstantOrWriteNode).void }
233
+ #: (Prism::ConstantOrWriteNode node) -> void
247
234
  def on_constant_or_write_node_enter(node)
248
235
  name = fully_qualify_name(node.name.to_s)
249
236
  add_constant(node, name)
250
237
  end
251
238
 
252
- sig { params(node: Prism::ConstantAndWriteNode).void }
239
+ #: (Prism::ConstantAndWriteNode node) -> void
253
240
  def on_constant_and_write_node_enter(node)
254
241
  name = fully_qualify_name(node.name.to_s)
255
242
  add_constant(node, name)
256
243
  end
257
244
 
258
- sig { params(node: Prism::ConstantOperatorWriteNode).void }
245
+ #: (Prism::ConstantOperatorWriteNode node) -> void
259
246
  def on_constant_operator_write_node_enter(node)
260
247
  name = fully_qualify_name(node.name.to_s)
261
248
  add_constant(node, name)
262
249
  end
263
250
 
264
- sig { params(node: Prism::CallNode).void }
251
+ #: (Prism::CallNode node) -> void
265
252
  def on_call_node_enter(node)
266
253
  message = node.name
267
254
 
@@ -274,16 +261,19 @@ module RubyIndexer
274
261
  handle_attribute(node, reader: false, writer: true)
275
262
  when :attr_accessor
276
263
  handle_attribute(node, reader: true, writer: true)
264
+ when :attr
265
+ has_writer = node.arguments&.arguments&.last&.is_a?(Prism::TrueNode) || false
266
+ handle_attribute(node, reader: true, writer: has_writer)
277
267
  when :alias_method
278
268
  handle_alias_method(node)
279
269
  when :include, :prepend, :extend
280
270
  handle_module_operation(node, message)
281
271
  when :public
282
- @visibility_stack.push(VisibilityScope.public_scope)
272
+ handle_visibility_change(node, :public)
283
273
  when :protected
284
- @visibility_stack.push(VisibilityScope.new(visibility: Entry::Visibility::PROTECTED))
274
+ handle_visibility_change(node, :protected)
285
275
  when :private
286
- @visibility_stack.push(VisibilityScope.new(visibility: Entry::Visibility::PRIVATE))
276
+ handle_visibility_change(node, :private)
287
277
  when :module_function
288
278
  handle_module_function(node)
289
279
  when :private_class_method
@@ -299,7 +289,7 @@ module RubyIndexer
299
289
  end
300
290
  end
301
291
 
302
- sig { params(node: Prism::CallNode).void }
292
+ #: (Prism::CallNode node) -> void
303
293
  def on_call_node_leave(node)
304
294
  message = node.name
305
295
  case message
@@ -320,7 +310,7 @@ module RubyIndexer
320
310
  end
321
311
  end
322
312
 
323
- sig { params(node: Prism::DefNode).void }
313
+ #: (Prism::DefNode node) -> void
324
314
  def on_def_node_enter(node)
325
315
  owner = @owner_stack.last
326
316
  return unless owner
@@ -337,6 +327,7 @@ module RubyIndexer
337
327
  signatures = [Entry::Signature.new(list_params(node.parameters))]
338
328
 
339
329
  @index.add(Entry::Method.new(
330
+ @index.configuration,
340
331
  method_name,
341
332
  @uri,
342
333
  location,
@@ -351,13 +342,14 @@ module RubyIndexer
351
342
  singleton = @index.existing_or_new_singleton_class(owner.name)
352
343
 
353
344
  @index.add(Entry::Method.new(
345
+ @index.configuration,
354
346
  method_name,
355
347
  @uri,
356
348
  location,
357
349
  name_location,
358
350
  comments,
359
351
  signatures,
360
- Entry::Visibility::PUBLIC,
352
+ :public,
361
353
  singleton,
362
354
  ))
363
355
  end
@@ -365,6 +357,7 @@ module RubyIndexer
365
357
  singleton = @index.existing_or_new_singleton_class(owner.name)
366
358
 
367
359
  @index.add(Entry::Method.new(
360
+ @index.configuration,
368
361
  method_name,
369
362
  @uri,
370
363
  Location.from_prism_location(node.location, @code_units_cache),
@@ -379,7 +372,7 @@ module RubyIndexer
379
372
  end
380
373
  end
381
374
 
382
- sig { params(node: Prism::DefNode).void }
375
+ #: (Prism::DefNode node) -> void
383
376
  def on_def_node_leave(node)
384
377
  @inside_def = false
385
378
 
@@ -388,62 +381,63 @@ module RubyIndexer
388
381
  end
389
382
  end
390
383
 
391
- sig { params(node: Prism::GlobalVariableAndWriteNode).void }
384
+ #: (Prism::GlobalVariableAndWriteNode node) -> void
392
385
  def on_global_variable_and_write_node_enter(node)
393
386
  handle_global_variable(node, node.name_loc)
394
387
  end
395
388
 
396
- sig { params(node: Prism::GlobalVariableOperatorWriteNode).void }
389
+ #: (Prism::GlobalVariableOperatorWriteNode node) -> void
397
390
  def on_global_variable_operator_write_node_enter(node)
398
391
  handle_global_variable(node, node.name_loc)
399
392
  end
400
393
 
401
- sig { params(node: Prism::GlobalVariableOrWriteNode).void }
394
+ #: (Prism::GlobalVariableOrWriteNode node) -> void
402
395
  def on_global_variable_or_write_node_enter(node)
403
396
  handle_global_variable(node, node.name_loc)
404
397
  end
405
398
 
406
- sig { params(node: Prism::GlobalVariableTargetNode).void }
399
+ #: (Prism::GlobalVariableTargetNode node) -> void
407
400
  def on_global_variable_target_node_enter(node)
408
401
  handle_global_variable(node, node.location)
409
402
  end
410
403
 
411
- sig { params(node: Prism::GlobalVariableWriteNode).void }
404
+ #: (Prism::GlobalVariableWriteNode node) -> void
412
405
  def on_global_variable_write_node_enter(node)
413
406
  handle_global_variable(node, node.name_loc)
414
407
  end
415
408
 
416
- sig { params(node: Prism::InstanceVariableWriteNode).void }
409
+ #: (Prism::InstanceVariableWriteNode node) -> void
417
410
  def on_instance_variable_write_node_enter(node)
418
411
  handle_instance_variable(node, node.name_loc)
419
412
  end
420
413
 
421
- sig { params(node: Prism::InstanceVariableAndWriteNode).void }
414
+ #: (Prism::InstanceVariableAndWriteNode node) -> void
422
415
  def on_instance_variable_and_write_node_enter(node)
423
416
  handle_instance_variable(node, node.name_loc)
424
417
  end
425
418
 
426
- sig { params(node: Prism::InstanceVariableOperatorWriteNode).void }
419
+ #: (Prism::InstanceVariableOperatorWriteNode node) -> void
427
420
  def on_instance_variable_operator_write_node_enter(node)
428
421
  handle_instance_variable(node, node.name_loc)
429
422
  end
430
423
 
431
- sig { params(node: Prism::InstanceVariableOrWriteNode).void }
424
+ #: (Prism::InstanceVariableOrWriteNode node) -> void
432
425
  def on_instance_variable_or_write_node_enter(node)
433
426
  handle_instance_variable(node, node.name_loc)
434
427
  end
435
428
 
436
- sig { params(node: Prism::InstanceVariableTargetNode).void }
429
+ #: (Prism::InstanceVariableTargetNode node) -> void
437
430
  def on_instance_variable_target_node_enter(node)
438
431
  handle_instance_variable(node, node.location)
439
432
  end
440
433
 
441
- sig { params(node: Prism::AliasMethodNode).void }
434
+ #: (Prism::AliasMethodNode node) -> void
442
435
  def on_alias_method_node_enter(node)
443
436
  method_name = node.new_name.slice
444
437
  comments = collect_comments(node)
445
438
  @index.add(
446
439
  Entry::UnresolvedMethodAlias.new(
440
+ @index.configuration,
447
441
  method_name,
448
442
  node.old_name.slice,
449
443
  @owner_stack.last,
@@ -454,44 +448,37 @@ module RubyIndexer
454
448
  )
455
449
  end
456
450
 
457
- sig { params(node: Prism::ClassVariableAndWriteNode).void }
451
+ #: (Prism::ClassVariableAndWriteNode node) -> void
458
452
  def on_class_variable_and_write_node_enter(node)
459
453
  handle_class_variable(node, node.name_loc)
460
454
  end
461
455
 
462
- sig { params(node: Prism::ClassVariableOperatorWriteNode).void }
456
+ #: (Prism::ClassVariableOperatorWriteNode node) -> void
463
457
  def on_class_variable_operator_write_node_enter(node)
464
458
  handle_class_variable(node, node.name_loc)
465
459
  end
466
460
 
467
- sig { params(node: Prism::ClassVariableOrWriteNode).void }
461
+ #: (Prism::ClassVariableOrWriteNode node) -> void
468
462
  def on_class_variable_or_write_node_enter(node)
469
463
  handle_class_variable(node, node.name_loc)
470
464
  end
471
465
 
472
- sig { params(node: Prism::ClassVariableTargetNode).void }
466
+ #: (Prism::ClassVariableTargetNode node) -> void
473
467
  def on_class_variable_target_node_enter(node)
474
468
  handle_class_variable(node, node.location)
475
469
  end
476
470
 
477
- sig { params(node: Prism::ClassVariableWriteNode).void }
471
+ #: (Prism::ClassVariableWriteNode node) -> void
478
472
  def on_class_variable_write_node_enter(node)
479
473
  handle_class_variable(node, node.name_loc)
480
474
  end
481
475
 
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)
476
+ #: (String name, Prism::Location node_location, Array[Entry::Signature] signatures, ?visibility: Symbol, ?comments: String?) -> void
477
+ def add_method(name, node_location, signatures, visibility: :public, comments: nil)
492
478
  location = Location.from_prism_location(node_location, @code_units_cache)
493
479
 
494
480
  @index.add(Entry::Method.new(
481
+ @index.configuration,
495
482
  name,
496
483
  @uri,
497
484
  location,
@@ -503,19 +490,13 @@ module RubyIndexer
503
490
  ))
504
491
  end
505
492
 
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
493
+ #: (String name, Prism::Location full_location, Prism::Location name_location, ?comments: String?) -> void
514
494
  def add_module(name, full_location, name_location, comments: nil)
515
495
  location = Location.from_prism_location(full_location, @code_units_cache)
516
496
  name_loc = Location.from_prism_location(name_location, @code_units_cache)
517
497
 
518
498
  entry = Entry::Module.new(
499
+ @index.configuration,
519
500
  Index.actual_nesting(@stack, name),
520
501
  @uri,
521
502
  location,
@@ -526,18 +507,11 @@ module RubyIndexer
526
507
  advance_namespace_stack(name, entry)
527
508
  end
528
509
 
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
510
+ #: ((String | Array[String]) name_or_nesting, Prism::Location full_location, Prism::Location name_location, ?parent_class_name: String?, ?comments: String?) -> void
538
511
  def add_class(name_or_nesting, full_location, name_location, parent_class_name: nil, comments: nil)
539
512
  nesting = name_or_nesting.is_a?(Array) ? name_or_nesting : Index.actual_nesting(@stack, name_or_nesting)
540
513
  entry = Entry::Class.new(
514
+ @index.configuration,
541
515
  nesting,
542
516
  @uri,
543
517
  Location.from_prism_location(full_location, @code_units_cache),
@@ -546,10 +520,13 @@ module RubyIndexer
546
520
  parent_class_name,
547
521
  )
548
522
 
549
- advance_namespace_stack(T.must(nesting.last), entry)
523
+ advance_namespace_stack(
524
+ nesting.last, #: as !nil
525
+ entry,
526
+ )
550
527
  end
551
528
 
552
- sig { params(block: T.proc.params(index: Index, base: Entry::Namespace).void).void }
529
+ #: { (Index index, Entry::Namespace base) -> void } -> void
553
530
  def register_included_hook(&block)
554
531
  owner = @owner_stack.last
555
532
  return unless owner
@@ -559,37 +536,27 @@ module RubyIndexer
559
536
  end
560
537
  end
561
538
 
562
- sig { void }
539
+ #: -> void
563
540
  def pop_namespace_stack
564
541
  @stack.pop
565
542
  @owner_stack.pop
566
543
  @visibility_stack.pop
567
544
  end
568
545
 
569
- sig { returns(T.nilable(Entry::Namespace)) }
546
+ #: -> Entry::Namespace?
570
547
  def current_owner
571
548
  @owner_stack.last
572
549
  end
573
550
 
574
551
  private
575
552
 
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
553
+ #: ((Prism::GlobalVariableAndWriteNode | Prism::GlobalVariableOperatorWriteNode | Prism::GlobalVariableOrWriteNode | Prism::GlobalVariableTargetNode | Prism::GlobalVariableWriteNode) node, Prism::Location loc) -> void
588
554
  def handle_global_variable(node, loc)
589
555
  name = node.name.to_s
590
556
  comments = collect_comments(node)
591
557
 
592
558
  @index.add(Entry::GlobalVariable.new(
559
+ @index.configuration,
593
560
  name,
594
561
  @uri,
595
562
  Location.from_prism_location(loc, @code_units_cache),
@@ -597,18 +564,7 @@ module RubyIndexer
597
564
  ))
598
565
  end
599
566
 
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
567
+ #: ((Prism::ClassVariableAndWriteNode | Prism::ClassVariableOperatorWriteNode | Prism::ClassVariableOrWriteNode | Prism::ClassVariableTargetNode | Prism::ClassVariableWriteNode) node, Prism::Location loc) -> void
612
568
  def handle_class_variable(node, loc)
613
569
  name = node.name.to_s
614
570
  # Ignore incomplete class variable names, which aren't valid Ruby syntax.
@@ -625,6 +581,7 @@ module RubyIndexer
625
581
  end
626
582
 
627
583
  @index.add(Entry::ClassVariable.new(
584
+ @index.configuration,
628
585
  name,
629
586
  @uri,
630
587
  Location.from_prism_location(loc, @code_units_cache),
@@ -633,18 +590,7 @@ module RubyIndexer
633
590
  ))
634
591
  end
635
592
 
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
593
+ #: ((Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode) node, Prism::Location loc) -> void
648
594
  def handle_instance_variable(node, loc)
649
595
  name = node.name.to_s
650
596
  return if name == "@"
@@ -658,6 +604,7 @@ module RubyIndexer
658
604
  end
659
605
 
660
606
  @index.add(Entry::InstanceVariable.new(
607
+ @index.configuration,
661
608
  name,
662
609
  @uri,
663
610
  Location.from_prism_location(loc, @code_units_cache),
@@ -666,7 +613,7 @@ module RubyIndexer
666
613
  ))
667
614
  end
668
615
 
669
- sig { params(node: Prism::CallNode).void }
616
+ #: (Prism::CallNode node) -> void
670
617
  def handle_private_constant(node)
671
618
  arguments = node.arguments&.arguments
672
619
  return unless arguments
@@ -688,10 +635,10 @@ module RubyIndexer
688
635
  # The private_constant method does not resolve the constant name. It always points to a constant that needs to
689
636
  # exist in the current namespace
690
637
  entries = @index[fully_qualify_name(name)]
691
- entries&.each { |entry| entry.visibility = Entry::Visibility::PRIVATE }
638
+ entries&.each { |entry| entry.visibility = :private }
692
639
  end
693
640
 
694
- sig { params(node: Prism::CallNode).void }
641
+ #: (Prism::CallNode node) -> void
695
642
  def handle_alias_method(node)
696
643
  arguments = node.arguments&.arguments
697
644
  return unless arguments
@@ -720,6 +667,7 @@ module RubyIndexer
720
667
  comments = collect_comments(node)
721
668
  @index.add(
722
669
  Entry::UnresolvedMethodAlias.new(
670
+ @index.configuration,
723
671
  new_name_value,
724
672
  old_name_value,
725
673
  @owner_stack.last,
@@ -730,24 +678,7 @@ module RubyIndexer
730
678
  )
731
679
  end
732
680
 
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
681
+ #: ((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
682
  def add_constant(node, name, value = nil)
752
683
  value = node.value unless node.is_a?(Prism::ConstantTargetNode) || node.is_a?(Prism::ConstantPathTargetNode)
753
684
  comments = collect_comments(node)
@@ -756,6 +687,7 @@ module RubyIndexer
756
687
  case value
757
688
  when Prism::ConstantReadNode, Prism::ConstantPathNode
758
689
  Entry::UnresolvedConstantAlias.new(
690
+ @index.configuration,
759
691
  value.slice,
760
692
  @stack.dup,
761
693
  name,
@@ -769,6 +701,7 @@ module RubyIndexer
769
701
  # If the right hand side is another constant assignment, we need to visit it because that constant has to be
770
702
  # indexed too
771
703
  Entry::UnresolvedConstantAlias.new(
704
+ @index.configuration,
772
705
  value.name.to_s,
773
706
  @stack.dup,
774
707
  name,
@@ -780,6 +713,7 @@ module RubyIndexer
780
713
  Prism::ConstantPathAndWriteNode
781
714
 
782
715
  Entry::UnresolvedConstantAlias.new(
716
+ @index.configuration,
783
717
  value.target.slice,
784
718
  @stack.dup,
785
719
  name,
@@ -789,6 +723,7 @@ module RubyIndexer
789
723
  )
790
724
  else
791
725
  Entry::Constant.new(
726
+ @index.configuration,
792
727
  name,
793
728
  @uri,
794
729
  Location.from_prism_location(node.location, @code_units_cache),
@@ -798,7 +733,7 @@ module RubyIndexer
798
733
  )
799
734
  end
800
735
 
801
- sig { params(node: Prism::Node).returns(T.nilable(String)) }
736
+ #: (Prism::Node node) -> String?
802
737
  def collect_comments(node)
803
738
  return unless @collect_comments
804
739
 
@@ -810,6 +745,9 @@ module RubyIndexer
810
745
  comment = @comments_by_line[line]
811
746
  break unless comment
812
747
 
748
+ # a trailing comment from a previous line is not a comment for this node
749
+ break if comment.trailing?
750
+
813
751
  comment_content = comment.location.slice
814
752
 
815
753
  # invalid encodings would raise an "invalid byte sequence" exception
@@ -826,12 +764,12 @@ module RubyIndexer
826
764
  comments
827
765
  end
828
766
 
829
- sig { params(line: Integer).returns(T::Boolean) }
767
+ #: (Integer line) -> bool
830
768
  def comment_exists_at?(line)
831
769
  @comments_by_line.key?(line) || !@source_lines[line - 1].to_s.strip.empty?
832
770
  end
833
771
 
834
- sig { params(name: String).returns(String) }
772
+ #: (String name) -> String
835
773
  def fully_qualify_name(name)
836
774
  if @stack.empty? || name.start_with?("::")
837
775
  name
@@ -840,7 +778,7 @@ module RubyIndexer
840
778
  end.delete_prefix("::")
841
779
  end
842
780
 
843
- sig { params(node: Prism::CallNode, reader: T::Boolean, writer: T::Boolean).void }
781
+ #: (Prism::CallNode node, reader: bool, writer: bool) -> void
844
782
  def handle_attribute(node, reader:, writer:)
845
783
  arguments = node.arguments&.arguments
846
784
  return unless arguments
@@ -863,6 +801,7 @@ module RubyIndexer
863
801
 
864
802
  if reader
865
803
  @index.add(Entry::Accessor.new(
804
+ @index.configuration,
866
805
  name,
867
806
  @uri,
868
807
  Location.from_prism_location(loc, @code_units_cache),
@@ -875,6 +814,7 @@ module RubyIndexer
875
814
  next unless writer
876
815
 
877
816
  @index.add(Entry::Accessor.new(
817
+ @index.configuration,
878
818
  "#{name}=",
879
819
  @uri,
880
820
  Location.from_prism_location(loc, @code_units_cache),
@@ -885,7 +825,7 @@ module RubyIndexer
885
825
  end
886
826
  end
887
827
 
888
- sig { params(node: Prism::CallNode, operation: Symbol).void }
828
+ #: (Prism::CallNode node, Symbol operation) -> void
889
829
  def handle_module_operation(node, operation)
890
830
  return if @inside_def
891
831
 
@@ -919,7 +859,7 @@ module RubyIndexer
919
859
  end
920
860
  end
921
861
 
922
- sig { params(node: Prism::CallNode).void }
862
+ #: (Prism::CallNode node) -> void
923
863
  def handle_module_function(node)
924
864
  # Invoking `module_function` in a class raises
925
865
  owner = @owner_stack.last
@@ -952,25 +892,26 @@ module RubyIndexer
952
892
  entry_owner_name = entry.owner&.name
953
893
  next unless entry_owner_name
954
894
 
955
- entry.visibility = Entry::Visibility::PRIVATE
895
+ entry.visibility = :private
956
896
 
957
897
  singleton = @index.existing_or_new_singleton_class(entry_owner_name)
958
898
  location = Location.from_prism_location(argument.location, @code_units_cache)
959
899
  @index.add(Entry::Method.new(
900
+ @index.configuration,
960
901
  method_name,
961
902
  @uri,
962
903
  location,
963
904
  location,
964
905
  collect_comments(node)&.concat(entry.comments),
965
906
  entry.signatures,
966
- Entry::Visibility::PUBLIC,
907
+ :public,
967
908
  singleton,
968
909
  ))
969
910
  end
970
911
  end
971
912
  end
972
913
 
973
- sig { params(node: Prism::CallNode).void }
914
+ #: (Prism::CallNode node) -> void
974
915
  def handle_private_class_method(node)
975
916
  arguments = node.arguments&.arguments
976
917
  return unless arguments
@@ -978,7 +919,7 @@ module RubyIndexer
978
919
  # If we're passing a method definition directly to `private_class_method`, push a new private scope. That will be
979
920
  # applied when the indexer finds the method definition and then popped on `call_node_leave`
980
921
  if arguments.first.is_a?(Prism::DefNode)
981
- @visibility_stack.push(VisibilityScope.new(visibility: Entry::Visibility::PRIVATE))
922
+ @visibility_stack.push(VisibilityScope.new(visibility: :private))
982
923
  return
983
924
  end
984
925
 
@@ -987,10 +928,9 @@ module RubyIndexer
987
928
 
988
929
  # private_class_method accepts strings, symbols or arrays of strings and symbols as arguments. Here we build a
989
930
  # 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
- )
931
+ arrays, others = arguments.partition do |argument|
932
+ argument.is_a?(Prism::ArrayNode)
933
+ end #: as [Array[Prism::ArrayNode], Array[Prism::Node]]
994
934
  arrays.each { |array| others.concat(array.elements) }
995
935
 
996
936
  names = others.filter_map do |argument|
@@ -1006,18 +946,16 @@ module RubyIndexer
1006
946
  entries = @index.resolve_method(name, @index.existing_or_new_singleton_class(owner_name).name)
1007
947
  next unless entries
1008
948
 
1009
- entries.each do |entry|
1010
- entry.visibility = Entry::Visibility::PRIVATE
1011
- end
949
+ entries.each { |entry| entry.visibility = :private }
1012
950
  end
1013
951
  end
1014
952
 
1015
- sig { returns(VisibilityScope) }
953
+ #: -> VisibilityScope
1016
954
  def current_visibility_scope
1017
- T.must(@visibility_stack.last)
955
+ @visibility_stack.last #: as !nil
1018
956
  end
1019
957
 
1020
- sig { params(parameters_node: T.nilable(Prism::ParametersNode)).returns(T::Array[Entry::Parameter]) }
958
+ #: (Prism::ParametersNode? parameters_node) -> Array[Entry::Parameter]
1021
959
  def list_params(parameters_node)
1022
960
  return [] unless parameters_node
1023
961
 
@@ -1079,7 +1017,7 @@ module RubyIndexer
1079
1017
  parameters
1080
1018
  end
1081
1019
 
1082
- sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Symbol)) }
1020
+ #: (Prism::Node? node) -> Symbol?
1083
1021
  def parameter_name(node)
1084
1022
  case node
1085
1023
  when Prism::RequiredParameterNode, Prism::OptionalParameterNode,
@@ -1104,7 +1042,7 @@ module RubyIndexer
1104
1042
  end
1105
1043
  end
1106
1044
 
1107
- sig { params(short_name: String, entry: Entry::Namespace).void }
1045
+ #: (String short_name, Entry::Namespace entry) -> void
1108
1046
  def advance_namespace_stack(short_name, entry)
1109
1047
  @visibility_stack.push(VisibilityScope.public_scope)
1110
1048
  @owner_stack << entry
@@ -1114,12 +1052,50 @@ module RubyIndexer
1114
1052
 
1115
1053
  # Returns the last name in the stack not as we found it, but in terms of declared constants. For example, if the
1116
1054
  # last entry in the stack is a compact namespace like `Foo::Bar`, then the last name is `Bar`
1117
- sig { returns(T.nilable(String)) }
1055
+ #: -> String?
1118
1056
  def last_name_in_stack
1119
1057
  name = @stack.last
1120
1058
  return unless name
1121
1059
 
1122
1060
  name.split("::").last
1123
1061
  end
1062
+
1063
+ #: (Prism::CallNode, Symbol) -> void
1064
+ def handle_visibility_change(node, visibility)
1065
+ owner = @owner_stack.last
1066
+ return unless owner
1067
+
1068
+ owner_name = owner.name
1069
+ method_names = string_or_symbol_argument_values(node)
1070
+
1071
+ if method_names.empty?
1072
+ @visibility_stack.push(VisibilityScope.new(visibility: visibility))
1073
+ return
1074
+ end
1075
+
1076
+ method_names.each do |method_name|
1077
+ entries = @index.resolve_method(method_name, owner_name)
1078
+ next unless entries
1079
+
1080
+ entries.each do |entry|
1081
+ entry.visibility = visibility
1082
+ end
1083
+ end
1084
+ end
1085
+
1086
+ #: (Prism::CallNode) -> Array[String]
1087
+ def string_or_symbol_argument_values(node)
1088
+ arguments = node.arguments&.arguments
1089
+ return [] unless arguments
1090
+
1091
+ arguments.filter_map do |argument|
1092
+ case argument
1093
+ when Prism::StringNode
1094
+ argument.content
1095
+ when Prism::SymbolNode
1096
+ argument.value
1097
+ end
1098
+ end
1099
+ end
1124
1100
  end
1125
1101
  end