ruby-lsp 0.23.11 → 0.23.12

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 (98) 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_register_with_handler_method.rb +3 -5
  6. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +52 -77
  7. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +61 -144
  8. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +8 -6
  9. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +73 -182
  10. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +48 -181
  11. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  12. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +12 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +21 -44
  14. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +40 -58
  15. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
  16. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
  17. data/lib/ruby_indexer/test/configuration_test.rb +32 -2
  18. data/lib/ruby_indexer/test/method_test.rb +2 -2
  19. data/lib/ruby_lsp/addon.rb +32 -67
  20. data/lib/ruby_lsp/base_server.rb +10 -10
  21. data/lib/ruby_lsp/client_capabilities.rb +4 -6
  22. data/lib/ruby_lsp/document.rb +21 -32
  23. data/lib/ruby_lsp/erb_document.rb +17 -27
  24. data/lib/ruby_lsp/global_state.rb +30 -32
  25. data/lib/ruby_lsp/internal.rb +2 -0
  26. data/lib/ruby_lsp/listeners/code_lens.rb +21 -39
  27. data/lib/ruby_lsp/listeners/completion.rb +34 -53
  28. data/lib/ruby_lsp/listeners/definition.rb +35 -49
  29. data/lib/ruby_lsp/listeners/document_highlight.rb +60 -69
  30. data/lib/ruby_lsp/listeners/document_link.rb +9 -19
  31. data/lib/ruby_lsp/listeners/document_symbol.rb +34 -48
  32. data/lib/ruby_lsp/listeners/folding_ranges.rb +31 -38
  33. data/lib/ruby_lsp/listeners/hover.rb +37 -47
  34. data/lib/ruby_lsp/listeners/inlay_hints.rb +3 -10
  35. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +29 -35
  36. data/lib/ruby_lsp/listeners/signature_help.rb +4 -23
  37. data/lib/ruby_lsp/listeners/spec_style.rb +199 -0
  38. data/lib/ruby_lsp/listeners/test_style.rb +136 -30
  39. data/lib/ruby_lsp/node_context.rb +8 -35
  40. data/lib/ruby_lsp/rbs_document.rb +7 -5
  41. data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
  42. data/lib/ruby_lsp/requests/code_actions.rb +5 -14
  43. data/lib/ruby_lsp/requests/code_lens.rb +4 -13
  44. data/lib/ruby_lsp/requests/completion.rb +4 -15
  45. data/lib/ruby_lsp/requests/completion_resolve.rb +4 -4
  46. data/lib/ruby_lsp/requests/definition.rb +4 -12
  47. data/lib/ruby_lsp/requests/diagnostics.rb +6 -9
  48. data/lib/ruby_lsp/requests/discover_tests.rb +15 -3
  49. data/lib/ruby_lsp/requests/document_highlight.rb +3 -11
  50. data/lib/ruby_lsp/requests/document_link.rb +4 -13
  51. data/lib/ruby_lsp/requests/document_symbol.rb +4 -7
  52. data/lib/ruby_lsp/requests/folding_ranges.rb +4 -7
  53. data/lib/ruby_lsp/requests/formatting.rb +4 -7
  54. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
  55. data/lib/ruby_lsp/requests/hover.rb +6 -16
  56. data/lib/ruby_lsp/requests/inlay_hints.rb +4 -13
  57. data/lib/ruby_lsp/requests/on_type_formatting.rb +17 -24
  58. data/lib/ruby_lsp/requests/prepare_rename.rb +3 -8
  59. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
  60. data/lib/ruby_lsp/requests/range_formatting.rb +3 -4
  61. data/lib/ruby_lsp/requests/references.rb +5 -35
  62. data/lib/ruby_lsp/requests/rename.rb +9 -35
  63. data/lib/ruby_lsp/requests/request.rb +5 -17
  64. data/lib/ruby_lsp/requests/selection_ranges.rb +3 -3
  65. data/lib/ruby_lsp/requests/semantic_highlighting.rb +6 -23
  66. data/lib/ruby_lsp/requests/show_syntax_tree.rb +4 -5
  67. data/lib/ruby_lsp/requests/signature_help.rb +6 -24
  68. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  69. data/lib/ruby_lsp/requests/support/common.rb +12 -49
  70. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +12 -14
  71. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +7 -10
  72. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +9 -15
  73. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  74. data/lib/ruby_lsp/requests/support/sorbet.rb +1 -7
  75. data/lib/ruby_lsp/requests/support/source_uri.rb +5 -16
  76. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +7 -10
  77. data/lib/ruby_lsp/requests/support/test_item.rb +14 -13
  78. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +4 -5
  79. data/lib/ruby_lsp/requests/workspace_symbol.rb +3 -3
  80. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +4 -4
  81. data/lib/ruby_lsp/response_builders/document_symbol.rb +8 -11
  82. data/lib/ruby_lsp/response_builders/hover.rb +5 -5
  83. data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
  84. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +18 -40
  85. data/lib/ruby_lsp/response_builders/signature_help.rb +4 -5
  86. data/lib/ruby_lsp/response_builders/test_collection.rb +5 -9
  87. data/lib/ruby_lsp/ruby_document.rb +15 -40
  88. data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +106 -0
  89. data/lib/ruby_lsp/scope.rb +6 -10
  90. data/lib/ruby_lsp/server.rb +125 -74
  91. data/lib/ruby_lsp/setup_bundler.rb +22 -15
  92. data/lib/ruby_lsp/store.rb +12 -28
  93. data/lib/ruby_lsp/test_helper.rb +3 -12
  94. data/lib/ruby_lsp/test_reporter.rb +71 -0
  95. data/lib/ruby_lsp/test_unit_test_runner.rb +96 -0
  96. data/lib/ruby_lsp/type_inferrer.rb +9 -13
  97. data/lib/ruby_lsp/utils.rb +27 -65
  98. metadata +8 -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,7 +50,7 @@ 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
  # {
