ruby-lsp 0.23.11 → 0.23.13

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp-launcher +12 -11
  5. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
  6. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
  7. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +81 -115
  8. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
  9. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
  10. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +88 -200
  11. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +56 -192
  12. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  13. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
  14. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
  15. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
  16. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
  17. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
  18. data/lib/ruby_indexer/test/configuration_test.rb +42 -3
  19. data/lib/ruby_indexer/test/method_test.rb +28 -2
  20. data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
  21. data/lib/ruby_lsp/addon.rb +44 -71
  22. data/lib/ruby_lsp/base_server.rb +29 -32
  23. data/lib/ruby_lsp/client_capabilities.rb +10 -12
  24. data/lib/ruby_lsp/document.rb +34 -45
  25. data/lib/ruby_lsp/erb_document.rb +24 -36
  26. data/lib/ruby_lsp/global_state.rb +51 -56
  27. data/lib/ruby_lsp/internal.rb +2 -0
  28. data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
  29. data/lib/ruby_lsp/listeners/completion.rb +36 -55
  30. data/lib/ruby_lsp/listeners/definition.rb +37 -51
  31. data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
  32. data/lib/ruby_lsp/listeners/document_link.rb +43 -62
  33. data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
  34. data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
  35. data/lib/ruby_lsp/listeners/hover.rb +81 -100
  36. data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
  37. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
  38. data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
  39. data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
  40. data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
  41. data/lib/ruby_lsp/listeners/test_style.rb +160 -88
  42. data/lib/ruby_lsp/node_context.rb +12 -39
  43. data/lib/ruby_lsp/rbs_document.rb +8 -6
  44. data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
  45. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  46. data/lib/ruby_lsp/requests/code_lens.rb +6 -17
  47. data/lib/ruby_lsp/requests/completion.rb +7 -20
  48. data/lib/ruby_lsp/requests/completion_resolve.rb +5 -5
  49. data/lib/ruby_lsp/requests/definition.rb +8 -17
  50. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  51. data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
  52. data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
  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 +87 -0
  58. data/lib/ruby_lsp/requests/hover.rb +8 -18
  59. data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
  60. data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
  61. data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
  62. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
  63. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  64. data/lib/ruby_lsp/requests/references.rb +6 -36
  65. data/lib/ruby_lsp/requests/rename.rb +11 -37
  66. data/lib/ruby_lsp/requests/request.rb +7 -19
  67. data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
  68. data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
  69. data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
  70. data/lib/ruby_lsp/requests/signature_help.rb +8 -26
  71. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  72. data/lib/ruby_lsp/requests/support/common.rb +13 -50
  73. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  74. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
  75. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
  76. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  77. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  78. data/lib/ruby_lsp/requests/support/source_uri.rb +16 -30
  79. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  80. data/lib/ruby_lsp/requests/support/test_item.rb +10 -14
  81. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  82. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  83. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
  84. data/lib/ruby_lsp/response_builders/document_symbol.rb +10 -16
  85. data/lib/ruby_lsp/response_builders/hover.rb +10 -13
  86. data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
  87. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
  88. data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
  89. data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
  90. data/lib/ruby_lsp/ruby_document.rb +22 -60
  91. data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
  92. data/lib/ruby_lsp/scope.rb +7 -11
  93. data/lib/ruby_lsp/server.rb +133 -74
  94. data/lib/ruby_lsp/setup_bundler.rb +58 -57
  95. data/lib/ruby_lsp/static_docs.rb +4 -7
  96. data/lib/ruby_lsp/store.rb +21 -40
  97. data/lib/ruby_lsp/test_helper.rb +3 -12
  98. data/lib/ruby_lsp/test_reporter.rb +207 -0
  99. data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
  100. data/lib/ruby_lsp/type_inferrer.rb +9 -13
  101. data/lib/ruby_lsp/utils.rb +37 -81
  102. metadata +9 -3
@@ -3,8 +3,6 @@
3
3
 
4
4
  module RubyIndexer
5
5
  class Index
6
- extend T::Sig
7
-
8
6
  class UnresolvableAliasError < StandardError; end
9
7
  class NonExistingNamespaceError < StandardError; end
10
8
  class IndexNotEmptyError < StandardError; end
