ruby-lsp 0.23.11 → 0.23.16
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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp-launcher +20 -11
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +123 -169
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +92 -202
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +116 -222
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +18 -19
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +47 -61
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
- data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
- data/lib/ruby_indexer/test/configuration_test.rb +48 -7
- data/lib/ruby_indexer/test/constant_test.rb +34 -34
- data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +139 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +37 -37
- data/lib/ruby_indexer/test/method_test.rb +143 -117
- data/lib/ruby_indexer/test/prefix_tree_test.rb +13 -13
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +65 -71
- data/lib/ruby_indexer/test/test_case.rb +2 -2
- data/lib/ruby_indexer/test/uri_test.rb +15 -2
- data/lib/ruby_lsp/addon.rb +44 -71
- data/lib/ruby_lsp/base_server.rb +29 -32
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +39 -45
- data/lib/ruby_lsp/erb_document.rb +36 -40
- data/lib/ruby_lsp/global_state.rb +52 -57
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +60 -66
- data/lib/ruby_lsp/listeners/definition.rb +38 -52
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +46 -63
- data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
- data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
- data/lib/ruby_lsp/listeners/hover.rb +83 -102
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
- data/lib/ruby_lsp/listeners/signature_help.rb +11 -26
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
- data/lib/ruby_lsp/listeners/test_style.rb +160 -88
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +8 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +24 -25
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +6 -17
- data/lib/ruby_lsp/requests/completion.rb +7 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +8 -17
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
- data/lib/ruby_lsp/requests/document_link.rb +6 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
- data/lib/ruby_lsp/requests/formatting.rb +6 -9
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
- data/lib/ruby_lsp/requests/hover.rb +10 -20
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +8 -37
- data/lib/ruby_lsp/requests/rename.rb +19 -42
- data/lib/ruby_lsp/requests/request.rb +7 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +6 -6
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
- data/lib/ruby_lsp/requests/signature_help.rb +8 -26
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +16 -51
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +11 -14
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
- data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +10 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
- data/lib/ruby_lsp/response_builders/document_symbol.rb +13 -18
- data/lib/ruby_lsp/response_builders/hover.rb +11 -14
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +60 -88
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
- data/lib/ruby_lsp/ruby_document.rb +24 -62
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +147 -79
- data/lib/ruby_lsp/setup_bundler.rb +65 -60
- data/lib/ruby_lsp/static_docs.rb +11 -7
- data/lib/ruby_lsp/store.rb +24 -42
- data/lib/ruby_lsp/test_helper.rb +2 -12
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +164 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +105 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +94 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +49 -83
- 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
|
-
|
13
|
+
#: Configuration
|
16
14
|
attr_reader :configuration
|
17
15
|
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
82
|
+
@configuration = RubyIndexer::Configuration.new #: Configuration
|
97
83
|
|
98
|
-
@initial_indexing_completed =
|
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
|
-
|
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
|
-
|
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,37 +120,34 @@ module RubyIndexer
|
|
134
120
|
@require_paths_tree.delete(require_path) if require_path
|
135
121
|
end
|
136
122
|
|
137
|
-
|
123
|
+
#: (Entry entry, ?skip_prefix_tree: bool) -> void
|
138
124
|
def add(entry, skip_prefix_tree: false)
|
139
125
|
name = entry.name
|
140
126
|
|
141
127
|
(@entries[name] ||= []) << entry
|
142
128
|
(@uris_to_entries[entry.uri.to_s] ||= []) << entry
|
143
|
-
|
129
|
+
|
130
|
+
unless skip_prefix_tree
|
131
|
+
@entries_tree.insert(
|
132
|
+
name,
|
133
|
+
@entries[name], #: as !nil
|
134
|
+
)
|
135
|
+
end
|
144
136
|
end
|
145
137
|
|
146
|
-
|
138
|
+
#: (String fully_qualified_name) -> Array[Entry]?
|
147
139
|
def [](fully_qualified_name)
|
148
140
|
@entries[fully_qualified_name.delete_prefix("::")]
|
149
141
|
end
|
150
142
|
|
151
|
-
|
143
|
+
#: (String query) -> Array[URI::Generic]
|
152
144
|
def search_require_paths(query)
|
153
145
|
@require_paths_tree.search(query)
|
154
146
|
end
|
155
147
|
|
156
148
|
# Searches for a constant based on an unqualified name and returns the first possible match regardless of whether
|
157
149
|
# there are more possible matching entries
|
158
|
-
|
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
|
150
|
+
#: (String name) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias | Entry::Constant)]?
|
168
151
|
def first_unqualified_const(name)
|
169
152
|
# Look for an exact match first
|
170
153
|
_name, entries = @entries.find do |const_name, _entries|
|
@@ -202,7 +185,7 @@ module RubyIndexer
|
|
202
185
|
# [#<Entry::Class name="Foo::Baz">],
|
203
186
|
# ]
|
204
187
|
# ```
|
205
|
-
|
188
|
+
#: (String query, ?Array[String]? nesting) -> Array[Array[Entry]]
|
206
189
|
def prefix_search(query, nesting = nil)
|
207
190
|
unless nesting
|
208
191
|
results = @entries_tree.search(query)
|
@@ -211,7 +194,8 @@ module RubyIndexer
|
|
211
194
|
end
|
212
195
|
|
213
196
|
results = nesting.length.downto(0).flat_map do |i|
|
214
|
-
prefix =
|
197
|
+
prefix = nesting[0...i] #: as !nil
|
198
|
+
.join("::")
|
215
199
|
namespaced_query = prefix.empty? ? query : "#{prefix}::#{query}"
|
216
200
|
@entries_tree.search(namespaced_query)
|
217
201
|
end
|
@@ -221,7 +205,7 @@ module RubyIndexer
|
|
221
205
|
end
|
222
206
|
|
223
207
|
# Fuzzy searches index entries based on Jaro-Winkler similarity. If no query is provided, all entries are returned
|
224
|
-
|
208
|
+
#: (String? query) -> Array[Entry]
|
225
209
|
def fuzzy_search(query)
|
226
210
|
unless query
|
227
211
|
entries = @entries.filter_map do |_name, entries|
|
@@ -245,12 +229,7 @@ module RubyIndexer
|
|
245
229
|
results.flat_map(&:first)
|
246
230
|
end
|
247
231
|
|
248
|
-
|
249
|
-
params(
|
250
|
-
name: T.nilable(String),
|
251
|
-
receiver_name: String,
|
252
|
-
).returns(T::Array[T.any(Entry::Member, Entry::MethodAlias)])
|
253
|
-
end
|
232
|
+
#: (String? name, String receiver_name) -> Array[(Entry::Member | Entry::MethodAlias)]
|
254
233
|
def method_completion_candidates(name, receiver_name)
|
255
234
|
ancestors = linearized_ancestors_of(receiver_name)
|
256
235
|
|
@@ -293,17 +272,7 @@ module RubyIndexer
|
|
293
272
|
completion_items.values.map!(&:first)
|
294
273
|
end
|
295
274
|
|
296
|
-
|
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
|
275
|
+
#: (String name, Array[String] nesting) -> Array[Array[(Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias)]]
|
307
276
|
def constant_completion_candidates(name, nesting)
|
308
277
|
# If we have a top level reference, then we don't need to include completions inside the current nesting
|
309
278
|
if name.start_with?("::")
|
@@ -326,7 +295,8 @@ module RubyIndexer
|
|
326
295
|
|
327
296
|
# Constants defined in enclosing scopes
|
328
297
|
nesting.length.downto(1) do |i|
|
329
|
-
namespace =
|
298
|
+
namespace = nesting[0...i] #: as !nil
|
299
|
+
.join("::")
|
330
300
|
entries.concat(@entries_tree.search("#{namespace}::#{name}"))
|
331
301
|
end
|
332
302
|
|
@@ -358,17 +328,7 @@ module RubyIndexer
|
|
358
328
|
# nesting: the nesting structure where the reference was found (e.g.: ["Foo", "Bar"])
|
359
329
|
# seen_names: this parameter should not be used by consumers of the api. It is used to avoid infinite recursion when
|
360
330
|
# resolving circular references
|
361
|
-
|
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
|
331
|
+
#: (String name, Array[String] nesting, ?Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
|
372
332
|
def resolve(name, nesting, seen_names = [])
|
373
333
|
# If we have a top level reference, then we just search for it straight away ignoring the nesting
|
374
334
|
if name.start_with?("::")
|
@@ -404,12 +364,7 @@ module RubyIndexer
|
|
404
364
|
# Index all files for the given URIs, which defaults to what is configured. A block can be used to track and control
|
405
365
|
# indexing progress. That block is invoked with the current progress percentage and should return `true` to continue
|
406
366
|
# indexing or `false` to stop indexing.
|
407
|
-
|
408
|
-
params(
|
409
|
-
uris: T::Array[URI::Generic],
|
410
|
-
block: T.nilable(T.proc.params(progress: Integer).returns(T::Boolean)),
|
411
|
-
).void
|
412
|
-
end
|
367
|
+
#: (?uris: Array[URI::Generic]) ?{ (Integer progress) -> bool } -> void
|
413
368
|
def index_all(uris: @configuration.indexable_uris, &block)
|
414
369
|
# When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the
|
415
370
|
# existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this
|
@@ -419,8 +374,6 @@ module RubyIndexer
|
|
419
374
|
"The index is not empty. To prevent invalid entries, `index_all` can only be called once."
|
420
375
|
end
|
421
376
|
|
422
|
-
@initial_indexing_completed = true
|
423
|
-
|
424
377
|
RBSIndexer.new(self).index_ruby_core
|
425
378
|
# Calculate how many paths are worth 1% of progress
|
426
379
|
progress_step = (uris.length / 100.0).ceil
|
@@ -433,9 +386,11 @@ module RubyIndexer
|
|
433
386
|
|
434
387
|
index_file(uri, collect_comments: false)
|
435
388
|
end
|
389
|
+
|
390
|
+
@initial_indexing_completed = true
|
436
391
|
end
|
437
392
|
|
438
|
-
|
393
|
+
#: (URI::Generic uri, String source, ?collect_comments: bool) -> void
|
439
394
|
def index_single(uri, source, collect_comments: true)
|
440
395
|
dispatcher = Prism::Dispatcher.new
|
441
396
|
|
@@ -457,9 +412,10 @@ module RubyIndexer
|
|
457
412
|
end
|
458
413
|
|
459
414
|
# Indexes a File URI by reading the contents from disk
|
460
|
-
|
415
|
+
#: (URI::Generic uri, ?collect_comments: bool) -> void
|
461
416
|
def index_file(uri, collect_comments: true)
|
462
|
-
|
417
|
+
path = uri.full_path #: as !nil
|
418
|
+
index_single(uri, File.read(path), collect_comments: collect_comments)
|
463
419
|
rescue Errno::EISDIR, Errno::ENOENT
|
464
420
|
# If `path` is a directory, just ignore it and continue indexing. If the file doesn't exist, then we also ignore
|
465
421
|
# it
|
@@ -475,13 +431,14 @@ module RubyIndexer
|
|
475
431
|
# If we find an alias, then we want to follow its target. In the same example, if `Foo::Bar` is an alias to
|
476
432
|
# `Something::Else`, then we first discover `Something::Else::Baz`. But `Something::Else::Baz` might contain other
|
477
433
|
# aliases, so we have to invoke `follow_aliased_namespace` again to check until we only return a real name
|
478
|
-
|
434
|
+
#: (String name, ?Array[String] seen_names) -> String
|
479
435
|
def follow_aliased_namespace(name, seen_names = [])
|
480
436
|
parts = name.split("::")
|
481
437
|
real_parts = []
|
482
438
|
|
483
439
|
(parts.length - 1).downto(0) do |i|
|
484
|
-
current_name =
|
440
|
+
current_name = parts[0..i] #: as !nil
|
441
|
+
.join("::")
|
485
442
|
entry = @entries[current_name]&.first
|
486
443
|
|
487
444
|
case entry
|
@@ -498,7 +455,9 @@ module RubyIndexer
|
|
498
455
|
target = resolved.target
|
499
456
|
return follow_aliased_namespace("#{target}::#{real_parts.join("::")}", seen_names)
|
500
457
|
else
|
501
|
-
real_parts.unshift(
|
458
|
+
real_parts.unshift(
|
459
|
+
parts[i], #: as !nil
|
460
|
+
)
|
502
461
|
end
|
503
462
|
end
|
504
463
|
|
@@ -508,14 +467,7 @@ module RubyIndexer
|
|
508
467
|
# Attempts to find methods for a resolved fully qualified receiver name. Do not provide the `seen_names` parameter
|
509
468
|
# as it is used only internally to prevent infinite loops when resolving circular aliases
|
510
469
|
# Returns `nil` if the method does not exist on that receiver
|
511
|
-
|
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
|
470
|
+
#: (String method_name, String receiver_name, ?Array[String] seen_names, ?inherited_only: bool) -> Array[(Entry::Member | Entry::MethodAlias)]?
|
519
471
|
def resolve_method(method_name, receiver_name, seen_names = [], inherited_only: false)
|
520
472
|
method_entries = self[method_name]
|
521
473
|
return unless method_entries
|
@@ -553,7 +505,7 @@ module RubyIndexer
|
|
553
505
|
# module that prepends another module, then the prepend module appears before the included module.
|
554
506
|
#
|
555
507
|
# The order of ancestors is [linearized_prepends, self, linearized_includes, linearized_superclass]
|
556
|
-
|
508
|
+
#: (String fully_qualified_name) -> Array[String]
|
557
509
|
def linearized_ancestors_of(fully_qualified_name)
|
558
510
|
# If we already computed the ancestors for this namespace, return it straight away
|
559
511
|
cached_ancestors = @ancestors[fully_qualified_name]
|
@@ -602,11 +554,12 @@ module RubyIndexer
|
|
602
554
|
|
603
555
|
# The original nesting where we discovered this namespace, so that we resolve the correct names of the
|
604
556
|
# included/prepended/extended modules and parent classes
|
605
|
-
nesting =
|
557
|
+
nesting = namespaces.first #: as !nil
|
558
|
+
.nesting.flat_map { |n| n.split("::") }
|
606
559
|
|
607
560
|
if nesting.any?
|
608
561
|
singleton_levels.times do
|
609
|
-
nesting << "<Class:#{
|
562
|
+
nesting << "<Class:#{nesting.last}>"
|
610
563
|
end
|
611
564
|
end
|
612
565
|
|
@@ -631,7 +584,7 @@ module RubyIndexer
|
|
631
584
|
|
632
585
|
# Resolves an instance variable name for a given owner name. This method will linearize the ancestors of the owner
|
633
586
|
# and find inherited instance variables as well
|
634
|
-
|
587
|
+
#: (String variable_name, String owner_name) -> Array[Entry::InstanceVariable]?
|
635
588
|
def resolve_instance_variable(variable_name, owner_name)
|
636
589
|
entries = T.cast(self[variable_name], T.nilable(T::Array[Entry::InstanceVariable]))
|
637
590
|
return unless entries
|
@@ -642,7 +595,7 @@ module RubyIndexer
|
|
642
595
|
entries.select { |e| ancestors.include?(e.owner&.name) }
|
643
596
|
end
|
644
597
|
|
645
|
-
|
598
|
+
#: (String variable_name, String owner_name) -> Array[Entry::ClassVariable]?
|
646
599
|
def resolve_class_variable(variable_name, owner_name)
|
647
600
|
entries = self[variable_name]&.grep(Entry::ClassVariable)
|
648
601
|
return unless entries&.any?
|
@@ -655,9 +608,7 @@ module RubyIndexer
|
|
655
608
|
|
656
609
|
# Returns a list of possible candidates for completion of instance variables for a given owner name. The name must
|
657
610
|
# include the `@` prefix
|
658
|
-
|
659
|
-
params(name: String, owner_name: String).returns(T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
|
660
|
-
end
|
611
|
+
#: (String name, String owner_name) -> Array[(Entry::InstanceVariable | Entry::ClassVariable)]
|
661
612
|
def instance_variable_completion_candidates(name, owner_name)
|
662
613
|
entries = T.cast(prefix_search(name).flatten, T::Array[T.any(Entry::InstanceVariable, Entry::ClassVariable)])
|
663
614
|
# Avoid wasting time linearizing ancestors if we didn't find anything
|
@@ -674,7 +625,8 @@ module RubyIndexer
|
|
674
625
|
name_parts = owner_name.split("::")
|
675
626
|
|
676
627
|
if name_parts.last&.start_with?("<Class:")
|
677
|
-
attached_name =
|
628
|
+
attached_name = name_parts[0..-2] #: as !nil
|
629
|
+
.join("::")
|
678
630
|
attached_ancestors = linearized_ancestors_of(attached_name)
|
679
631
|
variables.concat(class_variables.select { |e| attached_ancestors.any?(e.owner&.name) })
|
680
632
|
else
|
@@ -686,7 +638,7 @@ module RubyIndexer
|
|
686
638
|
variables
|
687
639
|
end
|
688
640
|
|
689
|
-
|
641
|
+
#: (String name, String owner_name) -> Array[Entry::ClassVariable]
|
690
642
|
def class_variable_completion_candidates(name, owner_name)
|
691
643
|
entries = T.cast(prefix_search(name).flatten, T::Array[Entry::ClassVariable])
|
692
644
|
# Avoid wasting time linearizing ancestors if we didn't find anything
|
@@ -702,9 +654,7 @@ module RubyIndexer
|
|
702
654
|
# declarations removed and that the ancestor linearization cache is cleared if necessary. If a block is passed, the
|
703
655
|
# consumer of this API has to handle deleting and inserting/updating entries in the index instead of passing the
|
704
656
|
# document's source (used to handle unsaved changes to files)
|
705
|
-
|
706
|
-
params(uri: URI::Generic, source: T.nilable(String), block: T.nilable(T.proc.params(index: Index).void)).void
|
707
|
-
end
|
657
|
+
#: (URI::Generic uri, ?String? source) ?{ (Index index) -> void } -> void
|
708
658
|
def handle_change(uri, source = nil, &block)
|
709
659
|
key = uri.to_s
|
710
660
|
original_entries = @uris_to_entries[key]
|
@@ -713,7 +663,10 @@ module RubyIndexer
|
|
713
663
|
block.call(self)
|
714
664
|
else
|
715
665
|
delete(uri)
|
716
|
-
index_single(
|
666
|
+
index_single(
|
667
|
+
uri,
|
668
|
+
source, #: as !nil
|
669
|
+
)
|
717
670
|
end
|
718
671
|
|
719
672
|
updated_entries = @uris_to_entries[key]
|
@@ -736,34 +689,34 @@ module RubyIndexer
|
|
736
689
|
@ancestors.clear if original_map.any? { |name, hash| updated_map[name] != hash }
|
737
690
|
end
|
738
691
|
|
739
|
-
|
692
|
+
#: -> bool
|
740
693
|
def empty?
|
741
694
|
@entries.empty?
|
742
695
|
end
|
743
696
|
|
744
|
-
|
697
|
+
#: -> Array[String]
|
745
698
|
def names
|
746
699
|
@entries.keys
|
747
700
|
end
|
748
701
|
|
749
|
-
|
702
|
+
#: (String name) -> bool
|
750
703
|
def indexed?(name)
|
751
704
|
@entries.key?(name)
|
752
705
|
end
|
753
706
|
|
754
|
-
|
707
|
+
#: -> Integer
|
755
708
|
def length
|
756
709
|
@entries.count
|
757
710
|
end
|
758
711
|
|
759
|
-
|
712
|
+
#: (String name) -> Entry::SingletonClass
|
760
713
|
def existing_or_new_singleton_class(name)
|
761
714
|
*_namespace, unqualified_name = name.split("::")
|
762
715
|
full_singleton_name = "#{name}::<Class:#{unqualified_name}>"
|
763
716
|
singleton = T.cast(self[full_singleton_name]&.first, T.nilable(Entry::SingletonClass))
|
764
717
|
|
765
718
|
unless singleton
|
766
|
-
attached_ancestor =
|
719
|
+
attached_ancestor = self[name]&.first #: as !nil
|
767
720
|
|
768
721
|
singleton = Entry::SingletonClass.new(
|
769
722
|
[full_singleton_name],
|
@@ -779,12 +732,7 @@ module RubyIndexer
|
|
779
732
|
singleton
|
780
733
|
end
|
781
734
|
|
782
|
-
|
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
|
735
|
+
#: [T] (String uri, ?Class[(T & Entry)]? type) -> (Array[Entry] | Array[T])?
|
788
736
|
def entries_for(uri, type = nil)
|
789
737
|
entries = @uris_to_entries[uri.to_s]
|
790
738
|
return entries unless type
|
@@ -796,12 +744,13 @@ module RubyIndexer
|
|
796
744
|
|
797
745
|
# Always returns the linearized ancestors for the attached class, regardless of whether `name` refers to a singleton
|
798
746
|
# or attached namespace
|
799
|
-
|
747
|
+
#: (String name) -> Array[String]
|
800
748
|
def linearized_attached_ancestors(name)
|
801
749
|
name_parts = name.split("::")
|
802
750
|
|
803
751
|
if name_parts.last&.start_with?("<Class:")
|
804
|
-
attached_name =
|
752
|
+
attached_name = name_parts[0..-2] #: as !nil
|
753
|
+
.join("::")
|
805
754
|
linearized_ancestors_of(attached_name)
|
806
755
|
else
|
807
756
|
linearized_ancestors_of(name)
|
@@ -809,7 +758,7 @@ module RubyIndexer
|
|
809
758
|
end
|
810
759
|
|
811
760
|
# Runs the registered included hooks
|
812
|
-
|
761
|
+
#: (String fully_qualified_name, Array[String] nesting) -> void
|
813
762
|
def run_included_hooks(fully_qualified_name, nesting)
|
814
763
|
return if @included_hooks.empty?
|
815
764
|
|
@@ -824,7 +773,8 @@ module RubyIndexer
|
|
824
773
|
resolved_modules = resolve(operation.module_name, nesting)
|
825
774
|
next unless resolved_modules
|
826
775
|
|
827
|
-
module_name =
|
776
|
+
module_name = resolved_modules.first #: as !nil
|
777
|
+
.name
|
828
778
|
|
829
779
|
# Then we grab any hooks registered for that module
|
830
780
|
hooks = @included_hooks[module_name]
|
@@ -838,13 +788,7 @@ module RubyIndexer
|
|
838
788
|
|
839
789
|
# Linearize mixins for an array of namespace entries. This method will mutate the `ancestors` array with the
|
840
790
|
# linearized ancestors of the mixins
|
841
|
-
|
842
|
-
params(
|
843
|
-
ancestors: T::Array[String],
|
844
|
-
namespace_entries: T::Array[Entry::Namespace],
|
845
|
-
nesting: T::Array[String],
|
846
|
-
).void
|
847
|
-
end
|
791
|
+
#: (Array[String] ancestors, Array[Entry::Namespace] namespace_entries, Array[String] nesting) -> void
|
848
792
|
def linearize_mixins(ancestors, namespace_entries, nesting)
|
849
793
|
mixin_operations = namespace_entries.flat_map(&:mixin_operations)
|
850
794
|
main_namespace_index = 0
|
@@ -853,7 +797,8 @@ module RubyIndexer
|
|
853
797
|
resolved_module = resolve(operation.module_name, nesting)
|
854
798
|
next unless resolved_module
|
855
799
|
|
856
|
-
module_fully_qualified_name =
|
800
|
+
module_fully_qualified_name = resolved_module.first #: as !nil
|
801
|
+
.name
|
857
802
|
|
858
803
|
case operation
|
859
804
|
when Entry::Prepend
|
@@ -865,36 +810,27 @@ module RubyIndexer
|
|
865
810
|
# When there are duplicate prepended modules, we have to insert the new prepends after the existing ones. For
|
866
811
|
# example, if the current ancestors are `["A", "Foo"]` and we try to prepend `["A", "B"]`, then `"B"` has to
|
867
812
|
# be inserted after `"A`
|
868
|
-
|
813
|
+
prepended_ancestors = ancestors[0...main_namespace_index] #: as !nil
|
814
|
+
uniq_prepends = linearized_prepends - prepended_ancestors
|
869
815
|
insert_position = linearized_prepends.length - uniq_prepends.length
|
870
816
|
|
871
|
-
|
872
|
-
insert_position,
|
873
|
-
*(linearized_prepends - T.must(ancestors[0...main_namespace_index])),
|
874
|
-
)
|
817
|
+
ancestors #: as untyped
|
818
|
+
.insert(insert_position, *uniq_prepends)
|
875
819
|
|
876
820
|
main_namespace_index += linearized_prepends.length
|
877
821
|
when Entry::Include
|
878
822
|
# When including a module, Ruby will always prevent duplicate entries in case the module has already been
|
879
823
|
# prepended or included
|
880
824
|
linearized_includes = linearized_ancestors_of(module_fully_qualified_name)
|
881
|
-
|
825
|
+
ancestors #: as untyped
|
826
|
+
.insert(main_namespace_index + 1, *(linearized_includes - ancestors))
|
882
827
|
end
|
883
828
|
end
|
884
829
|
end
|
885
830
|
|
886
831
|
# Linearize the superclass of a given namespace (including modules with the implicit `Module` superclass). This
|
887
832
|
# method will mutate the `ancestors` array with the linearized ancestors of the superclass
|
888
|
-
|
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
|
833
|
+
#: (Array[String] ancestors, String attached_class_name, String fully_qualified_name, Array[Entry::Namespace] namespace_entries, Array[String] nesting, Integer singleton_levels) -> void
|
898
834
|
def linearize_superclass( # rubocop:disable Metrics/ParameterLists
|
899
835
|
ancestors,
|
900
836
|
attached_class_name,
|
@@ -917,7 +853,7 @@ module RubyIndexer
|
|
917
853
|
if superclass
|
918
854
|
# If the user makes a mistake and creates a class that inherits from itself, this method would throw a stack
|
919
855
|
# error. We need to ensure that this isn't the case
|
920
|
-
parent_class =
|
856
|
+
parent_class = superclass.parent_class #: as !nil
|
921
857
|
|
922
858
|
resolved_parent_class = resolve(parent_class, nesting)
|
923
859
|
parent_class_name = resolved_parent_class&.first&.name
|
@@ -962,12 +898,7 @@ module RubyIndexer
|
|
962
898
|
|
963
899
|
# Attempts to resolve an UnresolvedAlias into a resolved Alias. If the unresolved alias is pointing to a constant
|
964
900
|
# that doesn't exist, then we return the same UnresolvedAlias
|
965
|
-
|
966
|
-
params(
|
967
|
-
entry: Entry::UnresolvedConstantAlias,
|
968
|
-
seen_names: T::Array[String],
|
969
|
-
).returns(T.any(Entry::ConstantAlias, Entry::UnresolvedConstantAlias))
|
970
|
-
end
|
901
|
+
#: (Entry::UnresolvedConstantAlias entry, Array[String] seen_names) -> (Entry::ConstantAlias | Entry::UnresolvedConstantAlias)
|
971
902
|
def resolve_alias(entry, seen_names)
|
972
903
|
alias_name = entry.name
|
973
904
|
return entry if seen_names.include?(alias_name)
|
@@ -977,11 +908,12 @@ module RubyIndexer
|
|
977
908
|
target = resolve(entry.target, entry.nesting, seen_names)
|
978
909
|
return entry unless target
|
979
910
|
|
980
|
-
target_name =
|
911
|
+
target_name = target.first #: as !nil
|
912
|
+
.name
|
981
913
|
resolved_alias = Entry::ConstantAlias.new(target_name, entry)
|
982
914
|
|
983
915
|
# Replace the UnresolvedAlias by a resolved one so that we don't have to do this again later
|
984
|
-
original_entries =
|
916
|
+
original_entries = @entries[alias_name] #: as !nil
|
985
917
|
original_entries.delete(entry)
|
986
918
|
original_entries << resolved_alias
|
987
919
|
|
@@ -990,20 +922,11 @@ module RubyIndexer
|
|
990
922
|
resolved_alias
|
991
923
|
end
|
992
924
|
|
993
|
-
|
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
|
925
|
+
#: (String name, Array[String] nesting, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
|
1004
926
|
def lookup_enclosing_scopes(name, nesting, seen_names)
|
1005
927
|
nesting.length.downto(1) do |i|
|
1006
|
-
namespace =
|
928
|
+
namespace = nesting[0...i] #: as !nil
|
929
|
+
.join("::")
|
1007
930
|
|
1008
931
|
# If we find an entry with `full_name` directly, then we can already return it, even if it contains aliases -
|
1009
932
|
# because the user might be trying to jump to the alias definition.
|
@@ -1019,17 +942,7 @@ module RubyIndexer
|
|
1019
942
|
nil
|
1020
943
|
end
|
1021
944
|
|
1022
|
-
|
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
|
945
|
+
#: (String name, Array[String] nesting, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
|
1033
946
|
def lookup_ancestor_chain(name, nesting, seen_names)
|
1034
947
|
*nesting_parts, constant_name = build_non_redundant_full_name(name, nesting).split("::")
|
1035
948
|
return if nesting_parts.empty?
|
@@ -1037,7 +950,9 @@ module RubyIndexer
|
|
1037
950
|
namespace_entries = resolve(nesting_parts.join("::"), [], seen_names)
|
1038
951
|
return unless namespace_entries
|
1039
952
|
|
1040
|
-
|
953
|
+
namespace_name = namespace_entries.first #: as !nil
|
954
|
+
.name
|
955
|
+
ancestors = nesting_parts.empty? ? [] : linearized_ancestors_of(namespace_name)
|
1041
956
|
|
1042
957
|
ancestors.each do |ancestor_name|
|
1043
958
|
entries = direct_or_aliased_constant("#{ancestor_name}::#{constant_name}", seen_names)
|
@@ -1049,17 +964,7 @@ module RubyIndexer
|
|
1049
964
|
nil
|
1050
965
|
end
|
1051
966
|
|
1052
|
-
|
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
|
967
|
+
#: (String? name, Array[String] nesting) -> Array[Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias | Entry::Constant)]]
|
1063
968
|
def inherited_constant_completion_candidates(name, nesting)
|
1064
969
|
namespace_entries = if name
|
1065
970
|
*nesting_parts, constant_name = build_non_redundant_full_name(name, nesting).split("::")
|
@@ -1071,7 +976,9 @@ module RubyIndexer
|
|
1071
976
|
end
|
1072
977
|
return [] unless namespace_entries
|
1073
978
|
|
1074
|
-
|
979
|
+
namespace_name = namespace_entries.first #: as !nil
|
980
|
+
.name
|
981
|
+
ancestors = linearized_ancestors_of(namespace_name)
|
1075
982
|
candidates = ancestors.flat_map do |ancestor_name|
|
1076
983
|
@entries_tree.search("#{ancestor_name}::#{constant_name}")
|
1077
984
|
end
|
@@ -1079,7 +986,8 @@ module RubyIndexer
|
|
1079
986
|
# For candidates with the same name, we must only show the first entry in the inheritance chain, since that's the
|
1080
987
|
# one the user will be referring to in completion
|
1081
988
|
completion_items = candidates.each_with_object({}) do |entries, hash|
|
1082
|
-
*parts, short_name =
|
989
|
+
*parts, short_name = entries.first #: as !nil
|
990
|
+
.name.split("::")
|
1083
991
|
namespace_name = parts.join("::")
|
1084
992
|
ancestor_index = ancestors.index(namespace_name)
|
1085
993
|
existing_entry, existing_entry_index = hash[short_name]
|
@@ -1098,7 +1006,7 @@ module RubyIndexer
|
|
1098
1006
|
# inside of the ["A", "B"] nesting, then we should not concatenate the nesting with the name or else we'll end up
|
1099
1007
|
# with `A::B::A::B::Foo`. This method will remove any redundant parts from the final name based on the reference and
|
1100
1008
|
# the nesting
|
1101
|
-
|
1009
|
+
#: (String name, Array[String] nesting) -> String
|
1102
1010
|
def build_non_redundant_full_name(name, nesting)
|
1103
1011
|
# If there's no nesting, then we can just return the name as is
|
1104
1012
|
return name if nesting.empty?
|
@@ -1115,22 +1023,11 @@ module RubyIndexer
|
|
1115
1023
|
# Otherwise, push all of the leading parts of the nesting that aren't redundant into the name. For example, if we
|
1116
1024
|
# have a reference to `Foo::Bar` inside the `[Namespace, Foo]` nesting, then only the `Foo` part is redundant, but
|
1117
1025
|
# we still need to include the `Namespace` part
|
1118
|
-
|
1026
|
+
name_parts.unshift(*nesting[0...first_redundant_part])
|
1119
1027
|
name_parts.join("::")
|
1120
1028
|
end
|
1121
1029
|
|
1122
|
-
|
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
|
1030
|
+
#: (String full_name, Array[String] seen_names) -> Array[(Entry::Namespace | Entry::ConstantAlias | Entry::UnresolvedConstantAlias)]?
|
1134
1031
|
def direct_or_aliased_constant(full_name, seen_names)
|
1135
1032
|
entries = @entries[full_name] || @entries[follow_aliased_namespace(full_name)]
|
1136
1033
|
|
@@ -1146,13 +1043,7 @@ module RubyIndexer
|
|
1146
1043
|
|
1147
1044
|
# Attempt to resolve a given unresolved method alias. This method returns the resolved alias if we managed to
|
1148
1045
|
# identify the target or the same unresolved alias entry if we couldn't
|
1149
|
-
|
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
|
1046
|
+
#: (Entry::UnresolvedMethodAlias entry, String receiver_name, Array[String] seen_names) -> (Entry::MethodAlias | Entry::UnresolvedMethodAlias)
|
1156
1047
|
def resolve_method_alias(entry, receiver_name, seen_names)
|
1157
1048
|
new_name = entry.new_name
|
1158
1049
|
return entry if new_name == entry.old_name
|
@@ -1163,8 +1054,11 @@ module RubyIndexer
|
|
1163
1054
|
target_method_entries = resolve_method(entry.old_name, receiver_name, seen_names)
|
1164
1055
|
return entry unless target_method_entries
|
1165
1056
|
|
1166
|
-
resolved_alias = Entry::MethodAlias.new(
|
1167
|
-
|
1057
|
+
resolved_alias = Entry::MethodAlias.new(
|
1058
|
+
target_method_entries.first, #: as !nil
|
1059
|
+
entry,
|
1060
|
+
)
|
1061
|
+
original_entries = @entries[new_name] #: as !nil
|
1168
1062
|
original_entries.delete(entry)
|
1169
1063
|
original_entries << resolved_alias
|
1170
1064
|
resolved_alias
|