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,672 +1,720 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
module Pin
|
|
5
|
-
# The base class for method and attribute pins.
|
|
6
|
-
#
|
|
7
|
-
class Method < Callable
|
|
8
|
-
include Solargraph::Parser::NodeMethods
|
|
9
|
-
|
|
10
|
-
# @return [::Symbol] :public, :private, or :protected
|
|
11
|
-
attr_reader :visibility
|
|
12
|
-
|
|
13
|
-
attr_writer :signatures
|
|
14
|
-
|
|
15
|
-
# @return [Parser::AST::Node]
|
|
16
|
-
attr_reader :node
|
|
17
|
-
|
|
18
|
-
# @param visibility [::Symbol] :public, :protected, or :private
|
|
19
|
-
# @param explicit [Boolean]
|
|
20
|
-
# @param block [Pin::Signature, nil, :undefined]
|
|
21
|
-
# @param node [Parser::AST::Node, nil]
|
|
22
|
-
# @param attribute [Boolean]
|
|
23
|
-
# @param signatures [::Array<Signature>, nil]
|
|
24
|
-
# @param anon_splat [Boolean]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
# @todo
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
m.
|
|
120
|
-
m.
|
|
121
|
-
m
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def
|
|
139
|
-
|
|
140
|
-
end
|
|
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
|
-
|
|
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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
-
method_docs += "
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
l
|
|
324
|
-
l += " #{
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
method_docs += "
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
l
|
|
337
|
-
l += " #{
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
unless
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
# @
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
# @
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
return
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
return
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
# The base class for method and attribute pins.
|
|
6
|
+
#
|
|
7
|
+
class Method < Callable
|
|
8
|
+
include Solargraph::Parser::NodeMethods
|
|
9
|
+
|
|
10
|
+
# @return [::Symbol] :public, :private, or :protected
|
|
11
|
+
attr_reader :visibility
|
|
12
|
+
|
|
13
|
+
attr_writer :signatures
|
|
14
|
+
|
|
15
|
+
# @return [Parser::AST::Node]
|
|
16
|
+
attr_reader :node
|
|
17
|
+
|
|
18
|
+
# @param visibility [::Symbol] :public, :protected, or :private
|
|
19
|
+
# @param explicit [Boolean]
|
|
20
|
+
# @param block [Pin::Signature, nil, :undefined]
|
|
21
|
+
# @param node [Parser::AST::Node, nil]
|
|
22
|
+
# @param attribute [Boolean]
|
|
23
|
+
# @param signatures [::Array<Signature>, nil]
|
|
24
|
+
# @param anon_splat [Boolean]
|
|
25
|
+
# @param context [ComplexType, ComplexType::UniqueType, nil]
|
|
26
|
+
def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false,
|
|
27
|
+
context: nil, **splat
|
|
28
|
+
super(**splat)
|
|
29
|
+
@visibility = visibility
|
|
30
|
+
@explicit = explicit
|
|
31
|
+
@block = block
|
|
32
|
+
@node = node
|
|
33
|
+
@attribute = attribute
|
|
34
|
+
@signatures = signatures
|
|
35
|
+
@anon_splat = anon_splat
|
|
36
|
+
@context = context if context
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @param other [Pin::Method]
|
|
40
|
+
# @return [::Symbol]
|
|
41
|
+
def combine_visibility(other)
|
|
42
|
+
if dodgy_visibility_source? && !other.dodgy_visibility_source?
|
|
43
|
+
other.visibility
|
|
44
|
+
elsif other.dodgy_visibility_source? && !dodgy_visibility_source?
|
|
45
|
+
visibility
|
|
46
|
+
else
|
|
47
|
+
assert_same(other, :visibility)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def combine_with(other, attrs = {})
|
|
52
|
+
priority_choice = choose_priority(other)
|
|
53
|
+
return priority_choice unless priority_choice.nil?
|
|
54
|
+
|
|
55
|
+
sigs = combine_signatures(other)
|
|
56
|
+
parameters = if sigs.length > 0
|
|
57
|
+
[].freeze
|
|
58
|
+
else
|
|
59
|
+
choose(other, :parameters).clone.freeze
|
|
60
|
+
end
|
|
61
|
+
new_attrs = {
|
|
62
|
+
visibility: combine_visibility(other),
|
|
63
|
+
explicit: explicit? || other.explicit?,
|
|
64
|
+
block: combine_blocks(other),
|
|
65
|
+
node: choose_node(other, :node),
|
|
66
|
+
attribute: prefer_rbs_location(other, :attribute?),
|
|
67
|
+
parameters: parameters,
|
|
68
|
+
signatures: sigs,
|
|
69
|
+
anon_splat: assert_same(other, :anon_splat?),
|
|
70
|
+
return_type: nil # pulled from signatures on first call
|
|
71
|
+
}.merge(attrs)
|
|
72
|
+
super(other, new_attrs)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @param other [Pin::Method]
|
|
76
|
+
def == other
|
|
77
|
+
super && other.node == node
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def transform_types(&transform)
|
|
81
|
+
# @todo 'super' alone should work here I think, but doesn't typecheck at level typed
|
|
82
|
+
m = super(&transform)
|
|
83
|
+
m.signatures = m.signatures.map do |sig|
|
|
84
|
+
sig.transform_types(&transform)
|
|
85
|
+
end
|
|
86
|
+
m.block = block&.transform_types(&transform)
|
|
87
|
+
m.reset_generated!
|
|
88
|
+
m
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @return [void]
|
|
92
|
+
def reset_generated!
|
|
93
|
+
super
|
|
94
|
+
unless signatures.empty?
|
|
95
|
+
return_type = nil
|
|
96
|
+
@block = :undefined
|
|
97
|
+
parameters = []
|
|
98
|
+
end
|
|
99
|
+
block&.reset_generated!
|
|
100
|
+
@signatures&.each(&:reset_generated!)
|
|
101
|
+
signature_help = nil
|
|
102
|
+
documentation = nil
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def all_rooted?
|
|
106
|
+
super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @param signature [Pin::Signature]
|
|
110
|
+
# @return [Pin::Method]
|
|
111
|
+
def with_single_signature(signature)
|
|
112
|
+
m = proxy signature.return_type
|
|
113
|
+
m.reset_generated!
|
|
114
|
+
# @todo populating the single parameters/return_type/block
|
|
115
|
+
# arguments here seems to be needed for some specs to pass,
|
|
116
|
+
# even though we have a signature with the same information.
|
|
117
|
+
# Is this a problem for RBS-populated methods, which don't
|
|
118
|
+
# populate these three?
|
|
119
|
+
m.parameters = signature.parameters
|
|
120
|
+
m.return_type = signature.return_type
|
|
121
|
+
m.block = signature.block
|
|
122
|
+
m.signatures = [signature]
|
|
123
|
+
m
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def block?
|
|
127
|
+
!block.nil?
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# @sg-ignore flow sensitive typing needs to remove literal with
|
|
131
|
+
# this unless block
|
|
132
|
+
# @return [Pin::Signature, nil]
|
|
133
|
+
def block
|
|
134
|
+
return @block unless @block == :undefined
|
|
135
|
+
@block = signatures.first&.block
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def completion_item_kind
|
|
139
|
+
attribute? ? Solargraph::LanguageServer::CompletionItemKinds::PROPERTY : Solargraph::LanguageServer::CompletionItemKinds::METHOD
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def symbol_kind
|
|
143
|
+
attribute? ? Solargraph::LanguageServer::SymbolKinds::PROPERTY : LanguageServer::SymbolKinds::METHOD
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def return_type
|
|
147
|
+
@return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @param parameters [::Array<Parameter>]
|
|
151
|
+
# @param return_type [ComplexType, nil]
|
|
152
|
+
# @return [Signature]
|
|
153
|
+
def generate_signature(parameters, return_type)
|
|
154
|
+
# @type [Pin::Signature, nil]
|
|
155
|
+
block = nil
|
|
156
|
+
yieldparam_tags = docstring.tags(:yieldparam)
|
|
157
|
+
yieldreturn_tags = docstring.tags(:yieldreturn)
|
|
158
|
+
generics = docstring.tags(:generic).map(&:name)
|
|
159
|
+
needs_block_param_signature =
|
|
160
|
+
parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
|
|
161
|
+
if needs_block_param_signature
|
|
162
|
+
yield_parameters = yieldparam_tags.map do |p|
|
|
163
|
+
name = p.name
|
|
164
|
+
decl = :arg
|
|
165
|
+
if name
|
|
166
|
+
decl = select_decl(name, false)
|
|
167
|
+
name = clean_param(name)
|
|
168
|
+
end
|
|
169
|
+
Pin::Parameter.new(
|
|
170
|
+
location: location,
|
|
171
|
+
closure: self,
|
|
172
|
+
comments: p.text,
|
|
173
|
+
name: name,
|
|
174
|
+
decl: decl,
|
|
175
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
176
|
+
presence: location ? location.range : nil,
|
|
177
|
+
return_type: ComplexType.try_parse(*p.types),
|
|
178
|
+
source: source
|
|
179
|
+
)
|
|
180
|
+
end
|
|
181
|
+
yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
|
|
182
|
+
block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source,
|
|
183
|
+
closure: self, location: location, type_location: type_location)
|
|
184
|
+
end
|
|
185
|
+
signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source,
|
|
186
|
+
location: location, type_location: type_location)
|
|
187
|
+
block.closure = signature if block
|
|
188
|
+
signature
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @return [::Array<Signature>]
|
|
192
|
+
def signatures
|
|
193
|
+
@signatures ||= begin
|
|
194
|
+
top_type = generate_complex_type
|
|
195
|
+
result = []
|
|
196
|
+
result.push generate_signature(parameters, top_type) if top_type.defined?
|
|
197
|
+
result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty?
|
|
198
|
+
result.push generate_signature(parameters, @return_type || ComplexType::UNDEFINED) if result.empty?
|
|
199
|
+
result
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# @param return_type [ComplexType]
|
|
204
|
+
# @return [self]
|
|
205
|
+
def proxy_with_signatures return_type
|
|
206
|
+
out = proxy return_type
|
|
207
|
+
out.signatures = out.signatures.map { |sig| sig.proxy return_type }
|
|
208
|
+
out
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# @return [String, nil]
|
|
212
|
+
def detail
|
|
213
|
+
# This property is not cached in an instance variable because it can
|
|
214
|
+
# change when pins get proxied.
|
|
215
|
+
detail = String.new
|
|
216
|
+
detail += if signatures.length > 1
|
|
217
|
+
"(*) "
|
|
218
|
+
else
|
|
219
|
+
"(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
|
|
220
|
+
end.to_s
|
|
221
|
+
# @sg-ignore Need to add nil check here
|
|
222
|
+
detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
|
|
223
|
+
detail.strip!
|
|
224
|
+
return nil if detail.empty?
|
|
225
|
+
detail
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# @return [::Array<Hash>]
|
|
229
|
+
def signature_help
|
|
230
|
+
@signature_help ||= signatures.map do |sig|
|
|
231
|
+
{
|
|
232
|
+
label: name + '(' + sig.parameters.map(&:full).join(', ') + ')',
|
|
233
|
+
documentation: documentation
|
|
234
|
+
}
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def inner_desc
|
|
239
|
+
# ensure the signatures line up when logged
|
|
240
|
+
if signatures.length > 1
|
|
241
|
+
path + " \n#{to_rbs}\n"
|
|
242
|
+
else
|
|
243
|
+
super
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def to_rbs
|
|
248
|
+
return nil if signatures.empty?
|
|
249
|
+
|
|
250
|
+
rbs = "def #{name}: #{signatures.first.to_rbs}"
|
|
251
|
+
# @sg-ignore Need to add nil check here
|
|
252
|
+
signatures[1..].each do |sig|
|
|
253
|
+
rbs += "\n"
|
|
254
|
+
rbs += (' ' * (4 + name.length))
|
|
255
|
+
rbs += "| #{name}: #{sig.to_rbs}"
|
|
256
|
+
end
|
|
257
|
+
rbs
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def path
|
|
261
|
+
@path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# @return [String]
|
|
265
|
+
def method_name
|
|
266
|
+
name
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def typify api_map
|
|
270
|
+
# @sg-ignore Need to add nil check here
|
|
271
|
+
logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" }
|
|
272
|
+
decl = super
|
|
273
|
+
unless decl.undefined?
|
|
274
|
+
logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" }
|
|
275
|
+
return decl
|
|
276
|
+
end
|
|
277
|
+
type = see_reference(api_map) || typify_from_super(api_map)
|
|
278
|
+
logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
|
|
279
|
+
unless type.nil?
|
|
280
|
+
# @sg-ignore Need to add nil check here
|
|
281
|
+
qualified = type.qualify(api_map, *closure.gates)
|
|
282
|
+
logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
|
283
|
+
return qualified
|
|
284
|
+
end
|
|
285
|
+
super
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def documentation
|
|
289
|
+
if @documentation.nil?
|
|
290
|
+
method_docs ||= super || ''
|
|
291
|
+
param_tags = docstring.tags(:param)
|
|
292
|
+
unless param_tags.nil? or param_tags.empty?
|
|
293
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
294
|
+
method_docs += "Params:\n"
|
|
295
|
+
lines = []
|
|
296
|
+
param_tags.each do |p|
|
|
297
|
+
l = "* #{p.name}"
|
|
298
|
+
l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
|
|
299
|
+
l += " #{p.text}"
|
|
300
|
+
lines.push l
|
|
301
|
+
end
|
|
302
|
+
method_docs += lines.join("\n")
|
|
303
|
+
end
|
|
304
|
+
yieldparam_tags = docstring.tags(:yieldparam)
|
|
305
|
+
unless yieldparam_tags.nil? or yieldparam_tags.empty?
|
|
306
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
307
|
+
method_docs += "Block Params:\n"
|
|
308
|
+
lines = []
|
|
309
|
+
yieldparam_tags.each do |p|
|
|
310
|
+
l = "* #{p.name}"
|
|
311
|
+
l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
|
|
312
|
+
l += " #{p.text}"
|
|
313
|
+
lines.push l
|
|
314
|
+
end
|
|
315
|
+
method_docs += lines.join("\n")
|
|
316
|
+
end
|
|
317
|
+
yieldreturn_tags = docstring.tags(:yieldreturn)
|
|
318
|
+
unless yieldreturn_tags.empty?
|
|
319
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
320
|
+
method_docs += "Block Returns:\n"
|
|
321
|
+
lines = []
|
|
322
|
+
yieldreturn_tags.each do |r|
|
|
323
|
+
l = "*"
|
|
324
|
+
l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
|
|
325
|
+
l += " #{r.text}"
|
|
326
|
+
lines.push l
|
|
327
|
+
end
|
|
328
|
+
method_docs += lines.join("\n")
|
|
329
|
+
end
|
|
330
|
+
return_tags = docstring.tags(:return)
|
|
331
|
+
unless return_tags.empty?
|
|
332
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
333
|
+
method_docs += "Returns:\n"
|
|
334
|
+
lines = []
|
|
335
|
+
return_tags.each do |r|
|
|
336
|
+
l = "*"
|
|
337
|
+
l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
|
|
338
|
+
l += " #{r.text}"
|
|
339
|
+
lines.push l
|
|
340
|
+
end
|
|
341
|
+
method_docs += lines.join("\n")
|
|
342
|
+
end
|
|
343
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
344
|
+
method_docs += "Visibility: #{visibility}"
|
|
345
|
+
@documentation = method_docs
|
|
346
|
+
concat_example_tags
|
|
347
|
+
end
|
|
348
|
+
@documentation.to_s
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def explicit?
|
|
352
|
+
@explicit
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def attribute?
|
|
356
|
+
@attribute
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# @parm other [self]
|
|
360
|
+
def nearly? other
|
|
361
|
+
super &&
|
|
362
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
363
|
+
parameters == other.parameters &&
|
|
364
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
365
|
+
scope == other.scope &&
|
|
366
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
367
|
+
visibility == other.visibility
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def probe api_map
|
|
371
|
+
attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# @return [::Array<Pin::Signature>]
|
|
375
|
+
def overloads
|
|
376
|
+
# Ignore overload tags with nil parameters. If it's not an array, the
|
|
377
|
+
# tag's source is likely malformed.
|
|
378
|
+
|
|
379
|
+
# @param tag [YARD::Tags::OverloadTag]
|
|
380
|
+
@overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
|
|
381
|
+
Pin::Signature.new(
|
|
382
|
+
generics: generics,
|
|
383
|
+
# @param src [Array(String, String)]
|
|
384
|
+
parameters: tag.parameters.map do |src|
|
|
385
|
+
name, decl = parse_overload_param(src.first)
|
|
386
|
+
Pin::Parameter.new(
|
|
387
|
+
location: location,
|
|
388
|
+
closure: self,
|
|
389
|
+
comments: tag.docstring.all.to_s,
|
|
390
|
+
name: name,
|
|
391
|
+
decl: decl,
|
|
392
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
393
|
+
presence: location ? location.range : nil,
|
|
394
|
+
return_type: param_type_from_name(tag, src.first),
|
|
395
|
+
source: :overloads
|
|
396
|
+
)
|
|
397
|
+
end,
|
|
398
|
+
closure: self,
|
|
399
|
+
return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)),
|
|
400
|
+
source: :overloads,
|
|
401
|
+
)
|
|
402
|
+
end
|
|
403
|
+
@overloads
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def anon_splat?
|
|
407
|
+
@anon_splat
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# @param api_map [ApiMap]
|
|
411
|
+
# @return [self]
|
|
412
|
+
def resolve_ref_tag api_map
|
|
413
|
+
return self if @resolved_ref_tag
|
|
414
|
+
|
|
415
|
+
@resolved_ref_tag = true
|
|
416
|
+
return self unless docstring.ref_tags.any?
|
|
417
|
+
docstring.ref_tags.each do |tag|
|
|
418
|
+
ref = if tag.owner.to_s.start_with?(/[#.]/)
|
|
419
|
+
api_map.get_methods(namespace)
|
|
420
|
+
.select { |pin| pin.path.end_with?(tag.owner.to_s) }
|
|
421
|
+
.first
|
|
422
|
+
else
|
|
423
|
+
# @todo Resolve relative namespaces
|
|
424
|
+
api_map.get_path_pins(tag.owner.to_s).first
|
|
425
|
+
end
|
|
426
|
+
next unless ref
|
|
427
|
+
|
|
428
|
+
docstring.add_tag(*ref.docstring.tags(:param))
|
|
429
|
+
end
|
|
430
|
+
self
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# @param api_map [ApiMap]
|
|
434
|
+
# @return [Array<Pin::Method>]
|
|
435
|
+
def rest_of_stack api_map
|
|
436
|
+
api_map.get_method_stack(method_namespace, method_name, scope: scope).reject { |pin| pin.path == path }
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
protected
|
|
440
|
+
|
|
441
|
+
attr_writer :block
|
|
442
|
+
|
|
443
|
+
attr_writer :signature_help
|
|
444
|
+
|
|
445
|
+
attr_writer :documentation
|
|
446
|
+
|
|
447
|
+
# @sg-ignore Need to add nil check here
|
|
448
|
+
def dodgy_visibility_source?
|
|
449
|
+
# as of 2025-03-12, the RBS generator used for
|
|
450
|
+
# e.g. activesupport did not understand 'private' markings
|
|
451
|
+
# inside 'class << self' blocks, but YARD did OK at it
|
|
452
|
+
# @sg-ignore Need to add nil check here
|
|
453
|
+
source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
|
|
454
|
+
# YARD's RBS generator seems to miss a lot of should-be protected instance methods
|
|
455
|
+
source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
|
|
456
|
+
# private on attr_readers seems to be broken in Prism's auto-generator script
|
|
457
|
+
source == :rbs && scope == :instance && namespace.start_with?('Prism::') ||
|
|
458
|
+
# The RBS for the RBS gem itself seems to use private as a
|
|
459
|
+
# 'is this a public API' concept, more aggressively than the
|
|
460
|
+
# actual code. Let's respect that and ignore the actual .rb file.
|
|
461
|
+
source == :yardoc && scope == :instance && namespace.start_with?('RBS::')
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
private
|
|
465
|
+
|
|
466
|
+
# @param other [Pin::Method]
|
|
467
|
+
# @return [Array<Pin::Signature>]
|
|
468
|
+
def combine_signatures(other)
|
|
469
|
+
all_undefined = signatures.all? { |sig| !sig.return_type&.defined? }
|
|
470
|
+
other_all_undefined = other.signatures.all? { |sig| !sig.return_type&.defined? }
|
|
471
|
+
if all_undefined && !other_all_undefined
|
|
472
|
+
other.signatures
|
|
473
|
+
elsif other_all_undefined && !all_undefined
|
|
474
|
+
signatures
|
|
475
|
+
else
|
|
476
|
+
combine_signatures_by_type_arity(*signatures, *other.signatures)
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# @param signature_pins [Array<Pin::Signature>]
|
|
481
|
+
#
|
|
482
|
+
# @return [Array<Pin::Signature>]
|
|
483
|
+
def combine_signatures_by_type_arity(*signature_pins)
|
|
484
|
+
# @type [Hash{Array => Array<Pin::Signature>}]
|
|
485
|
+
by_type_arity = {}
|
|
486
|
+
signature_pins.each do |signature_pin|
|
|
487
|
+
by_type_arity[signature_pin.type_arity] ||= []
|
|
488
|
+
by_type_arity[signature_pin.type_arity] << signature_pin
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
by_type_arity.transform_values! do |same_type_arity_signatures|
|
|
492
|
+
combine_same_type_arity_signatures same_type_arity_signatures
|
|
493
|
+
end
|
|
494
|
+
by_type_arity.values.flatten
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
# @param same_type_arity_signatures [Array<Pin::Signature>]
|
|
498
|
+
#
|
|
499
|
+
# @return [Array<Pin::Signature>]
|
|
500
|
+
def combine_same_type_arity_signatures(same_type_arity_signatures)
|
|
501
|
+
# This is an O(n^2) operation, so bail out if n is not small
|
|
502
|
+
return same_type_arity_signatures if same_type_arity_signatures.length > 10
|
|
503
|
+
|
|
504
|
+
# @param old_signatures [Array<Pin::Signature>]
|
|
505
|
+
# @param new_signature [Pin::Signature]
|
|
506
|
+
same_type_arity_signatures.reduce([]) do |old_signatures, new_signature|
|
|
507
|
+
next [new_signature] if old_signatures.empty?
|
|
508
|
+
|
|
509
|
+
found_merge = false
|
|
510
|
+
old_signatures.flat_map do |old_signature|
|
|
511
|
+
potential_new_signature = old_signature.combine_with(new_signature)
|
|
512
|
+
|
|
513
|
+
if potential_new_signature.type_arity == old_signature.type_arity
|
|
514
|
+
# the number of types in each parameter and return type
|
|
515
|
+
# match, so we found compatible signatures to merge. If
|
|
516
|
+
# we increased the number of types, we'd potentially
|
|
517
|
+
# have taken away the ability to use parameter types to
|
|
518
|
+
# choose the correct return type (while Ruby doesn't
|
|
519
|
+
# dispatch based on type, RBS does distinguish overloads
|
|
520
|
+
# based on types, not just arity, allowing for type
|
|
521
|
+
# information describing how methods behave based on
|
|
522
|
+
# their input types)
|
|
523
|
+
old_signatures - [old_signature] + [potential_new_signature]
|
|
524
|
+
else
|
|
525
|
+
old_signatures + [new_signature]
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# @param name [String]
|
|
532
|
+
# @param asgn [Boolean]
|
|
533
|
+
#
|
|
534
|
+
# @return [::Symbol]
|
|
535
|
+
def select_decl name, asgn
|
|
536
|
+
if name.start_with?('**')
|
|
537
|
+
:kwrestarg
|
|
538
|
+
elsif name.start_with?('*')
|
|
539
|
+
:restarg
|
|
540
|
+
elsif name.start_with?('&')
|
|
541
|
+
:blockarg
|
|
542
|
+
elsif name.end_with?(':') && asgn
|
|
543
|
+
:kwoptarg
|
|
544
|
+
elsif name.end_with?(':')
|
|
545
|
+
:kwarg
|
|
546
|
+
elsif asgn
|
|
547
|
+
:optarg
|
|
548
|
+
else
|
|
549
|
+
:arg
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
# @param name [String]
|
|
554
|
+
# @return [String]
|
|
555
|
+
def clean_param name
|
|
556
|
+
name.gsub(/[*&:]/, '')
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
# @param tag [YARD::Tags::OverloadTag]
|
|
560
|
+
# @param name [String]
|
|
561
|
+
#
|
|
562
|
+
# @return [ComplexType]
|
|
563
|
+
def param_type_from_name(tag, name)
|
|
564
|
+
# @param t [YARD::Tags::Tag]
|
|
565
|
+
param = tag.tags(:param).select { |t| t.name == name }.first
|
|
566
|
+
return ComplexType::UNDEFINED unless param
|
|
567
|
+
ComplexType.try_parse(*param.types)
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
# @return [ComplexType]
|
|
571
|
+
def generate_complex_type
|
|
572
|
+
tags = docstring.tags(:return).map(&:types).flatten.compact
|
|
573
|
+
return ComplexType::UNDEFINED if tags.empty?
|
|
574
|
+
ComplexType.try_parse *tags
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# @param api_map [ApiMap]
|
|
578
|
+
# @return [ComplexType, ComplexType::UniqueType, nil]
|
|
579
|
+
def see_reference api_map
|
|
580
|
+
# This should actually be an intersection type
|
|
581
|
+
# @param ref [YARD::Tags::Tag, YARD::Tags::RefTag]
|
|
582
|
+
docstring.ref_tags.each do |ref|
|
|
583
|
+
# @sg-ignore ref should actually be an intersection type
|
|
584
|
+
next unless ref.tag_name == 'return' && ref.owner
|
|
585
|
+
# @sg-ignore should actually be an intersection type
|
|
586
|
+
result = resolve_reference(ref.owner.to_s, api_map)
|
|
587
|
+
return result unless result.nil?
|
|
588
|
+
end
|
|
589
|
+
match = comments.match(/^[ \t]*\(see (.*)\)/m)
|
|
590
|
+
return nil if match.nil?
|
|
591
|
+
# @sg-ignore Need to add nil check here
|
|
592
|
+
resolve_reference match[1], api_map
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
# @return [String]
|
|
596
|
+
def method_namespace
|
|
597
|
+
namespace
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
# @param api_map [ApiMap]
|
|
601
|
+
# @return [ComplexType, nil]
|
|
602
|
+
def typify_from_super api_map
|
|
603
|
+
stack = rest_of_stack api_map
|
|
604
|
+
return nil if stack.empty?
|
|
605
|
+
stack.each do |pin|
|
|
606
|
+
# @sg-ignore Need to add nil check here
|
|
607
|
+
return pin.return_type unless pin.return_type.undefined?
|
|
608
|
+
end
|
|
609
|
+
nil
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
# @param ref [String]
|
|
613
|
+
# @param api_map [ApiMap]
|
|
614
|
+
# @return [ComplexType, ComplexType::UniqueType, nil]
|
|
615
|
+
def resolve_reference ref, api_map
|
|
616
|
+
parts = ref.split(/[.#]/)
|
|
617
|
+
if parts.first.empty? || parts.one?
|
|
618
|
+
path = "#{namespace}#{ref}"
|
|
619
|
+
else
|
|
620
|
+
fqns = api_map.qualify(parts.first, *gates)
|
|
621
|
+
return ComplexType::UNDEFINED if fqns.nil?
|
|
622
|
+
# @sg-ignore Need to add nil check here
|
|
623
|
+
path = fqns + ref[parts.first.length] + parts.last
|
|
624
|
+
end
|
|
625
|
+
pins = api_map.get_path_pins(path)
|
|
626
|
+
pins.each do |pin|
|
|
627
|
+
type = pin.typify(api_map)
|
|
628
|
+
return type unless type.undefined?
|
|
629
|
+
end
|
|
630
|
+
nil
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
# @return [Parser::AST::Node, nil]
|
|
634
|
+
def method_body_node
|
|
635
|
+
return nil if node.nil?
|
|
636
|
+
return node.children[1].children.last if node.type == :DEFN
|
|
637
|
+
return node.children[2].children.last if node.type == :DEFS
|
|
638
|
+
return node.children[2] if node.type == :def || node.type == :DEFS
|
|
639
|
+
return node.children[3] if node.type == :defs
|
|
640
|
+
nil
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
# @param api_map [ApiMap]
|
|
644
|
+
# @return [ComplexType]
|
|
645
|
+
def infer_from_return_nodes api_map
|
|
646
|
+
return ComplexType::UNDEFINED if node.nil?
|
|
647
|
+
result = []
|
|
648
|
+
has_nil = false
|
|
649
|
+
return ComplexType::NIL if method_body_node.nil?
|
|
650
|
+
returns_from_method_body(method_body_node).each do |n|
|
|
651
|
+
if n.nil? || [:NIL, :nil].include?(n.type)
|
|
652
|
+
has_nil = true
|
|
653
|
+
next
|
|
654
|
+
end
|
|
655
|
+
rng = Range.from_node(n)
|
|
656
|
+
next unless rng
|
|
657
|
+
clip = api_map.clip_at(
|
|
658
|
+
# @sg-ignore Need to add nil check here
|
|
659
|
+
location.filename,
|
|
660
|
+
rng.ending
|
|
661
|
+
)
|
|
662
|
+
# @sg-ignore Need to add nil check here
|
|
663
|
+
chain = Solargraph::Parser.chain(n, location.filename)
|
|
664
|
+
type = chain.infer(api_map, self, clip.locals)
|
|
665
|
+
result.push type unless type.undefined?
|
|
666
|
+
end
|
|
667
|
+
result.push ComplexType::NIL if has_nil
|
|
668
|
+
return ComplexType::UNDEFINED if result.empty?
|
|
669
|
+
ComplexType.new(result.uniq)
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
# @param [ApiMap] api_map
|
|
673
|
+
# @return [ComplexType]
|
|
674
|
+
def infer_from_iv api_map
|
|
675
|
+
types = []
|
|
676
|
+
varname = "@#{name.gsub(/=$/, '')}"
|
|
677
|
+
pins = api_map.get_instance_variable_pins(binder.namespace, binder.scope).select { |iv| iv.name == varname }
|
|
678
|
+
pins.each do |pin|
|
|
679
|
+
type = pin.typify(api_map)
|
|
680
|
+
type = pin.probe(api_map) if type.undefined?
|
|
681
|
+
types.push type if type.defined?
|
|
682
|
+
end
|
|
683
|
+
return ComplexType::UNDEFINED if types.empty?
|
|
684
|
+
ComplexType.new(types.uniq)
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
# When YARD parses an overload tag, it includes rest modifiers in the parameters names.
|
|
688
|
+
#
|
|
689
|
+
# @param name [String]
|
|
690
|
+
# @return [::Array(String, ::Symbol)]
|
|
691
|
+
def parse_overload_param(name)
|
|
692
|
+
# @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
|
|
693
|
+
if name.start_with?('**')
|
|
694
|
+
[name[2..-1], :kwrestarg]
|
|
695
|
+
elsif name.start_with?('*')
|
|
696
|
+
[name[1..-1], :restarg]
|
|
697
|
+
else
|
|
698
|
+
[name, :arg]
|
|
699
|
+
end
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
# @return [void]
|
|
703
|
+
def concat_example_tags
|
|
704
|
+
example_tags = docstring.tags(:example)
|
|
705
|
+
return if example_tags.empty?
|
|
706
|
+
@documentation += "\n\nExamples:\n\n```ruby\n"
|
|
707
|
+
@documentation += example_tags.map do |tag|
|
|
708
|
+
(tag.name && !tag.name.empty? ? "# #{tag.name}\n" : '') +
|
|
709
|
+
"#{tag.text}\n"
|
|
710
|
+
end
|
|
711
|
+
.join("\n")
|
|
712
|
+
.concat("```\n")
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
protected
|
|
716
|
+
|
|
717
|
+
attr_writer :return_type
|
|
718
|
+
end
|
|
719
|
+
end
|
|
720
|
+
end
|