@@ -99,12 +88,12 @@ module RubyIndexer
99
88
  end
100
89
 
101
90
  # 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 }
91
+ #: (String module_name) { (Index index, Entry::Namespace base) -> void } -> void
103
92
  def register_included_hook(module_name, &hook)
104
93
  (@included_hooks[module_name] ||= []) << hook
105
94
  end
106
95
 
107
- sig { params(uri: URI::Generic, skip_require_paths_tree: T::Boolean).void }
96
+ #: (URI::Generic uri, ?skip_require_paths_tree: bool) -> void
108
97
  def delete(uri, skip_require_paths_tree: false)
109
98
  key = uri.to_s
110
99
  # For each constant discovered in `path`, delete the associated entry from the index. If there are no entries
@@ -134,7 +123,7 @@ module RubyIndexer
134
123
  @require_paths_tree.delete(require_path) if require_path
135
124
  end
136
125
 
137
- sig { params(entry: Entry, skip_prefix_tree: T::Boolean).void }
126
+ #: (Entry entry, ?skip_prefix_tree: bool) -> void
138
127
  def add(entry, skip_prefix_tree: false)
139
128
  name = entry.name
140
129
 
@@ -143,28 +132,19 @@ module RubyIndexer
143
132
  @entries_tree.insert(name, T.must(@entries[name])) unless skip_prefix_tree
144
133
  end
145
134
 
146
- sig { params(fully_qualified_name: String).returns(T.nilable(T::Array[Entry])) }
135
+ #: (String fully_qualified_name) -> Array[Entry]?
147
136
  def [](fully_qualified_name)
148
137
  @entries[fully_qualified_name.delete_prefix("::")]
149
138
  end
150
139
 
151
- sig { params(query: String).returns(T::Array[URI::Generic]) }
140
+ #: (String query) -> Array[URI::Generic]
152
141
  def search_require_paths(query)
153
142
  @require_paths_tree.search(query)
154
143
  end