@@ -12,16 +10,17 @@ module RubyIndexer
12
10
  # The minimum Jaro-Winkler similarity score for an entry to be considered a match for a given fuzzy search query
13
11
  ENTRY_SIMILARITY_THRESHOLD = 0.7
14
12
 
15
- sig { returns(Configuration) }
13
+ #: Configuration
16
14
  attr_reader :configuration
17
15
 
18
- class << self
19
- extend T::Sig
16
+ #: bool
17
+ attr_reader :initial_indexing_completed
20
18
 
19
+ class << self
21
20
  # Returns the real nesting of a constant name taking into account top level
22
21
  # references that may be included anywhere in the name or nesting where that
23
22
  # constant was found
24
- sig { params(stack: T::Array[String], name: T.nilable(String)).returns(T::Array[String]) }
23
+ #: (Array[String] stack, String? name) -> Array[String]
25
24
  def actual_nesting(stack, name)
26
25
  nesting = name ? stack + [name] : stack
27
26
  corrected_nesting = []
@@ -37,17 +36,7 @@ module RubyIndexer
37
36
 
38
37
  # Returns the unresolved name for a constant reference including all parts of a constant path, or `nil` if the
39
38
  # constant contains dynamic or incomplete parts
40
- sig do
41
- params(
42
- node: T.any(
43
- Prism::ConstantPathNode,
44
- Prism::ConstantReadNode,
45
- Prism::ConstantPathTargetNode,
46
- Prism::CallNode,
47
- Prism::MissingNode,
48
- ),
49
- ).returns(T.nilable(String))
50
- end
39
+ #: ((Prism::ConstantPathNode | Prism::ConstantReadNode | Prism::ConstantPathTargetNode | Prism::CallNode | Prism::MissingNode) node) -> String?
51
40
  def constant_name(node)
52
41
  case node
53
42
  when Prism::CallNode, Prism::MissingNode
@@ -61,17 +50,17 @@ module RubyIndexer
61
50
  end
62
51
  end
63
52
 
64
- sig { void }
53
+ #: -> void
65
54
  def initialize
66
55
  # Holds all entries in the index using the following format:
67
56
  # {
68
57
  # "Foo" => [#<Entry::Class>, #<Entry::Class>],
69
58
  # "Foo::Bar" => [#<Entry::Class>],
70
59
  # }
71
- @entries = T.let({}, T::Hash[String, T::Array[Entry]])
60
+ @entries = {} #: Hash[String, Array[Entry]]
72
61
 
73
62
  # Holds all entries in the index using a prefix tree for searching based on prefixes to provide autocompletion
74
- @entries_tree = T.let(PrefixTree[T::Array[Entry]].new, PrefixTree[T::Array[Entry]])
63
+ @entries_tree = PrefixTree[T::Array[Entry]].new #: PrefixTree[Array[Entry]]
75
64
 
76
65
  # Holds references to where entries where discovered so that we can easily delete them
77
66
  # {
@@ -79,32 +68,29 @@ module RubyIndexer
79
68
  # "file:///my/project/bar.rb" => [#<Entry::Class>],
80
69
  # "untitled:Untitled-1" => [#<Entry::Class>],
81
70
  # }
82
- @uris_to_entries = T.let({}, T::Hash[String, T::Array[Entry]])
71
+ @uris_to_entries = {} #: Hash[String, Array[Entry]]
83
72
 
84
73
  # Holds all require paths for every indexed item so that we can provide autocomplete for requires
85
- @require_paths_tree = T.let(PrefixTree[URI::Generic].new, PrefixTree[URI::Generic])
74
+ @require_paths_tree = PrefixTree[URI::Generic].new #: PrefixTree[URI::Generic]
86
75
 
87
76
  # Holds the linearized ancestors list for every namespace
88
- @ancestors = T.let({}, T::Hash[String, T::Array[String]])
77
+ @ancestors = {} #: Hash[String, Array[String]]
89
78
 
90
79
  # Map of module name to included hooks that have to be executed when we include the given module
91
- @included_hooks = T.let(
92
- {},
93
- T::Hash[String, T::Array[T.proc.params(index: Index, base: Entry::Namespace).void]],
94
- )
80
+ @included_hooks = {} #: Hash[String, Array[^(Index index, Entry::Namespace base) -> void]]
95
81
 
