rdl 2.0.0.rc2 → 2.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +7 -1
- data/README.md +94 -20
- data/lib/rdl.rb +4 -1
- data/lib/rdl/config.rb +90 -3
- data/lib/rdl/info.rb +16 -0
- data/lib/rdl/typecheck.rb +207 -79
- data/lib/rdl/types/bot.rb +1 -1
- data/lib/rdl/types/dependent_arg.rb +17 -8
- data/lib/rdl/types/{finitehash.rb → finite_hash.rb} +3 -29
- data/lib/rdl/types/generic.rb +1 -37
- data/lib/rdl/types/intersection.rb +1 -0
- data/lib/rdl/types/lexer.rex +2 -1
- data/lib/rdl/types/lexer.rex.rb +4 -1
- data/lib/rdl/types/method.rb +2 -12
- data/lib/rdl/types/nominal.rb +1 -22
- data/lib/rdl/types/non_null.rb +50 -0
- data/lib/rdl/types/parser.racc +3 -1
- data/lib/rdl/types/parser.tab.rb +222 -190
- data/lib/rdl/types/singleton.rb +1 -6
- data/lib/rdl/types/structural.rb +1 -10
- data/lib/rdl/types/top.rb +1 -2
- data/lib/rdl/types/tuple.rb +3 -19
- data/lib/rdl/types/type.rb +223 -0
- data/lib/rdl/types/union.rb +12 -2
- data/lib/rdl/types/var.rb +4 -1
- data/lib/rdl/types/wild_query.rb +1 -0
- data/lib/rdl/wrap.rb +199 -169
- data/lib/rdl_disable.rb +41 -0
- data/lib/rdl_types.rb +1 -4
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/_aliases.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/abbrev.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/array.rb +56 -56
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/base64.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/basic_object.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/benchmark.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bigdecimal.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bigmath.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bignum.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/class.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/complex.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/coverage.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/csv.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/date.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/dir.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/encoding.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/enumerable.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/enumerator.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/exception.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/file.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/fileutils.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/fixnum.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/float.rb +26 -26
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/gem.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/hash.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/integer.rb +8 -8
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/io.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/kernel.rb +12 -11
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/marshal.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/matchdata.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/math.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/module.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/nil.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/numeric.rb +0 -0
- data/lib/types/core-ruby-2.x/object.rb +75 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/pathname.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/process.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/random.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/range.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/rational.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/regexp.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/set.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/string.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/strscan.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/symbol.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/time.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/uri.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/yaml.rb +0 -0
- data/lib/types/core.rb +4 -0
- data/rdl.gemspec +2 -2
- data/test/test_le.rb +77 -35
- data/test/test_parser.rb +75 -59
- data/test/test_rdl.rb +18 -0
- data/test/test_typecheck.rb +73 -4
- metadata +54 -57
- data/lib/rails_types.rb +0 -1
- data/types/rails-4.2.1/fixnum.rb +0 -3
- data/types/rails-4.2.1/string.rb +0 -3
- data/types/rails-tmp/action_dispatch.rb +0 -406
- data/types/rails-tmp/active_record.rb +0 -406
- data/types/rails-tmp/devise_contracts.rb +0 -216
- data/types/ruby-2.x/object.rb +0 -73
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class Object
|
2
|
+
# Instead of rdl_nowrap, mark individual methods as not being wrapped so
|
3
|
+
# we can wrap stuff defined by the user at the top level (since those
|
4
|
+
# methods are added to Object).
|
5
|
+
|
6
|
+
# type :ARGF, ARGF
|
7
|
+
# type :ARGV, 'Array<String>'
|
8
|
+
# type :DATA, 'File'
|
9
|
+
# type :ENV, ENV
|
10
|
+
# type :FALSE, '%false'
|
11
|
+
# type :NIL, 'nil'
|
12
|
+
# type :RUBY_COPYRIGHT, 'String'
|
13
|
+
# type :RUBY_DESCRIPTION, 'String'
|
14
|
+
# type :RUBY_ENGINE, 'String'
|
15
|
+
# type :RUBY_PATCHLEVEL, Fixnum
|
16
|
+
# type :RUBY_PLATFORM, 'String'
|
17
|
+
# type :RUBY_RELEASE_DATE, 'String'
|
18
|
+
# type :RUBY_REVISION, Fixnum
|
19
|
+
# type :RUBY_VERSION, 'String'
|
20
|
+
# type :STDERR, 'IO'
|
21
|
+
# type :STDIN, 'IO'
|
22
|
+
# type :STDOUT, 'IO'
|
23
|
+
# type :TOPLEVEL_BINDING, 'Binding'
|
24
|
+
# type :TRUE, '%true'
|
25
|
+
|
26
|
+
type :!~, '(%any other) -> %bool', wrap: false
|
27
|
+
type :<=>, '(%any other) -> Fixnum or nil', wrap: false
|
28
|
+
type :===, '(%any other) -> %bool', wrap: false
|
29
|
+
type :=~, '(%any other) -> nil', wrap: false
|
30
|
+
type :class, '() -> Class', wrap: false
|
31
|
+
type :clone, '() -> self', wrap: false
|
32
|
+
# type :define_singleton_method, '(XXXX : *XXXX)') # TODO
|
33
|
+
type :display, '(IO port) -> nil', wrap: false
|
34
|
+
type :dup, '() -> self an_object', wrap: false
|
35
|
+
type :enum_for, '(?Symbol method, *%any args) -> Enumerator<%any>', wrap: false
|
36
|
+
type :enum_for, '(?Symbol method, *%any args) { (*%any args) -> %any } -> Enumerator<%any>', wrap: false
|
37
|
+
type :eql?, '(%any other) -> %bool', wrap: false
|
38
|
+
# type :extend, '(XXXX : *XXXX)') # TODO
|
39
|
+
type :freeze, '() -> self', wrap: false
|
40
|
+
type :frozen?, '() -> %bool', wrap: false
|
41
|
+
type :hash, '() -> Fixnum', wrap: false
|
42
|
+
type :inspect, '() -> String', wrap: false
|
43
|
+
type :instance_of?, '(Class) -> %bool', wrap: false
|
44
|
+
type :instance_variable_defined?, '(Symbol or String) -> %bool', wrap: false
|
45
|
+
type :instance_variable_get, '(Symbol or String) -> %any', wrap: false
|
46
|
+
type :instance_variable_set, '(Symbol or String, %any) -> %any', wrap: false # returns 2nd argument
|
47
|
+
type :instance_variables, '() -> Array<Symbol>', wrap: false
|
48
|
+
type :is_a?, '(Class or Module) -> %bool', wrap: false
|
49
|
+
type :kind_of?, '(Class) -> %bool', wrap: false
|
50
|
+
type :method, '(Symbol) -> Method', wrap: false
|
51
|
+
type :methods, '(?%bool regular) -> Array<Symbol>', wrap: false
|
52
|
+
type :nil?, '() -> %bool', wrap: false
|
53
|
+
type :private_methods, '(?%bool all) -> Array<Symbol>', wrap: false
|
54
|
+
type :protected_methods, '(?%bool all) -> Array<Symbol>', wrap: false
|
55
|
+
type :public_method, '(Symbol) -> Method', wrap: false
|
56
|
+
type :public_methods, '(?%bool all) -> Array<Symbol>', wrap: false
|
57
|
+
type :public_send, '(Symbol or String, *%any args) -> %any', wrap: false
|
58
|
+
type :remove_instance_variable, '(Symbol) -> %any', wrap: false
|
59
|
+
# type :respond_to?, '(Symbol or String, ?%bool include_all) -> %bool'
|
60
|
+
type :send, '(Symbol or String, *%any args) -> %any', wrap: false # Can't wrap this, used outside wrap switch
|
61
|
+
type :singleton_class, '() -> Class', wrap: false
|
62
|
+
type :singleton_method, '(Symbol) -> Method', wrap: false
|
63
|
+
type :singleton_methods, '(?%bool all) -> Array<Symbol>', wrap: false
|
64
|
+
type :taint, '() -> self', wrap: false
|
65
|
+
type :tainted?, '() -> %bool', wrap: false
|
66
|
+
# type :tap, '()') # TODO
|
67
|
+
type :to_enum, '(?Symbol method, *%any args) -> Enumerator<%any>', wrap: false
|
68
|
+
type :to_enum, '(?Symbol method, *%any args) {(*%any args) -> %any} -> Enumerator<%any>', wrap: false
|
69
|
+
# TODO: above alias for enum_for?
|
70
|
+
type :to_s, '() -> String', wrap: false
|
71
|
+
type :trust, '() -> self', wrap: false
|
72
|
+
type :untaint, '() -> self', wrap: false
|
73
|
+
type :untrust, '() -> self', wrap: false
|
74
|
+
type :untrusted?, '() -> %bool', wrap: false
|
75
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/types/core.rb
ADDED
data/rdl.gemspec
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'rdl'
|
7
|
-
s.version = '2.0.0.
|
8
|
-
s.date = '2016-
|
7
|
+
s.version = '2.0.0.rc3'
|
8
|
+
s.date = '2016-08-11'
|
9
9
|
s.summary = 'Ruby type and contract system'
|
10
10
|
s.description = <<-EOF
|
11
11
|
RDL is a gem that adds types and contracts to Ruby. RDL includes extensive
|
data/test/test_le.rb
CHANGED
@@ -15,6 +15,11 @@ class TestLe < Minitest::Test
|
|
15
15
|
class C < B
|
16
16
|
end
|
17
17
|
|
18
|
+
# convert arg string to a type
|
19
|
+
def tt(t)
|
20
|
+
$__rdl_parser.scan_str('#T ' + t)
|
21
|
+
end
|
22
|
+
|
18
23
|
def setup
|
19
24
|
@tbasicobject = NominalType.new "BasicObject"
|
20
25
|
@tsymfoo = SingletonType.new :foo
|
@@ -93,45 +98,42 @@ class TestLe < Minitest::Test
|
|
93
98
|
assert (not (t2 <= t1))
|
94
99
|
assert (not (tarray <= t1))
|
95
100
|
assert (t1 <= t2) # covariant subtyping since tuples are *immutable*
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
assert (t123 <= tfff) # covariant subtyping with singletons
|
100
|
-
assert (tfff <= tooo)
|
101
|
-
assert (t123 <= tooo)
|
101
|
+
assert (tt("[1, 2, 3]") <= tt("[Fixnum, Fixnum, Fixnum]")) # covariant subtyping with singletons
|
102
|
+
assert (tt("[Fixnum, Fixnum, Fixnum]") <= tt("[Object, Object, Object]"))
|
103
|
+
assert (tt("[1, 2, 3]") <= tt("[Object, Object, Object]"))
|
102
104
|
|
103
105
|
# subtyping of tuples and arrays
|
104
|
-
tfs_1 =
|
105
|
-
tafs_1 =
|
106
|
+
tfs_1 = tt "[Fixnum, String]"
|
107
|
+
tafs_1 = tt "Array<Fixnum or String>"
|
106
108
|
assert (tfs_1 <= tafs_1) # subtyping allowed by tfs_1 promoted to array
|
107
|
-
tfs2_1 =
|
109
|
+
tfs2_1 = tt "[Fixnum, String]"
|
108
110
|
assert (not (tfs_1 <= tfs2_1)) # t12 has been promoted to array, no longer subtype
|
109
111
|
|
110
|
-
tfs_2 =
|
111
|
-
tfs2_2 =
|
112
|
+
tfs_2 = tt "[Fixnum, String]"
|
113
|
+
tfs2_2 = tt "[Fixnum, String]"
|
112
114
|
assert (tfs_2 <= tfs2_2) # this is allowed here because tfs_2 is still a tuple
|
113
|
-
tafs_2 =
|
115
|
+
tafs_2 = tt "Array<Fixnum or String>"
|
114
116
|
assert (not (tfs_2 <= tafs_2)) # subtyping not allowed because tfs_2 <= tfs2_2 unsatisfiable after tfs_2 promoted
|
115
117
|
|
116
|
-
tfs_3 =
|
117
|
-
tfs2_3 =
|
118
|
+
tfs_3 = tt "[Fixnum, String]"
|
119
|
+
tfs2_3 = tt "[Object, Object]"
|
118
120
|
assert (tfs_3 <= tfs2_3) # this is allowed here because t12a is still a tuple
|
119
|
-
tafs_3 =
|
121
|
+
tafs_3 = tt "Array<Object>"
|
120
122
|
assert (not (tfs2_3 <= tafs_3)) # subtyping not allowed because tfs_3 <= tfs2_3 unsatisfiable after tfs2_3 promoted
|
121
123
|
|
122
|
-
tfs_4 =
|
123
|
-
tfs2_4 =
|
124
|
+
tfs_4 = tt "[Fixnum, String]"
|
125
|
+
tfs2_4 = tt "[Fixnum, String]"
|
124
126
|
assert (tfs_4 <= tfs2_4) # allowed, types are the same
|
125
|
-
tafs_4 =
|
127
|
+
tafs_4 = tt "Array<Fixnum or String>"
|
126
128
|
assert (tfs2_4 <= tafs_4) # allowed, both tfs2_4 and tfs_4 promoted to array
|
127
|
-
tfs3_4 =
|
129
|
+
tfs3_4 = tt "[Fixnum, String]"
|
128
130
|
assert (not(tfs_4 <= tfs3_4)) # not allowed, tfs_4 has been promoted
|
129
131
|
end
|
130
132
|
|
131
133
|
def test_finite_hash
|
132
|
-
t12 =
|
133
|
-
tfs =
|
134
|
-
too =
|
134
|
+
t12 = tt "{a: 1, b: 2}"
|
135
|
+
tfs = tt "{a: Fixnum, b: Fixnum}"
|
136
|
+
too = tt "{a: Object, b: Object}"
|
135
137
|
assert (t12 <= tfs)
|
136
138
|
assert (t12 <= too)
|
137
139
|
assert (tfs <= too)
|
@@ -141,30 +143,30 @@ class TestLe < Minitest::Test
|
|
141
143
|
|
142
144
|
# subtyping of finite hashes and hashes; same pattern as tuples
|
143
145
|
# subtyping of tuples and arrays
|
144
|
-
tfs_1 =
|
145
|
-
thfs_1 =
|
146
|
+
tfs_1 = tt "{x: Fixnum, y: String}"
|
147
|
+
thfs_1 = tt "Hash<Symbol, Fixnum or String>"
|
146
148
|
assert (tfs_1 <= thfs_1) # subtyping allowed because tfs_1 promoted to hash
|
147
|
-
tfs2_1 =
|
149
|
+
tfs2_1 = tt "{x: Fixnum, y: String}"
|
148
150
|
assert (not (tfs_1 <= tfs2_1)) # t12 has been promoted to hash, no longer subtype
|
149
151
|
|
150
|
-
tfs_2 =
|
151
|
-
tfs2_2 =
|
152
|
+
tfs_2 = tt "{x: Fixnum, y: String}"
|
153
|
+
tfs2_2 = tt "{x: Fixnum, y: String}"
|
152
154
|
assert (tfs_2 <= tfs2_2) # this is allowed here because tfs_2 is still finite
|
153
|
-
thfs_2 =
|
155
|
+
thfs_2 = tt "Hash<Symbol, Fixnum or String>"
|
154
156
|
assert (not (tfs_2 <= thfs_2)) # subtyping not allowed because tfs_2 <= tfs2_2 unsatisfiable after tfs_2 promoted
|
155
157
|
|
156
|
-
tfs_3 =
|
157
|
-
tfs2_3 =
|
158
|
+
tfs_3 = tt "{x: Fixnum, y: String}"
|
159
|
+
tfs2_3 = tt "{x: Object, y: Object}"
|
158
160
|
assert (tfs_3 <= tfs2_3) # this is allowed here because t12a is still finite
|
159
|
-
thfs_3 =
|
161
|
+
thfs_3 = tt "Hash<Symbol, Object>"
|
160
162
|
assert (not (tfs2_3 <= thfs_3)) # subtyping not allowed because tfs_3 <= tfs2_3 unsatisfiable after tfs2_3 promoted
|
161
163
|
|
162
|
-
tfs_4 =
|
163
|
-
tfs2_4 =
|
164
|
+
tfs_4 = tt "{x: Fixnum, y: String}"
|
165
|
+
tfs2_4 = tt "{x: Fixnum, y: String}"
|
164
166
|
assert (tfs_4 <= tfs2_4) # allowed, types are the same
|
165
|
-
thfs_4 =
|
167
|
+
thfs_4 = tt "Hash<Symbol, Fixnum or String>"
|
166
168
|
assert (tfs2_4 <= thfs_4) # allowed, both tfs2_4 and tfs_4 promoted to hash
|
167
|
-
tfs3_4 =
|
169
|
+
tfs3_4 = tt "{x: Fixnum, y: String}"
|
168
170
|
assert (not(tfs_4 <= tfs3_4)) # not allowed, tfs_4 has been promoted
|
169
171
|
end
|
170
172
|
|
@@ -251,6 +253,46 @@ class TestLe < Minitest::Test
|
|
251
253
|
assert (not (tnomt <= ts4))
|
252
254
|
end
|
253
255
|
|
256
|
+
def test_leq_inst
|
257
|
+
# when return of do_leq is false, ignore resulting inst, since that's very implementation dependent
|
258
|
+
assert_equal [true, {t: @ta}], do_leq(tt("t"), @ta, true)
|
259
|
+
assert_equal false, do_leq(tt("t"), @ta, false)[0]
|
260
|
+
assert_equal false, do_leq(@ta, tt("t"), true)[0]
|
261
|
+
assert_equal [true, {t: @ta}], do_leq(@ta, tt("t"), false)
|
262
|
+
assert_equal [true, {}], do_leq($__rdl_bot_type, tt("t"), true)
|
263
|
+
assert_equal [true, {}], do_leq($__rdl_bot_type, tt("t"), false)
|
264
|
+
assert_equal false, do_leq($__rdl_top_type, tt("t"), true)[0]
|
265
|
+
assert_equal [true, {t: $__rdl_top_type}], do_leq($__rdl_top_type, tt("t"), false)
|
266
|
+
assert_equal [true, {t: @ta, u: @ta}], do_leq(tt("t or u"), @ta, true)
|
267
|
+
assert_equal false, do_leq(tt("t or u"), @ta, false)[0]
|
268
|
+
assert_equal false, do_leq(tt("3"), tt("t"), true)[0]
|
269
|
+
assert_equal [true, {t: tt("3")}], do_leq(tt("3"), tt("t"), false)
|
270
|
+
assert_equal [true, {t: $__rdl_fixnum_type}], do_leq(tt("Array<t>"), tt("Array<Fixnum>"), true)
|
271
|
+
assert_equal false, do_leq(tt("Array<t>"), tt("Array<Fixnum>"), false)[0]
|
272
|
+
assert_equal [true, {t: $__rdl_fixnum_type}], do_leq(tt("Array<Fixnum>"), tt("Array<t>"), false)
|
273
|
+
assert_equal false, do_leq(tt("Array<Fixnum>"), tt("Array<t>"), true)[0]
|
274
|
+
assert_equal [true, {t: $__rdl_fixnum_type, u: $__rdl_string_type}], do_leq(tt("Hash<t,u>"), tt("Hash<Fixnum,String>"), true)
|
275
|
+
assert_equal [true, {t: $__rdl_fixnum_type}], do_leq(tt("Hash<t,t>"), tt("Hash<Fixnum,Fixnum>"), true)
|
276
|
+
assert_equal false, do_leq(tt("Hash<t,t>"), tt("Hash<Fixnum,String>"), true)[0]
|
277
|
+
assert_equal false, do_leq(tt("[m:()->t]"), tt("[m:()->Fixnum]"), true)[0] # no inst inside structural types
|
278
|
+
end
|
279
|
+
|
280
|
+
def do_leq(tleft, tright, ileft)
|
281
|
+
inst = Hash.new
|
282
|
+
r = Type.leq(tleft, tright, inst, ileft)
|
283
|
+
return [r, inst]
|
284
|
+
end
|
285
|
+
|
286
|
+
# nonnull annotation is simply removed! so doesn't matter
|
287
|
+
def test_leq_nonnull
|
288
|
+
assert tt("!Fixnum") <= tt("!Fixnum")
|
289
|
+
assert tt("!Fixnum") <= tt("Fixnum")
|
290
|
+
assert tt("Fixnum") <= tt("!Fixnum")
|
291
|
+
assert tt("!Fixnum") <= tt("!Object")
|
292
|
+
assert tt("!Fixnum") <= tt("Object")
|
293
|
+
assert tt("Fixnum") <= tt("!Object")
|
294
|
+
end
|
295
|
+
|
254
296
|
# def test_intersection
|
255
297
|
# skip "<= not defined on intersection"
|
256
298
|
# tobject_and_basicobject = IntersectionType.new($__rdl_object_type, @tbasicobject)
|
data/test/test_parser.rb
CHANGED
@@ -26,168 +26,184 @@ class TestParser < Minitest::Test
|
|
26
26
|
@tsymbolx = AnnotatedArgType.new("x", @tsymbol)
|
27
27
|
end
|
28
28
|
|
29
|
+
def tt(t)
|
30
|
+
$__rdl_parser.scan_str('#T ' + t)
|
31
|
+
end
|
32
|
+
|
33
|
+
def tm(t)
|
34
|
+
$__rdl_parser.scan_str t
|
35
|
+
end
|
36
|
+
|
29
37
|
def test_basic
|
30
|
-
t1 =
|
38
|
+
t1 = tm "(nil) -> nil"
|
31
39
|
assert_equal (MethodType.new [$__rdl_nil_type], nil, $__rdl_nil_type), t1
|
32
|
-
t2 =
|
40
|
+
t2 = tm "(Fixnum, Fixnum) -> Fixnum"
|
33
41
|
assert_equal (MethodType.new [$__rdl_fixnum_type, $__rdl_fixnum_type], nil, $__rdl_fixnum_type), t2
|
34
|
-
t3 =
|
42
|
+
t3 = tm "() -> Enumerator"
|
35
43
|
assert_equal (MethodType.new [], nil, @tenum), t3
|
36
|
-
t4 =
|
44
|
+
t4 = tm "(%any) -> nil"
|
37
45
|
assert_equal (MethodType.new [$__rdl_top_type], nil, $__rdl_nil_type), t4
|
38
|
-
t5 =
|
46
|
+
t5 = tm "(%bool) -> Fixnum"
|
39
47
|
assert_equal (MethodType.new [$__rdl_bool_type], nil, $__rdl_fixnum_type), t5
|
40
|
-
assert_raises(RuntimeError) {
|
41
|
-
t6 =
|
48
|
+
assert_raises(RuntimeError) { tm "(%foo) -> nil" }
|
49
|
+
t6 = tm "(A) -> nil"
|
42
50
|
assert_equal (MethodType.new [@ta], nil, $__rdl_nil_type), t6
|
43
|
-
t7 =
|
51
|
+
t7 = tm "(TestParser::A) -> nil"
|
44
52
|
assert_equal (MethodType.new [NominalType.new("TestParser::A")], nil, $__rdl_nil_type), t7
|
45
|
-
t8 =
|
53
|
+
t8 = tm "(Fixnum) { (%any, String) -> nil } -> :symbol"
|
46
54
|
assert_equal (MethodType.new [$__rdl_fixnum_type], MethodType.new([$__rdl_top_type, $__rdl_string_type], nil, $__rdl_nil_type), @tsymbol), t8
|
47
|
-
t9 =
|
55
|
+
t9 = tm "(true) -> false"
|
48
56
|
assert_equal (MethodType.new [$__rdl_true_type], nil, $__rdl_false_type), t9
|
49
57
|
end
|
50
58
|
|
51
59
|
def test_opt_vararg
|
52
|
-
t1 =
|
60
|
+
t1 = tm "(Fixnum, ?Fixnum) -> Fixnum"
|
53
61
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumopt], nil, $__rdl_fixnum_type), t1
|
54
|
-
t2 =
|
62
|
+
t2 = tm "(Fixnum, *Fixnum) -> Fixnum"
|
55
63
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumvararg], nil, $__rdl_fixnum_type), t2
|
56
|
-
t3 =
|
64
|
+
t3 = tm "(Fixnum, ?Fixnum, ?Fixnum, *Fixnum) -> Fixnum"
|
57
65
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumopt, @tfixnumopt, @tfixnumvararg], nil, $__rdl_fixnum_type), t3
|
58
|
-
t4 =
|
66
|
+
t4 = tm "(?Fixnum) -> nil"
|
59
67
|
assert_equal (MethodType.new [@tfixnumopt], nil, $__rdl_nil_type), t4
|
60
|
-
t5 =
|
68
|
+
t5 = tm "(*Fixnum) -> nil"
|
61
69
|
assert_equal (MethodType.new [@tfixnumvararg], nil, $__rdl_nil_type), t5
|
62
70
|
end
|
63
71
|
|
64
72
|
def test_union
|
65
|
-
t1 =
|
73
|
+
t1 = tm "(Fixnum or String) -> nil"
|
66
74
|
assert_equal (MethodType.new [UnionType.new($__rdl_fixnum_type, $__rdl_string_type)], nil, $__rdl_nil_type), t1
|
67
|
-
t2 =
|
75
|
+
t2 = tm "(Fixnum or String or Symbol) -> nil"
|
68
76
|
assert_equal (MethodType.new [UnionType.new($__rdl_fixnum_type, $__rdl_string_type, $__rdl_symbol_type)], nil, $__rdl_nil_type), t2
|
69
|
-
t3 =
|
77
|
+
t3 = tm "() -> Fixnum or String or Symbol"
|
70
78
|
assert_equal (MethodType.new [], nil, UnionType.new($__rdl_fixnum_type, $__rdl_string_type, $__rdl_symbol_type)), t3
|
71
79
|
end
|
72
80
|
|
73
81
|
def test_bare
|
74
|
-
t1 =
|
82
|
+
t1 = tt "nil"
|
75
83
|
assert_equal $__rdl_nil_type, t1
|
76
|
-
t2 =
|
84
|
+
t2 = tt "%any"
|
77
85
|
assert_equal $__rdl_top_type, t2
|
78
|
-
t3 =
|
86
|
+
t3 = tt "A"
|
79
87
|
assert_equal NominalType.new("A"), t3
|
80
88
|
end
|
81
89
|
|
82
90
|
def test_symbol
|
83
|
-
t1 =
|
91
|
+
t1 = tt ":symbol"
|
84
92
|
assert_equal @tsymbol, t1
|
85
93
|
end
|
86
94
|
|
87
95
|
def test_annotated_params
|
88
|
-
t1 =
|
96
|
+
t1 = tm "(Fixnum x, Fixnum) -> Fixnum"
|
89
97
|
assert_equal (MethodType.new [@tfixnumx, $__rdl_fixnum_type], nil, $__rdl_fixnum_type), t1
|
90
|
-
t2 =
|
98
|
+
t2 = tm "(Fixnum, ?Fixnum x) -> Fixnum"
|
91
99
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumoptx], nil, $__rdl_fixnum_type), t2
|
92
|
-
t3 =
|
100
|
+
t3 = tm "(Fixnum, *Fixnum x) -> Fixnum"
|
93
101
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumvarargx], nil, $__rdl_fixnum_type), t3
|
94
|
-
t4 =
|
102
|
+
t4 = tm "(Fixnum, Fixnum y) -> Fixnum"
|
95
103
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumy], nil, $__rdl_fixnum_type), t4
|
96
|
-
t5 =
|
104
|
+
t5 = tm "(Fixnum x, Fixnum y) -> Fixnum"
|
97
105
|
assert_equal (MethodType.new [@tfixnumx, @tfixnumy], nil, $__rdl_fixnum_type), t5
|
98
|
-
t6 =
|
106
|
+
t6 = tm "(Fixnum, Fixnum) -> Fixnum ret"
|
99
107
|
assert_equal (MethodType.new [$__rdl_fixnum_type, $__rdl_fixnum_type], nil, @tfixnumret), t6
|
100
|
-
t7 =
|
108
|
+
t7 = tm "(Fixnum x, Fixnum) -> Fixnum ret"
|
101
109
|
assert_equal (MethodType.new [@tfixnumx, $__rdl_fixnum_type], nil, @tfixnumret), t7
|
102
|
-
t8 =
|
110
|
+
t8 = tm "(Fixnum, Fixnum y) -> Fixnum ret"
|
103
111
|
assert_equal (MethodType.new [$__rdl_fixnum_type, @tfixnumy], nil, @tfixnumret), t8
|
104
|
-
t9 =
|
112
|
+
t9 = tm "(Fixnum x, Fixnum y) -> Fixnum ret"
|
105
113
|
assert_equal (MethodType.new [@tfixnumx, @tfixnumy], nil, @tfixnumret), t9
|
106
|
-
t10 =
|
114
|
+
t10 = tm "(:symbol x) -> Fixnum"
|
107
115
|
assert_equal (MethodType.new [@tsymbolx], nil, $__rdl_fixnum_type), t10
|
108
116
|
end
|
109
117
|
|
110
118
|
def test_generic
|
111
|
-
t1 =
|
119
|
+
t1 = tt "t"
|
112
120
|
assert_equal (VarType.new "t"), t1
|
113
|
-
t2 =
|
121
|
+
t2 = tt "Array"
|
114
122
|
assert_equal (NominalType.new "Array"), t2
|
115
|
-
t3 =
|
123
|
+
t3 = tt "Array<t>"
|
116
124
|
assert_equal (GenericType.new(t2, t1)), t3
|
117
|
-
t4 =
|
125
|
+
t4 = tt "Array<Array<t>>"
|
118
126
|
assert_equal (GenericType.new(t2, t3)), t4
|
119
|
-
t5 =
|
127
|
+
t5 = tt "Hash"
|
120
128
|
assert_equal (NominalType.new "Hash"), t5
|
121
|
-
t6 =
|
129
|
+
t6 = tt "Hash<u, v>"
|
122
130
|
assert_equal (GenericType.new(t5, VarType.new("u"), VarType.new("v"))), t6
|
123
|
-
t7 =
|
131
|
+
t7 = tt "Foo<String, Array<t>, Array<Array<t>>>"
|
124
132
|
assert_equal (GenericType.new(NominalType.new("Foo"), $__rdl_string_type, t3, t4)), t7
|
125
133
|
end
|
126
134
|
|
127
135
|
def test_tuple
|
128
|
-
t1 =
|
136
|
+
t1 = tt "[Fixnum, String]"
|
129
137
|
assert_equal (TupleType.new($__rdl_fixnum_type, $__rdl_string_type)), t1
|
130
|
-
t2 =
|
138
|
+
t2 = tt "[String]"
|
131
139
|
assert_equal (TupleType.new($__rdl_string_type)), t2
|
132
140
|
end
|
133
141
|
|
134
142
|
def test_fixnum
|
135
|
-
t1 =
|
143
|
+
t1 = tt "42"
|
136
144
|
assert_equal (SingletonType.new(42)), t1
|
137
|
-
t2 =
|
145
|
+
t2 = tt "-42"
|
138
146
|
assert_equal (SingletonType.new(-42)), t2
|
139
147
|
end
|
140
148
|
|
141
149
|
def test_float
|
142
|
-
t1 =
|
150
|
+
t1 = tt "3.14"
|
143
151
|
assert_equal (SingletonType.new(3.14)), t1
|
144
152
|
end
|
145
153
|
|
146
154
|
def test_const
|
147
|
-
t1 =
|
155
|
+
t1 = tt "${Math::PI}"
|
148
156
|
assert_equal (SingletonType.new(Math::PI)), t1
|
149
157
|
end
|
150
158
|
|
151
159
|
def test_type_alias
|
152
160
|
type_alias '%foobarbaz', $__rdl_nil_type
|
153
|
-
assert_equal $__rdl_nil_type, (
|
161
|
+
assert_equal $__rdl_nil_type, (tt "%foobarbaz")
|
154
162
|
type_alias '%quxquxqux', 'nil'
|
155
|
-
assert_equal $__rdl_nil_type, (
|
163
|
+
assert_equal $__rdl_nil_type, (tt "%quxquxqux")
|
156
164
|
assert_raises(RuntimeError) { type_alias '%quxquxqux', 'nil' }
|
157
|
-
assert_raises(RuntimeError) {
|
165
|
+
assert_raises(RuntimeError) { tt "%qux" }
|
158
166
|
end
|
159
167
|
|
160
168
|
def test_structural
|
161
|
-
t1 =
|
169
|
+
t1 = tt "[to_str: () -> String]"
|
162
170
|
tm1 = MethodType.new [], nil, $__rdl_string_type
|
163
171
|
ts1 = StructuralType.new(to_str: tm1)
|
164
172
|
assert_equal ts1, t1
|
165
173
|
end
|
166
174
|
|
167
175
|
def test_finite_hash
|
168
|
-
t1 =
|
176
|
+
t1 = tt "{a: Fixnum, b: String}"
|
169
177
|
assert_equal (FiniteHashType.new({a: $__rdl_fixnum_type, b: $__rdl_string_type})), t1
|
170
|
-
t2 =
|
178
|
+
t2 = tt "{'a'=>Fixnum, 2=>String}"
|
171
179
|
assert_equal (FiniteHashType.new({"a"=>$__rdl_fixnum_type, 2=>$__rdl_string_type})), t2
|
172
180
|
end
|
173
181
|
|
174
182
|
def test_named_params
|
175
|
-
t1 =
|
183
|
+
t1 = tm "(Fixnum, x: Fixnum) -> Fixnum"
|
176
184
|
assert_equal (MethodType.new [$__rdl_fixnum_type, FiniteHashType.new(x: $__rdl_fixnum_type)], nil, $__rdl_fixnum_type), t1
|
177
|
-
t2 =
|
185
|
+
t2 = tm "(Fixnum, x: Fixnum, y: String) -> Fixnum"
|
178
186
|
assert_equal (MethodType.new [$__rdl_fixnum_type, FiniteHashType.new(x: $__rdl_fixnum_type, y: $__rdl_string_type)], nil, $__rdl_fixnum_type), t2
|
179
|
-
t3 =
|
187
|
+
t3 = tm "(Fixnum, y: String, x: Fixnum) -> Fixnum"
|
180
188
|
assert_equal (MethodType.new [$__rdl_fixnum_type, FiniteHashType.new(x: $__rdl_fixnum_type, y: $__rdl_string_type)], nil, $__rdl_fixnum_type), t3
|
181
|
-
t4 =
|
189
|
+
t4 = tm "(Fixnum, y: String, x: ?Fixnum) -> Fixnum"
|
182
190
|
assert_equal (MethodType.new [$__rdl_fixnum_type, FiniteHashType.new(x: @tfixnumopt, y: $__rdl_string_type)], nil, $__rdl_fixnum_type), t4
|
183
|
-
t4 =
|
191
|
+
t4 = tm "(Fixnum, y: ?String, x: Fixnum) -> Fixnum"
|
184
192
|
assert_equal (MethodType.new [$__rdl_fixnum_type, FiniteHashType.new(x: $__rdl_fixnum_type, y: @tstringopt)], nil, $__rdl_fixnum_type), t4
|
185
|
-
t5 =
|
193
|
+
t5 = tm "(Fixnum x, x: Fixnum) -> Fixnum"
|
186
194
|
assert_equal (MethodType.new [@tfixnumx, FiniteHashType.new(x: $__rdl_fixnum_type)], nil, $__rdl_fixnum_type), t5
|
187
|
-
t6 =
|
195
|
+
t6 = tm "(x: Fixnum) -> Fixnum"
|
188
196
|
assert_equal (MethodType.new [FiniteHashType.new(x: $__rdl_fixnum_type)], nil, $__rdl_fixnum_type), t6
|
189
|
-
t7 =
|
197
|
+
t7 = tm "(x: Fixnum) { (%any, String) -> nil } -> :symbol"
|
190
198
|
assert_equal (MethodType.new [FiniteHashType.new(x: $__rdl_fixnum_type)], MethodType.new([$__rdl_top_type, $__rdl_string_type], nil, $__rdl_nil_type), @tsymbol), t7
|
191
199
|
end
|
192
200
|
|
201
|
+
def test_nonnull
|
202
|
+
assert_equal NonNullType.new(@ta), tt("!A")
|
203
|
+
tm2 = MethodType.new [], nil, $__rdl_string_type
|
204
|
+
ts2 = StructuralType.new(to_str: tm2)
|
205
|
+
assert_equal NonNullType.new(ts2), tt("![to_str: () -> String]")
|
206
|
+
assert_raises(RuntimeError) { tt("!3") }
|
207
|
+
end
|
208
|
+
|
193
209
|
end
|