155
144
 
156
145
  # Searches for a constant based on an unqualified name and returns the first possible match regardless of whether
157
146
  # 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
147
+ #: (String name) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias | Entry::Constant)]?
168
148
  def first_unqualified_const(name)
169
149
  # Look for an exact match first
170
150
  _name, entries = @entries.find do |const_name, _entries|
@@ -202,7 +182,7 @@ module RubyIndexer
202
182
  # [#<Entry::Class name="Foo::Baz">],
203
183
  # ]
204
184
  # ```
205
- sig { params(query: String, nesting: T.nilable(T::Array[String])).returns(T::Array[T::Array[Entry]]) }
185
+ #: (String query, ?Array[String]? nesting) -> Array[Array[Entry]]
206
186
  def prefix_search(query, nesting = nil)
207
187
  unless nesting
208
188
  results = @entries_tree.search(query)
@@ -221,7 +201,7 @@ module RubyIndexer
221
201
  end
222
202
 
223
203
  # 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]) }
204
+ #: (String? query) -> Array[Entry]
225
205
  def fuzzy_search(query)
226
206
  unless query
227
207
  entries = @entries.filter_map do |_name, entries|
@@ -245,12 +225,7 @@ module RubyIndexer
245
225
  results.flat_map(&:first)
246
226
  end
247
227
 
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
228
+ #: (String? name, String receiver_name) -> Array[(Entry::Member | Entry::MethodAlias)]
254
229
  def method_completion_candidates(name, receiver_name)
255
230
  ancestors = linearized_ancestors_of(receiver_name)
256
231
 
@@ -293,17 +268,7 @@ module RubyIndexer
293
268
  completion_items.values.map!(&:first)
294
269
  end
295
270
 
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
271
+ #: (String name, Array[String] nesting) -> Array[Array[(Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias)]]
307
272
  def constant_completion_candidates(name, nesting)
308
273
  # If we have a top level reference, then we don't need to include completions inside the current nesting
309
274
  if name.start_with?("::")
@@ -358,17 +323,7 @@ module RubyIndexer
358
323
  # nesting: the nesting structure where the reference was found (e.g.: ["Foo", "Bar"])
359
324
  # seen_names: this parameter should not be used by consumers of the api. It is used to avoid infinite recursion when
360
325
  # 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
326
+ #: (String name, Array[String] nesting, ?Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
372
327
  def resolve(name, nesting, seen_names = [])
373
328
  # If we have a top level reference, then we just search for it straight away ignoring the nesting
374
329
  if name.start_with?("::")
@@ -404,12 +359,7 @@ module RubyIndexer
404
359
  # Index all files for the given URIs, which defaults to what is configured. A block can be used to track and control
405
360
  # indexing progress. That block is invoked with the current progress percentage and should return `true` to continue
406
361
  # 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
362
+ #: (?uris: Array[URI::Generic]) ?{ (Integer progress) -> bool } -> void
413
363
  def index_all(uris: @configuration.indexable_uris, &block)
414
364
  # When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the
415
365
  # existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this
@@ -419,8 +369,6 @@ module RubyIndexer
419
369
  "The index is not empty. To prevent invalid entries, `index_all` can only be called once."
420
370
  end
421
371
 
422
- @initial_indexing_completed = true
423
-
424
372
  RBSIndexer.new(self).index_ruby_core
425
373
  # Calculate how many paths are worth 1% of progress
426
374
  progress_step = (uris.length / 100.0).ceil
@@ -433,9 +381,11 @@ module RubyIndexer
433
381
 
434
382
  index_file(uri, collect_comments: false)
435
383
  end
384
+
385
+ @initial_indexing_completed = true
436
386
  end
437
387
 
438
- sig { params(uri: URI::Generic, source: String, collect_comments: T::Boolean).void }
388
+ #: (URI::Generic uri, String source, ?collect_comments: bool) -> void
439
389
  def index_single(uri, source, collect_comments: true)