96
- @configuration = T.let(RubyIndexer::Configuration.new, Configuration)
82
+ @configuration = RubyIndexer::Configuration.new #: Configuration
97
83
 
98
- @initial_indexing_completed = T.let(false, T::Boolean)
84
+ @initial_indexing_completed = false #: bool
99
85
  end
100
86
 
101
87
  # Register an included `hook` that will be executed when `module_name` is included into any namespace
102
- sig { params(module_name: String, hook: T.proc.params(index: Index, base: Entry::Namespace).void).void }
88
+ #: (String module_name) { (Index index, Entry::Namespace base) -> void } -> void
103
89
  def register_included_hook(module_name, &hook)
104
90
  (@included_hooks[module_name] ||= []) << hook
105
91
  end
106
92
 
107
- sig { params(uri: URI::Generic, skip_require_paths_tree: T::Boolean).void }
93
+ #: (URI::Generic uri, ?skip_require_paths_tree: bool) -> void
108
94
  def delete(uri, skip_require_paths_tree: false)
109
95
  key = uri.to_s
110
96
  # For each constant discovered in `path`, delete the associated entry from the index. If there are no entries
@@ -134,7 +120,7 @@ module RubyIndexer
134
120
  @require_paths_tree.delete(require_path) if require_path
135
121
  end
136
122
 
137
- sig { params(entry: Entry, skip_prefix_tree: T::Boolean).void }
123
+ #: (Entry entry, ?skip_prefix_tree: bool) -> void
138
124
  def add(entry, skip_prefix_tree: false)
139
125
  name = entry.name
140
126
 
@@ -143,28 +129,19 @@ module RubyIndexer
143
129
  @entries_tree.insert(name, T.must(@entries[name])) unless skip_prefix_tree
144
130
  end
145
131
 
146
- sig { params(fully_qualified_name: String).returns(T.nilable(T::Array[Entry])) }
132
+ #: (String fully_qualified_name) -> Array[Entry]?
147
133
  def [](fully_qualified_name)
148
134
  @entries[fully_qualified_name.delete_prefix("::")]
149
135
  end
150
136
 
151
- sig { params(query: String).returns(T::Array[URI::Generic]) }
137
+ #: (String query) -> Array[URI::Generic]
152
138
  def search_require_paths(query)
153
139
  @require_paths_tree.search(query)
154
140
  end
155
141
 
156
142
  # Searches for a constant based on an unqualified name and returns the first possible match regardless of whether
157
143
  # there are more possible matching entries
158
- sig do
159
- params(
160
- name: String,
161
- ).returns(T.nilable(T::Array[T.any(
162
- Entry::Namespace,
163
- Entry::ConstantAlias,
164
- Entry::UnresolvedConstantAlias,
165
- Entry::Constant,
166
- )]))
167
- end
144
+ #: (String name) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias | Entry::Constant)]?
168
145
  def first_unqualified_const(name)
169
146
  # Look for an exact match first
170
147
  _name, entries = @entries.find do |const_name, _entries|
@@ -202,7 +179,7 @@ module RubyIndexer
202
179
  # [#<Entry::Class name="Foo::Baz">],
203
180
  # ]
204
181
  # ```
205
- sig { params(query: String, nesting: T.nilable(T::Array[String])).returns(T::Array[T::Array[Entry]]) }
182
+ #: (String query, ?Array[String]? nesting) -> Array[Array[Entry]]
206
183
  def prefix_search(query, nesting = nil)
207
184
  unless nesting
208
185
  results = @entries_tree.search(query)
@@ -221,7 +198,7 @@ module RubyIndexer
221
198
  end
222
199
 
223
200
  # Fuzzy searches index entries based on Jaro-Winkler similarity. If no query is provided, all entries are returned
224
- sig { params(query: T.nilable(String)).returns(T::Array[Entry]) }
201
+ #: (String? query) -> Array[Entry]
225
202
  def fuzzy_search(query)
226
203
  unless query
227
204
  entries = @entries.filter_map do |_name, entries|
@@ -245,12 +222,7 @@ module RubyIndexer
245
222
  results.flat_map(&:first)
246
223
  end
247
224
 
