solargraph 0.58.1 → 0.59.0.dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop_todo.yml +27 -49
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/lib/solargraph/api_map/cache.rb +110 -110
- data/lib/solargraph/api_map/constants.rb +289 -279
- data/lib/solargraph/api_map/index.rb +204 -193
- data/lib/solargraph/api_map/source_to_yard.rb +109 -97
- data/lib/solargraph/api_map/store.rb +387 -384
- data/lib/solargraph/api_map.rb +1000 -945
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +242 -228
- data/lib/solargraph/complex_type/unique_type.rb +632 -482
- data/lib/solargraph/complex_type.rb +549 -444
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
- data/lib/solargraph/convention/data_definition.rb +108 -105
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
- data/lib/solargraph/convention/struct_definition.rb +168 -164
- data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
- data/lib/solargraph/diagnostics/rubocop.rb +119 -118
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
- data/lib/solargraph/diagnostics/type_check.rb +56 -55
- data/lib/solargraph/doc_map.rb +200 -439
- data/lib/solargraph/equality.rb +34 -34
- data/lib/solargraph/gem_pins.rb +97 -98
- data/lib/solargraph/language_server/host/dispatch.rb +131 -130
- data/lib/solargraph/language_server/host/message_worker.rb +113 -112
- data/lib/solargraph/language_server/host/sources.rb +100 -99
- data/lib/solargraph/language_server/host.rb +883 -878
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
- data/lib/solargraph/language_server/message/extended/document.rb +24 -23
- data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
- data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
- data/lib/solargraph/library.rb +729 -683
- data/lib/solargraph/location.rb +87 -82
- data/lib/solargraph/logging.rb +57 -37
- data/lib/solargraph/parser/comment_ripper.rb +76 -69
- data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
- data/lib/solargraph/parser/node_processor/base.rb +122 -92
- data/lib/solargraph/parser/node_processor.rb +63 -62
- data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
- data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
- data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
- data/lib/solargraph/parser/region.rb +75 -69
- data/lib/solargraph/parser/snippet.rb +17 -17
- data/lib/solargraph/pin/base.rb +761 -729
- data/lib/solargraph/pin/base_variable.rb +418 -126
- data/lib/solargraph/pin/block.rb +126 -104
- data/lib/solargraph/pin/breakable.rb +13 -9
- data/lib/solargraph/pin/callable.rb +278 -231
- data/lib/solargraph/pin/closure.rb +68 -72
- data/lib/solargraph/pin/common.rb +94 -79
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +124 -123
- data/lib/solargraph/pin/delegated_method.rb +131 -120
- data/lib/solargraph/pin/documenting.rb +115 -114
- data/lib/solargraph/pin/instance_variable.rb +38 -34
- data/lib/solargraph/pin/keyword.rb +16 -20
- data/lib/solargraph/pin/local_variable.rb +31 -75
- data/lib/solargraph/pin/method.rb +720 -672
- data/lib/solargraph/pin/method_alias.rb +42 -34
- data/lib/solargraph/pin/namespace.rb +121 -115
- data/lib/solargraph/pin/parameter.rb +338 -275
- data/lib/solargraph/pin/proxy_type.rb +40 -39
- data/lib/solargraph/pin/reference/override.rb +47 -47
- data/lib/solargraph/pin/reference/superclass.rb +17 -15
- data/lib/solargraph/pin/reference.rb +41 -39
- data/lib/solargraph/pin/search.rb +62 -61
- data/lib/solargraph/pin/signature.rb +69 -61
- data/lib/solargraph/pin/symbol.rb +53 -53
- data/lib/solargraph/pin/until.rb +18 -18
- data/lib/solargraph/pin/while.rb +18 -18
- data/lib/solargraph/pin.rb +46 -44
- data/lib/solargraph/pin_cache.rb +665 -245
- data/lib/solargraph/position.rb +118 -119
- data/lib/solargraph/range.rb +112 -112
- data/lib/solargraph/rbs_map/conversions.rb +846 -823
- data/lib/solargraph/rbs_map/core_map.rb +65 -58
- data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
- data/lib/solargraph/rbs_map.rb +217 -163
- data/lib/solargraph/shell.rb +397 -352
- data/lib/solargraph/source/chain/call.rb +372 -337
- data/lib/solargraph/source/chain/constant.rb +28 -26
- data/lib/solargraph/source/chain/hash.rb +35 -34
- data/lib/solargraph/source/chain/if.rb +29 -28
- data/lib/solargraph/source/chain/instance_variable.rb +34 -13
- data/lib/solargraph/source/chain/literal.rb +53 -48
- data/lib/solargraph/source/chain/or.rb +31 -23
- data/lib/solargraph/source/chain.rb +294 -291
- data/lib/solargraph/source/change.rb +89 -82
- data/lib/solargraph/source/cursor.rb +172 -166
- data/lib/solargraph/source/source_chainer.rb +204 -194
- data/lib/solargraph/source/updater.rb +59 -55
- data/lib/solargraph/source.rb +524 -498
- data/lib/solargraph/source_map/clip.rb +237 -226
- data/lib/solargraph/source_map/data.rb +37 -34
- data/lib/solargraph/source_map/mapper.rb +282 -259
- data/lib/solargraph/source_map.rb +220 -212
- data/lib/solargraph/type_checker/problem.rb +34 -32
- data/lib/solargraph/type_checker/rules.rb +157 -84
- data/lib/solargraph/type_checker.rb +895 -814
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +257 -255
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +98 -97
- data/lib/solargraph/workspace.rb +362 -220
- data/lib/solargraph/yard_map/helpers.rb +45 -44
- data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
- data/lib/solargraph/yard_map/mapper.rb +84 -79
- data/lib/solargraph/yardoc.rb +97 -87
- data/lib/solargraph.rb +126 -105
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +5 -0
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/rbs_collection.yaml +1 -1
- data/solargraph.gemspec +2 -1
- metadata +22 -17
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
- data/sig/shims/ast/0/node.rbs +0 -5
- /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
|
@@ -1,279 +1,289 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class ApiMap
|
|
5
|
-
# Methods for handling constants.
|
|
6
|
-
#
|
|
7
|
-
class Constants
|
|
8
|
-
# @param store [Store]
|
|
9
|
-
def initialize store
|
|
10
|
-
@store = store
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Resolve a name to a fully qualified namespace or constant.
|
|
14
|
-
#
|
|
15
|
-
# `Constants#resolve` finds fully qualified (absolute)
|
|
16
|
-
# namespaces based on relative names and the open gates
|
|
17
|
-
# (namespaces) provided. Names must be runtime-visible (erased)
|
|
18
|
-
# non-literal types, non-duck, non-signature types - e.g.,
|
|
19
|
-
# TrueClass, NilClass, Integer and Hash instead of true, nil,
|
|
20
|
-
# 96, or Hash{String => Symbol}
|
|
21
|
-
#
|
|
22
|
-
# Note: You may want to be using #qualify. Notably, #resolve:
|
|
23
|
-
# - does not handle anything with type parameters
|
|
24
|
-
# - will not gracefully handle nil, self and Boolean
|
|
25
|
-
# - will return a constant name instead of following its assignment
|
|
26
|
-
#
|
|
27
|
-
# @param name [String] Namespace which may relative and not be rooted.
|
|
28
|
-
# @param gates [Array<Array<String>, String>] Namespaces to search while resolving the name
|
|
29
|
-
#
|
|
30
|
-
# @
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
# @
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
# @
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# @
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
# @
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
#
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
#
|
|
202
|
-
#
|
|
203
|
-
#
|
|
204
|
-
#
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
roots.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
incs
|
|
242
|
-
|
|
243
|
-
foundinc
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class ApiMap
|
|
5
|
+
# Methods for handling constants.
|
|
6
|
+
#
|
|
7
|
+
class Constants
|
|
8
|
+
# @param store [Store]
|
|
9
|
+
def initialize store
|
|
10
|
+
@store = store
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Resolve a name to a fully qualified namespace or constant.
|
|
14
|
+
#
|
|
15
|
+
# `Constants#resolve` finds fully qualified (absolute)
|
|
16
|
+
# namespaces based on relative names and the open gates
|
|
17
|
+
# (namespaces) provided. Names must be runtime-visible (erased)
|
|
18
|
+
# non-literal types, non-duck, non-signature types - e.g.,
|
|
19
|
+
# TrueClass, NilClass, Integer and Hash instead of true, nil,
|
|
20
|
+
# 96, or Hash{String => Symbol}
|
|
21
|
+
#
|
|
22
|
+
# Note: You may want to be using #qualify. Notably, #resolve:
|
|
23
|
+
# - does not handle anything with type parameters
|
|
24
|
+
# - will not gracefully handle nil, self and Boolean
|
|
25
|
+
# - will return a constant name instead of following its assignment
|
|
26
|
+
#
|
|
27
|
+
# @param name [String] Namespace which may relative and not be rooted.
|
|
28
|
+
# @param gates [Array<Array<String>, String>] Namespaces to search while resolving the name
|
|
29
|
+
#
|
|
30
|
+
# @sg-ignore flow sensitive typing needs to eliminate literal from union with return if foo == :bar
|
|
31
|
+
# @return [String, nil] fully qualified namespace (i.e., is
|
|
32
|
+
# absolute, but will not start with ::)
|
|
33
|
+
def resolve(name, *gates)
|
|
34
|
+
# @sg-ignore Need to add nil check here
|
|
35
|
+
return store.get_path_pins(name[2..]).first&.path if name.start_with?('::')
|
|
36
|
+
|
|
37
|
+
flat = gates.flatten
|
|
38
|
+
flat.push '' if flat.empty?
|
|
39
|
+
if cached_resolve.include? [name, flat]
|
|
40
|
+
cached_result = cached_resolve[[name, flat]]
|
|
41
|
+
# don't recurse
|
|
42
|
+
return nil if cached_result == :in_process
|
|
43
|
+
return cached_result
|
|
44
|
+
end
|
|
45
|
+
resolve_and_cache(name, flat)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get a fully qualified namespace from a reference pin.
|
|
49
|
+
#
|
|
50
|
+
# @param pin [Pin::Reference]
|
|
51
|
+
# @return [String, nil]
|
|
52
|
+
def dereference pin
|
|
53
|
+
qualify_type(pin.type, *pin.reference_gates)&.tag
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Collect a list of all constants defined in the specified gates.
|
|
57
|
+
#
|
|
58
|
+
# @param gates [Array<Array<String>, String>]
|
|
59
|
+
# @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
60
|
+
def collect(*gates)
|
|
61
|
+
flat = gates.flatten
|
|
62
|
+
cached_collect[flat] || collect_and_cache(flat)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Determine a fully qualified namespace for a given tag
|
|
66
|
+
# referenced from the specified open gates. This method will
|
|
67
|
+
# search in each gate until it finds a match for the name.
|
|
68
|
+
#
|
|
69
|
+
# @param tag [String, nil] The type to match
|
|
70
|
+
# @param gates [Array<String>]
|
|
71
|
+
# @return [String, nil] fully qualified tag
|
|
72
|
+
def qualify tag, *gates
|
|
73
|
+
type = ComplexType.try_parse(tag)
|
|
74
|
+
qualify_type(type, *gates)&.tag
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @param type [ComplexType, nil] The type to match
|
|
78
|
+
# @param gates [Array<String>]
|
|
79
|
+
#
|
|
80
|
+
# @return [ComplexType, nil] A new rooted ComplexType
|
|
81
|
+
def qualify_type type, *gates
|
|
82
|
+
return nil if type.nil?
|
|
83
|
+
return type if type.selfy? || type.literal? || type.tag == 'nil' || type.interface? ||
|
|
84
|
+
type.tag == 'Boolean'
|
|
85
|
+
|
|
86
|
+
gates.push '' unless gates.include?('')
|
|
87
|
+
fqns = resolve(type.rooted_namespace, *gates)
|
|
88
|
+
return unless fqns
|
|
89
|
+
pin = store.get_path_pins(fqns).first
|
|
90
|
+
if pin.is_a?(Pin::Constant)
|
|
91
|
+
# @sg-ignore Need to add nil check here
|
|
92
|
+
const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment)
|
|
93
|
+
return unless const
|
|
94
|
+
fqns = resolve(const, *pin.gates)
|
|
95
|
+
end
|
|
96
|
+
type.recreate(new_name: fqns, make_rooted: true)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @return [void]
|
|
100
|
+
def clear
|
|
101
|
+
[cached_collect, cached_resolve].each(&:clear)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
# @return [Store]
|
|
107
|
+
attr_reader :store
|
|
108
|
+
|
|
109
|
+
# @param name [String]
|
|
110
|
+
# @param gates [Array<String>]
|
|
111
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
112
|
+
# @return [String, nil]
|
|
113
|
+
def resolve_and_cache name, gates
|
|
114
|
+
cached_resolve[[name, gates]] = :in_process
|
|
115
|
+
cached_resolve[[name, gates]] = resolve_uncached(name, gates)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @param name [String]
|
|
119
|
+
# @param gates [Array<String>]
|
|
120
|
+
# @return [String, nil]
|
|
121
|
+
def resolve_uncached name, gates
|
|
122
|
+
resolved = nil
|
|
123
|
+
base = gates
|
|
124
|
+
parts = name.split('::')
|
|
125
|
+
first = nil
|
|
126
|
+
parts.each.with_index do |nam, idx|
|
|
127
|
+
resolved, remainder = complex_resolve(nam, base, idx != parts.length - 1)
|
|
128
|
+
first ||= remainder
|
|
129
|
+
if resolved
|
|
130
|
+
base = [resolved]
|
|
131
|
+
else
|
|
132
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
133
|
+
return resolve(name, first) unless first.empty?
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
resolved
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# @todo I'm not sure of a better way to express the return value in YARD.
|
|
140
|
+
# It's a tuple where the first element is a nullable string. Something
|
|
141
|
+
# like `Array(String|nil, Array<String>)` would be more accurate.
|
|
142
|
+
#
|
|
143
|
+
# @param name [String]
|
|
144
|
+
# @param gates [Array<String>]
|
|
145
|
+
# @param internal [Boolean] True if the name is not the last in the namespace
|
|
146
|
+
# @return [Array(String, Array<String>), Array(nil, Array<String>), String]
|
|
147
|
+
def complex_resolve name, gates, internal
|
|
148
|
+
resolved = nil
|
|
149
|
+
gates.each.with_index do |gate, idx|
|
|
150
|
+
resolved = simple_resolve(name, gate, internal)
|
|
151
|
+
return [resolved, gates[(idx + 1)..]] if resolved
|
|
152
|
+
store.get_ancestor_references(gate).each do |ref|
|
|
153
|
+
return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") && ref.name.start_with?('::')
|
|
154
|
+
|
|
155
|
+
mixin = resolve(ref.name, ref.reference_gates)
|
|
156
|
+
next unless mixin
|
|
157
|
+
|
|
158
|
+
resolved = simple_resolve(name, mixin, internal)
|
|
159
|
+
return [resolved, gates[(idx + 1)..]] if resolved
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
[nil, []]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# @param name [String]
|
|
166
|
+
# @param gate [String]
|
|
167
|
+
# @param internal [Boolean] True if the name is not the last in the namespace
|
|
168
|
+
# @return [String, nil]
|
|
169
|
+
def simple_resolve name, gate, internal
|
|
170
|
+
here = "#{gate}::#{name}".sub(/^::/, '').sub(/::$/, '')
|
|
171
|
+
pin = store.get_path_pins(here).first
|
|
172
|
+
if pin.is_a?(Pin::Constant) && internal
|
|
173
|
+
# @sg-ignore Need to add nil check here
|
|
174
|
+
const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment)
|
|
175
|
+
return unless const
|
|
176
|
+
resolve(const, pin.gates)
|
|
177
|
+
else
|
|
178
|
+
pin&.path
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# @param gates [Array<String>]
|
|
183
|
+
# @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
184
|
+
def collect_and_cache gates
|
|
185
|
+
skip = Set.new
|
|
186
|
+
cached_collect[gates] = gates.flat_map do |gate|
|
|
187
|
+
inner_get_constants(gate, %i[public private], skip)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @return [Hash{Array(String, Array<String>) => String, :in_process, nil}]
|
|
192
|
+
def cached_resolve
|
|
193
|
+
@cached_resolve ||= {}
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @return [Hash{Array<String> => Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>}]
|
|
197
|
+
def cached_collect
|
|
198
|
+
@cached_collect ||= {}
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Determine fully qualified namespace for a given namespace used
|
|
202
|
+
# inside the definition of another tag ("context"). This method
|
|
203
|
+
# will start the search in the specified context until it finds a
|
|
204
|
+
# match for the namespace.
|
|
205
|
+
#
|
|
206
|
+
# @param namespace [String] The namespace to
|
|
207
|
+
# match
|
|
208
|
+
# @param context_namespace [String] The context namespace in which the
|
|
209
|
+
# tag was referenced; start from here to resolve the name
|
|
210
|
+
# @return [String, nil] fully qualified namespace
|
|
211
|
+
def qualify_namespace namespace, context_namespace = ''
|
|
212
|
+
if namespace.start_with?('::')
|
|
213
|
+
# @sg-ignore Need to add nil check here
|
|
214
|
+
inner_qualify(namespace[2..], '', Set.new)
|
|
215
|
+
else
|
|
216
|
+
inner_qualify(namespace, context_namespace, Set.new)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# @param name [String] Namespace to fully qualify
|
|
221
|
+
# @param root [String] The context to search
|
|
222
|
+
# @param skip [Set<String>] Contexts already searched
|
|
223
|
+
# @return [String, nil] Fully qualified ("rooted") namespace
|
|
224
|
+
def inner_qualify name, root, skip
|
|
225
|
+
return name if name == ComplexType::GENERIC_TAG_NAME
|
|
226
|
+
return nil if name.nil?
|
|
227
|
+
return nil if skip.include?(root)
|
|
228
|
+
skip.add root
|
|
229
|
+
possibles = []
|
|
230
|
+
if name == ''
|
|
231
|
+
return '' if root == ''
|
|
232
|
+
|
|
233
|
+
inner_qualify(root, '', skip)
|
|
234
|
+
else
|
|
235
|
+
return name if root == '' && store.namespace_exists?(name)
|
|
236
|
+
roots = root.to_s.split('::')
|
|
237
|
+
while roots.length.positive?
|
|
238
|
+
fqns = "#{roots.join('::')}::#{name}"
|
|
239
|
+
return fqns if store.namespace_exists?(fqns)
|
|
240
|
+
incs = store.get_includes(roots.join('::'))
|
|
241
|
+
incs.each do |inc|
|
|
242
|
+
foundinc = inner_qualify(name, inc.type.to_s, skip)
|
|
243
|
+
possibles.push foundinc unless foundinc.nil?
|
|
244
|
+
end
|
|
245
|
+
roots.pop
|
|
246
|
+
end
|
|
247
|
+
if possibles.empty?
|
|
248
|
+
incs = store.get_includes('')
|
|
249
|
+
incs.each do |inc|
|
|
250
|
+
foundinc = inner_qualify(name, inc.type.to_s, skip)
|
|
251
|
+
possibles.push foundinc unless foundinc.nil?
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
return name if store.namespace_exists?(name)
|
|
255
|
+
possibles.last
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# @param fqns [String, nil]
|
|
260
|
+
# @param visibility [Array<Symbol>]
|
|
261
|
+
# @param skip [Set<String>]
|
|
262
|
+
# @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
263
|
+
def inner_get_constants fqns, visibility, skip
|
|
264
|
+
return [] if fqns.nil? || skip.include?(fqns)
|
|
265
|
+
skip.add fqns
|
|
266
|
+
result = []
|
|
267
|
+
|
|
268
|
+
store.get_prepends(fqns).each do |pre|
|
|
269
|
+
# @sg-ignore Need to add nil check here
|
|
270
|
+
pre_fqns = resolve(pre.name, pre.closure.gates - skip.to_a)
|
|
271
|
+
result.concat inner_get_constants(pre_fqns, [:public], skip)
|
|
272
|
+
end
|
|
273
|
+
result.concat(store.get_constants(fqns, visibility).sort { |a, b| a.name <=> b.name })
|
|
274
|
+
store.get_includes(fqns).each do |pin|
|
|
275
|
+
# @sg-ignore Need to add nil check here
|
|
276
|
+
inc_fqns = resolve(pin.name, pin.closure.gates - skip.to_a)
|
|
277
|
+
result.concat inner_get_constants(inc_fqns, [:public], skip)
|
|
278
|
+
end
|
|
279
|
+
sc_ref = store.get_superclass(fqns)
|
|
280
|
+
if sc_ref
|
|
281
|
+
fqsc = dereference(sc_ref)
|
|
282
|
+
# @sg-ignore Need to add nil check here
|
|
283
|
+
result.concat inner_get_constants(fqsc, [:public], skip) unless %w[Object BasicObject].include?(fqsc)
|
|
284
|
+
end
|
|
285
|
+
result
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|