rdl 1.1.1 → 2.0.0.rc1
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/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:
|