rdl 2.0.0.rc2 → 2.0.0.rc3
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 +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
|