rdl 1.1.1 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/README.md +211 -32
- data/gemfiles/Gemfile.travis +1 -1
- data/lib/rdl.rb +85 -18
- data/lib/rdl/info.rb +74 -0
- data/lib/rdl/query.rb +8 -9
- data/lib/rdl/typecheck.rb +1057 -0
- data/lib/rdl/types/annotated_arg.rb +5 -5
- data/lib/rdl/types/{nil.rb → bot.rb} +9 -13
- data/lib/rdl/types/dependent_arg.rb +5 -5
- data/lib/rdl/types/dots_query.rb +2 -0
- data/lib/rdl/types/finitehash.rb +67 -24
- data/lib/rdl/types/generic.rb +13 -21
- data/lib/rdl/types/intersection.rb +9 -8
- data/lib/rdl/types/method.rb +30 -32
- data/lib/rdl/types/nominal.rb +22 -16
- data/lib/rdl/types/optional.rb +8 -22
- data/lib/rdl/types/parser.racc +8 -3
- data/lib/rdl/types/parser.tab.rb +131 -118
- data/lib/rdl/types/singleton.rb +15 -10
- data/lib/rdl/types/structural.rb +6 -6
- data/lib/rdl/types/top.rb +6 -6
- data/lib/rdl/types/tuple.rb +56 -24
- data/lib/rdl/types/type.rb +9 -0
- data/lib/rdl/types/type_inferencer.rb +1 -1
- data/lib/rdl/types/union.rb +52 -26
- data/lib/rdl/types/var.rb +7 -6
- data/lib/rdl/types/vararg.rb +5 -6
- data/lib/rdl/types/wild_query.rb +9 -2
- data/lib/rdl/util.rb +9 -7
- data/lib/rdl/wrap.rb +90 -72
- data/lib/rdl_types.rb +2 -2
- data/rdl.gemspec +6 -8
- data/test/test_alias.rb +4 -3
- data/test/test_contract.rb +5 -4
- data/test/test_dsl.rb +2 -1
- data/test/test_generic.rb +30 -26
- data/test/test_intersection.rb +3 -3
- data/test/test_le.rb +129 -61
- data/test/test_lib_types.rb +3 -2
- data/test/test_member.rb +33 -46
- data/test/test_parser.rb +113 -116
- data/test/test_query.rb +2 -1
- data/test/test_rdl.rb +64 -6
- data/test/test_rdl_type.rb +3 -2
- data/test/test_type_contract.rb +30 -12
- data/test/test_typecheck.rb +893 -0
- data/test/test_types.rb +50 -54
- data/test/test_wrap.rb +2 -1
- data/types/ruby-2.x/_aliases.rb +13 -2
- data/types/ruby-2.x/bigdecimal.rb +60 -85
- data/types/ruby-2.x/bignum.rb +80 -119
- data/types/ruby-2.x/complex.rb +33 -40
- data/types/ruby-2.x/fixnum.rb +81 -120
- data/types/ruby-2.x/float.rb +79 -116
- data/types/ruby-2.x/integer.rb +187 -22
- data/types/ruby-2.x/nil.rb +12 -0
- data/types/ruby-2.x/numeric.rb +38 -38
- data/types/ruby-2.x/object.rb +3 -3
- data/types/ruby-2.x/random.rb +2 -0
- data/types/ruby-2.x/range.rb +20 -19
- data/types/ruby-2.x/rational.rb +40 -40
- data/types/ruby-2.x/regexp.rb +4 -4
- data/types/ruby-2.x/string.rb +15 -17
- metadata +17 -16
- data/lib/rdl/types/.#lexer.rex +0 -1
@@ -16,17 +16,17 @@ module RDL::Type
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def to_s
|
19
|
-
"#{@type.to_s} #{@name}"
|
20
|
-
end
|
21
|
-
|
22
|
-
def eql?(other)
|
23
|
-
self == other
|
19
|
+
return "#{@type.to_s} #{@name}"
|
24
20
|
end
|
25
21
|
|
26
22
|
def ==(other) # :nodoc:
|
23
|
+
return false if other.nil?
|
24
|
+
other = other.canonical
|
27
25
|
return (other.instance_of? AnnotatedArgType) && (other.name == @name) && (other.type == @type)
|
28
26
|
end
|
29
27
|
|
28
|
+
alias eql? ==
|
29
|
+
|
30
30
|
# doesn't have a match method - queries shouldn't have annotations in them
|
31
31
|
|
32
32
|
def hash # :nodoc:
|
@@ -1,7 +1,5 @@
|
|
1
|
-
require_relative 'type'
|
2
|
-
|
3
1
|
module RDL::Type
|
4
|
-
class
|
2
|
+
class BotType < Type
|
5
3
|
@@cache = nil
|
6
4
|
|
7
5
|
class << self
|
@@ -9,7 +7,7 @@ module RDL::Type
|
|
9
7
|
end
|
10
8
|
|
11
9
|
def self.new
|
12
|
-
@@cache =
|
10
|
+
@@cache = BotType.__new__ unless @@cache
|
13
11
|
return @@cache
|
14
12
|
end
|
15
13
|
|
@@ -18,18 +16,17 @@ module RDL::Type
|
|
18
16
|
end
|
19
17
|
|
20
18
|
def to_s
|
21
|
-
"
|
22
|
-
end
|
23
|
-
|
24
|
-
def eql?(other)
|
25
|
-
self == other
|
19
|
+
"%bot"
|
26
20
|
end
|
27
21
|
|
28
22
|
def ==(other)
|
29
|
-
other.instance_of?
|
23
|
+
other.instance_of? BotType
|
30
24
|
end
|
31
25
|
|
26
|
+
alias eql? ==
|
27
|
+
|
32
28
|
def match(other)
|
29
|
+
other = other.canonical
|
33
30
|
other = other.type if other.instance_of? AnnotatedArgType
|
34
31
|
return true if other.instance_of? WildQuery
|
35
32
|
return self == other
|
@@ -40,9 +37,8 @@ module RDL::Type
|
|
40
37
|
end
|
41
38
|
|
42
39
|
def member?(obj, *args)
|
43
|
-
|
44
|
-
|
45
|
-
obj.nil?
|
40
|
+
# There are no values of this type (note nil does *not* have type %bot)
|
41
|
+
false
|
46
42
|
end
|
47
43
|
|
48
44
|
def instantiate(inst)
|
@@ -19,17 +19,17 @@ module RDL::Type
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_s
|
22
|
-
"#{@type.to_s} #{@name} {{#{@predicate}}}"
|
23
|
-
end
|
24
|
-
|
25
|
-
def eql?(other)
|
26
|
-
self == other
|
22
|
+
return "#{@type.to_s} #{@name} {{#{@predicate}}}"
|
27
23
|
end
|
28
24
|
|
29
25
|
def ==(other) # :nodoc:
|
26
|
+
return false if other.nil?
|
27
|
+
other = other.canonical
|
30
28
|
return (other.instance_of? DependentArgType) && (other.name == @name) && (other.type == @type)
|
31
29
|
end
|
32
30
|
|
31
|
+
alias eql? ==
|
32
|
+
|
33
33
|
# doesn't have a match method - queries shouldn't have annotations in them
|
34
34
|
|
35
35
|
def hash # :nodoc:
|
data/lib/rdl/types/dots_query.rb
CHANGED
data/lib/rdl/types/finitehash.rb
CHANGED
@@ -6,19 +6,9 @@ module RDL::Type
|
|
6
6
|
# to see if they match.
|
7
7
|
class FiniteHashType < Type
|
8
8
|
attr_reader :elts
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
class << self
|
13
|
-
alias :__new__ :new
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.new(elts)
|
17
|
-
ct = @@cache[elts]
|
18
|
-
return ct if ct
|
19
|
-
t = FiniteHashType.__new__(elts)
|
20
|
-
return (@@cache[elts] = t) # assignment evaluates to t
|
21
|
-
end
|
9
|
+
attr_reader :the_hash # either nil or hash type if self has been promoted to hash
|
10
|
+
attr_reader :ubounds # upper bounds this tuple has been compared with using <=
|
11
|
+
attr_reader :lbounds # lower bounds...
|
22
12
|
|
23
13
|
# [+elts+] is a map from keys to types
|
24
14
|
def initialize(elts)
|
@@ -27,36 +17,85 @@ module RDL::Type
|
|
27
17
|
raise RuntimeError, "Type may not be annotated or vararg" if (t.instance_of? AnnotatedArgType) || (t.instance_of? VarargType)
|
28
18
|
}
|
29
19
|
@elts = elts
|
20
|
+
@the_hash = nil
|
21
|
+
@cant_promote = false
|
22
|
+
@ubounds = []
|
23
|
+
@lbounds = []
|
30
24
|
super()
|
31
25
|
end
|
32
26
|
|
33
|
-
def
|
34
|
-
|
27
|
+
def canonical
|
28
|
+
return @the_hash if @the_hash
|
29
|
+
return self
|
35
30
|
end
|
36
31
|
|
37
|
-
def
|
38
|
-
|
32
|
+
def to_s
|
33
|
+
return @the_hash.to_s if @the_hash
|
34
|
+
"{" + @elts.map { |k, t| k.to_s + ": " + t.to_s }.join(', ') + "}"
|
39
35
|
end
|
40
36
|
|
41
37
|
def ==(other) # :nodoc:
|
38
|
+
return false if other.nil?
|
39
|
+
return (@the_hash == other) if @the_hash
|
40
|
+
other = other.canonical
|
42
41
|
return (other.instance_of? FiniteHashType) && (other.elts == @elts)
|
43
42
|
end
|
44
43
|
|
44
|
+
alias eql? ==
|
45
|
+
|
45
46
|
def match(other)
|
47
|
+
return @the_hash.match(other) if @the_hash
|
48
|
+
other = other.canonical
|
46
49
|
other = other.type if other.instance_of? AnnotatedArgType
|
47
50
|
return true if other.instance_of? WildQuery
|
48
51
|
return (@elts.length == other.elts.length &&
|
49
52
|
@elts.all? { |k, v| (other.elts.has_key? k) && (v.match(other.elts[k]))})
|
50
53
|
end
|
51
54
|
|
55
|
+
def promote!
|
56
|
+
return false if @cant_promote
|
57
|
+
@the_hash = GenericType.new($__rdl_hash_type, $__rdl_symbol_type, UnionType.new(*@elts.values))
|
58
|
+
# same logic as Tuple
|
59
|
+
return (@lbounds.all? { |lbound| lbound <= self }) && (@ubounds.all? { |ubound| self <= ubound })
|
60
|
+
end
|
61
|
+
|
62
|
+
def cant_promote!
|
63
|
+
raise RuntimeError, "already promoted!" if @the_hash
|
64
|
+
@cant_promote = true
|
65
|
+
end
|
66
|
+
|
52
67
|
def <=(other)
|
68
|
+
return @the_hash <= other if @the_hash
|
69
|
+
other = other.canonical
|
53
70
|
return true if other.instance_of? TopType
|
54
|
-
|
55
|
-
|
56
|
-
|
71
|
+
other = other.the_hash if other.instance_of?(FiniteHashType) && other.the_hash
|
72
|
+
if other.instance_of? FiniteHashType
|
73
|
+
# Like Tuples, FiniteHashes are immutable, so covariant subtyping allowed
|
74
|
+
# But note, no width subtyping allowed, to match #member?
|
75
|
+
rest = other.elts.clone # shallow copy
|
76
|
+
@elts.each_pair { |k, tleft|
|
77
|
+
return false unless rest.has_key? k
|
78
|
+
tright = rest[k]
|
79
|
+
tleft = tleft.type if tleft.instance_of? OptionalType
|
80
|
+
tright = tright.type if tright.instance_of? OptionalType
|
81
|
+
return false unless tleft <= tright
|
82
|
+
rest.delete k
|
83
|
+
}
|
84
|
+
rest.each_pair { |k, tright|
|
85
|
+
return false unless tright.instance_of? OptionalType
|
86
|
+
}
|
87
|
+
ubounds << other
|
88
|
+
other.lbounds << self
|
89
|
+
return true
|
90
|
+
elsif (other.instance_of? GenericType) && (other.base == $__rdl_hash_type)
|
91
|
+
r = promote!
|
92
|
+
return (self <= other) && r
|
93
|
+
end
|
94
|
+
return false
|
57
95
|
end
|
58
96
|
|
59
97
|
def member?(obj, *args)
|
98
|
+
return @the_hash.member(obj, *args) if @the_hash
|
60
99
|
t = RDL::Util.rdl_type obj
|
61
100
|
return t <= self if t
|
62
101
|
rest = @elts.clone # shallow copy
|
@@ -65,10 +104,10 @@ module RDL::Type
|
|
65
104
|
|
66
105
|
# Check that every mapping in obj exists in @map and matches the type
|
67
106
|
obj.each_pair { |k, v|
|
68
|
-
return false unless @elts.has_key?
|
107
|
+
return false unless @elts.has_key? k
|
69
108
|
t = @elts[k]
|
70
109
|
t = t.type if t.instance_of? OptionalType
|
71
|
-
return false unless t.member?
|
110
|
+
return false unless t.member? v
|
72
111
|
rest.delete(k)
|
73
112
|
}
|
74
113
|
|
@@ -76,14 +115,18 @@ module RDL::Type
|
|
76
115
|
rest.each_pair { |k, vt|
|
77
116
|
return false unless vt.instance_of? OptionalType
|
78
117
|
}
|
118
|
+
|
119
|
+
return true
|
79
120
|
end
|
80
121
|
|
81
122
|
def instantiate(inst)
|
82
|
-
|
123
|
+
return @the_hash.instantiate(inst) if @the_hash
|
124
|
+
return FiniteHashType.new(Hash[@elts.map { |k, t| [k, t.instantiate(inst)] }])
|
83
125
|
end
|
84
126
|
|
85
127
|
def hash
|
86
|
-
|
128
|
+
# note don't change hash value if @the_hash becomes non-nil
|
129
|
+
return 229 * @elts.hash
|
87
130
|
end
|
88
131
|
end
|
89
132
|
end
|
data/lib/rdl/types/generic.rb
CHANGED
@@ -7,23 +7,9 @@ module RDL::Type
|
|
7
7
|
attr_reader :base
|
8
8
|
attr_reader :params
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
class << self
|
13
|
-
alias :__new__ :new
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.new(base, *params)
|
17
|
-
t = @@cache[[base, params]]
|
18
|
-
return t if t
|
10
|
+
def initialize(base, *params)
|
19
11
|
raise RuntimeError, "Attempt to create generic type with non-type param" unless params.all? { |p| p.is_a? Type }
|
20
|
-
t = GenericType.__new__(base, params)
|
21
|
-
return (@@cache[[base, params]] = t) # assignment evaluates to t
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(base, params)
|
25
12
|
raise "base must be NominalType" unless base.instance_of? NominalType
|
26
|
-
|
27
13
|
@base = base
|
28
14
|
@params = params
|
29
15
|
super()
|
@@ -33,21 +19,23 @@ module RDL::Type
|
|
33
19
|
"#{@base}<#{@params.map { |t| t.to_s }.join(', ')}>"
|
34
20
|
end
|
35
21
|
|
36
|
-
def eql?(other)
|
37
|
-
self == other
|
38
|
-
end
|
39
|
-
|
40
22
|
def ==(other) # :nodoc:
|
23
|
+
return false if other.nil?
|
24
|
+
other = other.canonical
|
41
25
|
return (other.instance_of? GenericType) && (other.base == @base) && (other.params == @params)
|
42
26
|
end
|
43
27
|
|
28
|
+
alias eql? ==
|
29
|
+
|
44
30
|
def match(other)
|
31
|
+
other = other.canonical
|
45
32
|
other = other.type if other.instance_of? AnnotatedArgType
|
46
33
|
return true if other.instance_of? WildQuery
|
47
34
|
return @params.length == other.params.length && @params.zip(other.params).all? { |t,o| t.match(o) }
|
48
35
|
end
|
49
36
|
|
50
37
|
def <=(other)
|
38
|
+
other = other.canonical
|
51
39
|
formals, variance, _ = $__rdl_type_params[base.name]
|
52
40
|
# do check here to avoid hiding errors if generic type written
|
53
41
|
# with wrong number of parameters but never checked against
|
@@ -76,8 +64,8 @@ module RDL::Type
|
|
76
64
|
k = base.klass
|
77
65
|
other.methods.each_pair { |m, t|
|
78
66
|
return false unless k.method_defined? m
|
79
|
-
|
80
|
-
|
67
|
+
types = $__rdl_info.get(k, m, :type)
|
68
|
+
if types
|
81
69
|
return false unless types.all? { |t_self| t_self.instantiate(inst) <= t }
|
82
70
|
end
|
83
71
|
}
|
@@ -102,5 +90,9 @@ module RDL::Type
|
|
102
90
|
def hash
|
103
91
|
(61 + @base.hash) * @params.hash
|
104
92
|
end
|
93
|
+
|
94
|
+
def to_inst
|
95
|
+
return $__rdl_type_params[base.name][0].zip(@params).to_h
|
96
|
+
end
|
105
97
|
end
|
106
98
|
end
|
@@ -13,7 +13,7 @@ module RDL::Type
|
|
13
13
|
def self.new(*types)
|
14
14
|
ts = []
|
15
15
|
types.each { |t|
|
16
|
-
if t.
|
16
|
+
if t.nil_type?
|
17
17
|
next
|
18
18
|
elsif t.instance_of? IntersectionType
|
19
19
|
ts.concat t.types
|
@@ -25,7 +25,7 @@ module RDL::Type
|
|
25
25
|
ts.sort! { |a,b| a.object_id <=> b.object_id }
|
26
26
|
ts.uniq!
|
27
27
|
|
28
|
-
return
|
28
|
+
return $__rdl_nil_type if ts.size == 0
|
29
29
|
return ts[0] if ts.size == 1
|
30
30
|
|
31
31
|
t = @@cache[ts]
|
@@ -40,18 +40,19 @@ module RDL::Type
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def to_s # :nodoc:
|
43
|
-
"(#{@types.map { |t| t.to_s }.join(' and ')})"
|
44
|
-
end
|
45
|
-
|
46
|
-
def eql?(other)
|
47
|
-
self == other
|
43
|
+
return "(#{@types.map { |t| t.to_s }.join(' and ')})"
|
48
44
|
end
|
49
45
|
|
50
46
|
def ==(other) # :nodoc:
|
47
|
+
return false if other.nil?
|
48
|
+
other = other.canonical
|
51
49
|
return (other.instance_of? IntersectionType) && (other.types == @types)
|
52
50
|
end
|
53
51
|
|
52
|
+
alias eql? ==
|
53
|
+
|
54
54
|
def match(other)
|
55
|
+
other = other.canonical
|
55
56
|
other = other.type if other.instance_of? AnnotatedArgType
|
56
57
|
return true if other.instance_of? WildQuery
|
57
58
|
return false if @types.length != other.types.length
|
@@ -67,7 +68,7 @@ module RDL::Type
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def hash # :nodoc:
|
70
|
-
47 + @types.hash
|
71
|
+
return 47 + @types.hash
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end
|
data/lib/rdl/types/method.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'type'
|
2
|
-
|
3
1
|
module RDL::Type
|
4
2
|
|
5
3
|
# A type representing some method or block. MethodType has subcomponent
|
@@ -37,7 +35,7 @@ module RDL::Type
|
|
37
35
|
state = :hash
|
38
36
|
else
|
39
37
|
raise "Attempt to create method type with non-type arg" unless arg.is_a? Type
|
40
|
-
raise "Required arguments not allowed after varargs" if state == :vararg
|
38
|
+
# raise "Required arguments not allowed after varargs" if state == :vararg # actually they are allowed!
|
41
39
|
raise "Required arguments not allowed after named arguments" if state == :hash
|
42
40
|
end
|
43
41
|
}
|
@@ -52,27 +50,29 @@ module RDL::Type
|
|
52
50
|
super()
|
53
51
|
end
|
54
52
|
|
55
|
-
def le(other, h={})
|
56
|
-
raise RuntimeError, "should not be called"
|
57
|
-
end
|
58
|
-
|
59
53
|
# TODO: Check blk
|
54
|
+
# Very similar to Typecheck.check_arg_types
|
60
55
|
def pre_cond?(blk, slf, inst, bind, *args)
|
61
56
|
states = [[0, 0]] # [position in @arg, position in args]
|
62
57
|
preds = []
|
63
58
|
until states.empty?
|
64
59
|
formal, actual = states.pop
|
65
60
|
if formal == @args.size && actual == args.size then # Matched all actuals, no formals left over
|
66
|
-
|
67
|
-
@args.each_with_index {|a,i| args[i] = block_wrap(slf,inst,a,bind
|
68
|
-
|
61
|
+
check_arg_preds(bind, preds) if preds.size > 0
|
62
|
+
@args.each_with_index {|a,i| args[i] = block_wrap(slf, inst, a, bind, &args[i]) if a.is_a? MethodType }
|
63
|
+
if @block then
|
64
|
+
raise TypeError, "Expected method block of type {@block}, received no block." unless blk
|
65
|
+
blk = block_wrap(slf, inst, @block, bind, &blk)
|
66
|
+
elsif blk then
|
67
|
+
raise TypeError, "Block passed to method expecting no block."
|
68
|
+
end
|
69
69
|
return [true, args, blk, bind]
|
70
70
|
end
|
71
71
|
next if formal >= @args.size # Too many actuals to match
|
72
72
|
t = @args[formal]
|
73
73
|
if t.instance_of? AnnotatedArgType then
|
74
|
-
|
75
|
-
|
74
|
+
bind.local_variable_set(t.name.to_sym,args[actual])
|
75
|
+
t = t.type
|
76
76
|
end
|
77
77
|
case t
|
78
78
|
when OptionalType
|
@@ -83,7 +83,7 @@ module RDL::Type
|
|
83
83
|
states << [formal+1, actual+1] # match
|
84
84
|
states << [formal+1, actual] # skip
|
85
85
|
else
|
86
|
-
states << [formal+1, actual] #
|
86
|
+
states << [formal+1, actual] # types don't match; must skip this formal
|
87
87
|
end
|
88
88
|
when VarargType
|
89
89
|
t = t.type.instantiate(inst)
|
@@ -92,12 +92,12 @@ module RDL::Type
|
|
92
92
|
elsif t.member?(args[actual], vars_wild: true)
|
93
93
|
states << [formal, actual+1] # match, more varargs coming
|
94
94
|
states << [formal+1, actual+1] # match, no more varargs
|
95
|
-
|
95
|
+
states << [formal+1, actual] # skip over even though matches
|
96
96
|
else
|
97
|
-
states << [formal+1, actual] # skip
|
97
|
+
states << [formal+1, actual] # doesn't match, must skip
|
98
98
|
end
|
99
99
|
when DependentArgType
|
100
|
-
|
100
|
+
bind.local_variable_set(t.name.to_sym,args[actual])
|
101
101
|
preds.push(t)
|
102
102
|
t = t.type.instantiate(inst)
|
103
103
|
the_actual = nil
|
@@ -111,7 +111,7 @@ module RDL::Type
|
|
111
111
|
# no else case; if there is no match, this is a dead end
|
112
112
|
end
|
113
113
|
else
|
114
|
-
t =
|
114
|
+
t = NominalType.new 'Proc' if t.instance_of? MethodType
|
115
115
|
t = t.instantiate(inst)
|
116
116
|
the_actual = nil
|
117
117
|
if actual == args.size
|
@@ -158,18 +158,18 @@ RUBY
|
|
158
158
|
|
159
159
|
def post_cond?(slf, inst, ret, bind, *args)
|
160
160
|
new_ret = ret
|
161
|
-
if @ret.is_a?(
|
161
|
+
if @ret.is_a?(MethodType) then
|
162
162
|
if !ret.is_a?(Proc) then
|
163
163
|
return [false,ret]
|
164
164
|
else
|
165
|
-
new_ret = block_wrap(slf,inst
|
165
|
+
new_ret = block_wrap(slf, inst, @ret, bind, &ret)
|
166
166
|
return [true, new_ret]
|
167
167
|
end
|
168
168
|
end
|
169
169
|
method_name = method_name ? method_name + ": " : ""
|
170
|
-
if @ret.is_a?
|
170
|
+
if @ret.is_a? DependentArgType then
|
171
171
|
bind.local_variable_set(@ret.name.to_sym, ret)
|
172
|
-
check_ret_pred(bind
|
172
|
+
check_ret_pred(bind, @ret)
|
173
173
|
end
|
174
174
|
return [@ret.instantiate(inst).member?(ret, vars_wild: true), new_ret]
|
175
175
|
end
|
@@ -219,10 +219,10 @@ RUBY
|
|
219
219
|
$__rdl_contract_switch.off {
|
220
220
|
matches = [] # types that matched args
|
221
221
|
types.each_with_index { |t, i|
|
222
|
-
res,args,blk,bind =t.pre_cond?(blk,slf,inst,bind
|
222
|
+
res, args, blk, bind = t.pre_cond?(blk, slf, inst, bind, *args)
|
223
223
|
matches << i if res
|
224
|
-
|
225
|
-
|
224
|
+
}
|
225
|
+
return [matches, args, blk, bind] if matches.size > 0
|
226
226
|
method_name = method_name ? method_name + ": " : ""
|
227
227
|
raise TypeError, <<RUBY
|
228
228
|
#{method_name}Argument type error.
|
@@ -284,10 +284,6 @@ RUBY
|
|
284
284
|
@ret.instantiate(inst))
|
285
285
|
end
|
286
286
|
|
287
|
-
def eql?(other)
|
288
|
-
self == other
|
289
|
-
end
|
290
|
-
|
291
287
|
# Return +true+ if +other+ is the same type
|
292
288
|
def ==(other)
|
293
289
|
return (other.instance_of? MethodType) &&
|
@@ -296,6 +292,8 @@ RUBY
|
|
296
292
|
(other.ret == @ret)
|
297
293
|
end
|
298
294
|
|
295
|
+
alias eql? ==
|
296
|
+
|
299
297
|
# other may not be a query
|
300
298
|
def match(other)
|
301
299
|
other = other.type if other.instance_of? AnnotatedArgType
|
@@ -342,8 +340,8 @@ RUBY
|
|
342
340
|
|
343
341
|
def self.check_block_arg_types(slf, types, inst, bind, *args)
|
344
342
|
$__rdl_contract_switch.off {
|
345
|
-
|
346
|
-
|
343
|
+
res,args,blk,bind = types.pre_cond?(nil, slf, inst, bind, *args)
|
344
|
+
return [true, args, blk, bind] if res
|
347
345
|
raise TypeError, <<RUBY
|
348
346
|
Proc argument type error.
|
349
347
|
Proc type:
|
@@ -358,8 +356,8 @@ RUBY
|
|
358
356
|
|
359
357
|
def self.check_block_ret_types(slf, types, inst, ret, bind, *args)
|
360
358
|
$__rdl_contract_switch.off {
|
361
|
-
|
362
|
-
|
359
|
+
res,new_ret = types.post_cond?(slf, inst, ret, bind, *args)
|
360
|
+
return new_ret if res
|
363
361
|
raise TypeError, <<RUBY
|
364
362
|
Proc return type error.
|
365
363
|
Proc type:
|