steep 0.22.0 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -1
  3. data/bin/smoke_runner.rb +3 -4
  4. data/lib/steep.rb +1 -1
  5. data/lib/steep/ast/builtin.rb +2 -20
  6. data/lib/steep/ast/types.rb +5 -3
  7. data/lib/steep/ast/types/any.rb +1 -3
  8. data/lib/steep/ast/types/boolean.rb +1 -3
  9. data/lib/steep/ast/types/bot.rb +1 -3
  10. data/lib/steep/ast/types/class.rb +2 -2
  11. data/lib/steep/ast/types/factory.rb +106 -55
  12. data/lib/steep/ast/types/helper.rb +6 -0
  13. data/lib/steep/ast/types/instance.rb +2 -2
  14. data/lib/steep/ast/types/intersection.rb +20 -13
  15. data/lib/steep/ast/types/literal.rb +1 -3
  16. data/lib/steep/ast/types/name.rb +15 -67
  17. data/lib/steep/ast/types/nil.rb +1 -3
  18. data/lib/steep/ast/types/proc.rb +5 -2
  19. data/lib/steep/ast/types/record.rb +9 -4
  20. data/lib/steep/ast/types/self.rb +1 -1
  21. data/lib/steep/ast/types/top.rb +1 -3
  22. data/lib/steep/ast/types/tuple.rb +5 -3
  23. data/lib/steep/ast/types/union.rb +16 -9
  24. data/lib/steep/ast/types/var.rb +2 -2
  25. data/lib/steep/ast/types/void.rb +1 -3
  26. data/lib/steep/drivers/check.rb +4 -0
  27. data/lib/steep/errors.rb +14 -0
  28. data/lib/steep/interface/interface.rb +5 -62
  29. data/lib/steep/interface/method_type.rb +383 -92
  30. data/lib/steep/interface/substitution.rb +48 -6
  31. data/lib/steep/project/completion_provider.rb +1 -1
  32. data/lib/steep/project/hover_content.rb +1 -1
  33. data/lib/steep/project/target.rb +5 -2
  34. data/lib/steep/server/base_worker.rb +5 -3
  35. data/lib/steep/server/code_worker.rb +2 -0
  36. data/lib/steep/server/master.rb +10 -1
  37. data/lib/steep/source.rb +4 -3
  38. data/lib/steep/subtyping/check.rb +49 -60
  39. data/lib/steep/type_construction.rb +629 -366
  40. data/lib/steep/type_inference/block_params.rb +5 -0
  41. data/lib/steep/type_inference/constant_env.rb +1 -1
  42. data/lib/steep/type_inference/context.rb +8 -0
  43. data/lib/steep/type_inference/context_array.rb +4 -3
  44. data/lib/steep/type_inference/logic.rb +31 -0
  45. data/lib/steep/typing.rb +7 -0
  46. data/lib/steep/version.rb +1 -1
  47. data/smoke/alias/a.rb +1 -1
  48. data/smoke/case/a.rb +1 -1
  49. data/smoke/hash/d.rb +1 -1
  50. data/smoke/if/a.rb +1 -1
  51. data/smoke/module/a.rb +1 -1
  52. data/smoke/rescue/a.rb +4 -13
  53. data/steep.gemspec +1 -1
  54. metadata +5 -5
@@ -17,15 +17,14 @@ module Steep
17
17
  @rest_keywords = rest_keywords
18
18
  end
19
19
 
20
- NONE = Object.new
21
- def update(required: NONE, optional: NONE, rest: NONE, required_keywords: NONE, optional_keywords: NONE, rest_keywords: NONE)
20
+ def update(required: self.required, optional: self.optional, rest: self.rest, required_keywords: self.required_keywords, optional_keywords: self.optional_keywords, rest_keywords: self.rest_keywords)
22
21
  self.class.new(
23
- required: required.equal?(NONE) ? self.required : required,
24
- optional: optional.equal?(NONE) ? self.optional : optional,
25
- rest: rest.equal?(NONE) ? self.rest : rest,
26
- required_keywords: required_keywords.equal?(NONE) ? self.required_keywords : required_keywords,
27
- optional_keywords: optional_keywords.equal?(NONE) ? self.optional_keywords : optional_keywords,
28
- rest_keywords: rest_keywords.equal?(NONE) ? self.rest_keywords : rest_keywords
22
+ required: required,
23
+ optional: optional,
24
+ rest: rest,
25
+ required_keywords: required_keywords,
26
+ optional_keywords: optional_keywords,
27
+ rest_keywords: rest_keywords,
29
28
  )
