typeprof 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/doc/demo.md +398 -0
- data/doc/doc.ja.md +4 -0
- data/doc/doc.md +4 -0
- data/lib/typeprof.rb +8 -0
- data/lib/typeprof/analyzer.rb +229 -245
- data/lib/typeprof/arguments.rb +397 -0
- data/lib/typeprof/block.rb +133 -0
- data/lib/typeprof/builtin.rb +14 -10
- data/lib/typeprof/container-type.rb +94 -17
- data/lib/typeprof/export.rb +185 -108
- data/lib/typeprof/import.rb +76 -54
- data/lib/typeprof/iseq.rb +27 -2
- data/lib/typeprof/method.rb +87 -73
- data/lib/typeprof/type.rb +125 -309
- data/lib/typeprof/version.rb +1 -1
- data/smoke/arguments2.rb +1 -1
- data/smoke/array-each3.rb +1 -4
- data/smoke/array12.rb +1 -1
- data/smoke/array6.rb +1 -0
- data/smoke/block-ambiguous.rb +36 -0
- data/smoke/block-args1-rest.rb +62 -0
- data/smoke/block-args1.rb +59 -0
- data/smoke/block-args2-rest.rb +62 -0
- data/smoke/block-args2.rb +59 -0
- data/smoke/block-args3-rest.rb +73 -0
- data/smoke/block-args3.rb +70 -0
- data/smoke/block-blockarg.rb +27 -0
- data/smoke/block-kwarg.rb +52 -0
- data/smoke/block11.rb +1 -1
- data/smoke/block14.rb +17 -0
- data/smoke/block4.rb +2 -2
- data/smoke/block5.rb +1 -0
- data/smoke/block6.rb +1 -1
- data/smoke/block7.rb +0 -2
- data/smoke/block8.rb +2 -2
- data/smoke/block9.rb +1 -1
- data/smoke/blown.rb +1 -1
- data/smoke/class-hierarchy.rb +54 -0
- data/smoke/class-hierarchy2.rb +27 -0
- data/smoke/constant1.rb +11 -6
- data/smoke/constant2.rb +2 -0
- data/smoke/cvar.rb +1 -0
- data/smoke/demo10.rb +1 -1
- data/smoke/demo8.rb +2 -2
- data/smoke/demo9.rb +1 -3
- data/smoke/flow7.rb +1 -7
- data/smoke/flow8.rb +13 -0
- data/smoke/instance_eval.rb +1 -1
- data/smoke/int_times.rb +1 -1
- data/smoke/multiple-superclass.rb +4 -0
- data/smoke/next2.rb +1 -1
- data/smoke/optional3.rb +10 -0
- data/smoke/proc4.rb +1 -1
- data/smoke/rbs-proc1.rb +9 -0
- data/smoke/rbs-proc1.rbs +3 -0
- data/smoke/rbs-proc2.rb +20 -0
- data/smoke/rbs-proc2.rbs +3 -0
- data/smoke/rbs-proc3.rb +13 -0
- data/smoke/rbs-proc3.rbs +4 -0
- data/smoke/rbs-record.rb +17 -0
- data/smoke/rbs-record.rbs +4 -0
- data/smoke/rbs-tyvar3.rb +25 -0
- data/smoke/rbs-tyvar3.rbs +4 -0
- data/smoke/rest2.rb +1 -1
- data/smoke/rest5.rb +1 -1
- data/smoke/return.rb +1 -1
- data/smoke/singleton_method.rb +3 -0
- data/smoke/struct.rb +4 -3
- data/smoke/struct3.rb +14 -0
- data/smoke/symbol-proc.rb +24 -0
- metadata +31 -3
- data/smoke/variadic1.rb.notyet +0 -5
data/lib/typeprof/type.rb
CHANGED
|
@@ -148,7 +148,7 @@ module TypeProf
|
|
|
148
148
|
# invariant check
|
|
149
149
|
local = nil
|
|
150
150
|
tys.each do |ty|
|
|
151
|
-
raise unless ty.is_a?(Type)
|
|
151
|
+
raise ty.inspect unless ty.is_a?(Type)
|
|
152
152
|
local = true if ty.is_a?(LocalArray) || ty.is_a?(LocalHash)
|
|
153
153
|
end
|
|
154
154
|
raise if local && elems
|
|
@@ -226,12 +226,15 @@ module TypeProf
|
|
|
226
226
|
bool = true
|
|
227
227
|
end
|
|
228
228
|
types.delete(Type.any) unless Config.options[:pedantic_output]
|
|
229
|
+
proc_tys, types = types.partition {|ty| ty.is_a?(Proc) }
|
|
229
230
|
types = types.map {|ty| ty.screen_name(scratch) }
|
|
231
|
+
types << scratch.show_proc_signature(proc_tys) unless proc_tys.empty?
|
|
230
232
|
types << "bool" if bool
|
|
231
233
|
types = types.sort
|
|
232
234
|
if optional
|
|
233
|
-
|
|
234
|
-
|
|
235
|
+
case types.size
|
|
236
|
+
when 0 then "nil"
|
|
237
|
+
when 1 then types.first + "?"
|
|
235
238
|
else
|
|
236
239
|
"(#{ types.join (" | ") })?"
|
|
237
240
|
end
|
|
@@ -516,56 +519,51 @@ module TypeProf
|
|
|
516
519
|
end
|
|
517
520
|
end
|
|
518
521
|
|
|
519
|
-
class
|
|
520
|
-
def initialize(
|
|
521
|
-
@
|
|
522
|
-
@ep = ep
|
|
523
|
-
@type = type
|
|
522
|
+
class Proc < Type
|
|
523
|
+
def initialize(block_body, type)
|
|
524
|
+
@block_body, @type = block_body, type
|
|
524
525
|
end
|
|
525
526
|
|
|
526
|
-
attr_reader :
|
|
527
|
-
|
|
528
|
-
def inspect
|
|
529
|
-
"#<ISeqProc>"
|
|
530
|
-
end
|
|
527
|
+
attr_reader :block_body, :type
|
|
531
528
|
|
|
532
|
-
def
|
|
533
|
-
|
|
529
|
+
def consistent?(other, subst)
|
|
530
|
+
case other
|
|
531
|
+
when Type::Any then true
|
|
532
|
+
when Type::Var then other.add_subst!(self, subst)
|
|
533
|
+
when Type::Union
|
|
534
|
+
other.types.each do |ty2|
|
|
535
|
+
return true if consistent?(ty2, subst)
|
|
536
|
+
end
|
|
537
|
+
when Type::Proc
|
|
538
|
+
@block_body.consistent?(other.block_body)
|
|
539
|
+
else
|
|
540
|
+
self == other
|
|
541
|
+
end
|
|
534
542
|
end
|
|
535
543
|
|
|
536
544
|
def get_method(mid, scratch)
|
|
537
545
|
@type.get_method(mid, scratch)
|
|
538
546
|
end
|
|
539
547
|
|
|
540
|
-
def substitute(
|
|
541
|
-
|
|
542
|
-
end
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
class TypedProc < Type
|
|
546
|
-
def initialize(fargs, ret_ty, type)
|
|
547
|
-
@fargs = fargs
|
|
548
|
-
@ret_ty = ret_ty
|
|
549
|
-
@type = type
|
|
548
|
+
def substitute(subst, depth)
|
|
549
|
+
Proc.new(@block_body.substitute(subst, depth), @type)
|
|
550
550
|
end
|
|
551
551
|
|
|
552
|
-
attr_reader :fargs, :ret_ty
|
|
553
|
-
|
|
554
552
|
def screen_name(scratch)
|
|
555
|
-
|
|
553
|
+
scratch.show_proc_signature([self])
|
|
556
554
|
end
|
|
557
555
|
end
|
|
558
556
|
|
|
559
557
|
class Symbol < Type
|
|
560
|
-
def initialize(sym,
|
|
558
|
+
def initialize(sym, base_type)
|
|
561
559
|
@sym = sym
|
|
562
|
-
@
|
|
560
|
+
@base_type = base_type
|
|
563
561
|
end
|
|
564
562
|
|
|
565
|
-
attr_reader :sym, :
|
|
563
|
+
attr_reader :sym, :base_type
|
|
566
564
|
|
|
567
565
|
def inspect
|
|
568
|
-
"Type::Symbol[#{ @sym ? @sym.inspect : "(dynamic symbol)" }, #{ @
|
|
566
|
+
"Type::Symbol[#{ @sym ? @sym.inspect : "(dynamic symbol)" }, #{ @base_type.inspect }]"
|
|
569
567
|
end
|
|
570
568
|
|
|
571
569
|
def consistent?(other, subst)
|
|
@@ -575,7 +573,7 @@ module TypeProf
|
|
|
575
573
|
when Symbol
|
|
576
574
|
@sym == other.sym
|
|
577
575
|
else
|
|
578
|
-
@
|
|
576
|
+
@base_type.consistent?(other, subst)
|
|
579
577
|
end
|
|
580
578
|
end
|
|
581
579
|
|
|
@@ -583,12 +581,12 @@ module TypeProf
|
|
|
583
581
|
if @sym
|
|
584
582
|
@sym.inspect
|
|
585
583
|
else
|
|
586
|
-
@
|
|
584
|
+
@base_type.screen_name(scratch)
|
|
587
585
|
end
|
|
588
586
|
end
|
|
589
587
|
|
|
590
588
|
def get_method(mid, scratch)
|
|
591
|
-
@
|
|
589
|
+
@base_type.get_method(mid, scratch)
|
|
592
590
|
end
|
|
593
591
|
|
|
594
592
|
def substitute(_subst, _depth)
|
|
@@ -747,66 +745,74 @@ module TypeProf
|
|
|
747
745
|
end
|
|
748
746
|
end
|
|
749
747
|
|
|
750
|
-
|
|
751
|
-
class FormalArguments
|
|
748
|
+
class Signature
|
|
752
749
|
include Utils::StructuralEquality
|
|
753
750
|
|
|
754
|
-
def initialize(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
|
|
755
|
-
@lead_tys = lead_tys
|
|
756
|
-
@opt_tys = opt_tys
|
|
757
|
-
@rest_ty = rest_ty
|
|
758
|
-
@post_tys = post_tys
|
|
759
|
-
@kw_tys = kw_tys
|
|
760
|
-
kw_tys.each {|a| raise if a.size != 3 } if kw_tys
|
|
761
|
-
@kw_rest_ty = kw_rest_ty
|
|
762
|
-
@blk_ty = blk_ty
|
|
763
|
-
end
|
|
764
|
-
|
|
765
|
-
attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty
|
|
766
|
-
|
|
767
|
-
def consistent?(fargs, subst)
|
|
768
|
-
warn "used?"
|
|
769
|
-
return false if @lead_tys.size != fargs.lead_tys.size
|
|
770
|
-
return false unless @lead_tys.zip(fargs.lead_tys).all? {|ty1, ty2| ty1.consistent?(ty2, subst) }
|
|
771
|
-
return false if (@opt_tys || []) != (fargs.opt_tys || []) # ??
|
|
772
|
-
if @rest_ty
|
|
773
|
-
return false unless @rest_ty.consistent?(fargs.rest_ty, subst)
|
|
774
|
-
end
|
|
775
|
-
if @post_tys
|
|
776
|
-
return false if @post_tys.size != fargs.post_tys.size
|
|
777
|
-
return false unless @post_tys.zip(fargs.post_tys).all? {|ty1, ty2| ty1.consistent?(ty2, subst) }
|
|
778
|
-
end
|
|
779
|
-
return false if @kw_tys.size != fargs.kw_tys.size
|
|
780
|
-
return false unless @kw_tys.zip(fargs.kw_tys).all? {|(_, ty1), (_, ty2)| ty1.consistent?(ty2, subst) }
|
|
781
|
-
if @kw_rest_ty
|
|
782
|
-
return false unless @kw_rest_ty.consistent?(fargs.kw_rest_ty, subst)
|
|
783
|
-
end
|
|
784
|
-
# intentionally skip blk_ty
|
|
785
|
-
true
|
|
786
|
-
end
|
|
787
|
-
|
|
788
751
|
def screen_name(scratch)
|
|
789
|
-
|
|
752
|
+
str = @lead_tys.map {|ty| ty.screen_name(scratch) }
|
|
790
753
|
if @opt_tys
|
|
791
|
-
|
|
754
|
+
str += @opt_tys.map {|ty| "?" + ty.screen_name(scratch) }
|
|
792
755
|
end
|
|
793
756
|
if @rest_ty
|
|
794
|
-
|
|
757
|
+
str << ("*" + @rest_ty.screen_name(scratch))
|
|
795
758
|
end
|
|
796
759
|
if @post_tys
|
|
797
|
-
|
|
760
|
+
str += @post_tys.map {|ty| ty.screen_name(scratch) }
|
|
798
761
|
end
|
|
799
762
|
if @kw_tys
|
|
800
763
|
@kw_tys.each do |req, sym, ty|
|
|
801
764
|
opt = req ? "" : "?"
|
|
802
|
-
|
|
765
|
+
str << "#{ opt }#{ sym }: #{ ty.screen_name(scratch) }"
|
|
803
766
|
end
|
|
804
767
|
end
|
|
805
768
|
if @kw_rest_ty
|
|
806
|
-
|
|
769
|
+
str << ("**" + @kw_rest_ty.screen_name(scratch))
|
|
770
|
+
end
|
|
771
|
+
str = str.empty? ? "" : "(#{ str.join(", ") })"
|
|
772
|
+
|
|
773
|
+
optional = false
|
|
774
|
+
blks = []
|
|
775
|
+
@blk_ty.each_child_global do |ty|
|
|
776
|
+
if ty.is_a?(Type::Proc)
|
|
777
|
+
blks << ty
|
|
778
|
+
else
|
|
779
|
+
# XXX: how should we handle types other than Type.nil
|
|
780
|
+
optional = true
|
|
781
|
+
end
|
|
807
782
|
end
|
|
808
|
-
|
|
809
|
-
|
|
783
|
+
if blks != []
|
|
784
|
+
str << " " if str != ""
|
|
785
|
+
str << "?" if optional
|
|
786
|
+
str << scratch.show_block_signature(blks)
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
str
|
|
790
|
+
end
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
class MethodSignature < Signature
|
|
794
|
+
def initialize(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
|
|
795
|
+
@lead_tys = lead_tys
|
|
796
|
+
@opt_tys = opt_tys
|
|
797
|
+
@rest_ty = rest_ty
|
|
798
|
+
@post_tys = post_tys
|
|
799
|
+
@kw_tys = kw_tys
|
|
800
|
+
kw_tys.each {|a| raise if a.size != 3 } if kw_tys
|
|
801
|
+
@kw_rest_ty = kw_rest_ty
|
|
802
|
+
@blk_ty = blk_ty
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty
|
|
806
|
+
|
|
807
|
+
def substitute(subst, depth)
|
|
808
|
+
lead_tys = @lead_tys.map {|ty| ty.substitute(subst, depth - 1) }
|
|
809
|
+
opt_tys = @opt_tys.map {|ty| ty.substitute(subst, depth - 1) }
|
|
810
|
+
rest_ty = @rest_ty&.substitute(subst, depth - 1)
|
|
811
|
+
post_tys = @post_tys.map {|ty| ty.substitute(subst, depth - 1) }
|
|
812
|
+
kw_tys = @kw_tys.map {|req, key, ty| [req, key, ty.substitute(subst, depth - 1)] }
|
|
813
|
+
kw_rest_ty = @kw_rest_ty&.substitute(subst, depth - 1)
|
|
814
|
+
blk_ty = @blk_ty.substitute(subst, depth - 1)
|
|
815
|
+
MethodSignature.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
|
|
810
816
|
end
|
|
811
817
|
|
|
812
818
|
def merge(other)
|
|
@@ -868,250 +874,60 @@ module TypeProf
|
|
|
868
874
|
end
|
|
869
875
|
end
|
|
870
876
|
blk_ty = @blk_ty.union(other.blk_ty) if @blk_ty
|
|
871
|
-
|
|
877
|
+
MethodSignature.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
|
|
872
878
|
end
|
|
873
879
|
end
|
|
874
880
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
def initialize(lead_tys, rest_ty, kw_tys, blk_ty)
|
|
881
|
+
class BlockSignature < Signature
|
|
882
|
+
def initialize(lead_tys, opt_tys, rest_ty, blk_ty)
|
|
878
883
|
@lead_tys = lead_tys
|
|
884
|
+
@opt_tys = opt_tys
|
|
879
885
|
@rest_ty = rest_ty
|
|
880
|
-
@kw_tys = kw_tys # kw_tys should be {:key1 => Type.bool, :key2 => Type.bool, ...} or {nil => Type.bool}
|
|
881
|
-
raise if !kw_tys.is_a?(::Hash)
|
|
882
886
|
@blk_ty = blk_ty
|
|
883
|
-
|
|
884
|
-
end
|
|
885
|
-
|
|
886
|
-
attr_reader :lead_tys, :
|
|
887
|
-
|
|
888
|
-
def merge(
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
else
|
|
904
|
-
kw_tys[sym] = ty
|
|
905
|
-
end
|
|
906
|
-
end
|
|
907
|
-
blk_ty = @blk_ty.union(aargs.blk_ty)
|
|
908
|
-
ActualArguments.new(lead_tys, rest_ty, kw_tys, blk_ty)
|
|
909
|
-
end
|
|
910
|
-
|
|
911
|
-
def globalize(caller_env, visited, depth)
|
|
912
|
-
lead_tys = @lead_tys.map {|ty| ty.globalize(caller_env, visited, depth) }
|
|
913
|
-
rest_ty = @rest_ty.globalize(caller_env, visited, depth) if @rest_ty
|
|
914
|
-
kw_tys = @kw_tys.to_h do |key, ty|
|
|
915
|
-
[key, ty.globalize(caller_env, visited, depth)]
|
|
916
|
-
end
|
|
917
|
-
ActualArguments.new(lead_tys, rest_ty, kw_tys, @blk_ty)
|
|
918
|
-
end
|
|
919
|
-
|
|
920
|
-
def limit_size(limit)
|
|
921
|
-
self
|
|
922
|
-
end
|
|
923
|
-
|
|
924
|
-
def each_formal_arguments(fargs_format)
|
|
925
|
-
lead_num = fargs_format[:lead_num] || 0
|
|
926
|
-
post_num = fargs_format[:post_num] || 0
|
|
927
|
-
rest_acceptable = !!fargs_format[:rest_start]
|
|
928
|
-
keyword = fargs_format[:keyword]
|
|
929
|
-
kw_rest_acceptable = !!fargs_format[:kwrest]
|
|
930
|
-
opt = fargs_format[:opt]
|
|
931
|
-
#p fargs_format
|
|
932
|
-
|
|
933
|
-
# TODO: expand tuples to normal arguments
|
|
934
|
-
|
|
935
|
-
# check number of arguments
|
|
936
|
-
if !@rest_ty && lead_num + post_num > @lead_tys.size
|
|
937
|
-
# too less
|
|
938
|
-
yield "wrong number of arguments (given #{ @lead_tys.size }, expected #{ lead_num + post_num })"
|
|
939
|
-
return
|
|
940
|
-
end
|
|
941
|
-
if !rest_acceptable
|
|
942
|
-
# too many
|
|
943
|
-
if opt
|
|
944
|
-
if lead_num + post_num + opt.size - 1 < @lead_tys.size
|
|
945
|
-
yield "wrong number of arguments (given #{ @lead_tys.size }, expected #{ lead_num + post_num }..#{ lead_num + post_num + opt.size - 1})"
|
|
946
|
-
return
|
|
947
|
-
end
|
|
948
|
-
else
|
|
949
|
-
if lead_num + post_num < @lead_tys.size
|
|
950
|
-
yield "wrong number of arguments (given #{ @lead_tys.size }, expected #{ lead_num + post_num })"
|
|
951
|
-
return
|
|
952
|
-
end
|
|
953
|
-
end
|
|
954
|
-
end
|
|
955
|
-
|
|
956
|
-
if @rest_ty
|
|
957
|
-
lower_bound = [lead_num + post_num - @lead_tys.size, 0].max
|
|
958
|
-
upper_bound = lead_num + post_num - @lead_tys.size + (opt ? opt.size - 1 : 0) + (rest_acceptable ? 1 : 0)
|
|
959
|
-
rest_elem = @rest_ty.is_a?(Type::Array) ? @rest_ty.elems.squash : Type.any
|
|
960
|
-
else
|
|
961
|
-
lower_bound = upper_bound = 0
|
|
962
|
-
end
|
|
963
|
-
|
|
964
|
-
a_kw_tys = @kw_tys.dup
|
|
965
|
-
if keyword
|
|
966
|
-
kw_tys = []
|
|
967
|
-
keyword.each do |kw|
|
|
968
|
-
case
|
|
969
|
-
when kw.is_a?(Symbol) # required keyword
|
|
970
|
-
key = kw
|
|
971
|
-
req = true
|
|
972
|
-
when kw.size == 2 # optional keyword (default value is a literal)
|
|
973
|
-
key, default_ty = *kw
|
|
974
|
-
default_ty = Type.guess_literal_type(default_ty)
|
|
975
|
-
default_ty = default_ty.type if default_ty.is_a?(Type::Literal)
|
|
976
|
-
req = false
|
|
977
|
-
else # optional keyword (default value is an expression)
|
|
978
|
-
key, = kw
|
|
979
|
-
req = false
|
|
980
|
-
end
|
|
981
|
-
|
|
982
|
-
if a_kw_tys.key?(key)
|
|
983
|
-
ty = a_kw_tys.delete(key)
|
|
887
|
+
# TODO: kw_tys
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
attr_reader :lead_tys, :opt_tys, :rest_ty, :blk_ty
|
|
891
|
+
|
|
892
|
+
def merge(bsig)
|
|
893
|
+
if @rest_ty && bsig.rest_ty
|
|
894
|
+
rest_ty = @rest_ty.union(bsig.rest_ty)
|
|
895
|
+
BlockSignature.new(@lead_tys, [], rest_ty, @blk_ty.union(bsig.blk_ty))
|
|
896
|
+
elsif @rest_ty || bsig.rest_ty
|
|
897
|
+
rest_ty = @rest_ty || bsig.rest_ty
|
|
898
|
+
rest_ty = @opt_tys.inject(rest_ty, &:union)
|
|
899
|
+
rest_ty = bsig.opt_tys.inject(rest_ty, &:union)
|
|
900
|
+
|
|
901
|
+
lead_tys = []
|
|
902
|
+
[@lead_tys.size, bsig.lead_tys.size].max.times do |i|
|
|
903
|
+
ty1 = @lead_tys[i]
|
|
904
|
+
ty2 = bsig.lead_tys[i]
|
|
905
|
+
if ty1 && ty2
|
|
906
|
+
lead_tys << ty1.union(ty2)
|
|
984
907
|
else
|
|
985
|
-
|
|
986
|
-
end
|
|
987
|
-
if ty == Type.bot && req
|
|
988
|
-
yield "no argument for required keywords"
|
|
989
|
-
return
|
|
990
|
-
end
|
|
991
|
-
ty = ty.union(default_ty) if default_ty
|
|
992
|
-
kw_tys << [req, key, ty]
|
|
993
|
-
end
|
|
994
|
-
end
|
|
995
|
-
if kw_rest_acceptable
|
|
996
|
-
if a_kw_tys.key?(nil)
|
|
997
|
-
kw_rest_ty = Type.gen_hash {|h| h[Type.any] = a_kw_tys[nil] }
|
|
998
|
-
else
|
|
999
|
-
kw_rest_ty = Type.gen_hash do |h|
|
|
1000
|
-
a_kw_tys.each do |key, ty|
|
|
1001
|
-
sym = Type::Symbol.new(key, Type::Instance.new(Type::Builtin[:sym]))
|
|
1002
|
-
h[sym] = ty
|
|
1003
|
-
end
|
|
908
|
+
rest_ty = rest_ty.union(ty1 || ty2)
|
|
1004
909
|
end
|
|
1005
910
|
end
|
|
1006
|
-
end
|
|
1007
|
-
#if @kw_tys
|
|
1008
|
-
# yield "passed a keyword to non-keyword method"
|
|
1009
|
-
#end
|
|
1010
|
-
|
|
1011
|
-
(lower_bound .. upper_bound).each do |rest_len|
|
|
1012
|
-
aargs = @lead_tys + [rest_elem] * rest_len
|
|
1013
|
-
lead_tys = aargs.shift(lead_num)
|
|
1014
|
-
lead_tys << rest_elem until lead_tys.size == lead_num
|
|
1015
|
-
post_tys = aargs.pop(post_num)
|
|
1016
|
-
post_tys.unshift(rest_elem) until post_tys.size == post_num
|
|
1017
|
-
start_pc = 0
|
|
1018
|
-
if opt
|
|
1019
|
-
tmp_opt = opt[1..]
|
|
1020
|
-
opt_tys = []
|
|
1021
|
-
until aargs.empty? || tmp_opt.empty?
|
|
1022
|
-
opt_tys << aargs.shift
|
|
1023
|
-
start_pc = tmp_opt.shift
|
|
1024
|
-
end
|
|
1025
|
-
end
|
|
1026
|
-
if rest_acceptable
|
|
1027
|
-
acc = aargs.inject {|acc, ty| acc.union(ty) }
|
|
1028
|
-
acc = acc ? acc.union(rest_elem) : rest_elem if rest_elem
|
|
1029
|
-
acc ||= Type.bot
|
|
1030
|
-
rest_ty = acc
|
|
1031
|
-
aargs.clear
|
|
1032
|
-
end
|
|
1033
|
-
if !aargs.empty?
|
|
1034
|
-
yield "wrong number of arguments (given #{ @lead_tys.size }, expected #{ lead_num + post_num })"
|
|
1035
|
-
return
|
|
1036
|
-
end
|
|
1037
|
-
yield FormalArguments.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, @blk_ty), start_pc
|
|
1038
|
-
end
|
|
1039
|
-
end
|
|
1040
|
-
|
|
1041
|
-
def consistent_with_formal_arguments?(fargs, subst)
|
|
1042
|
-
aargs = @lead_tys.dup
|
|
1043
911
|
|
|
1044
|
-
|
|
1045
|
-
# fargs: lead_tys, opt_tys, rest_ty, post_tys
|
|
1046
|
-
if @rest_ty
|
|
1047
|
-
lower_bound = [0, fargs.lead_tys.size + fargs.post_tys.size - aargs.size].max
|
|
1048
|
-
upper_bound = [0, lower_bound + fargs.opt_tys.size].max
|
|
1049
|
-
(lower_bound..upper_bound).each do |n|
|
|
1050
|
-
tmp_aargs = ActualArguments.new(@lead_tys + [@rest_ty] * n, nil, @kw_tys, @blk_ty)
|
|
1051
|
-
if tmp_aargs.consistent_with_formal_arguments?(fargs, subst)
|
|
1052
|
-
return true
|
|
1053
|
-
end
|
|
1054
|
-
end
|
|
1055
|
-
return false
|
|
1056
|
-
end
|
|
1057
|
-
|
|
1058
|
-
if fargs.rest_ty
|
|
1059
|
-
return false if aargs.size < fargs.lead_tys.size + fargs.post_tys.size
|
|
1060
|
-
aargs.shift(fargs.lead_tys.size).zip(fargs.lead_tys) do |aarg, farg|
|
|
1061
|
-
return false unless aarg.consistent?(farg, subst)
|
|
1062
|
-
end
|
|
1063
|
-
aargs.pop(fargs.post_tys.size).zip(fargs.post_tys) do |aarg, farg|
|
|
1064
|
-
return false unless aarg.consistent?(farg, subst)
|
|
1065
|
-
end
|
|
1066
|
-
fargs.opt_tys.each do |farg|
|
|
1067
|
-
aarg = aargs.shift
|
|
1068
|
-
return false unless aarg.consistent?(farg, subst)
|
|
1069
|
-
end
|
|
1070
|
-
aargs.each do |aarg|
|
|
1071
|
-
return false unless aarg.consistent?(fargs.rest_ty, subst)
|
|
1072
|
-
end
|
|
912
|
+
BlockSignature.new(lead_tys, [], rest_ty, @blk_ty.union(bsig.blk_ty))
|
|
1073
913
|
else
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
end
|
|
1079
|
-
aargs.pop(fargs.post_tys.size).zip(fargs.post_tys) do |aarg, farg|
|
|
1080
|
-
return false unless aarg.consistent?(farg, subst)
|
|
914
|
+
lead_tys = []
|
|
915
|
+
n = [@lead_tys.size, bsig.lead_tys.size].min
|
|
916
|
+
n.times do |i|
|
|
917
|
+
lead_tys << @lead_tys[i].union(bsig.lead_tys[i])
|
|
1081
918
|
end
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
when Type.nil
|
|
1092
|
-
return false if @blk_ty != Type.nil
|
|
1093
|
-
when Type::Any
|
|
1094
|
-
else
|
|
1095
|
-
raise "unknown typo of formal block signature"
|
|
1096
|
-
end
|
|
1097
|
-
true
|
|
1098
|
-
end
|
|
1099
|
-
|
|
1100
|
-
def screen_name(scratch)
|
|
1101
|
-
aargs = @lead_tys.map {|ty| ty.screen_name(scratch) }
|
|
1102
|
-
if @rest_ty
|
|
1103
|
-
aargs << ("*" + @rest_ty.screen_name(scratch))
|
|
1104
|
-
end
|
|
1105
|
-
if @kw_tys.key?(nil)
|
|
1106
|
-
aargs << "(unknown key): #{ @kw_tys[nil].screen_name(scratch) }"
|
|
1107
|
-
else
|
|
1108
|
-
@kw_tys.sort.each do |key, ty|
|
|
1109
|
-
aargs << "#{ key }: #{ ty.screen_name(scratch) }"
|
|
919
|
+
opt_tys1 = @lead_tys[n..] + @opt_tys
|
|
920
|
+
opt_tys2 = bsig.lead_tys[n..] + bsig.opt_tys
|
|
921
|
+
opt_tys = []
|
|
922
|
+
[opt_tys1.size, opt_tys2.size].max.times do |i|
|
|
923
|
+
if opt_tys1[i] && opt_tys2[i]
|
|
924
|
+
opt_tys << opt_tys1[i].union(opt_tys2[i])
|
|
925
|
+
else
|
|
926
|
+
opt_tys << (opt_tys1[i] || opt_tys2[i])
|
|
927
|
+
end
|
|
1110
928
|
end
|
|
929
|
+
BlockSignature.new(lead_tys, opt_tys, nil, @blk_ty.union(bsig.blk_ty))
|
|
1111
930
|
end
|
|
1112
|
-
s = "(#{ aargs.join(", ") })"
|
|
1113
|
-
s << " { #{ scratch.proc_screen_name(@blk_ty) } }" if @blk_ty != Type.nil
|
|
1114
|
-
s
|
|
1115
931
|
end
|
|
1116
932
|
end
|
|
1117
933
|
end
|