steep 0.1.0.pre2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/README.md +146 -33
  4. data/bin/smoke_runner.rb +43 -10
  5. data/lib/steep/ast/annotation/collection.rb +93 -0
  6. data/lib/steep/ast/annotation.rb +131 -0
  7. data/lib/steep/ast/buffer.rb +47 -0
  8. data/lib/steep/ast/location.rb +82 -0
  9. data/lib/steep/ast/method_type.rb +116 -0
  10. data/lib/steep/ast/signature/class.rb +33 -0
  11. data/lib/steep/ast/signature/const.rb +17 -0
  12. data/lib/steep/ast/signature/env.rb +123 -0
  13. data/lib/steep/ast/signature/extension.rb +21 -0
  14. data/lib/steep/ast/signature/gvar.rb +17 -0
  15. data/lib/steep/ast/signature/interface.rb +31 -0
  16. data/lib/steep/ast/signature/members.rb +71 -0
  17. data/lib/steep/ast/signature/module.rb +21 -0
  18. data/lib/steep/ast/type_params.rb +13 -0
  19. data/lib/steep/ast/types/any.rb +39 -0
  20. data/lib/steep/ast/types/bot.rb +39 -0
  21. data/lib/steep/ast/types/class.rb +35 -0
  22. data/lib/steep/ast/types/helper.rb +21 -0
  23. data/lib/steep/ast/types/instance.rb +39 -0
  24. data/lib/steep/ast/types/intersection.rb +74 -0
  25. data/lib/steep/ast/types/name.rb +124 -0
  26. data/lib/steep/ast/types/self.rb +39 -0
  27. data/lib/steep/ast/types/top.rb +39 -0
  28. data/lib/steep/ast/types/union.rb +74 -0
  29. data/lib/steep/ast/types/var.rb +57 -0
  30. data/lib/steep/ast/types/void.rb +35 -0
  31. data/lib/steep/cli.rb +28 -1
  32. data/lib/steep/drivers/annotations.rb +32 -0
  33. data/lib/steep/drivers/check.rb +53 -77
  34. data/lib/steep/drivers/scaffold.rb +303 -0
  35. data/lib/steep/drivers/utils/each_signature.rb +66 -0
  36. data/lib/steep/drivers/utils/validator.rb +115 -0
  37. data/lib/steep/drivers/validate.rb +39 -0
  38. data/lib/steep/errors.rb +291 -19
  39. data/lib/steep/interface/abstract.rb +44 -0
  40. data/lib/steep/interface/builder.rb +470 -0
  41. data/lib/steep/interface/instantiated.rb +126 -0
  42. data/lib/steep/interface/ivar_chain.rb +26 -0
  43. data/lib/steep/interface/method.rb +60 -0
  44. data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
  45. data/lib/steep/interface/substitution.rb +65 -0
  46. data/lib/steep/module_name.rb +116 -0
  47. data/lib/steep/parser.rb +1314 -814
  48. data/lib/steep/parser.y +536 -175
  49. data/lib/steep/source.rb +220 -25
  50. data/lib/steep/subtyping/check.rb +673 -0
  51. data/lib/steep/subtyping/constraints.rb +275 -0
  52. data/lib/steep/subtyping/relation.rb +41 -0
  53. data/lib/steep/subtyping/result.rb +126 -0
  54. data/lib/steep/subtyping/trace.rb +48 -0
  55. data/lib/steep/subtyping/variable_occurrence.rb +49 -0
  56. data/lib/steep/subtyping/variable_variance.rb +69 -0
  57. data/lib/steep/type_construction.rb +1630 -524
  58. data/lib/steep/type_inference/block_params.rb +100 -0
  59. data/lib/steep/type_inference/constant_env.rb +55 -0
  60. data/lib/steep/type_inference/send_args.rb +222 -0
  61. data/lib/steep/type_inference/type_env.rb +226 -0
  62. data/lib/steep/type_name.rb +27 -7
  63. data/lib/steep/typing.rb +4 -0
  64. data/lib/steep/version.rb +1 -1
  65. data/lib/steep.rb +71 -16
  66. data/smoke/and/a.rb +4 -2
  67. data/smoke/array/a.rb +4 -5
  68. data/smoke/array/b.rb +4 -4
  69. data/smoke/block/a.rb +2 -2
  70. data/smoke/block/a.rbi +2 -0
  71. data/smoke/block/b.rb +15 -0
  72. data/smoke/case/a.rb +3 -3
  73. data/smoke/class/a.rb +3 -3
  74. data/smoke/class/b.rb +0 -2
  75. data/smoke/class/d.rb +2 -2
  76. data/smoke/class/e.rb +1 -1
  77. data/smoke/class/f.rb +2 -2
  78. data/smoke/class/g.rb +8 -0
  79. data/smoke/const/a.rb +3 -3
  80. data/smoke/dstr/a.rb +1 -1
  81. data/smoke/ensure/a.rb +22 -0
  82. data/smoke/enumerator/a.rb +6 -6
  83. data/smoke/enumerator/b.rb +22 -0
  84. data/smoke/extension/a.rb +2 -2
  85. data/smoke/extension/b.rb +3 -3
  86. data/smoke/extension/c.rb +1 -1
  87. data/smoke/hello/hello.rb +2 -2
  88. data/smoke/if/a.rb +4 -2
  89. data/smoke/kwbegin/a.rb +8 -0
  90. data/smoke/literal/a.rb +5 -5
  91. data/smoke/method/a.rb +5 -5
  92. data/smoke/method/a.rbi +4 -0
  93. data/smoke/method/b.rb +29 -0
  94. data/smoke/module/a.rb +3 -3
  95. data/smoke/module/a.rbi +9 -0
  96. data/smoke/module/b.rb +2 -2
  97. data/smoke/module/c.rb +1 -1
  98. data/smoke/module/d.rb +5 -0
  99. data/smoke/module/e.rb +13 -0
  100. data/smoke/module/f.rb +13 -0
  101. data/smoke/rescue/a.rb +62 -0
  102. data/smoke/super/a.rb +2 -2
  103. data/smoke/type_case/a.rb +35 -0
  104. data/smoke/yield/a.rb +2 -2
  105. data/stdlib/builtin.rbi +463 -24
  106. data/steep.gemspec +3 -2
  107. metadata +91 -29
  108. data/lib/steep/annotation.rb +0 -223
  109. data/lib/steep/signature/class.rb +0 -450
  110. data/lib/steep/signature/extension.rb +0 -51
  111. data/lib/steep/signature/interface.rb +0 -49
  112. data/lib/steep/types/any.rb +0 -31
  113. data/lib/steep/types/class.rb +0 -27
  114. data/lib/steep/types/instance.rb +0 -27
  115. data/lib/steep/types/merge.rb +0 -32
  116. data/lib/steep/types/name.rb +0 -57
  117. data/lib/steep/types/union.rb +0 -42
  118. data/lib/steep/types/var.rb +0 -38
  119. data/lib/steep/types.rb +0 -4