30
29
  end
31
30
 
@@ -84,6 +83,12 @@ module Steep
84
83
  other.rest_keywords == rest_keywords
85
84
  end
86
85
 
86
+ alias eql? ==
87
+
88
+ def hash
89
+ required.hash ^ optional.hash ^ rest.hash ^ required_keywords.hash ^ optional_keywords.hash ^ rest_keywords.hash
90
+ end
91
+
87
92
  def flat_unnamed_params
88
93
  required.map {|p| [:required, p] } + optional.map {|p| [:optional, p] }
89
94
  end
@@ -211,10 +216,10 @@ module Steep
211
216
  end
212
217
  end
213
218
 
214
- def free_variables
215
- Set.new.tap do |fvs|
219
+ def free_variables()
220
+ @fvs ||= Set.new.tap do |set|
216
221
  each_type do |type|
217
- fvs.merge type.free_variables
222
+ set.merge(type.free_variables)
218
223
  end
219
224
  end
220
225
  end
@@ -224,14 +229,29 @@ module Steep
224
229
  end
225
230
 
226
231
  def subst(s)
227
- self.class.new(
228
- required: required.map {|t| t.subst(s) },
229
- optional: optional.map {|t| t.subst(s) },
230
- rest: rest&.subst(s),
231
- required_keywords: required_keywords.transform_values {|t| t.subst(s) },
232
- optional_keywords: optional_keywords.transform_values {|t| t.subst(s) },
233
- rest_keywords: rest_keywords&.subst(s)
234
- )
232
+ return self if s.empty?
233
+ return self if empty?
234
+ return self if free_variables.disjoint?(s.domain)
235
+
236
+ rs = required.map {|t| t.subst(s) }
237
+ os = optional.map {|t| t.subst(s) }
238
+ r = rest&.subst(s)
239
+ rk = required_keywords.transform_values {|t| t.subst(s) }
240
+ ok = optional_keywords.transform_values {|t| t.subst(s) }
241
+ k = rest_keywords&.subst(s)
242
+
243
+ if rs == required && os == optional && r == rest && rk == required_keywords && ok == optional_keywords && k == rest_keywords
244
+ self
245
+ else
246
+ self.class.new(
247
+ required: required.map {|t| t.subst(s) },
248
+ optional: optional.map {|t| t.subst(s) },
249
+ rest: rest&.subst(s),
250
+ required_keywords: required_keywords.transform_values {|t| t.subst(s) },
251
+ optional_keywords: optional_keywords.transform_values {|t| t.subst(s) },
252
+ rest_keywords: rest_keywords&.subst(s)
253
+ )
254
+ end
235
255
  end
236
256
 
237
257
  def size
@@ -263,59 +283,61 @@ module Steep
263
283
  !has_positional? && !has_keywords?
264
284
  end
265
285
 
266
- def |(other)
286
+ # self + params returns a new params for overloading.
287
+ #
288
+ def +(other)
267
289
  a = first_param
268
290
  b = other.first_param
269
291
 
270
292
  case
271
293
  when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
272
294
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
273
- (self.drop_first | other.drop_first).with_first_param(RequiredPositional.new(type))
295
+ (self.drop_first + other.drop_first).with_first_param(RequiredPositional.new(type))
274
296
  end
275
297
  when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
276
298
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
277
- (self.drop_first | other.drop_first).with_first_param(OptionalPositional.new(type))
299
+ (self.drop_first + other.drop_first).with_first_param(OptionalPositional.new(type))
278
300
  end
279
301
  when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
280
302
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
281
- (self.drop_first | other).with_first_param(OptionalPositional.new(type))
303
+ (self.drop_first + other).with_first_param(OptionalPositional.new(type))
282
304
  end
283
305
  when a.is_a?(RequiredPositional) && b.nil?
284
- (self.drop_first | other).with_first_param(OptionalPositional.new(a.type))
306
+ (self.drop_first + other).with_first_param(OptionalPositional.new(a.type))
285
307
  when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
286
308
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
287
- (self.drop_first | other.drop_first).with_first_param(OptionalPositional.new(type))
309
+ (self.drop_first + other.drop_first).with_first_param(OptionalPositional.new(type))
288
310
  end
