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,337 +1,372 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
#
|
|
7
|
-
# Handles both method calls and local variable references by
|
|
8
|
-
# first looking for a variable with the name 'word', then
|
|
9
|
-
# proceeding to method signature resolution if not found.
|
|
10
|
-
#
|
|
11
|
-
class Call < Chain::Link
|
|
12
|
-
include Solargraph::Parser::NodeMethods
|
|
13
|
-
|
|
14
|
-
# @return [String]
|
|
15
|
-
attr_reader :word
|
|
16
|
-
|
|
17
|
-
# @return [Location]
|
|
18
|
-
attr_reader :location
|
|
19
|
-
|
|
20
|
-
# @return [::Array<Chain>]
|
|
21
|
-
attr_reader :arguments
|
|
22
|
-
|
|
23
|
-
# @return [Chain, nil]
|
|
24
|
-
attr_reader :block
|
|
25
|
-
|
|
26
|
-
# @param word [String]
|
|
27
|
-
# @param location [Location, nil]
|
|
28
|
-
# @param arguments [::Array<Chain>]
|
|
29
|
-
# @param block [Chain, nil]
|
|
30
|
-
def initialize word, location = nil, arguments = [], block = nil
|
|
31
|
-
@word = word
|
|
32
|
-
@location = location
|
|
33
|
-
@arguments = arguments
|
|
34
|
-
@block = block
|
|
35
|
-
fix_block_pass
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
39
|
-
protected def equality_fields
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# @param
|
|
49
|
-
# @param
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return
|
|
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
|
-
end
|
|
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
|
-
# @param
|
|
233
|
-
# @param context [ComplexType]
|
|
234
|
-
# @
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
# @param api_map [ApiMap]
|
|
294
|
-
# @param
|
|
295
|
-
# @
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
#
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
# @param
|
|
323
|
-
# @param
|
|
324
|
-
# @param
|
|
325
|
-
# @
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
#
|
|
7
|
+
# Handles both method calls and local variable references by
|
|
8
|
+
# first looking for a variable with the name 'word', then
|
|
9
|
+
# proceeding to method signature resolution if not found.
|
|
10
|
+
#
|
|
11
|
+
class Call < Chain::Link
|
|
12
|
+
include Solargraph::Parser::NodeMethods
|
|
13
|
+
|
|
14
|
+
# @return [String]
|
|
15
|
+
attr_reader :word
|
|
16
|
+
|
|
17
|
+
# @return [Location]
|
|
18
|
+
attr_reader :location
|
|
19
|
+
|
|
20
|
+
# @return [::Array<Chain>]
|
|
21
|
+
attr_reader :arguments
|
|
22
|
+
|
|
23
|
+
# @return [Chain, nil]
|
|
24
|
+
attr_reader :block
|
|
25
|
+
|
|
26
|
+
# @param word [String]
|
|
27
|
+
# @param location [Location, nil]
|
|
28
|
+
# @param arguments [::Array<Chain>]
|
|
29
|
+
# @param block [Chain, nil]
|
|
30
|
+
def initialize word, location = nil, arguments = [], block = nil
|
|
31
|
+
@word = word
|
|
32
|
+
@location = location
|
|
33
|
+
@arguments = arguments
|
|
34
|
+
@block = block
|
|
35
|
+
fix_block_pass
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
39
|
+
protected def equality_fields
|
|
40
|
+
# @sg-ignore literal arrays in this module turn into ::Solargraph::Source::Chain::Array
|
|
41
|
+
super + [arguments, block]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def with_block?
|
|
45
|
+
!!@block
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @param api_map [ApiMap]
|
|
49
|
+
# @param name_pin [Pin::Closure] name_pin.binder should give us the type of the object on which 'word' will be invoked
|
|
50
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
|
51
|
+
def resolve api_map, name_pin, locals
|
|
52
|
+
return super_pins(api_map, name_pin) if word == 'super'
|
|
53
|
+
return yield_pins(api_map, name_pin) if word == 'yield'
|
|
54
|
+
found = api_map.var_at_location(locals, word, name_pin, location) if head?
|
|
55
|
+
|
|
56
|
+
return inferred_pins([found], api_map, name_pin, locals) unless found.nil?
|
|
57
|
+
binder = name_pin.binder
|
|
58
|
+
# this is a q_call - i.e., foo&.bar - assume result of call
|
|
59
|
+
# will be nil or result as if binder were not nil -
|
|
60
|
+
# chain.rb#maybe_nil will add the nil type later, we just
|
|
61
|
+
# need to worry about the not-nil case
|
|
62
|
+
|
|
63
|
+
# @sg-ignore Need to handle duck-typed method calls on union types
|
|
64
|
+
binder = binder.without_nil if nullable?
|
|
65
|
+
# @sg-ignore Need to handle duck-typed method calls on union types
|
|
66
|
+
pin_groups = binder.each_unique_type.map do |context|
|
|
67
|
+
ns_tag = context.namespace == '' ? '' : context.namespace_type.tag
|
|
68
|
+
stack = api_map.get_method_stack(ns_tag, word, scope: context.scope)
|
|
69
|
+
[stack.first].compact
|
|
70
|
+
end
|
|
71
|
+
# @sg-ignore literal arrays in this module turn into ::Solargraph::Source::Chain::Array
|
|
72
|
+
if !api_map.loose_unions && pin_groups.any? { |pins| pins.empty? }
|
|
73
|
+
pin_groups = []
|
|
74
|
+
end
|
|
75
|
+
pins = pin_groups.flatten.uniq(&:path)
|
|
76
|
+
return [] if pins.empty?
|
|
77
|
+
inferred_pins(pins, api_map, name_pin, locals)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# @param pins [::Enumerable<Pin::Base>]
|
|
83
|
+
# @param api_map [ApiMap]
|
|
84
|
+
# @param name_pin [Pin::Base]
|
|
85
|
+
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
86
|
+
# @return [::Array<Pin::Base>]
|
|
87
|
+
def inferred_pins pins, api_map, name_pin, locals
|
|
88
|
+
result = pins.map do |p|
|
|
89
|
+
next p unless p.is_a?(Pin::Method)
|
|
90
|
+
overloads = p.signatures
|
|
91
|
+
# next p if overloads.empty?
|
|
92
|
+
type = ComplexType::UNDEFINED
|
|
93
|
+
# start with overloads that require blocks; if we are
|
|
94
|
+
# passing a block, we want to find a signature that will
|
|
95
|
+
# use it. If we didn't pass a block, the logic below will
|
|
96
|
+
# reject it regardless
|
|
97
|
+
|
|
98
|
+
with_block, without_block = overloads.partition(&:block?)
|
|
99
|
+
# @sg-ignore flow sensitive typing should handle is_a? and next
|
|
100
|
+
# @type Array<Pin::Signature>
|
|
101
|
+
sorted_overloads = with_block + without_block
|
|
102
|
+
# @type [Pin::Signature, nil]
|
|
103
|
+
new_signature_pin = nil
|
|
104
|
+
# @sg-ignore flow sensitive typing should handle is_a? and next
|
|
105
|
+
# @param ol [Pin::Signature]
|
|
106
|
+
sorted_overloads.each do |ol|
|
|
107
|
+
next unless ol.arity_matches?(arguments, with_block?)
|
|
108
|
+
match = true
|
|
109
|
+
|
|
110
|
+
atypes = []
|
|
111
|
+
arguments.each_with_index do |arg, idx|
|
|
112
|
+
param = ol.parameters[idx]
|
|
113
|
+
if param.nil?
|
|
114
|
+
match = ol.parameters.any?(&:restarg?)
|
|
115
|
+
break
|
|
116
|
+
end
|
|
117
|
+
arg_name_pin = Pin::ProxyType.anonymous(name_pin.context,
|
|
118
|
+
closure: name_pin.closure,
|
|
119
|
+
gates: name_pin.gates,
|
|
120
|
+
source: :chain)
|
|
121
|
+
atype = atypes[idx] ||= arg.infer(api_map, arg_name_pin, locals)
|
|
122
|
+
unless param.compatible_arg?(atype, api_map) || param.restarg?
|
|
123
|
+
match = false
|
|
124
|
+
break
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
if match
|
|
128
|
+
if ol.block && with_block?
|
|
129
|
+
block_atypes = ol.block.parameters.map(&:return_type)
|
|
130
|
+
# @todo Need to add nil check here
|
|
131
|
+
if block.links.map(&:class) == [BlockSymbol]
|
|
132
|
+
# like the bar in foo(&:bar)
|
|
133
|
+
blocktype = block_symbol_call_type(api_map, name_pin.context, block_atypes, locals)
|
|
134
|
+
else
|
|
135
|
+
blocktype = block_call_type(api_map, name_pin, locals)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
# @type new_signature_pin [Pin::Signature]
|
|
139
|
+
new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype)
|
|
140
|
+
new_return_type = new_signature_pin.return_type
|
|
141
|
+
if head?
|
|
142
|
+
# If we're at the head of the chain, we called a
|
|
143
|
+
# method somewhere that marked itself as returning
|
|
144
|
+
# self. Given we didn't invoke this on an object,
|
|
145
|
+
# this must be a method in this same class - so we
|
|
146
|
+
# use our own self type
|
|
147
|
+
self_type = name_pin.context
|
|
148
|
+
else
|
|
149
|
+
# if we're past the head in the chain, whatever the
|
|
150
|
+
# type of the lhs side is what 'self' will be in its
|
|
151
|
+
# declaration - we can't just use the type of the
|
|
152
|
+
# method pin, as this might be a subclass of the
|
|
153
|
+
# place where the method is defined
|
|
154
|
+
self_type = name_pin.binder
|
|
155
|
+
end
|
|
156
|
+
# This same logic applies to the YARD work done by
|
|
157
|
+
# 'with_params()'.
|
|
158
|
+
#
|
|
159
|
+
# qualify(), however, happens in the namespace where
|
|
160
|
+
# the docs were written - from the method pin.
|
|
161
|
+
# @todo Need to add nil check here
|
|
162
|
+
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, *p.gates) if new_return_type.defined?
|
|
163
|
+
type ||= ComplexType::UNDEFINED
|
|
164
|
+
end
|
|
165
|
+
break if type.defined?
|
|
166
|
+
end
|
|
167
|
+
p = p.with_single_signature(new_signature_pin) unless new_signature_pin.nil?
|
|
168
|
+
next p.proxy(type) if type.defined?
|
|
169
|
+
if !p.macros.empty?
|
|
170
|
+
result = process_macro(p, api_map, name_pin.context, locals)
|
|
171
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
172
|
+
next result unless result.return_type.undefined?
|
|
173
|
+
elsif !p.directives.empty?
|
|
174
|
+
result = process_directive(p, api_map, name_pin.context, locals)
|
|
175
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
176
|
+
next result unless result.return_type.undefined?
|
|
177
|
+
end
|
|
178
|
+
p
|
|
179
|
+
end
|
|
180
|
+
logger.debug { "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}" }
|
|
181
|
+
out = result.map do |pin|
|
|
182
|
+
if pin.path == 'Class#new' && name_pin.binder.tag != 'Class'
|
|
183
|
+
reduced_context = name_pin.binder.reduce_class_type
|
|
184
|
+
pin.proxy(reduced_context)
|
|
185
|
+
else
|
|
186
|
+
# @sg-ignore Need to add nil check here
|
|
187
|
+
next pin if pin.return_type.undefined?
|
|
188
|
+
# @sg-ignore Need to add nil check here
|
|
189
|
+
selfy = pin.return_type.self_to_type(name_pin.binder)
|
|
190
|
+
# @sg-ignore Need to add nil check here
|
|
191
|
+
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @param pin [Pin::Base]
|
|
197
|
+
# @param api_map [ApiMap]
|
|
198
|
+
# @param context [ComplexType, ComplexType::UniqueType]
|
|
199
|
+
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
200
|
+
# @return [Pin::Base]
|
|
201
|
+
def process_macro pin, api_map, context, locals
|
|
202
|
+
pin.macros.each do |macro|
|
|
203
|
+
# @todo 'Wrong argument type for
|
|
204
|
+
# Solargraph::Source::Chain::Call#inner_process_macro:
|
|
205
|
+
# macro expected YARD::Tags::MacroDirective, received
|
|
206
|
+
# generic<Elem>' is because we lose 'rooted' information
|
|
207
|
+
# in the 'Chain::Array' class internally, leaving
|
|
208
|
+
# ::Array#each shadowed when it shouldn't be.
|
|
209
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
210
|
+
return result unless result.return_type.undefined?
|
|
211
|
+
end
|
|
212
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# @param pin [Pin::Method]
|
|
216
|
+
# @param api_map [ApiMap]
|
|
217
|
+
# @param context [ComplexType, ComplexType::UniqueType]
|
|
218
|
+
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
219
|
+
# @return [Pin::ProxyType]
|
|
220
|
+
def process_directive pin, api_map, context, locals
|
|
221
|
+
pin.directives.each do |dir|
|
|
222
|
+
macro = api_map.named_macro(dir.tag.name)
|
|
223
|
+
next if macro.nil?
|
|
224
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
225
|
+
return result unless result.return_type.undefined?
|
|
226
|
+
end
|
|
227
|
+
Pin::ProxyType.anonymous ComplexType::UNDEFINED, source: :chain
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# @param pin [Pin::Base]
|
|
231
|
+
# @param macro [YARD::Tags::MacroDirective]
|
|
232
|
+
# @param api_map [ApiMap]
|
|
233
|
+
# @param context [ComplexType, ComplexType::UniqueType]
|
|
234
|
+
# @param locals [::Array<Pin::LocalVariable, Pin::Parameter>]
|
|
235
|
+
# @return [Pin::ProxyType]
|
|
236
|
+
def inner_process_macro pin, macro, api_map, context, locals
|
|
237
|
+
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) }
|
|
238
|
+
txt = macro.tag.text.clone
|
|
239
|
+
# @sg-ignore Need to add nil check here
|
|
240
|
+
if txt.empty? && macro.tag.name
|
|
241
|
+
named = api_map.named_macro(macro.tag.name)
|
|
242
|
+
txt = named.tag.text.clone if named
|
|
243
|
+
end
|
|
244
|
+
i = 1
|
|
245
|
+
vals.each do |v|
|
|
246
|
+
# @sg-ignore Need to add nil check here
|
|
247
|
+
txt.gsub!(/\$#{i}/, v.context.namespace)
|
|
248
|
+
i += 1
|
|
249
|
+
end
|
|
250
|
+
# @sg-ignore Need to add nil check here
|
|
251
|
+
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
|
252
|
+
tag = docstring.tag(:return)
|
|
253
|
+
unless tag.nil? || tag.types.nil?
|
|
254
|
+
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types), source: :chain)
|
|
255
|
+
end
|
|
256
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# @param docstring [YARD::Docstring]
|
|
260
|
+
# @param context [ComplexType]
|
|
261
|
+
# @return [ComplexType, nil]
|
|
262
|
+
def extra_return_type docstring, context
|
|
263
|
+
if docstring.has_tag?('return_single_parameter') #&& context.subtypes.one?
|
|
264
|
+
return context.subtypes.first || ComplexType::UNDEFINED
|
|
265
|
+
elsif docstring.has_tag?('return_value_parameter') && context.value_types.one?
|
|
266
|
+
return context.value_types.first
|
|
267
|
+
end
|
|
268
|
+
nil
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# @param name_pin [Pin::Base]
|
|
272
|
+
# @return [Pin::Method, nil]
|
|
273
|
+
def find_method_pin(name_pin)
|
|
274
|
+
method_pin = name_pin
|
|
275
|
+
until method_pin.is_a?(Pin::Method)
|
|
276
|
+
# @sg-ignore Need to support this in flow sensitive typing
|
|
277
|
+
method_pin = method_pin.closure
|
|
278
|
+
return if method_pin.nil?
|
|
279
|
+
end
|
|
280
|
+
method_pin
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# @param api_map [ApiMap]
|
|
284
|
+
# @param name_pin [Pin::Base]
|
|
285
|
+
# @return [::Array<Pin::Base>]
|
|
286
|
+
def super_pins api_map, name_pin
|
|
287
|
+
method_pin = find_method_pin(name_pin)
|
|
288
|
+
return [] if method_pin.nil?
|
|
289
|
+
pins = api_map.get_method_stack(method_pin.namespace, method_pin.name, scope: method_pin.context.scope)
|
|
290
|
+
pins.reject{|p| p.path == name_pin.path}
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# @param api_map [ApiMap]
|
|
294
|
+
# @param name_pin [Pin::Base]
|
|
295
|
+
# @return [::Array<Pin::Base>]
|
|
296
|
+
def yield_pins api_map, name_pin
|
|
297
|
+
method_pin = find_method_pin(name_pin)
|
|
298
|
+
return [] unless method_pin
|
|
299
|
+
|
|
300
|
+
# @param signature_pin [Pin::Signature]
|
|
301
|
+
method_pin.signatures.map(&:block).compact.map do |signature_pin|
|
|
302
|
+
# @sg-ignore Need to add nil check here
|
|
303
|
+
return_type = signature_pin.return_type.qualify(api_map, *name_pin.gates)
|
|
304
|
+
signature_pin.proxy(return_type)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# @param type [ComplexType]
|
|
309
|
+
# @param context [ComplexType, ComplexType::UniqueType]
|
|
310
|
+
# @return [ComplexType]
|
|
311
|
+
def with_params type, context
|
|
312
|
+
return type unless type.to_s.include?('$')
|
|
313
|
+
ComplexType.try_parse(type.to_s.gsub('$', context.value_types.map(&:rooted_tag).join(', ')).gsub('<>', ''))
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# @return [void]
|
|
317
|
+
def fix_block_pass
|
|
318
|
+
argument = @arguments.last&.links&.first
|
|
319
|
+
@block = @arguments.pop if argument.is_a?(BlockSymbol) || argument.is_a?(BlockVariable)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# @param api_map [ApiMap]
|
|
323
|
+
# @param context [ComplexType, ComplexType::UniqueType]
|
|
324
|
+
# @param block_parameter_types [::Array<ComplexType>]
|
|
325
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
|
326
|
+
# @return [ComplexType, nil]
|
|
327
|
+
def block_symbol_call_type(api_map, context, block_parameter_types, locals)
|
|
328
|
+
# Ruby's shorthand for sending the passed in method name
|
|
329
|
+
# to the first yield parameter with no arguments
|
|
330
|
+
# @sg-ignore Need to add nil check here
|
|
331
|
+
block_symbol_name = block.links.first.word
|
|
332
|
+
block_symbol_call_path = "#{block_parameter_types.first}##{block_symbol_name}"
|
|
333
|
+
callee = api_map.get_path_pins(block_symbol_call_path).first
|
|
334
|
+
return_type = callee&.return_type
|
|
335
|
+
# @todo: Figure out why we get unresolved generics at
|
|
336
|
+
# this point and need to assume method return types
|
|
337
|
+
# based on the generic type
|
|
338
|
+
# @sg-ignore Need to add nil check here
|
|
339
|
+
return_type ||= api_map.get_path_pins("#{context.subtypes.first}##{block.links.first.word}").first&.return_type
|
|
340
|
+
return_type || ComplexType::UNDEFINED
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# @param api_map [ApiMap]
|
|
344
|
+
# @return [Pin::Block, nil]
|
|
345
|
+
def find_block_pin(api_map)
|
|
346
|
+
# @sg-ignore Need to add nil check here
|
|
347
|
+
node_location = Solargraph::Location.from_node(block.node)
|
|
348
|
+
return if node_location.nil?
|
|
349
|
+
block_pins = api_map.get_block_pins
|
|
350
|
+
# @sg-ignore Need to add nil check here
|
|
351
|
+
block_pins.find { |pin| pin.location.contain?(node_location) }
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# @param api_map [ApiMap]
|
|
355
|
+
# @param name_pin [Pin::Base]
|
|
356
|
+
# @param block_parameter_types [::Array<ComplexType>]
|
|
357
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
|
358
|
+
# @return [ComplexType, nil]
|
|
359
|
+
def block_call_type(api_map, name_pin, locals)
|
|
360
|
+
return nil unless with_block?
|
|
361
|
+
|
|
362
|
+
block_pin = find_block_pin(api_map)
|
|
363
|
+
# We use the block pin as the closure, as the parameters
|
|
364
|
+
# here will only be defined inside the block itself and we
|
|
365
|
+
# need to be able to see them
|
|
366
|
+
# @sg-ignore Need to add nil check here
|
|
367
|
+
block.infer(api_map, block_pin, locals)
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end
|