248
- sig do
249
- params(
250
- name: T.nilable(String),
251
- receiver_name: String,
252
- ).returns(T::Array[T.any(Entry::Member, Entry::MethodAlias)])
253
- end
225
+ #: (String? name, String receiver_name) -> Array[(Entry::Member | Entry::MethodAlias)]
254
226
  def method_completion_candidates(name, receiver_name)
255
227
  ancestors = linearized_ancestors_of(receiver_name)
256
228
 
@@ -293,17 +265,7 @@ module RubyIndexer
293
265
  completion_items.values.map!(&:first)
294
266
  end
295
267
 
296
- sig do
297
- params(
298
- name: String,
299
- nesting: T::Array[String],
300
- ).returns(T::Array[T::Array[T.any(
301
- Entry::Constant,
302
- Entry::ConstantAlias,
303
- Entry::Namespace,
304
- Entry::UnresolvedConstantAlias,
305
- )]])
306
- end
268
+ #: (String name, Array[String] nesting) -> Array[Array[(Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias)]]
307
269
  def constant_completion_candidates(name, nesting)
308
270
  # If we have a top level reference, then we don't need to include completions inside the current nesting
309
271
  if name.start_with?("::")
@@ -358,17 +320,7 @@ module RubyIndexer
358
320
  # nesting: the nesting structure where the reference was found (e.g.: ["Foo", "Bar"])
359
321
  # seen_names: this parameter should not be used by consumers of the api. It is used to avoid infinite recursion when
360
322
  # resolving circular references
361
- sig do
362
- params(
363
- name: String,
364
- nesting: T::Array[String],
365
- seen_names: T::Array[String],
366
- ).returns(T.nilable(T::Array[T.any(
367
- Entry::Namespace,
368
- Entry::ConstantAlias,
369
- Entry::UnresolvedConstantAlias,
370
- )]))
371
- end
323
+ #: (String name, Array[String] nesting, ?Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
372
324
  def resolve(name, nesting, seen_names = [])
373
325
  # If we have a top level reference, then we just search for it straight away ignoring the nesting
374
326
  if name.start_with?("::")
@@ -404,12 +356,7 @@ module RubyIndexer
404
356
  # Index all files for the given URIs, which defaults to what is configured. A block can be used to track and control
405
357
  # indexing progress. That block is invoked with the current progress percentage and should return `true` to continue
406
358
  # indexing or `false` to stop indexing.
407
- sig do
408
- params(
409
- uris: T::Array[URI::Generic],
410
- block: T.nilable(T.proc.params(progress: Integer).returns(T::Boolean)),
411
- ).void
412
- end
359
+ #: (?uris: Array[URI::Generic]) ?{ (Integer progress) -> bool } -> void
413
360
  def index_all(uris: @configuration.indexable_uris, &block)
414
361
  # When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the
415
362
  # existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this
@@ -419,8 +366,6 @@ module RubyIndexer
419
366
  "The index is not empty. To prevent invalid entries, `index_all` can only be called once."
420
367
  end
421
368
 
422
- @initial_indexing_completed = true
423
-
424
369
  RBSIndexer.new(self).index_ruby_core
425
370
  # Calculate how many paths are worth 1% of progress
426
371
  progress_step = (uris.length / 100.0).ceil
@@ -433,9 +378,11 @@ module RubyIndexer
433
378
 
434
379
  index_file(uri, collect_comments: false)
435
380
  end
381
+
382
+ @initial_indexing_completed = true
436
383
  end
437
384
 
438
- sig { params(uri: URI::Generic, source: String, collect_comments: T::Boolean).void }
385
+ #: (URI::Generic uri, String source, ?collect_comments: bool) -> void
439
386
  def index_single(uri, source, collect_comments: true)
440
387
  dispatcher = Prism::Dispatcher.new
441
388
 
@@ -457,7 +404,7 @@ module RubyIndexer
457
404
  end
458
405
 
459
406
  # Indexes a File URI by reading the contents from disk
460
- sig { params(uri: URI::Generic, collect_comments: T::Boolean).void }
407
+ #: (URI::Generic uri, ?collect_comments: bool) -> void
461
408
  def index_file(uri, collect_comments: true)
462
409
  index_single(uri, File.read(T.must(uri.full_path)), collect_comments: collect_comments)
463
410
  rescue Errno::EISDIR, Errno::ENOENT
@@ -475,7 +422,7 @@ module RubyIndexer
475
422
  # If we find an alias, then we want to follow its target. In the same example, if `Foo::Bar` is an alias to