289
311
  when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
290
312
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
291
- (self.drop_first | other.drop_first).with_first_param(OptionalPositional.new(type))
313
+ (self.drop_first + other.drop_first).with_first_param(OptionalPositional.new(type))
292
314
  end
293
315
  when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
294
316
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
295
- (self.drop_first | other).with_first_param(OptionalPositional.new(type))
317
+ (self.drop_first + other).with_first_param(OptionalPositional.new(type))
296
318
  end
297
319
  when a.is_a?(OptionalPositional) && b.nil?
298
- (self.drop_first | other).with_first_param(OptionalPositional.new(a.type))
320
+ (self.drop_first + other).with_first_param(OptionalPositional.new(a.type))
299
321
  when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
300
322
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
301
- (self | other.drop_first).with_first_param(OptionalPositional.new(type))
323
+ (self + other.drop_first).with_first_param(OptionalPositional.new(type))
302
324
  end
303
325
  when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
304
326
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
305
- (self | other.drop_first).with_first_param(OptionalPositional.new(type))
327
+ (self + other.drop_first).with_first_param(OptionalPositional.new(type))
306
328
  end
307
329
  when a.is_a?(RestPositional) && b.is_a?(RestPositional)
308
330
  AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
309
- (self.drop_first | other.drop_first).with_first_param(RestPositional.new(type))
331
+ (self.drop_first + other.drop_first).with_first_param(RestPositional.new(type))
310
332
  end
311
333
  when a.is_a?(RestPositional) && b.nil?
312
- (self.drop_first | other).with_first_param(RestPositional.new(a.type))
334
+ (self.drop_first + other).with_first_param(RestPositional.new(a.type))
313
335
  when a.nil? && b.is_a?(RequiredPositional)
314
- (self | other.drop_first).with_first_param(OptionalPositional.new(b.type))
336
+ (self + other.drop_first).with_first_param(OptionalPositional.new(b.type))
315
337
  when a.nil? && b.is_a?(OptionalPositional)
316
- (self | other.drop_first).with_first_param(OptionalPositional.new(b.type))
338
+ (self + other.drop_first).with_first_param(OptionalPositional.new(b.type))
317
339
  when a.nil? && b.is_a?(RestPositional)
318
- (self | other.drop_first).with_first_param(RestPositional.new(b.type))
340
+ (self + other.drop_first).with_first_param(RestPositional.new(b.type))
319
341
  when a.nil? && b.nil?
320
342
  required_keywords = {}
321
343
 
@@ -395,6 +417,9 @@ module Steep
395
417
  end
396
418
  end
397
419
 
420
+ # Returns the intersection between self and other.
421
+ # Returns nil if the intersection cannot be computed.
422
+ #
398
423
  def &(other)
399
424
  a = first_param
400
425
  b = other.first_param
@@ -402,48 +427,48 @@ module Steep
402
427
  case
403
428
  when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
404
429
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
405
- (self.drop_first & other.drop_first).with_first_param(RequiredPositional.new(type))
430
+ (self.drop_first & other.drop_first)&.with_first_param(RequiredPositional.new(type))
406
431
  end
407
432
  when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
408
433
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
409
- (self.drop_first & other.drop_first).with_first_param(RequiredPositional.new(type))
434
+ (self.drop_first & other.drop_first)&.with_first_param(RequiredPositional.new(type))
410
435
  end
411
436
  when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
412
437
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
413
- (self.drop_first & other).with_first_param(RequiredPositional.new(type))
438
+ (self.drop_first & other)&.with_first_param(RequiredPositional.new(type))
414
439
  end
415
440
  when a.is_a?(RequiredPositional) && b.nil?
416
- (self.drop_first & other).with_first_param(RequiredPositional.new(AST::Types::Bot.new))
441
+ nil
417
442
  when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
418
443
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
419
- (self.drop_first & other.drop_first).with_first_param(RequiredPositional.new(type))
444
+ (self.drop_first & other.drop_first)&.with_first_param(RequiredPositional.new(type))
420
445
  end
421
446
  when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
422
447
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
423
- (self.drop_first & other.drop_first).with_first_param(OptionalPositional.new(type))
448
+ (self.drop_first & other.drop_first)&.with_first_param(OptionalPositional.new(type))
424
449
  end
425
450
  when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