440
390
  dispatcher = Prism::Dispatcher.new
441
391
 
@@ -457,7 +407,7 @@ module RubyIndexer
457
407
  end
458
408
 
459
409
  # Indexes a File URI by reading the contents from disk
460
- sig { params(uri: URI::Generic, collect_comments: T::Boolean).void }
410
+ #: (URI::Generic uri, ?collect_comments: bool) -> void
461
411
  def index_file(uri, collect_comments: true)
462
412
  index_single(uri, File.read(T.must(uri.full_path)), collect_comments: collect_comments)
463
413
  rescue Errno::EISDIR, Errno::ENOENT
@@ -475,7 +425,7 @@ module RubyIndexer
475
425
  # If we find an alias, then we want to follow its target. In the same example, if `Foo::Bar` is an alias to
476
426
  # `Something::Else`, then we first discover `Something::Else::Baz`. But `Something::Else::Baz` might contain other
477
427
  # 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) }
428
+ #: (String name, ?Array[String] seen_names) -> String
479
429
  def follow_aliased_namespace(name, seen_names = [])
480
430
  parts = name.split("::")
481
431
  real_parts = []
@@ -508,14 +458,7 @@ module RubyIndexer
508
458
  # Attempts to find methods for a resolved fully qualified receiver name. Do not provide the `seen_names` parameter
509
459
  # as it is used only internally to prevent infinite loops when resolving circular aliases
510
460
  # 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
461
+ #: (String method_name, String receiver_name, ?Array[String] seen_names, ?inherited_only: bool) -> Array[(Entry::Member | Entry::MethodAlias)]?
519
462
  def resolve_method(method_name, receiver_name, seen_names = [], inherited_only: false)
520
463
  method_entries = self[method_name]
521
464
  return unless method_entries
@@ -553,7 +496,7 @@ module RubyIndexer
553
496
  # module that prepends another module, then the prepend module appears before the included module.
554
497
  #
555
498
  # The order of ancestors is [linearized_prepends, self, linearized_includes, linearized_superclass]
556
- sig { params(fully_qualified_name: String).returns(T::Array[String]) }
499
+ #: (String fully_qualified_name) -> Array[String]
557
500
  def linearized_ancestors_of(fully_qualified_name)
558
501
  # If we already computed the ancestors for this namespace, return it straight away
559
502
  cached_ancestors = @ancestors[fully_qualified_name]
@@ -631,7 +574,7 @@ module RubyIndexer
631
574
 
632
575
  # Resolves an instance variable name for a given owner name. This method will linearize the ancestors of the owner
633
576
  # and find inherited instance variables as well
634
- sig { params(variable_name: String, owner_name: String).returns(T.nilable(T::Array[Entry::InstanceVariable])) }
577
+ #: (String variable_name, String owner_name) -> Array[Entry::InstanceVariable]?
635
578
  def resolve_instance_variable(variable_name, owner_name)
636
579
  entries = T.cast(self[variable_name], T.nilable(T::Array[Entry::InstanceVariable]))
637
580
  return unless entries
@@ -642,7 +585,7 @@ module RubyIndexer
642
585
  entries.select { |e| ancestors.include?(e.owner&.name) }
643
586
  end
644
587
 
645
- sig { params(variable_name: String, owner_name: String).returns(T.nilable(T::Array[Entry::ClassVariable])) }
588
+ #: (String variable_name, String owner_name) -> Array[Entry::ClassVariable]?
646
589
  def resolve_class_variable(variable_name, owner_name)
647
590
  entries = self[variable_name]&.grep(Entry::ClassVariable)
648
591
  return unless entries&.any?
@@ -655,9 +598,7 @@ module RubyIndexer
655
598
 
656
599
  # Returns a list of possible candidates for completion of instance variables for a given owner name. The name must
657
600
  # include the `@` prefix
