steep 0.1.0.pre2 → 0.1.0

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.
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