426
451
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
427
- (self.drop_first & other).with_first_param(OptionalPositional.new(type))
452
+ (self.drop_first & other)&.with_first_param(OptionalPositional.new(type))
428
453
  end
429
454
  when a.is_a?(OptionalPositional) && b.nil?
430
455
  self.drop_first & other
431
456
  when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
432
457
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
433
- (self & other.drop_first).with_first_param(RequiredPositional.new(type))
458
+ (self & other.drop_first)&.with_first_param(RequiredPositional.new(type))
434
459
  end
435
460
  when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
436
461
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
437
- (self & other.drop_first).with_first_param(OptionalPositional.new(type))
462
+ (self & other.drop_first)&.with_first_param(OptionalPositional.new(type))
438
463
  end
439
464
  when a.is_a?(RestPositional) && b.is_a?(RestPositional)
440
465
  AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
441
- (self.drop_first & other.drop_first).with_first_param(RestPositional.new(type))
466
+ (self.drop_first & other.drop_first)&.with_first_param(RestPositional.new(type))
442
467
  end
443
468
  when a.is_a?(RestPositional) && b.nil?
444
469
  self.drop_first & other
445
470
  when a.nil? && b.is_a?(RequiredPositional)
446
- (self & other.drop_first).with_first_param(RequiredPositional.new(AST::Types::Bot.new))
471
+ nil
447
472
  when a.nil? && b.is_a?(OptionalPositional)
448
473
  self & other.drop_first
449
474
  when a.nil? && b.is_a?(RestPositional)
@@ -452,7 +477,7 @@ module Steep
452
477
  optional_keywords = {}
453
478
 
454
479
  (Set.new(self.optional_keywords.keys) & Set.new(other.optional_keywords.keys)).each do |keyword|
455
- self.optional_keywords[keyword] = AST::Types::Intersection.build(
480
+ optional_keywords[keyword] = AST::Types::Intersection.build(
456
481
  types: [
457
482
  self.optional_keywords[keyword],
458
483
  other.optional_keywords[keyword]
@@ -467,9 +492,7 @@ module Steep
467
492
  when other.required_keywords.key?(keyword)
468
493
  required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.required_keywords[keyword]])
469
494
  when other.rest_keywords
470
- required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
471
- else
472
- required_keywords[keyword] = t
495
+ optional_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
473
496
  end
474
497
  end
475
498
  end
@@ -479,9 +502,7 @@ module Steep
479
502
  when self.required_keywords.key?(keyword)
480
503
  required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.required_keywords[keyword]])
481
504
  when self.rest_keywords
482
- required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
483
- else
484
- required_keywords[keyword] = t
505
+ optional_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
485
506
  end
486
507
  end
487
508
  end
@@ -493,7 +514,7 @@ module Steep
493
514
  when other.rest_keywords
494
515
  required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
495
516
  else
496
- required_keywords[keyword] = t
517
+ return
497
518
  end
498
519
  end
499
520
  end
@@ -505,7 +526,7 @@ module Steep
505
526
  when self.rest_keywords
506
527
  required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
507
528
  else
508
- required_keywords[keyword] = t
529
+ return
509
530
  end
510
531
  end
511
532
  end
@@ -514,7 +535,153 @@ module Steep
514
535
  when self.rest_keywords && other.rest_keywords
515
536
  AST::Types::Intersection.build(types: [self.rest_keywords, other.rest_keywords])
516
537
  else