658
- sig do
659
- params(name: String, owner_name: String).returns(T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
660
- end
601
+ #: (String name, String owner_name) -> Array[(Entry::InstanceVariable | Entry::ClassVariable)]
661
602
  def instance_variable_completion_candidates(name, owner_name)
662
603
  entries = T.cast(prefix_search(name).flatten, T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
663
604
  # Avoid wasting time linearizing ancestors if we didn't find anything
@@ -686,7 +627,7 @@ module RubyIndexer
686
627
  variables
687
628
  end
688
629
 
689
- sig { params(name: String, owner_name: String).returns(T::Array[Entry::ClassVariable]) }
630
+ #: (String name, String owner_name) -> Array[Entry::ClassVariable]
690
631
  def class_variable_completion_candidates(name, owner_name)
691
632
  entries = T.cast(prefix_search(name).flatten, T::Array[Entry::ClassVariable])
692
633
  # Avoid wasting time linearizing ancestors if we didn't find anything
@@ -702,9 +643,7 @@ module RubyIndexer
702
643
  # declarations removed and that the ancestor linearization cache is cleared if necessary. If a block is passed, the
703
644
  # consumer of this API has to handle deleting and inserting/updating entries in the index instead of passing the
704
645
  # 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
646
+ #: (URI::Generic uri, ?String? source) ?{ (Index index) -> void } -> void
708
647
  def handle_change(uri, source = nil, &block)
709
648
  key = uri.to_s
710
649
  original_entries = @uris_to_entries[key]
@@ -736,27 +675,27 @@ module RubyIndexer
736
675
  @ancestors.clear if original_map.any? { |name, hash| updated_map[name] != hash }
737
676
  end
738
677
 
739
- sig { returns(T::Boolean) }
678
+ #: -> bool
740
679
  def empty?
741
680
  @entries.empty?
742
681
  end
743
682
 
744
- sig { returns(T::Array[String]) }
683
+ #: -> Array[String]
745
684
  def names
746
685
  @entries.keys
747
686
  end
748
687
 
749
- sig { params(name: String).returns(T::Boolean) }
688
+ #: (String name) -> bool
750
689
  def indexed?(name)
751
690
  @entries.key?(name)
752
691
  end
753
692
 
754
- sig { returns(Integer) }
693
+ #: -> Integer
755
694
  def length
756
695
  @entries.count
757
696
  end
758
697
 
759
- sig { params(name: String).returns(Entry::SingletonClass) }
698
+ #: (String name) -> Entry::SingletonClass
760
699
  def existing_or_new_singleton_class(name)
761
700
  *_namespace, unqualified_name = name.split("::")
762
701
  full_singleton_name = "#{name}::<Class:#{unqualified_name}>"
@@ -779,12 +718,7 @@ module RubyIndexer
779
718
  singleton
780
719
  end
781
720
 
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
721
+ #: [T] (String uri, ?Class[(T & Entry)]? type) -> (Array[Entry] | Array[T])?
788
722
  def entries_for(uri, type = nil)
789
723
  entries = @uris_to_entries[uri.to_s]
790
724
  return entries unless type
@@ -796,7 +730,7 @@ module RubyIndexer
796
730
 
797
731
  # Always returns the linearized ancestors for the attached class, regardless of whether `name` refers to a singleton
798
732
  # or attached namespace
799
- sig { params(name: String).returns(T::Array[String]) }
733
+ #: (String name) -> Array[String]
800
734
  def linearized_attached_ancestors(name)
801
735
  name_parts = name.split("::")
802
736
 
@@ -809,7 +743,7 @@ module RubyIndexer
809
743
  end
810
744
 
811
745
  # Runs the registered included hooks
812
- sig { params(fully_qualified_name: String, nesting: T::Array[String]).void }
746
+ #: (String fully_qualified_name, Array[String] nesting) -> void
813
747
  def run_included_hooks(fully_qualified_name, nesting)
814
748
  return if @included_hooks.empty?
815
749
 
@@ -838,13 +772,7 @@ module RubyIndexer
838
772
 
839
773
  # Linearize mixins for an array of namespace entries. This method will mutate the `ancestors` array with the
840
774
  # 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
775
+ #: (Array[String] ancestors, Array[Entry::Namespace] namespace_entries, Array[String] nesting) -> void
848
776
  def linearize_mixins(ancestors, namespace_entries, nesting)
849
777
  mixin_operations = namespace_entries.flat_map(&:mixin_operations)
850
778
  main_namespace_index = 0
@@ -885,16 +813,7 @@ module RubyIndexer
885
813
 
886
814
  # Linearize the superclass of a given namespace (including modules with the implicit `Module` superclass). This
887
815
  # 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
816
+ #: (Array[String] ancestors, String attached_class_name, String fully_qualified_name, Array[Entry::Namespace] namespace_entries, Array[String] nesting, Integer singleton_levels) -> void
898
817
  def linearize_superclass( # rubocop:disable Metrics/ParameterLists
899
818
  ancestors,
900
819
  attached_class_name,
@@ -962,12 +881,7 @@ module RubyIndexer
962
881
 
963
882
  # Attempts to resolve an UnresolvedAlias into a resolved Alias. If the unresolved alias is pointing to a constant
964
883
  # 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
884
+ #: (Entry::UnresolvedConstantAlias entry, Array[String] seen_names) -> (Entry::ConstantAlias | Entry::UnresolvedConstantAlias)
971
885
  def resolve_alias(entry, seen_names)
972
886
  alias_name = entry.name
973
887
  return entry if seen_names.include?(alias_name)
@@ -990,17 +904,7 @@ module RubyIndexer
990
904
  resolved_alias
991
905
  end
992
906
 
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
907
+ #: (String name, Array[String] nesting, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
1004
908
  def lookup_enclosing_scopes(name, nesting, seen_names)
1005
909
  nesting.length.downto(1) do |i|
1006
910
  namespace = T.must(nesting[0...i]).join("::")
@@ -1019,17 +923,7 @@ module RubyIndexer
1019
923
  nil
1020
924
  end
1021
925
 
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
926
+ #: (String name, Array[String] nesting, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
1033
927
  def lookup_ancestor_chain(name, nesting, seen_names)
1034
928
  *nesting_parts, constant_name = build_non_redundant_full_name(name, nesting).split("::")
1035
929
  return if nesting_parts.empty?
@@ -1049,17 +943,7 @@ module RubyIndexer
1049
943
  nil
1050
944
  end
1051
945
 
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
946
+ #: (String? name, Array[String] nesting) -> Array[Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias | Entry::Constant)]]
1063
947
  def inherited_constant_completion_candidates(name, nesting)
1064
948
  namespace_entries = if name
1065
949
  *nesting_parts, constant_name = build_non_redundant_full_name(name, nesting).split("::")
@@ -1098,7 +982,7 @@ module RubyIndexer
1098
982
  # inside of the ["A", "B"] nesting, then we should not concatenate the nesting with the name or else we'll end up
1099
983
  # with `A::B::A::B::Foo`. This method will remove any redundant parts from the final name based on the reference and
1100
984
  # the nesting
1101
- sig { params(name: String, nesting: T::Array[String]).returns(String) }
985
+ #: (String name, Array[String] nesting) -> String
1102
986
  def build_non_redundant_full_name(name, nesting)
1103
987
  # If there's no nesting, then we can just return the name as is
1104
988
  return name if nesting.empty?
@@ -1119,18 +1003,7 @@ module RubyIndexer
1119
1003
  name_parts.join("::")
1120
1004
  end
1121
1005
 
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
1006
+ #: (String full_name, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
1134
1007
  def direct_or_aliased_constant(full_name, seen_names)
1135
1008
  entries = @entries[full_name] || @entries[follow_aliased_namespace(full_name)]
1136
1009
 
@@ -1146,13 +1019,7 @@ module RubyIndexer
1146
1019
 
1147
1020
  # Attempt to resolve a given unresolved method alias. This method returns the resolved alias if we managed to
1148
1021
  # 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
1022
+ #: (Entry::UnresolvedMethodAlias entry, String receiver_name, Array[String] seen_names) -> (Entry::MethodAlias | Entry::UnresolvedMethodAlias)
1156
1023
  def resolve_method_alias(entry, receiver_name, seen_names)
1157
1024
  new_name = entry.new_name
1158
1025
  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 &&
@@ -33,12 +33,11 @@ module RubyIndexer
33
33
  #
34
34
  # See https://en.wikipedia.org/wiki/Trie for more information
35
35
  class PrefixTree
36
- extend T::Sig
37
36
  extend T::Generic
38
37
 
39
38
  Value = type_member
40
39
 
41
- sig { void }
40
+ #: -> void
42
41
  def initialize
43
42
  @root = T.let(Node.new("", ""), Node[Value])
44
43
  end
@@ -47,7 +46,7 @@ module RubyIndexer
47
46
  # return it as a result. The result is always an array of the type of value attribute to the generic `Value` type.
48
47
  # Notice that if the `Value` is an array, this method will return an array of arrays, where each entry is the array
49
48
  # of values for a given match
50
- sig { params(prefix: String).returns(T::Array[Value]) }
49
+ #: (String prefix) -> Array[Value]
51
50
  def search(prefix)
52
51
  node = find_node(prefix)
53
52
  return [] unless node
@@ -56,7 +55,7 @@ module RubyIndexer
56
55
  end
57
56
 
58
57
  # Inserts a `value` using the given `key`
59
- sig { params(key: String, value: Value).void }
58
+ #: (String key, Value value) -> void
60
59
  def insert(key, value)
61
60
  node = @root
62
61
 
@@ -73,7 +72,7 @@ module RubyIndexer
73
72
 
74
73
  # Deletes the entry identified by `key` from the tree. Notice that a partial match will still delete all entries
75
74
  # that match it. For example, if the tree contains `foo` and we ask to delete `fo`, then `foo` will be deleted
76
- sig { params(key: String).void }
75
+ #: (String key) -> void
77
76
  def delete(key)
78
77
  node = find_node(key)
79
78
  return unless node
@@ -93,7 +92,7 @@ module RubyIndexer
93
92
  private
94
93
 
95
94
  # Find a node that matches the given `key`
96
- sig { params(key: String).returns(T.nilable(Node[Value])) }
95
+ #: (String key) -> Node[Value]?
97
96
  def find_node(key)
98
97
  node = @root
99
98
 
@@ -108,27 +107,26 @@ module RubyIndexer
108
107
  end
109
108
 
110
109
  class Node
111
- extend T::Sig
112
110
  extend T::Generic
113
111
 
114
112
  Value = type_member
115
113
 
116
- sig { returns(T::Hash[String, Node[Value]]) }
114
+ #: Hash[String, Node[Value]]
117
115
  attr_reader :children
118
116
 
119
- sig { returns(String) }
117
+ #: String
120
118
  attr_reader :key
121
119
 
122
- sig { returns(Value) }
120
+ #: Value
123
121
  attr_accessor :value
124
122
 
125
- sig { returns(T::Boolean) }
123
+ #: bool
126
124
  attr_accessor :leaf
127
125
 
128
- sig { returns(T.nilable(Node[Value])) }
126
+ #: Node[Value]?
129
127
  attr_reader :parent
130
128
 
131
- sig { params(key: String, value: Value, parent: T.nilable(Node[Value])).void }
129
+ #: (String key, Value value, ?Node[Value]? parent) -> void
132
130
  def initialize(key, value, parent = nil)
133
131
  @key = key
134
132
  @value = value
@@ -137,7 +135,7 @@ module RubyIndexer
137
135
  @leaf = false
138
136
  end
139
137
 
140
- sig { returns(T::Array[Value]) }
138
+ #: -> Array[Value]
141
139
  def collect
142
140
  result = []
143
141
  result << @value if @leaf