476
423
  # `Something::Else`, then we first discover `Something::Else::Baz`. But `Something::Else::Baz` might contain other
477
424
  # aliases, so we have to invoke `follow_aliased_namespace` again to check until we only return a real name
478
- sig { params(name: String, seen_names: T::Array[String]).returns(String) }
425
+ #: (String name, ?Array[String] seen_names) -> String
479
426
  def follow_aliased_namespace(name, seen_names = [])
480
427
  parts = name.split("::")
481
428
  real_parts = []
@@ -508,14 +455,7 @@ module RubyIndexer
508
455
  # Attempts to find methods for a resolved fully qualified receiver name. Do not provide the `seen_names` parameter
509
456
  # as it is used only internally to prevent infinite loops when resolving circular aliases
510
457
  # Returns `nil` if the method does not exist on that receiver
511
- sig do
512
- params(
513
- method_name: String,
514
- receiver_name: String,
515
- seen_names: T::Array[String],
516
- inherited_only: T::Boolean,
517
- ).returns(T.nilable(T::Array[T.any(Entry::Member, Entry::MethodAlias)]))
518
- end
458
+ #: (String method_name, String receiver_name, ?Array[String] seen_names, ?inherited_only: bool) -> Array[(Entry::Member | Entry::MethodAlias)]?
519
459
  def resolve_method(method_name, receiver_name, seen_names = [], inherited_only: false)
520
460
  method_entries = self[method_name]
521
461
  return unless method_entries
@@ -553,7 +493,7 @@ module RubyIndexer
553
493
  # module that prepends another module, then the prepend module appears before the included module.
554
494
  #
555
495
  # The order of ancestors is [linearized_prepends, self, linearized_includes, linearized_superclass]
556
- sig { params(fully_qualified_name: String).returns(T::Array[String]) }
496
+ #: (String fully_qualified_name) -> Array[String]
557
497
  def linearized_ancestors_of(fully_qualified_name)
558
498
  # If we already computed the ancestors for this namespace, return it straight away
559
499
  cached_ancestors = @ancestors[fully_qualified_name]
@@ -631,7 +571,7 @@ module RubyIndexer
631
571
 
632
572
  # Resolves an instance variable name for a given owner name. This method will linearize the ancestors of the owner
633
573
  # and find inherited instance variables as well
634
- sig { params(variable_name: String, owner_name: String).returns(T.nilable(T::Array[Entry::InstanceVariable])) }
574
+ #: (String variable_name, String owner_name) -> Array[Entry::InstanceVariable]?
635
575
  def resolve_instance_variable(variable_name, owner_name)
636
576
  entries = T.cast(self[variable_name], T.nilable(T::Array[Entry::InstanceVariable]))
637
577
  return unless entries
@@ -642,7 +582,7 @@ module RubyIndexer
642
582
  entries.select { |e| ancestors.include?(e.owner&.name) }
643
583
  end
644
584
 
645
- sig { params(variable_name: String, owner_name: String).returns(T.nilable(T::Array[Entry::ClassVariable])) }
585
+ #: (String variable_name, String owner_name) -> Array[Entry::ClassVariable]?
646
586
  def resolve_class_variable(variable_name, owner_name)
647
587
  entries = self[variable_name]&.grep(Entry::ClassVariable)
648
588
  return unless entries&.any?
@@ -655,9 +595,7 @@ module RubyIndexer
655
595
 
656
596
  # Returns a list of possible candidates for completion of instance variables for a given owner name. The name must
657
597
  # include the `@` prefix