517
- self.rest_keywords || other.rest_keywords
538
+ nil
539
+ end
540
+
541
+ Params.new(
542
+ required: [],
543
+ optional: [],
544
+ rest: nil,
545
+ required_keywords: required_keywords,
546
+ optional_keywords: optional_keywords,
547
+ rest_keywords: rest)
548
+ end
549
+ end
550
+
551
+ # Returns the union between self and other.
552
+ #
553
+ def |(other)
554
+ a = first_param
555
+ b = other.first_param
556
+
557
+ case
558
+ when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
559
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
560
+ (self.drop_first | other.drop_first)&.with_first_param(RequiredPositional.new(type))
561
+ end
562
+ when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
563
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
564
+ (self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
565
+ end
566
+ when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
567
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
568
+ (self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
569
+ end
570
+ when a.is_a?(RequiredPositional) && b.nil?
571
+ self.drop_first&.with_first_param(OptionalPositional.new(a.type))
572
+ when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
573
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
574
+ (self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
575
+ end
576
+ when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
577
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
578
+ (self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
579
+ end
580
+ when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
581
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
582
+ (self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
583
+ end
584
+ when a.is_a?(OptionalPositional) && b.nil?
585
+ (self.drop_first | other)&.with_first_param(a)
586
+ when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
587
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
588
+ (self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
589
+ end
590
+ when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
591
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
592
+ (self | other.drop_first)&.with_first_param(OptionalPositional.new(type))
593
+ end
594
+ when a.is_a?(RestPositional) && b.is_a?(RestPositional)
595
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
596
+ (self.drop_first | other.drop_first)&.with_first_param(RestPositional.new(type))
597
+ end
598
+ when a.is_a?(RestPositional) && b.nil?
599
+ (self.drop_first | other)&.with_first_param(a)
600
+ when a.nil? && b.is_a?(RequiredPositional)
601
+ other.drop_first&.with_first_param(OptionalPositional.new(b.type))
602
+ when a.nil? && b.is_a?(OptionalPositional)
603
+ (self | other.drop_first)&.with_first_param(b)
604
+ when a.nil? && b.is_a?(RestPositional)
605
+ (self | other.drop_first)&.with_first_param(b)
606
+ when a.nil? && b.nil?
607
+ required_keywords = {}
608
+ optional_keywords = {}
609
+
610
+ (Set.new(self.required_keywords.keys) & Set.new(other.required_keywords.keys)).each do |keyword|
611
+ required_keywords[keyword] = AST::Types::Union.build(
612
+ types: [
613
+ self.required_keywords[keyword],
614
+ other.required_keywords[keyword]
615
+ ]
616
+ )
617
+ end
618
+
619
+ self.optional_keywords.each do |keyword, t|
620
+ unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
621
+ case
622
+ when s = other.required_keywords[keyword]
623
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
624
+ when s = other.optional_keywords[keyword]
625
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
626
+ when r = other.rest_keywords
627
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
628
+ else
629
+ optional_keywords[keyword] = t
630
+ end
631
+ end
632
+ end
633
+ other.optional_keywords.each do |keyword, t|
634
+ unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
635
+ case
636
+ when s = self.required_keywords[keyword]
637
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
638
+ when s = self.optional_keywords[keyword]
639
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
640
+ when r = self.rest_keywords
641
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
642
+ else
643
+ optional_keywords[keyword] = t
644
+ end
645
+ end
646
+ end
647
+ self.required_keywords.each do |keyword, t|
648
+ unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
649
+ case
650
+ when s = other.optional_keywords[keyword]
651
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
652
+ when r = other.rest_keywords
653
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
654
+ else
655
+ optional_keywords[keyword] = t
656
+ end
657
+ end
658
+ end
659
+ other.required_keywords.each do |keyword, t|
660
+ unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
661
+ case
662
+ when s = self.optional_keywords[keyword]
663
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
664
+ when r = self.rest_keywords
665
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
666
+ else
667
+ optional_keywords[keyword] = t
668
+ end
669
+ end
670
+ end
671
+
672
+ rest = case
673
+ when self.rest_keywords && other.rest_keywords
674
+ AST::Types::Union.build(types: [self.rest_keywords, other.rest_keywords])
675
+ when self.rest_keywords
676
+ if required_keywords.empty? && optional_keywords.empty?
677
+ self.rest_keywords
678
+ end
679
+ when other.rest_keywords
680
+ if required_keywords.empty? && optional_keywords.empty?
681
+ other.rest_keywords
682
+ end
683
+ else
684
+ nil
518
685
  end
519
686
 
520
687
  Params.new(
@@ -552,19 +719,30 @@ module Steep
552
719
  other.is_a?(self.class) && other.type == type && other.optional == optional
553
720
  end
554
721
 
722
+ alias eql? ==
723
+
724
+ def hash
725
+ type.hash ^ optional.hash
726
+ end
727
+
555
728
  def closed?
556
729
  type.closed?
557
730
  end
558
731
 
559
732
  def subst(s)
560
- self.class.new(
561
- type: type.subst(s),
562
- optional: optional
563
- )
733
+ ty = type.subst(s)
734
+ if ty == type
735
+ self
736
+ else
737
+ self.class.new(
738
+ type: ty,
739
+ optional: optional
740
+ )
741
+ end
564
742
  end
565
743
 
566
- def free_variables
567
- type.free_variables
744
+ def free_variables()
745
+ @fvs ||= type.free_variables
568
746
  end
569
747
 
570
748
  def to_s
@@ -580,9 +758,10 @@ module Steep
580
758
 
581
759
  def +(other)
582
760
  optional = self.optional? || other.optional?
583
- type = AST::Types::Proc.new(params: self.type.params | other.type.params,
584
- return_type: AST::Types::Union.build(types: [self.type.return_type,
585
- other.type.return_type]))
761
+ type = AST::Types::Proc.new(
762
+ params: self.type.params + other.type.params,
763
+ return_type: AST::Types::Union.build(types: [self.type.return_type, other.type.return_type])
764
+ )
586
765
  self.class.new(
587
766
  type: type,
588
767
  optional: optional
@@ -597,8 +776,6 @@ module Steep
597
776
  attr_reader :return_type
598
777
  attr_reader :location
599
778
 
600
- NONE = Object.new
601
-
602
779
  def initialize(type_params:, params:, block:, return_type:, location:)
603
780
  @type_params = type_params
604
781
  @params = params
@@ -616,11 +793,27 @@ module Steep
616
793
  (!other.location || !location || other.location == location)
617
794
  end
618
795
 
796
+ alias eql? ==
797
+
798
+ def hash
799
+ type_params.hash ^ params.hash ^ block.hash ^ return_type.hash
800
+ end
801
+
619
802
  def free_variables
620
- (params.free_variables + (block&.free_variables || Set.new) + return_type.free_variables) - Set.new(type_params)
803
+ @fvs ||= Set.new.tap do |set|
804
+ set.merge(params.free_variables)
805
+ if block
806
+ set.merge(block.free_variables)
807
+ end
808
+ set.merge(return_type.free_variables)
809
+ set.subtract(type_params)
810
+ end
621
811
  end
622
812
 
623
813
  def subst(s)
814
+ return self if s.empty?
815
+ return self if free_variables.disjoint?(s.domain)
816
+
624
817
  s_ = s.except(type_params)
625
818
 
626
819
  self.class.new(
@@ -646,23 +839,19 @@ module Steep
646
839
  end
647
840
 
648
841
  def instantiate(s)
649
- self.class.new(
650
- type_params: [],
651
- params: params.subst(s),
652
- block: block&.subst(s),
653
- return_type: return_type.subst(s),
654
- location: location,
655
- )
842
+ self.class.new(type_params: [],
843
+ params: params.subst(s),
844
+ block: block&.subst(s),
845
+ return_type: return_type.subst(s),
846
+ location: location)
656
847
  end
657
848
 
658
- def with(type_params: NONE, params: NONE, block: NONE, return_type: NONE, location: NONE)
659
- self.class.new(
660
- type_params: type_params.equal?(NONE) ? self.type_params : type_params,
661
- params: params.equal?(NONE) ? self.params : params,
662
- block: block.equal?(NONE) ? self.block : block,
663
- return_type: return_type.equal?(NONE) ? self.return_type : return_type,
664
- location: location.equal?(NONE) ? self.location : location
665
- )
849
+ def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, location: self.location)
850
+ self.class.new(type_params: type_params,
851
+ params: params,
852
+ block: block,
853
+ return_type: return_type,
854
+ location: location)
666
855
  end
667
856
 
668
857
  def to_s
@@ -674,16 +863,16 @@ module Steep
674
863
  end
675
864
 
676
865
  def map_type(&block)
677
- self.class.new(
678
- type_params: type_params,
679
- params: params.map_type(&block),
680
- block: self.block&.yield_self {|blk| blk.map_type(&block) },
681
- return_type: yield(return_type),
682
- location: location
683
- )
866
+ self.class.new(type_params: type_params,
867
+ params: params.map_type(&block),
868
+ block: self.block&.yield_self {|blk| blk.map_type(&block) },
869
+ return_type: yield(return_type),
870
+ location: location)
684
871
  end
685
872
 
686
- def +(other)
873
+ # Returns a new method type which can be used for the method implementation type of both `self` and `other`.
874
+ #
875
+ def unify_overload(other)
687
876
  type_params = []
688
877
  s1 = Substitution.build(self.type_params)
689
878
  type_params.push(*s1.dictionary.values.map(&:name))
@@ -701,7 +890,7 @@ module Steep
701
890
 
702
891
  self.class.new(
703
892
  type_params: type_params,
704
- params: params.subst(s1) | other.params.subst(s2),
893
+ params: params.subst(s1) + other.params.subst(s2),
705
894
  block: block,
706
895
  return_type: AST::Types::Union.build(
707
896
  types: [return_type.subst(s1),other.return_type.subst(s2)]
@@ -709,6 +898,108 @@ module Steep
709
898
  location: nil
710
899
  )
711
900
  end
901
+
902
+ def +(other)
903
+ unify_overload(other)
904
+ end
905
+
906
+ # Returns a method type which is a super-type of both self and other.
907
+ # self <: (self | other) && other <: (self | other)
908
+ #
909
+ # Returns nil if self and other are incompatible.
910
+ #
911
+ def |(other)
912
+ self_type_params = Set.new(self.type_params)
913
+ other_type_params = Set.new(other.type_params)
914
+
915
+ unless (common_type_params = (self_type_params & other_type_params).to_a).empty?
916
+ fresh_types = common_type_params.map {|name| AST::Types::Var.fresh(name) }
917
+ fresh_names = fresh_types.map(&:name)
918
+ subst = Substitution.build(common_type_params, fresh_types)
919
+ other = other.instantiate(subst)
920
+ type_params = (self_type_params + (other_type_params - common_type_params + Set.new(fresh_names))).to_a
921
+ else
922
+ type_params = (self_type_params + other_type_params).to_a
923
+ end
924
+
925
+ params = self.params & other.params or return
926
+ block = case
927
+ when self.block && other.block
928
+ block_params = self.block.type.params | other.block.type.params
929
+ block_return_type = AST::Types::Intersection.build(types: [self.block.type.return_type, other.block.type.return_type])
930
+ block_type = AST::Types::Proc.new(params: block_params,
931
+ return_type: block_return_type,
932
+ location: nil)
933
+ Block.new(
934
+ type: block_type,
935
+ optional: self.block.optional && other.block.optional
936
+ )
937
+ when self.block && self.block.optional?
938
+ self.block
939
+ when other.block && other.block.optional?
940
+ other.block
941
+ when !self.block && !other.block
942
+ nil
943
+ else
944
+ return
945
+ end
946
+ return_type = AST::Types::Union.build(types: [self.return_type, other.return_type])
947
+
948
+ MethodType.new(
949
+ params: params,
950
+ block: block,
951
+ return_type: return_type,
952
+ type_params: type_params,
953
+ location: nil
954
+ )
955
+ end
956
+
957
+ # Returns a method type which is a sub-type of both self and other.
958
+ # (self & other) <: self && (self & other) <: other
959
+ #
960
+ # Returns nil if self and other are incompatible.
961
+ #
962
+ def &(other)
963
+ self_type_params = Set.new(self.type_params)
964
+ other_type_params = Set.new(other.type_params)
965
+
966
+ unless (common_type_params = (self_type_params & other_type_params).to_a).empty?
967
+ fresh_types = common_type_params.map {|name| AST::Types::Var.fresh(name) }
968
+ fresh_names = fresh_types.map(&:name)
969
+ subst = Substitution.build(common_type_params, fresh_types)
970
+ other = other.subst(subst)
971
+ type_params = (self_type_params + (other_type_params - common_type_params + Set.new(fresh_names))).to_a
972
+ else
973
+ type_params = (self_type_params + other_type_params).to_a
974
+ end
975
+
976
+ params = self.params | other.params
977
+ block = case
978
+ when self.block && other.block
979
+ block_params = self.block.type.params & other.block.type.params or return
980
+ block_return_type = AST::Types::Union.build(types: [self.block.type.return_type, other.block.type.return_type])
981
+ block_type = AST::Types::Proc.new(params: block_params,
982
+ return_type: block_return_type,
983
+ location: nil)
984
+ Block.new(
985
+ type: block_type,
986
+ optional: self.block.optional || other.block.optional
987
+ )
988
+
989
+ else
990
+ self.block || other.block
991
+ end
992
+
993
+ return_type = AST::Types::Intersection.build(types: [self.return_type, other.return_type])
994
+
995
+ MethodType.new(
996
+ params: params,
997
+ block: block,
998
+ return_type: return_type,
999
+ type_params: type_params,
1000
+ location: nil
1001
+ )
1002
+ end
712
1003
  end
713
1004
  end
714
1005
  end