steep-activesupport-4 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGELOG.md +1032 -0
  5. data/LICENSE +21 -0
  6. data/README.md +260 -0
  7. data/Rakefile +227 -0
  8. data/Steepfile +68 -0
  9. data/bin/console +14 -0
  10. data/bin/generate-diagnostics-docs.rb +112 -0
  11. data/bin/mem_graph.rb +67 -0
  12. data/bin/mem_prof.rb +102 -0
  13. data/bin/output_rebaseline.rb +34 -0
  14. data/bin/output_test.rb +60 -0
  15. data/bin/rbs +20 -0
  16. data/bin/rbs-inline +19 -0
  17. data/bin/setup +9 -0
  18. data/bin/stackprof_test.rb +19 -0
  19. data/bin/steep +19 -0
  20. data/bin/steep-check.rb +251 -0
  21. data/bin/steep-prof +16 -0
  22. data/doc/narrowing.md +195 -0
  23. data/doc/shape.md +194 -0
  24. data/exe/steep +18 -0
  25. data/guides/README.md +5 -0
  26. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  27. data/guides/src/getting-started/getting-started.md +163 -0
  28. data/guides/src/nil-optional/nil-optional.md +195 -0
  29. data/lib/steep/annotation_parser.rb +199 -0
  30. data/lib/steep/ast/annotation/collection.rb +172 -0
  31. data/lib/steep/ast/annotation.rb +137 -0
  32. data/lib/steep/ast/builtin.rb +104 -0
  33. data/lib/steep/ast/ignore.rb +148 -0
  34. data/lib/steep/ast/node/type_application.rb +88 -0
  35. data/lib/steep/ast/node/type_assertion.rb +81 -0
  36. data/lib/steep/ast/types/any.rb +35 -0
  37. data/lib/steep/ast/types/boolean.rb +45 -0
  38. data/lib/steep/ast/types/bot.rb +35 -0
  39. data/lib/steep/ast/types/class.rb +43 -0
  40. data/lib/steep/ast/types/factory.rb +557 -0
  41. data/lib/steep/ast/types/helper.rb +40 -0
  42. data/lib/steep/ast/types/instance.rb +42 -0
  43. data/lib/steep/ast/types/intersection.rb +93 -0
  44. data/lib/steep/ast/types/literal.rb +59 -0
  45. data/lib/steep/ast/types/logic.rb +84 -0
  46. data/lib/steep/ast/types/name.rb +128 -0
  47. data/lib/steep/ast/types/nil.rb +41 -0
  48. data/lib/steep/ast/types/proc.rb +117 -0
  49. data/lib/steep/ast/types/record.rb +79 -0
  50. data/lib/steep/ast/types/self.rb +43 -0
  51. data/lib/steep/ast/types/shared_instance.rb +11 -0
  52. data/lib/steep/ast/types/top.rb +35 -0
  53. data/lib/steep/ast/types/tuple.rb +60 -0
  54. data/lib/steep/ast/types/union.rb +97 -0
  55. data/lib/steep/ast/types/var.rb +65 -0
  56. data/lib/steep/ast/types/void.rb +35 -0
  57. data/lib/steep/cli.rb +401 -0
  58. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  59. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  60. data/lib/steep/diagnostic/helper.rb +18 -0
  61. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  62. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  63. data/lib/steep/diagnostic/ruby.rb +1221 -0
  64. data/lib/steep/diagnostic/signature.rb +570 -0
  65. data/lib/steep/drivers/annotations.rb +52 -0
  66. data/lib/steep/drivers/check.rb +339 -0
  67. data/lib/steep/drivers/checkfile.rb +210 -0
  68. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  69. data/lib/steep/drivers/init.rb +66 -0
  70. data/lib/steep/drivers/langserver.rb +56 -0
  71. data/lib/steep/drivers/print_project.rb +113 -0
  72. data/lib/steep/drivers/stats.rb +203 -0
  73. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  74. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  75. data/lib/steep/drivers/vendor.rb +27 -0
  76. data/lib/steep/drivers/watch.rb +194 -0
  77. data/lib/steep/drivers/worker.rb +58 -0
  78. data/lib/steep/equatable.rb +23 -0
  79. data/lib/steep/expectations.rb +228 -0
  80. data/lib/steep/index/rbs_index.rb +350 -0
  81. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  82. data/lib/steep/index/source_index.rb +167 -0
  83. data/lib/steep/interface/block.rb +103 -0
  84. data/lib/steep/interface/builder.rb +843 -0
  85. data/lib/steep/interface/function.rb +1090 -0
  86. data/lib/steep/interface/method_type.rb +330 -0
  87. data/lib/steep/interface/shape.rb +239 -0
  88. data/lib/steep/interface/substitution.rb +159 -0
  89. data/lib/steep/interface/type_param.rb +115 -0
  90. data/lib/steep/located_value.rb +20 -0
  91. data/lib/steep/method_name.rb +42 -0
  92. data/lib/steep/module_helper.rb +24 -0
  93. data/lib/steep/node_helper.rb +273 -0
  94. data/lib/steep/path_helper.rb +30 -0
  95. data/lib/steep/project/dsl.rb +268 -0
  96. data/lib/steep/project/group.rb +31 -0
  97. data/lib/steep/project/options.rb +63 -0
  98. data/lib/steep/project/pattern.rb +59 -0
  99. data/lib/steep/project/target.rb +92 -0
  100. data/lib/steep/project.rb +78 -0
  101. data/lib/steep/rake_task.rb +132 -0
  102. data/lib/steep/range_extension.rb +29 -0
  103. data/lib/steep/server/base_worker.rb +97 -0
  104. data/lib/steep/server/change_buffer.rb +73 -0
  105. data/lib/steep/server/custom_methods.rb +77 -0
  106. data/lib/steep/server/delay_queue.rb +45 -0
  107. data/lib/steep/server/interaction_worker.rb +492 -0
  108. data/lib/steep/server/lsp_formatter.rb +455 -0
  109. data/lib/steep/server/master.rb +912 -0
  110. data/lib/steep/server/target_group_files.rb +205 -0
  111. data/lib/steep/server/type_check_controller.rb +366 -0
  112. data/lib/steep/server/type_check_worker.rb +303 -0
  113. data/lib/steep/server/work_done_progress.rb +64 -0
  114. data/lib/steep/server/worker_process.rb +176 -0
  115. data/lib/steep/services/completion_provider.rb +802 -0
  116. data/lib/steep/services/content_change.rb +61 -0
  117. data/lib/steep/services/file_loader.rb +74 -0
  118. data/lib/steep/services/goto_service.rb +441 -0
  119. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  120. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  121. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  122. data/lib/steep/services/path_assignment.rb +46 -0
  123. data/lib/steep/services/signature_help_provider.rb +202 -0
  124. data/lib/steep/services/signature_service.rb +428 -0
  125. data/lib/steep/services/stats_calculator.rb +68 -0
  126. data/lib/steep/services/type_check_service.rb +394 -0
  127. data/lib/steep/services/type_name_completion.rb +236 -0
  128. data/lib/steep/signature/validator.rb +651 -0
  129. data/lib/steep/source/ignore_ranges.rb +69 -0
  130. data/lib/steep/source.rb +691 -0
  131. data/lib/steep/subtyping/cache.rb +30 -0
  132. data/lib/steep/subtyping/check.rb +1113 -0
  133. data/lib/steep/subtyping/constraints.rb +341 -0
  134. data/lib/steep/subtyping/relation.rb +101 -0
  135. data/lib/steep/subtyping/result.rb +324 -0
  136. data/lib/steep/subtyping/variable_variance.rb +89 -0
  137. data/lib/steep/test.rb +9 -0
  138. data/lib/steep/thread_waiter.rb +43 -0
  139. data/lib/steep/type_construction.rb +5183 -0
  140. data/lib/steep/type_inference/block_params.rb +416 -0
  141. data/lib/steep/type_inference/case_when.rb +303 -0
  142. data/lib/steep/type_inference/constant_env.rb +56 -0
  143. data/lib/steep/type_inference/context.rb +195 -0
  144. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  145. data/lib/steep/type_inference/method_call.rb +193 -0
  146. data/lib/steep/type_inference/method_params.rb +531 -0
  147. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  148. data/lib/steep/type_inference/send_args.rb +712 -0
  149. data/lib/steep/type_inference/type_env.rb +341 -0
  150. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  151. data/lib/steep/typing.rb +321 -0
  152. data/lib/steep/version.rb +3 -0
  153. data/lib/steep.rb +369 -0
  154. data/manual/annotations.md +181 -0
  155. data/manual/ignore.md +20 -0
  156. data/manual/ruby-diagnostics.md +1879 -0
  157. data/sample/Steepfile +22 -0
  158. data/sample/lib/conference.rb +49 -0
  159. data/sample/lib/length.rb +35 -0
  160. data/sample/sig/conference.rbs +42 -0
  161. data/sample/sig/generics.rbs +15 -0
  162. data/sample/sig/length.rbs +34 -0
  163. data/steep-activesupport-4.gemspec +55 -0
  164. metadata +437 -0