@@ -0,0 +1,673 @@
1
+ module Steep
2
+ module Subtyping
3
+ class Check
4
+ attr_reader :builder
5
+ attr_reader :cache
6
+
7
+ def initialize(builder:)
8
+ @builder = builder
9
+ @cache = {}
10
+ end
11
+
12
+ def check(relation, constraints:, assumption: Set.new, trace: Trace.new)
13
+ Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
14
+ prefix = trace.size
15
+ cached = cache[relation]
16
+ if cached && constraints.empty?
17
+ if cached.success?
18
+ cached
19
+ else
20
+ cached.merge_trace(trace)
21
+ end
22
+ else
23
+ if assumption.member?(relation)
24
+ success(constraints: constraints)
25
+ else
26
+ trace.add(relation.sub_type, relation.super_type) do
27
+ assumption = assumption + Set.new([relation])
28
+ check0(relation, assumption: assumption, trace: trace, constraints: constraints).tap do |result|
29
+ result = result.else do |failure|
30
+ failure.drop(prefix)
31
+ end
32
+
33
+ Steep.logger.debug "result=#{result.class}"
34
+ cache[relation] = result if cacheable?(relation)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def cacheable?(relation)
43
+ relation.sub_type.free_variables.empty? && relation.super_type.free_variables.empty?
44
+ end
45
+
46
+ def success(constraints:)
47
+ Result::Success.new(constraints: constraints)
48
+ end
49
+
50
+ def failure(error:, trace:)
51
+ Result::Failure.new(error: error, trace: trace)
52
+ end
53
+
54
+ def check0(relation, assumption:, trace:, constraints:)
55
+ case
56
+ when same_type?(relation, assumption: assumption)
57
+ success(constraints: constraints)
58
+
59
+ when relation.sub_type.is_a?(AST::Types::Any) || relation.super_type.is_a?(AST::Types::Any)
60
+ success(constraints: constraints)
61
+
62
+ when relation.super_type.is_a?(AST::Types::Top)
63
+ success(constraints: constraints)
64
+
65
+ when relation.sub_type.is_a?(AST::Types::Bot)
66
+ success(constraints: constraints)
67
+
68
+ when relation.super_type.is_a?(AST::Types::Var)
69
+ if constraints.unknown?(relation.super_type.name)
70
+ constraints.add(relation.super_type.name, sub_type: relation.sub_type)
71
+ success(constraints: constraints)
72
+ else
73
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation),
74
+ trace: trace)
75
+ end
76
+
77
+ when relation.sub_type.is_a?(AST::Types::Var)
78
+ if constraints.unknown?(relation.sub_type.name)
79
+ constraints.add(relation.sub_type.name, super_type: relation.super_type)
80
+ success(constraints: constraints)
81
+ else
82
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation),
83
+ trace: trace)
84
+ end
85
+
86
+ when relation.sub_type.is_a?(AST::Types::Union)
87
+ results = relation.sub_type.types.map do |sub_type|
88
+ check0(Relation.new(sub_type: sub_type, super_type: relation.super_type),
89
+ assumption: assumption,
90
+ trace: trace,
91
+ constraints: constraints)
92
+ end
93
+
94
+ if results.all?(&:success?)
95
+ results.first
96
+ else
97
+ results.find(&:failure?)
98
+ end
99
+
100
+ when relation.super_type.is_a?(AST::Types::Union)
101
+ results = relation.super_type.types.map do |super_type|
102
+ check0(Relation.new(sub_type: relation.sub_type, super_type: super_type),
103
+ assumption: assumption,
104
+ trace: trace,
105
+ constraints: constraints)
106
+ end
107
+
108
+ results.find(&:success?) || results.first
109
+
110
+ when relation.sub_type.is_a?(AST::Types::Intersection)
111
+ results = relation.sub_type.types.map do |sub_type|
112
+ check0(Relation.new(sub_type: sub_type, super_type: relation.super_type),
113
+ assumption: assumption,
114
+ trace: trace,
115
+ constraints: constraints)
116
+ end
117
+
118
+ results.find(&:success?) || results.first
119
+
120
+ when relation.super_type.is_a?(AST::Types::Intersection)
121
+ results = relation.super_type.types.map do |super_type|
122
+ check0(Relation.new(sub_type: relation.sub_type, super_type: super_type),
123
+ assumption: assumption,
124
+ trace: trace,
125
+ constraints: constraints)
126
+ end
127
+
128
+ if results.all?(&:success?)
129
+ results.first
130
+ else
131
+ results.find(&:failure?)
132
+ end
133
+
134
+ when relation.sub_type.is_a?(AST::Types::Name) && relation.super_type.is_a?(AST::Types::Name)
135
+ if relation.sub_type.name == relation.super_type.name && relation.sub_type.args.size == relation.super_type.args.size
136
+ results = relation.sub_type.args.zip(relation.super_type.args).flat_map do |(sub, sup)|
137
+ Relation.new(sub_type: sub, super_type: sup).yield_self do |rel|
138
+ [rel, rel.flip]
139
+ end
140
+ end.map do |relation|
141
+ check0(relation,
142
+ assumption: assumption,
143
+ trace: trace,
144
+ constraints: constraints)
145
+ end
146
+
147
+ if results.all?(&:success?)
148
+ results.first
149
+ else
150
+ results.find(&:failure?)
151
+ end
152
+ else
153
+ sub_interface = resolve(relation.sub_type, with_initialize: false)
154
+ super_interface = resolve(relation.super_type, with_initialize: false)
155
+
156
+ check_interface(sub_interface, super_interface, assumption: assumption, trace: trace, constraints: constraints)
157
+ end
158
+
159
+ else
160
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation),
161
+ trace: trace)
162
+ end
163
+ end
164
+
165
+ def same_type?(relation, assumption:)
166
+ if assumption.include?(relation) && assumption.include?(relation.flip)
167
+ return true
168
+ end
169
+
170
+ case
171
+ when relation.sub_type == relation.super_type
172
+ true
173
+ when relation.sub_type.is_a?(AST::Types::Name) && relation.super_type.is_a?(AST::Types::Name)
174
+ return false unless relation.sub_type.name == relation.super_type.name
175
+ return false unless relation.sub_type.args.size == relation.super_type.args.size
176
+ relation.sub_type.args.zip(relation.super_type.args).all? do |(s, t)|
177
+ same_type?(Relation.new(sub_type: s, super_type: t), assumption: assumption)
178
+ end
179
+ else
180
+ false
181
+ end
182
+ end
183
+
184
+ def check_interface(sub_type, super_type, assumption:, trace:, constraints:)
185
+ method_pairs = []
186
+
187
+ super_type.methods.each do |name, sup_method|
188
+ sub_method = sub_type.methods[name]
189
+
190
+ if sub_method
191
+ method_pairs << [sub_method, sup_method]
192
+ else
193
+ return failure(error: Result::Failure::MethodMissingError.new(name: name),
194
+ trace: trace)
195
+ end
196
+ end
197
+
198
+ method_pairs.each do |(sub_method, sup_method)|
199
+ result = check_method(sub_method.name, sub_method, sup_method, assumption: assumption, trace: trace, constraints: constraints)
200
+ return result if result.failure?
201
+ end
202
+
203
+ success(constraints: constraints)
204
+ end
205
+
206
+ def check_method(name, sub_method, super_method, assumption:, trace:, constraints:)
207
+ trace.add(sub_method, super_method) do
208
+ all_results = super_method.types.map do |super_type|
209
+ sub_method.types.map do |sub_type|
210
+ trace.add(sub_type, super_type) do
211
+ case
212
+ when super_type.type_params.empty? && sub_type.type_params.empty?
213
+ check_method_type(name,
214
+ sub_type,
215
+ super_type,
216
+ assumption: assumption,
217
+ trace: trace,
218
+ constraints: constraints)
219
+
220
+ when super_type.type_params.empty?
221
+ yield_self do
222
+ sub_args = sub_type.type_params.map {|x| AST::Types::Var.fresh(x) }
223
+ sub_type = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params,
224
+ sub_args))
225
+
226
+ constraints.add_var(*sub_args)
227
+
228
+ match_method_type(name, sub_type, super_type, trace: trace).yield_self do |pairs|
229
+ case pairs
230
+ when Array
231
+ subst = pairs.each.with_object(Interface::Substitution.empty) do |(sub, sup), subst|
232
+ case
233
+ when sub.is_a?(AST::Types::Var) && sub_args.include?(sub)
234
+ subst.add!(sub.name, sup)
235
+ when sup.is_a?(AST::Types::Var) && sub_args.include?(sup)
236
+ subst.add!(sup.name, sub)
237
+ end
238
+ end
239
+
240
+ check_method_type(name,
241
+ sub_type.subst(subst),
242
+ super_type,
243
+ assumption: assumption,
244
+ trace: trace,
245
+ constraints: constraints)
246
+ else
247
+ pairs
248
+ end
249
+ end
250
+ end
251
+
252
+ when super_type.type_params.size == sub_type.type_params.size
253
+ yield_self do
254
+ args = sub_type.type_params.map {|x| AST::Types::Var.fresh(x) }
255
+
256
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params, args))
257
+ super_type_ = super_type.instantiate(Interface::Substitution.build(super_type.type_params, args))
258
+
259
+ constraints.add_var(*args)
260
+
261
+ check_method_type(name,
262
+ sub_type_,
263
+ super_type_,
264
+ assumption: assumption,
265
+ trace: trace,
266
+ constraints: constraints)
267
+ end
268
+ else
269
+ failure(error: Result::Failure::PolyMethodSubtyping.new(name: name),
270
+ trace: trace)
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ all_results.each do |results|
277
+ if results.any?(&:success?)
278
+ #ok
279
+ else
280
+ return results.find(&:failure?)
281
+ end
282
+ end
283
+
284
+ success(constraints: constraints)
285
+ end
286
+ end
287
+
288
+ def check_method_type(name, sub_type, super_type, assumption:, trace:, constraints:)
289
+ Steep.logger.tagged("#{name}: #{sub_type} <: #{super_type}") do
290
+ check_method_params(name, sub_type.params, super_type.params, assumption: assumption, trace: trace, constraints: constraints).then do
291
+ check_block_given(name, sub_type.block, super_type.block, trace: trace, constraints: constraints).then do
292
+ check_block_params(name, sub_type.block, super_type.block, assumption: assumption, trace: trace, constraints: constraints).then do
293
+ check_block_return(sub_type.block, super_type.block, assumption: assumption, trace: trace, constraints:constraints).then do
294
+ relation = Relation.new(super_type: super_type.return_type,
295
+ sub_type: sub_type.return_type)
296
+ check(relation, assumption: assumption, trace: trace, constraints: constraints)
297
+ end
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+
304
+ def check_block_given(name, sub_block, super_block, trace:, constraints:)
305
+ case
306
+ when !super_block && !sub_block
307
+ success(constraints: constraints)
308
+ when super_block && sub_block
309
+ success(constraints: constraints)
310
+ else
311
+ failure(
312
+ error: Result::Failure::BlockMismatchError.new(name: name),
313
+ trace: trace
314
+ )
315
+ end
316
+ end
317
+
318
+ def check_method_params(name, sub_params, super_params, assumption:, trace:, constraints:)
319
+ match_params(name, sub_params, super_params, trace: trace).yield_self do |pairs|
320
+ case pairs
321
+ when Array
322
+ pairs.each do |(sub_type, super_type)|
323
+ relation = Relation.new(super_type: sub_type, sub_type: super_type)
324
+
325
+ result = check(relation, assumption: assumption, trace: trace, constraints: constraints)
326
+ return result if result.failure?
327
+ end
328
+
329
+ success(constraints: constraints)
330
+ else
331
+ pairs
332
+ end
333
+ end
334
+ end
335
+
336
+ def match_method_type(name, sub_type, super_type, trace:)
337
+ [].tap do |pairs|
338
+ match_params(name, sub_type.params, super_type.params, trace: trace).yield_self do |result|
339
+ return result unless result.is_a?(Array)
340
+ pairs.push(*result)
341
+ pairs.push [sub_type.return_type, super_type.return_type]
342
+
343
+ case
344
+ when !super_type.block && !sub_type.block
345
+ # No block required and given
346
+
347
+ when super_type.block && sub_type.block
348
+ match_params(name, super_type.block.params, sub_type.block.params, trace: trace).yield_self do |block_result|
349
+ return block_result unless block_result.is_a?(Array)
350
+ pairs.push(*block_result)
351
+ pairs.push [super_type.block.return_type, sub_type.block.return_type]
352
+ end
353
+
354
+ else
355
+ return failure(error: Result::Failure::BlockMismatchError.new(name: name),
356
+ trace: trace)
357
+ end
358
+ end
359
+ end
360
+ end
361
+
362
+ def match_params(name, sub_params, super_params, trace:)
363
+ pairs = []
364
+
365
+ sub_flat = sub_params.flat_unnamed_params
366
+ sup_flat = super_params.flat_unnamed_params
367
+
368
+ failure = failure(error: Result::Failure::ParameterMismatchError.new(name: name),
369
+ trace: trace)
370
+
371
+ case
372
+ when super_params.rest
373
+ return failure unless sub_params.rest
374
+
375
+ while sub_flat.size > 0
376
+ sub_type = sub_flat.shift
377
+ sup_type = sup_flat.shift
378
+
379
+ if sup_type
380
+ pairs << [sub_type.last, sup_type.last]
381
+ else
382
+ pairs << [sub_type.last, super_params.rest]
383
+ end
384
+ end
385
+
386
+ if sub_params.rest
387
+ pairs << [sub_params.rest, super_params.rest]
388
+ end
389
+
390
+ when sub_params.rest
391
+ while sub_flat.size > 0
392
+ sub_type = sub_flat.shift
393
+ sup_type = sup_flat.shift
394
+
395
+ if sup_type
396
+ pairs << [sub_type.last, sup_type.last]
397
+ else
398
+ break
399
+ end
400
+ end
401
+
402
+ if sub_params.rest && !sup_flat.empty?
403
+ sup_flat.each do |sup_type|
404
+ pairs << [sub_params.rest, sup_type.last]
405
+ end
406
+ end
407
+ when sub_params.required.size + sub_params.optional.size >= super_params.required.size + super_params.optional.size
408
+ while sub_flat.size > 0
409
+ sub_type = sub_flat.shift
410
+ sup_type = sup_flat.shift
411
+
412
+ if sup_type
413
+ pairs << [sub_type.last, sup_type.last]
414
+ else
415
+ if sub_type.first == :required
416
+ return failure
417
+ else
418
+ break
419
+ end
420
+ end
421
+ end
422
+ else
423
+ return failure
424
+ end
425
+
426
+ sub_flat_kws = sub_params.flat_keywords
427
+ sup_flat_kws = super_params.flat_keywords
428
+
429
+ sup_flat_kws.each do |name, _|
430
+ if sub_flat_kws.key?(name)
431
+ pairs << [sub_flat_kws[name], sup_flat_kws[name]]
432
+ else
433
+ if sub_params.rest_keywords
434
+ pairs << [sub_params.rest_keywords, sup_flat_kws[name]]
435
+ else
436
+ return failure
437
+ end
438
+ end
439
+ end
440
+
441
+ sub_params.required_keywords.each do |name, _|
442
+ unless super_params.required_keywords.key?(name)
443
+ return failure
444
+ end
445
+ end
446
+
447
+ if sub_params.rest_keywords && super_params.rest_keywords
448
+ pairs << [sub_params.rest_keywords, super_params.rest_keywords]
449
+ end
450
+
451
+ pairs
452
+ end
453
+
454
+ def check_block_params(name, sub_block, super_block, assumption:, trace:, constraints:)
455
+ if sub_block
456
+ check_method_params(name,
457
+ super_block.params,
458
+ sub_block.params,
459
+ assumption: assumption,
460
+ trace: trace,
461
+ constraints: constraints)
462
+ else
463
+ success(constraints: constraints)
464
+ end
465
+ end
466
+
467
+ def check_block_return(sub_block, super_block, assumption:, trace:, constraints:)
468
+ if sub_block
469
+ relation = Relation.new(sub_type: super_block.return_type,
470
+ super_type: sub_block.return_type)
471
+ check(relation, assumption: assumption, trace: trace, constraints: constraints)
472
+ else
473
+ success(constraints: constraints)
474
+ end
475
+ end
476
+
477
+ def module_type(type)
478
+ case
479
+ when builder.signatures.class?(type.name)
480
+ type.class_type(constructor: nil)
481
+ when builder.signatures.module?(type.name)
482
+ type.module_type
483
+ end
484
+ end
485
+
486
+ def compact(types)
487
+ types = types.reject {|type| type.is_a?(AST::Types::Any) }
488
+
489
+ if types.empty?
490
+ [AST::Types::Any.new]
491
+ else
492
+ compact0(types)
493
+ end
494
+ end
495
+
496
+ def compact0(types)
497
+ if types.size == 1
498
+ types
499
+ else
500
+ type, *types_ = types
501
+ compacted = compact0(types_)
502
+ compacted.flat_map do |type_|
503
+ case
504
+ when type == type_
505
+ [type]
506
+ when check(Relation.new(sub_type: type_, super_type: type), constraints: Constraints.empty).success?
507
+ [type]
508
+ when check(Relation.new(sub_type: type, super_type: type_), constraints: Constraints.empty).success?
509
+ [type_]
510
+ else
511
+ [type, type_]
512
+ end
513
+ end.uniq
514
+ end
515
+ end
516
+
517
+ class CannotResolveError < StandardError
518
+ attr_reader :type
519
+
520
+ def initialize(type:)
521
+ @type = type
522
+ super "Type #{type} cannot resolve to interface"
523
+ end
524
+ end
525
+
526
+ def resolve(type, self_type: type, instance_type: nil, module_type: nil, with_initialize:)
527
+ Steep.logger.debug("Check#resolve: type=#{type}")
528
+ case type
529
+ when AST::Types::Any, AST::Types::Var, AST::Types::Class, AST::Types::Instance
530
+ raise CannotResolveError.new(type: type)
531
+ when AST::Types::Name
532
+ builder.build(type.name, with_initialize: with_initialize).yield_self do |abstract|
533
+ case type.name
534
+ when TypeName::Instance, TypeName::Interface
535
+ abstract.instantiate(
536
+ type: self_type,
537
+ args: type.args,
538
+ instance_type: type,
539
+ module_type: module_type || module_type(type)
540
+ )
541
+ when TypeName::Class, TypeName::Module
542
+ signature = builder.signatures.find_class_or_module(type.name.name)
543
+ args = signature.params&.variables&.map {|var| AST::Types::Var.new(name: var) } || []
544
+ abstract.instantiate(
545
+ type: self_type,
546
+ args: [],
547
+ instance_type: AST::Types::Name.new_instance(name: type.name.name, args: args),
548
+ module_type: module_type || module_type(type)
549
+ )
550
+ end
551
+ end
552
+ when AST::Types::Union
553
+ interfaces = type.types.map do |member_type|
554
+ fresh = AST::Types::Var.fresh(:___)
555
+
556
+ resolve(member_type, self_type: type, instance_type: fresh, module_type: fresh, with_initialize: with_initialize).select_method_type do |method_type|
557
+ !method_type.each_type.include?(fresh)
558
+ end
559
+ end
560
+
561
+ methods = interfaces.inject(nil) do |methods, i|
562
+ if methods
563
+ intersection = {}
564
+ i.methods.each do |name, new_method|
565
+ existing_method = methods[name]
566
+
567
+ if existing_method
568
+ case
569
+ when new_method == existing_method
570
+ intersection[name] = new_method
571
+ when check_method(name, new_method, existing_method,
572
+ assumption: Set.new,
573
+ trace: Trace.new,
574
+ constraints: Constraints.empty).success?
575
+ intersection[name] = existing_method
576
+ when check_method(name, existing_method, new_method,
577
+ assumption: Set.new,
578
+ trace: Trace.new,
579
+ constraints: Constraints.empty).success?
580
+ intersection[name] = new_method
581
+ else
582
+ merged_method_types = []
583
+
584
+ existing_method.types.each do |existing_method_type|
585
+ new_method.types.each do |new_method_type|
586
+ if existing_method_type.params == new_method_type.params &&
587
+ existing_method_type.block == new_method_type.block &&
588
+ existing_method_type.type_params == new_method_type.type_params
589
+ merged_method_types << existing_method_type.with(
590
+ return_type: AST::Types::Union.build(
591
+ types: [
592
+ existing_method_type.return_type,
593
+ new_method_type.return_type
594
+ ]
595
+ ),
596
+ location: nil
597
+ )
598
+ end
599
+ end
600
+ end
601
+
602
+ unless merged_method_types.empty?
603
+ intersection[name] = Interface::Method.new(
604
+ type_name: nil,
605
+ name: name,
606
+ types: merged_method_types,
607
+ super_method: nil,
608
+ attributes: []
609
+ )
610
+ end
611
+ end
612
+ end
613
+ end
614
+ intersection
615
+ else
616
+ i.methods
617
+ end
618
+ end
619
+
620
+ Interface::Instantiated.new(type: type,
621
+ methods: methods,
622
+ ivar_chains: {})
623
+
624
+ when AST::Types::Intersection
625
+ interfaces = type.types.map do |type| resolve(type, with_initialize: with_initialize) end
626
+
627
+ methods = interfaces.inject(nil) do |methods, i|
628
+ if methods
629
+ i.methods.each do |name, method|
630
+ if methods.key?(name)
631
+ case
632
+ when method == methods[name]
633
+ when check_method(name, method, methods[name],
634
+ assumption: Set.new,
635
+ trace: Trace.new,
636
+ constraints: Constraints.empty).success?
637
+ methods[name] = method
638
+ when check_method(name, methods[name], method,
639
+ assumption: Set.new,
640
+ trace: Trace.new,
641
+ constraints: Constraints.empty).success?
642
+ methods[name] = methods[name]
643
+ else
644
+ methods[name] = Interface::Method.new(
645
+ type_name: nil,
646
+ name: name,
647
+ types: methods[name].types + method.types,
648
+ super_method: nil,
649
+ attributes: []
650
+ )
651
+ end
652
+ else
653
+ methods[name] = i.methods[name]
654
+ end
655
+ end
656
+ methods
657
+ else
658
+ i.methods
659
+ end
660
+ end
661
+
662
+ Interface::Instantiated.new(type: type,
663
+ methods: methods,
664
+ ivar_chains: {})
665
+ when AST::Types::Void
666
+ Interface::Instantiated.new(type: type,
667
+ methods: {},
668
+ ivar_chains: {})
669
+ end
670
+ end
671
+ end
672
+ end
673
+ end