658
- sig do
659
- params(name: String, owner_name: String).returns(T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
660
- end
598
+ #: (String name, String owner_name) -> Array[(Entry::InstanceVariable | Entry::ClassVariable)]
661
599
  def instance_variable_completion_candidates(name, owner_name)
662
600
  entries = T.cast(prefix_search(name).flatten, T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
663
601
  # Avoid wasting time linearizing ancestors if we didn't find anything
@@ -686,7 +624,7 @@ module RubyIndexer
686
624
  variables
687
625
  end
688
626
 
689
- sig { params(name: String, owner_name: String).returns(T::Array[Entry::ClassVariable]) }
627
+ #: (String name, String owner_name) -> Array[Entry::ClassVariable]
690
628
  def class_variable_completion_candidates(name, owner_name)
691
629
  entries = T.cast(prefix_search(name).flatten, T::Array[Entry::ClassVariable])
692
630
  # Avoid wasting time linearizing ancestors if we didn't find anything
@@ -702,9 +640,7 @@ module RubyIndexer
702
640
  # declarations removed and that the ancestor linearization cache is cleared if necessary. If a block is passed, the
703
641
  # consumer of this API has to handle deleting and inserting/updating entries in the index instead of passing the
704
642
  # document's source (used to handle unsaved changes to files)
705
- sig do
706
- params(uri: URI::Generic, source: T.nilable(String), block: T.nilable(T.proc.params(index: Index).void)).void
707
- end
643
+ #: (URI::Generic uri, ?String? source) ?{ (Index index) -> void } -> void
708
644
  def handle_change(uri, source = nil, &block)
709
645
  key = uri.to_s
710
646
  original_entries = @uris_to_entries[key]
@@ -736,27 +672,27 @@ module RubyIndexer
736
672
  @ancestors.clear if original_map.any? { |name, hash| updated_map[name] != hash }
737
673
  end
738
674
 
739
- sig { returns(T::Boolean) }
675
+ #: -> bool
740
676
  def empty?
741
677
  @entries.empty?
742
678
  end
743
679
 
744
- sig { returns(T::Array[String]) }
680
+ #: -> Array[String]
745
681
  def names
746
682
  @entries.keys
747
683
  end
748
684
 
749
- sig { params(name: String).returns(T::Boolean) }
685
+ #: (String name) -> bool
750
686
  def indexed?(name)
751
687
  @entries.key?(name)
752
688
  end
753
689
 
754
- sig { returns(Integer) }
690
+ #: -> Integer
755
691
  def length
756
692
  @entries.count
757
693
  end
758
694
 
759
- sig { params(name: String).returns(Entry::SingletonClass) }
695
+ #: (String name) -> Entry::SingletonClass
760
696
  def existing_or_new_singleton_class(name)
761
697
  *_namespace, unqualified_name = name.split("::")
762
698
  full_singleton_name = "#{name}::<Class:#{unqualified_name}>"
@@ -779,12 +715,7 @@ module RubyIndexer
779
715
  singleton
780
716
  end
781
717
 
782
- sig do
783
- type_parameters(:T).params(
784
- uri: String,
785
- type: T.nilable(T::Class[T.all(T.type_parameter(:T), Entry)]),
786
- ).returns(T.nilable(T.any(T::Array[Entry], T::Array[T.type_parameter(:T)])))
787
- end
718
+ #: [T] (String uri, ?Class[(T & Entry)]? type) -> (Array[Entry] | Array[T])?
788
719
  def entries_for(uri, type = nil)
789
720
  entries = @uris_to_entries[uri.to_s]
790
721
  return entries unless type
@@ -796,7 +727,7 @@ module RubyIndexer
796
727
 
797
728
  # Always returns the linearized ancestors for the attached class, regardless of whether `name` refers to a singleton
798
729
  # or attached namespace
799
- sig { params(name: String).returns(T::Array[String]) }
730
+ #: (String name) -> Array[String]
800
731
  def linearized_attached_ancestors(name)
801
732
  name_parts = name.split("::")
802
733
 
@@ -809,7 +740,7 @@ module RubyIndexer
809
740
  end
810
741
 
811
742
  # Runs the registered included hooks
812
- sig { params(fully_qualified_name: String, nesting: T::Array[String]).void }
743
+ #: (String fully_qualified_name, Array[String] nesting) -> void
813
744
  def run_included_hooks(fully_qualified_name, nesting)
814
745
  return if @included_hooks.empty?
815
746
 
@@ -838,13 +769,7 @@ module RubyIndexer
838
769
 
839
770
  # Linearize mixins for an array of namespace entries. This method will mutate the `ancestors` array with the
840
771
  # linearized ancestors of the mixins
841
- sig do
842
- params(
843
- ancestors: T::Array[String],
844
- namespace_entries: T::Array[Entry::Namespace],
845
- nesting: T::Array[String],
846
- ).void
847
- end
772
+ #: (Array[String] ancestors, Array[Entry::Namespace] namespace_entries, Array[String] nesting) -> void
848
773
  def linearize_mixins(ancestors, namespace_entries, nesting)
849
774
  mixin_operations = namespace_entries.flat_map(&:mixin_operations)
850
775
  main_namespace_index = 0
@@ -885,16 +810,7 @@ module RubyIndexer
885
810
 
886
811
  # Linearize the superclass of a given namespace (including modules with the implicit `Module` superclass). This
887
812
  # method will mutate the `ancestors` array with the linearized ancestors of the superclass
888
- sig do
889
- params(
890
- ancestors: T::Array[String],
891
- attached_class_name: String,
892
- fully_qualified_name: String,
893
- namespace_entries: T::Array[Entry::Namespace],
894
- nesting: T::Array[String],
895
- singleton_levels: Integer,
896
- ).void
897
- end
813
+ #: (Array[String] ancestors, String attached_class_name, String fully_qualified_name, Array[Entry::Namespace] namespace_entries, Array[String] nesting, Integer singleton_levels) -> void
898
814
  def linearize_superclass( # rubocop:disable Metrics/ParameterLists
899
815
  ancestors,
900
816
  attached_class_name,
@@ -962,12 +878,7 @@ module RubyIndexer
962
878
 
963
879
  # Attempts to resolve an UnresolvedAlias into a resolved Alias. If the unresolved alias is pointing to a constant
964
880
  # that doesn't exist, then we return the same UnresolvedAlias
965
- sig do
966
- params(
967
- entry: Entry::UnresolvedConstantAlias,
968
- seen_names: T::Array[String],
969
- ).returns(T.any(Entry::ConstantAlias, Entry::UnresolvedConstantAlias))
970
- end
881
+ #: (Entry::UnresolvedConstantAlias entry, Array[String] seen_names) -> (Entry::ConstantAlias | Entry::UnresolvedConstantAlias)
971
882
  def resolve_alias(entry, seen_names)
972
883
  alias_name = entry.name
973
884
  return entry if seen_names.include?(alias_name)
@@ -990,17 +901,7 @@ module RubyIndexer
990
901
  resolved_alias
991
902
  end
992
903
 
993
- sig do
994
- params(
995
- name: String,
996
- nesting: T::Array[String],
997
- seen_names: T::Array[String],
998
- ).returns(T.nilable(T::Array[T.any(
999
- Entry::Namespace,
1000
- Entry::ConstantAlias,
1001
- Entry::UnresolvedConstantAlias,
1002
- )]))
1003
- end
904
+ #: (String name, Array[String] nesting, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
1004
905
  def lookup_enclosing_scopes(name, nesting, seen_names)
1005
906
  nesting.length.downto(1) do |i|
1006
907
  namespace = T.must(nesting[0...i]).join("::")
@@ -1019,17 +920,7 @@ module RubyIndexer
1019
920
  nil
1020
921
  end
1021
922
 
1022
- sig do
1023
- params(
1024
- name: String,
1025
- nesting: T::Array[String],
1026
- seen_names: T::Array[String],
1027
- ).returns(T.nilable(T::Array[T.any(
1028
- Entry::Namespace,
1029
- Entry::ConstantAlias,
1030
- Entry::UnresolvedConstantAlias,
1031
- )]))
1032
- end
923
+ #: (String name, Array[String] nesting, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
1033
924
  def lookup_ancestor_chain(name, nesting, seen_names)
1034
925
  *nesting_parts, constant_name = build_non_redundant_full_name(name, nesting).split("::")
1035
926
  return if nesting_parts.empty?
@@ -1049,17 +940,7 @@ module RubyIndexer
1049
940
  nil
1050
941
  end
1051
942
 
1052
- sig do
1053
- params(
1054
- name: T.nilable(String),
1055
- nesting: T::Array[String],
1056
- ).returns(T::Array[T::Array[T.any(
1057
- Entry::Namespace,
1058
- Entry::ConstantAlias,
1059
- Entry::UnresolvedConstantAlias,
1060
- Entry::Constant,
1061
- )]])
1062
- end
943
+ #: (String? name, Array[String] nesting) -> Array[Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias | Entry::Constant)]]
1063
944
  def inherited_constant_completion_candidates(name, nesting)
1064
945
  namespace_entries = if name
1065
946
  *nesting_parts, constant_name = build_non_redundant_full_name(name, nesting).split("::")
@@ -1098,7 +979,7 @@ module RubyIndexer
1098
979
  # inside of the ["A", "B"] nesting, then we should not concatenate the nesting with the name or else we'll end up
1099
980
  # with `A::B::A::B::Foo`. This method will remove any redundant parts from the final name based on the reference and
1100
981
  # the nesting
1101
- sig { params(name: String, nesting: T::Array[String]).returns(String) }
982
+ #: (String name, Array[String] nesting) -> String
1102
983
  def build_non_redundant_full_name(name, nesting)
1103
984
  # If there's no nesting, then we can just return the name as is
1104
985
  return name if nesting.empty?
@@ -1119,18 +1000,7 @@ module RubyIndexer
1119
1000
  name_parts.join("::")
1120
1001
  end
1121
1002
 
1122
- sig do
1123
- params(
1124
- full_name: String,
1125
- seen_names: T::Array[String],
1126
- ).returns(
1127
- T.nilable(T::Array[T.any(
1128
- Entry::Namespace,
1129
- Entry::ConstantAlias,
1130
- Entry::UnresolvedConstantAlias,
1131
- )]),
1132
- )
1133
- end
1003
+ #: (String full_name, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
1134
1004
  def direct_or_aliased_constant(full_name, seen_names)
1135
1005
  entries = @entries[full_name] || @entries[follow_aliased_namespace(full_name)]
1136
1006
 
@@ -1146,13 +1016,7 @@ module RubyIndexer
1146
1016
 
1147
1017
  # Attempt to resolve a given unresolved method alias. This method returns the resolved alias if we managed to
1148
1018
  # identify the target or the same unresolved alias entry if we couldn't
1149
- sig do
1150
- params(
1151
- entry: Entry::UnresolvedMethodAlias,
1152
- receiver_name: String,
1153
- seen_names: T::Array[String],
1154
- ).returns(T.any(Entry::MethodAlias, Entry::UnresolvedMethodAlias))
1155
- end
1019
+ #: (Entry::UnresolvedMethodAlias entry, String receiver_name, Array[String] seen_names) -> (Entry::MethodAlias | Entry::UnresolvedMethodAlias)
1156
1020
  def resolve_method_alias(entry, receiver_name, seen_names)
1157
1021
  new_name = entry.new_name
1158
1022
  return entry if new_name == entry.old_name
@@ -3,20 +3,8 @@
3
3
 
4
4
  module RubyIndexer
5
5
  class Location
6
- extend T::Sig
7
-
8
6
  class << self
9
- extend T::Sig
10
-
11
- sig do
12
- params(
13
- prism_location: Prism::Location,
14
- code_units_cache: T.any(
15
- T.proc.params(arg0: Integer).returns(Integer),
16
- Prism::CodeUnitsCache,
17
- ),
18
- ).returns(T.attached_class)
19
- end
7
+ #: (Prism::Location prism_location, (^(Integer arg0) -> Integer | Prism::CodeUnitsCache) code_units_cache) -> instance
20
8
  def from_prism_location(prism_location, code_units_cache)
21
9
  new(
22
10
  prism_location.start_line,
@@ -27,17 +15,10 @@ module RubyIndexer
27
15
  end
28
16
  end
29
17
 
30
- sig { returns(Integer) }
18
+ #: Integer
31
19
  attr_reader :start_line, :end_line, :start_column, :end_column
32
20
 
33
- sig do
34
- params(
35
- start_line: Integer,
36
- end_line: Integer,
37
- start_column: Integer,
38
- end_column: Integer,
39
- ).void
40
- end
21
+ #: (Integer start_line, Integer end_line, Integer start_column, Integer end_column) -> void
41
22
  def initialize(start_line, end_line, start_column, end_column)
42
23
  @start_line = start_line
43
24
  @end_line = end_line
@@ -45,11 +26,7 @@ module RubyIndexer
45
26
  @end_column = end_column
46
27
  end
47
28
 
48
- sig do
49
- params(
50
- other: T.any(Location, Prism::Location),
51
- ).returns(T::Boolean)
52
- end
29
+ #: ((Location | Prism::Location) other) -> bool
53
30
  def ==(other)
54
31
  start_line == other.start_line &&
55
32
  end_line == other.end_line &&