@@ -0,0 +1,712 @@
1
+ module Steep
2
+ module TypeInference
3
+ class SendArgs
4
+ class PositionalArgs
5
+ class NodeParamPair
6
+ attr_reader :node
7
+ attr_reader :param
8
+
9
+ def initialize(node:, param:)
10
+ @node = node
11
+ @param = param
12
+ end
13
+
14
+ include Equatable
15
+
16
+ def to_ary
17
+ [node, param]
18
+ end
19
+ end
20
+
21
+ class NodeTypePair
22
+ attr_reader :node
23
+ attr_reader :type
24
+
25
+ def initialize(node:, type:)
26
+ @node = node
27
+ @type = type
28
+ end
29
+
30
+ include Equatable
31
+
32
+ def node_type
33
+ case node.type
34
+ when :splat
35
+ AST::Builtin::Array.instance_type(type)
36
+ else
37
+ type
38
+ end
39
+ end
40
+ end
41
+
42
+ class SplatArg
43
+ attr_reader :node
44
+ attr_accessor :type
45
+
46
+ def initialize(node:)
47
+ @node = node
48
+ @type = nil
49
+ end
50
+
51
+ include Equatable
52
+ end
53
+
54
+ class UnexpectedArg
55
+ attr_reader :node
56
+
57
+ def initialize(node:)
58
+ @node = node
59
+ end
60
+
61
+ include Equatable
62
+ end
63
+
64
+ class MissingArg
65
+ attr_reader :params
66
+
67
+ def initialize(params:)
68
+ @params = params
69
+ end
70
+
71
+ include Equatable
72
+ end
73
+
74
+ attr_reader :args
75
+ attr_reader :index
76
+ attr_reader :positional_params
77
+ attr_reader :uniform
78
+
79
+ def initialize(args:, index:, positional_params:, uniform: false)
80
+ @args = args
81
+ @index = index
82
+ @positional_params = positional_params
83
+ @uniform = uniform
84
+ end
85
+
86
+ def node
87
+ args[index]
88
+ end
89
+
90
+ def following_args
91
+ args[index..] or raise
92
+ end
93
+
94
+ def param
95
+ positional_params&.head
96
+ end
97
+
98
+ def update(index: self.index, positional_params: self.positional_params, uniform: self.uniform)
99
+ PositionalArgs.new(args: args, index: index, positional_params: positional_params, uniform: uniform)
100
+ end
101
+
102
+ def next()
103
+ case
104
+ when node && node.type == :forwarded_args
105
+ # If the node is a `:forwarded_args`, abort
106
+ nil
107
+ when !node && param.is_a?(Interface::Function::Params::PositionalParams::Required)
108
+ [
109
+ MissingArg.new(params: positional_params),
110
+ update(index: index, positional_params: nil)
111
+ ]
112
+ when !node && param.is_a?(Interface::Function::Params::PositionalParams::Optional)
113
+ nil
114
+ when !node && param.is_a?(Interface::Function::Params::PositionalParams::Rest)
115
+ nil
116
+ when !node && !param
117
+ nil
118
+ when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Required)
119
+ [
120
+ NodeParamPair.new(node: node, param: param),
121
+ update(index: index+1, positional_params: positional_params&.tail)
122
+ ]
123
+ when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Optional)
124
+ [
125
+ NodeParamPair.new(node: node, param: param),
126
+ update(index: index+1, positional_params: positional_params&.tail)
127
+ ]
128
+ when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Rest)
129
+ [
130
+ NodeParamPair.new(node: node, param: param),
131
+ update(index: index+1)
132
+ ]
133
+ when node && node.type != :splat && !param
134
+ [
135
+ UnexpectedArg.new(node: node),
136
+ update(index: index + 1)
137
+ ]
138
+ when node && node.type == :splat
139
+ [
140
+ SplatArg.new(node: node),
141
+ self
142
+ ]
143
+ end
144
+ end
145
+
146
+ def uniform_type
147
+ return nil unless positional_params
148
+ if positional_params.each.any? {|param| param.is_a?(Interface::Function::Params::PositionalParams::Rest) }
149
+ AST::Types::Intersection.build(types: positional_params.each.map(&:type))
150
+ end
151
+ end
152
+
153
+ def consume(n, node:)
154
+ # @type var ps: Array[Interface::Function::Params::PositionalParams::param]
155
+ ps = []
156
+ params = consume0(n, node: node, params: positional_params, ps: ps)
157
+ case params
158
+ when UnexpectedArg
159
+ [
160
+ params,
161
+ update(index: index+1, positional_params: nil)
162
+ ]
163
+ else
164
+ [ps, update(index: index+1, positional_params: params)]
165
+ end
166
+ end
167
+
168
+ def consume0(n, node:, params:, ps:)
169
+ case n
170
+ when 0
171
+ params
172
+ else
173
+ head = params&.head
174
+ case head
175
+ when nil
176
+ UnexpectedArg.new(node: node)
177
+ when Interface::Function::Params::PositionalParams::Required, Interface::Function::Params::PositionalParams::Optional
178
+ ps << head
179
+ consume0(n-1, node: node, params: params&.tail, ps: ps)
180
+ when Interface::Function::Params::PositionalParams::Rest
181
+ ps << head
182
+ consume0(n-1, node: node, params: params, ps: ps)
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ class KeywordArgs
189
+ class ArgTypePairs
190
+ attr_reader :pairs
191
+
192
+ def initialize(pairs:)
193
+ @pairs = pairs
194
+ end
195
+
196
+ include Equatable
197
+
198
+ def [](index)
199
+ pairs[index]
200
+ end
201
+
202
+ def size
203
+ pairs.size
204
+ end
205
+ end
206
+
207
+ class SplatArg
208
+ attr_reader :node
209
+ attr_accessor :type
210
+
211
+ def initialize(node:)
212
+ @node = node
213
+ @type = nil
214
+ end
215
+
216
+ include Equatable
217
+ end
218
+
219
+ class UnexpectedKeyword
220
+ attr_reader :keyword
221
+ attr_reader :node
222
+
223
+ include Equatable
224
+
225
+ def initialize(keyword:, node:)
226
+ @keyword = keyword
227
+ @node = node
228
+ end
229
+
230
+ def key_node
231
+ if node.type == :pair
232
+ node.children[0]
233
+ end
234
+ end
235
+
236
+ def value_node
237
+ if node.type == :pair
238
+ node.children[1]
239
+ end
240
+ end
241
+ end
242
+
243
+ class MissingKeyword
244
+ attr_reader :keywords
245
+
246
+ include Equatable
247
+
248
+ def initialize(keywords:)
249
+ @keywords = keywords
250
+ end
251
+ end
252
+
253
+ attr_reader :kwarg_nodes
254
+ attr_reader :keyword_params
255
+ attr_reader :index
256
+ attr_reader :consumed_keywords
257
+
258
+ def initialize(kwarg_nodes:, keyword_params:, index: 0, consumed_keywords: Set[])
259
+ @kwarg_nodes = kwarg_nodes
260
+ @keyword_params = keyword_params
261
+ @index = index
262
+ @consumed_keywords = consumed_keywords
263
+ end
264
+
265
+ def update(index: self.index, consumed_keywords: self.consumed_keywords)
266
+ KeywordArgs.new(
267
+ kwarg_nodes: kwarg_nodes,
268
+ keyword_params: keyword_params,
269
+ index: index,
270
+ consumed_keywords: consumed_keywords
271
+ )
272
+ end
273
+
274
+ def keyword_pair
275
+ kwarg_nodes[index]
276
+ end
277
+
278
+ def required_keywords
279
+ keyword_params.requireds
280
+ end
281
+
282
+ def optional_keywords
283
+ keyword_params.optionals
284
+ end
285
+
286
+ def rest_type
287
+ keyword_params.rest
288
+ end
289
+
290
+ def keyword_type(key)
291
+ required_keywords[key] || optional_keywords[key]
292
+ end
293
+
294
+ def all_keys
295
+ keys = Set.new
296
+ keys.merge(required_keywords.each_key)
297
+ keys.merge(optional_keywords.each_key)
298
+ keys.sort_by(&:to_s).to_a
299
+ end
300
+
301
+ def all_values
302
+ keys = Set.new
303
+ keys.merge(required_keywords.each_value)
304
+ keys.merge(optional_keywords.each_value)
305
+ keys.sort_by(&:to_s).to_a
306
+ end
307
+
308
+ def possible_key_type
309
+ # @type var key_types: Array[AST::Types::t]
310
+ key_types = all_keys.map {|key| AST::Types::Literal.new(value: key) }
311
+ key_types << AST::Builtin::Symbol.instance_type if rest_type
312
+
313
+ AST::Types::Union.build(types: key_types)
314
+ end
315
+
316
+ def possible_value_type
317
+ value_types = all_values
318
+ value_types << rest_type if rest_type
319
+
320
+ AST::Types::Intersection.build(types: value_types)
321
+ end
322
+
323
+ def next()
324
+ node = keyword_pair
325
+
326
+ if node
327
+ case node.type
328
+ when :pair
329
+ key_node, value_node = node.children
330
+
331
+ if key_node.type == :sym
332
+ key = key_node.children[0]
333
+
334
+ case
335
+ when value_type = keyword_type(key)
336
+ [
337
+ ArgTypePairs.new(
338
+ pairs: [
339
+ [key_node, AST::Types::Literal.new(value: key)],
340
+ [value_node, value_type]
341
+ ]
342
+ ),
343
+ update(
344
+ index: index+1,
345
+ consumed_keywords: consumed_keywords + [key]
346
+ )
347
+ ]
348
+ when value_type = rest_type
349
+ [
350
+ ArgTypePairs.new(
351
+ pairs: [
352
+ [key_node, AST::Builtin::Symbol.instance_type],
353
+ [value_node, value_type]
354
+ ]
355
+ ),
356
+ update(
357
+ index: index+1,
358
+ consumed_keywords: consumed_keywords + [key]
359
+ )
360
+ ]
361
+ else
362
+ [
363
+ UnexpectedKeyword.new(keyword: key, node: node),
364
+ update(index: index+1)
365
+ ]
366
+ end
367
+ else
368
+ if !all_keys.empty? || rest_type
369
+ [
370
+ ArgTypePairs.new(
371
+ pairs: [
372
+ [key_node, possible_key_type],
373
+ [value_node, possible_value_type]
374
+ ]
375
+ ),
376
+ update(index: index+1)
377
+ ]
378
+ else
379
+ [
380
+ UnexpectedKeyword.new(keyword: nil, node: node),
381
+ update(index: index+1)
382
+ ]
383
+ end
384
+ end
385
+ when :kwsplat
386
+ [
387
+ SplatArg.new(node: node),
388
+ self
389
+ ]
390
+ end
391
+ else
392
+ left = Set.new(required_keywords.keys) - consumed_keywords
393
+ unless left.empty?
394
+ [
395
+ MissingKeyword.new(keywords: left),
396
+ update(consumed_keywords: consumed_keywords + left)
397
+ ]
398
+ end
399
+ end
400
+ end
401
+
402
+ def consume_keys(keys, node:)
403
+ # @type var consumed_keys: Array[Symbol]
404
+ consumed_keys = []
405
+ # @type var types: Array[AST::Types::t]
406
+ types = []
407
+
408
+ # @type var unexpected_keyword: Symbol?
409
+ unexpected_keyword = nil
410
+
411
+ keys.each do |key|
412
+ case
413
+ when type = keyword_type(key)
414
+ consumed_keys << key
415
+ types << type
416
+ when type = rest_type()
417
+ types << type
418
+ else
419
+ unexpected_keyword = key
420
+ end
421
+ end
422
+
423
+ [
424
+ if unexpected_keyword
425
+ UnexpectedKeyword.new(keyword: unexpected_keyword, node: node)
426
+ else
427
+ types
428
+ end,
429
+ update(index: index + 1, consumed_keywords: consumed_keywords + consumed_keys)
430
+ ]
431
+ end
432
+ end
433
+
434
+ class BlockPassArg
435
+ attr_reader :node
436
+ attr_reader :block
437
+
438
+ def initialize(node:, block:)
439
+ @node = node
440
+ @block = block
441
+ end
442
+
443
+ include Equatable
444
+
445
+ def no_block?
446
+ !node && !block
447
+ end
448
+
449
+ def compatible?
450
+ if node
451
+ block ? true : false
452
+ else
453
+ !block || block.optional?
454
+ end
455
+ end
456
+
457
+ def block_missing?
458
+ !node && block&.required?
459
+ end
460
+
461
+ def unexpected_block?
462
+ node && !block
463
+ end
464
+
465
+ def pair
466
+ raise unless compatible?
467
+
468
+ if node && block
469
+ [
470
+ node,
471
+ block.type
472
+ ]
473
+ end
474
+ end
475
+
476
+ def node_type
477
+ raise unless block
478
+
479
+ type = AST::Types::Proc.new(type: block.type, block: nil, self_type: block.self_type)
480
+
481
+ if block.optional?
482
+ type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
483
+ end
484
+
485
+ type
486
+ end
487
+ end
488
+
489
+ class ForwardedArgs
490
+ attr_reader :node, :params
491
+
492
+ def initialize(node:, params:)
493
+ @node = node
494
+ @params = params
495
+ end
496
+ end
497
+
498
+ attr_reader :node
499
+ attr_reader :arguments
500
+ attr_reader :type
501
+
502
+ def initialize(node:, arguments:, type:)
503
+ raise "Untyped function is not supported" unless type.type.params
504
+ @node = node
505
+ @arguments = arguments
506
+ @type = type
507
+ end
508
+
509
+ def params
510
+ case type
511
+ when Interface::MethodType
512
+ type.type.params or raise
513
+ when AST::Types::Proc
514
+ type.type.params or raise
515
+ else
516
+ raise
517
+ end
518
+ end
519
+
520
+ def block
521
+ case type
522
+ when Interface::MethodType
523
+ type.block
524
+ when AST::Types::Proc
525
+ type.block
526
+ end
527
+ end
528
+
529
+ def positional_params
530
+ params or raise
531
+ params.positional_params
532
+ end
533
+
534
+ def keyword_params
535
+ params or raise
536
+ params.keyword_params
537
+ end
538
+
539
+ def kwargs_node
540
+ unless keyword_params.empty?
541
+ arguments.find {|node| node.type == :kwargs }
542
+ end
543
+ end
544
+
545
+ def positional_arg
546
+ args =
547
+ if keyword_params.empty?
548
+ arguments.take_while {|node| node.type != :block_pass }
549
+ else
550
+ arguments.take_while {|node| node.type != :kwargs && node.type != :block_pass }
551
+ end
552
+
553
+ PositionalArgs.new(args: args, index: 0, positional_params: positional_params)
554
+ end
555
+
556
+ def forwarded_args_node
557
+ arguments.find {|node| node.type == :forwarded_args }
558
+ end
559
+
560
+ def keyword_args
561
+ KeywordArgs.new(
562
+ kwarg_nodes: kwargs_node&.children || [],
563
+ keyword_params: keyword_params
564
+ )
565
+ end
566
+
567
+ def block_pass_arg
568
+ node = arguments.find {|node| node.type == :block_pass }
569
+
570
+ BlockPassArg.new(node: node, block: block)
571
+ end
572
+
573
+ def each
574
+ if block_given?
575
+ errors = [] #: Array[PositionalArgs::error_arg | KeywordArgs::error_arg]
576
+
577
+ last_positional_args = positional_arg
578
+
579
+ positional_arg.tap do |args|
580
+ while (value, args = args.next())
581
+ yield value
582
+
583
+ case value
584
+ when PositionalArgs::SplatArg
585
+ type = value.type
586
+
587
+ case type
588
+ when nil
589
+ raise
590
+ when AST::Types::Tuple
591
+ ts, args = args.consume(type.types.size, node: value.node)
592
+
593
+ case ts
594
+ when Array
595
+ ty = AST::Types::Tuple.new(types: ts.map(&:type))
596
+ yield PositionalArgs::NodeTypePair.new(node: value.node, type: ty)
597
+ when PositionalArgs::UnexpectedArg
598
+ errors << ts
599
+ yield ts
600
+ end
601
+ else
602
+ if t = args.uniform_type
603
+ args.following_args.each do |node|
604
+ yield PositionalArgs::NodeTypePair.new(node: node, type: t)
605
+ end
606
+ else
607
+ args.following_args.each do |node|
608
+ arg = PositionalArgs::UnexpectedArg.new(node: node)
609
+ yield arg
610
+ errors << arg
611
+ end
612
+ end
613
+
614
+ break
615
+ end
616
+ when PositionalArgs::UnexpectedArg, PositionalArgs::MissingArg
617
+ errors << value
618
+ end
619
+
620
+ last_positional_args = args
621
+ end
622
+ end
623
+
624
+ if fag = forwarded_args_node
625
+ forward_params = Interface::Function::Params.new(
626
+ positional_params: last_positional_args.positional_params,
627
+ keyword_params: keyword_params
628
+ )
629
+
630
+ forwarded_args = ForwardedArgs.new(node: fag, params: forward_params)
631
+ else
632
+ keyword_args.tap do |args|
633
+ while (a, args = args.next)
634
+ case a
635
+ when KeywordArgs::MissingKeyword
636
+ errors << a
637
+ when KeywordArgs::UnexpectedKeyword
638
+ errors << a
639
+ end
640
+
641
+ yield a
642
+
643
+ case a
644
+ when KeywordArgs::SplatArg
645
+ case type = a.type
646
+ when nil
647
+ raise
648
+ when AST::Types::Record
649
+ # @type var keys: Array[Symbol]
650
+ keys = _ = type.elements.keys
651
+ ts, args = args.consume_keys(keys, node: a.node)
652
+
653
+ case ts
654
+ when KeywordArgs::UnexpectedKeyword
655
+ yield ts
656
+ errors << ts
657
+ when Array
658
+ pairs = keys.zip(ts) #: Array[[Symbol, AST::Types::t]]
659
+ record = AST::Types::Record.new(elements: Hash[pairs], required_keys: Set.new(keys))
660
+ yield KeywordArgs::ArgTypePairs.new(pairs: [[a.node, record]])
661
+ end
662
+ else
663
+ args = args.update(index: args.index + 1)
664
+
665
+ if args.rest_type
666
+ type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, args.possible_value_type)
667
+ yield KeywordArgs::ArgTypePairs.new(pairs: [[a.node, type]])
668
+ else
669
+ yield KeywordArgs::UnexpectedKeyword.new(keyword: nil, node: a.node)
670
+ end
671
+ end
672
+ end
673
+ end
674
+ end
675
+ end
676
+
677
+ diagnostics = [] #: Array[Diagnostic::Ruby::Base]
678
+
679
+ missing_keywords = [] #: Array[Symbol]
680
+ errors.each do |error|
681
+ case error
682
+ when KeywordArgs::UnexpectedKeyword
683
+ diagnostics << Diagnostic::Ruby::UnexpectedKeywordArgument.new(node: error.node, params: params)
684
+ when KeywordArgs::MissingKeyword
685
+ missing_keywords.push(*error.keywords.to_a)
686
+ when PositionalArgs::UnexpectedArg
687
+ if error.node.type == :kwargs
688
+ error.node.children.each do |kwarg|
689
+ if kwarg.type == :pair
690
+ diagnostics << Diagnostic::Ruby::UnexpectedKeywordArgument.new(node: kwarg, params: params)
691
+ end
692
+ end
693
+ else
694
+ diagnostics << Diagnostic::Ruby::UnexpectedPositionalArgument.new(node: error.node, params: params)
695
+ end
696
+ when PositionalArgs::MissingArg
697
+ diagnostics << Diagnostic::Ruby::InsufficientPositionalArguments.new(node: node, params: params)
698
+ end
699
+ end
700
+
701
+ unless missing_keywords.empty?
702
+ diagnostics << Diagnostic::Ruby::InsufficientKeywordArguments.new(node: node, params: params, missing_keywords: missing_keywords)
703
+ end
704
+
705
+ [forwarded_args, diagnostics]
706
+ else
707
+ enum_for :each
708
+ end
709
+ end
710
+ end
711
+ end
712
+ end