rubybreaker 0.0.1
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.
- data/AUTHORS +7 -0
- data/LICENSE +26 -0
- data/README.md +403 -0
- data/Rakefile +90 -0
- data/TODO +30 -0
- data/bin/gen_stub_rubylib +64 -0
- data/bin/rubybreaker +67 -0
- data/lib/rubybreaker/context.rb +122 -0
- data/lib/rubybreaker/debug.rb +48 -0
- data/lib/rubybreaker/error.rb +59 -0
- data/lib/rubybreaker/rubylib/core.rb +2316 -0
- data/lib/rubybreaker/rubylib.rb +3 -0
- data/lib/rubybreaker/runtime/inspector.rb +57 -0
- data/lib/rubybreaker/runtime/monitor.rb +235 -0
- data/lib/rubybreaker/runtime/object_wrapper.rb +77 -0
- data/lib/rubybreaker/runtime/overrides.rb +42 -0
- data/lib/rubybreaker/runtime/pluggable.rb +57 -0
- data/lib/rubybreaker/runtime/type_placeholder.rb +27 -0
- data/lib/rubybreaker/runtime/type_system.rb +228 -0
- data/lib/rubybreaker/runtime/typesig_parser.rb +45 -0
- data/lib/rubybreaker/runtime.rb +103 -0
- data/lib/rubybreaker/test/testcase.rb +39 -0
- data/lib/rubybreaker/test.rb +1 -0
- data/lib/rubybreaker/type/type.rb +241 -0
- data/lib/rubybreaker/type/type_comparer.rb +143 -0
- data/lib/rubybreaker/type/type_grammar.treetop +285 -0
- data/lib/rubybreaker/type/type_unparser.rb +142 -0
- data/lib/rubybreaker/type.rb +2 -0
- data/lib/rubybreaker/typing/rubytype.rb +47 -0
- data/lib/rubybreaker/typing/subtyping.rb +480 -0
- data/lib/rubybreaker/typing.rb +3 -0
- data/lib/rubybreaker/util.rb +31 -0
- data/lib/rubybreaker.rb +193 -0
- data/test/integrated/tc_method_missing.rb +30 -0
- data/test/integrated/tc_simple1.rb +77 -0
- data/test/runtime/tc_obj_wrapper.rb +73 -0
- data/test/runtime/tc_typesig_parser.rb +33 -0
- data/test/ts_integrated.rb +4 -0
- data/test/ts_runtime.rb +5 -0
- data/test/ts_type.rb +5 -0
- data/test/ts_typing.rb +4 -0
- data/test/type/tc_comparer.rb +211 -0
- data/test/type/tc_parser.rb +219 -0
- data/test/type/tc_unparser.rb +276 -0
- data/test/typing/tc_rubytype.rb +63 -0
- data/test/typing/tc_typing.rb +219 -0
- data/webpage/footer.html +5 -0
- data/webpage/generated_toc.js +319 -0
- data/webpage/header.html +14 -0
- data/webpage/images/logo.png +0 -0
- data/webpage/index.html +439 -0
- data/webpage/rubybreaker.css +53 -0
- metadata +119 -0
@@ -0,0 +1,276 @@
|
|
1
|
+
# This test verifies type unparser for RubyBreaker types.
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
require "test/unit"
|
5
|
+
require "#{dir}/../../lib/rubybreaker/type"
|
6
|
+
|
7
|
+
class UnparserTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include RubyBreaker
|
10
|
+
|
11
|
+
class A; end
|
12
|
+
class B; end
|
13
|
+
class C; end
|
14
|
+
class D; end
|
15
|
+
class E; end
|
16
|
+
|
17
|
+
def test_nil_type()
|
18
|
+
t1 = NilType.new
|
19
|
+
str1 = TypeUnparser.unparse(t1)
|
20
|
+
# puts str1
|
21
|
+
assert_equal("nil",str1.strip())
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_any_type()
|
25
|
+
t1 = AnyType.new
|
26
|
+
str1 = TypeUnparser.unparse(t1)
|
27
|
+
# puts str1
|
28
|
+
assert_equal("?",str1.strip())
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_nominal_type()
|
32
|
+
t1 = NominalType.new(A)
|
33
|
+
str1 = TypeUnparser.unparse(t1)
|
34
|
+
# puts str1
|
35
|
+
assert_equal("a",str1)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_self_type()
|
39
|
+
t1 = SelfType.new()
|
40
|
+
str1 = TypeUnparser.unparse(t1)
|
41
|
+
# puts str1
|
42
|
+
assert_equal("self", str1)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_opt_type()
|
46
|
+
t1 = NominalType.new(A)
|
47
|
+
t2 = OptionalType.new(t1)
|
48
|
+
str2 = TypeUnparser.unparse(t2)
|
49
|
+
# puts str1
|
50
|
+
assert_equal("a?",str2)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_opt_or_type()
|
54
|
+
t1 = NominalType.new(A)
|
55
|
+
t2 = NominalType.new(B)
|
56
|
+
t3 = OrType.new([t1, t2])
|
57
|
+
t4 = OptionalType.new(t3)
|
58
|
+
str4 = TypeUnparser.unparse(t4)
|
59
|
+
# puts str1
|
60
|
+
assert_equal("(a || b)?",str4)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_star_type()
|
64
|
+
t1 = NominalType.new(A)
|
65
|
+
t2 = VarLengthType.new(t1)
|
66
|
+
str2 = TypeUnparser.unparse(t2)
|
67
|
+
# puts str1
|
68
|
+
assert_equal("a*",str2)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_star_or_type()
|
72
|
+
t1 = NominalType.new(A)
|
73
|
+
t2 = NominalType.new(B)
|
74
|
+
t3 = OrType.new([t1, t2])
|
75
|
+
t4 = VarLengthType.new(t3)
|
76
|
+
str4 = TypeUnparser.unparse(t4)
|
77
|
+
# puts str1
|
78
|
+
assert_equal("(a || b)*",str4)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_duck_type()
|
82
|
+
t1 = DuckType.new(["+"])
|
83
|
+
str1 = TypeUnparser.unparse(t1)
|
84
|
+
# puts str1
|
85
|
+
assert_equal("[+]",str1)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_duck_type_more_meths()
|
89
|
+
t1 = DuckType.new(["+","foo","bar"])
|
90
|
+
str1 = TypeUnparser.unparse(t1)
|
91
|
+
#puts str1
|
92
|
+
assert_equal("[+, bar, foo]",str1)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_duck_type_symbolic_meths()
|
96
|
+
t1 = DuckType.new(["+","-","[]","[]="])
|
97
|
+
str1 = TypeUnparser.unparse(t1)
|
98
|
+
#puts str1
|
99
|
+
assert_equal("[+, -, [], []=]",str1)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_fusion_type()
|
103
|
+
t1 = FusionType.new(NominalType.new(A), ["+"])
|
104
|
+
str1 = TypeUnparser.unparse(t1)
|
105
|
+
# puts str1
|
106
|
+
assert_equal("a[+]",str1)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_fusion_type_more_meths()
|
110
|
+
t1 = FusionType.new(NominalType.new(A), ["+","foo","bar"])
|
111
|
+
str1 = TypeUnparser.unparse(t1)
|
112
|
+
# puts str1
|
113
|
+
assert_equal("a[+, bar, foo]",str1)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_fusion_type_symbolic_meths()
|
117
|
+
t1 = FusionType.new(NominalType.new(A), ["+","-","[]","[]="])
|
118
|
+
str1 = TypeUnparser.unparse(t1)
|
119
|
+
# puts str1
|
120
|
+
assert_equal("a[+, -, [], []=]",str1)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_or_type()
|
124
|
+
t1 = NominalType.new(A)
|
125
|
+
t2 = NominalType.new(B)
|
126
|
+
t3 = OrType.new([t1,t2])
|
127
|
+
str3 = TypeUnparser.unparse(t3)
|
128
|
+
# puts str3
|
129
|
+
assert_equal("a || b", str3)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_or_type_more_types()
|
133
|
+
t1 = NominalType.new(A)
|
134
|
+
t2 = NominalType.new(B)
|
135
|
+
t3 = NominalType.new(C)
|
136
|
+
t4 = OrType.new([t1,t2,t3])
|
137
|
+
str4 = TypeUnparser.unparse(t4)
|
138
|
+
# puts str3
|
139
|
+
assert_equal("a || b || c", str4)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_block_type_no_blk()
|
143
|
+
t1 = NominalType.new(A)
|
144
|
+
t2 = NominalType.new(B)
|
145
|
+
t3 = BlockType.new([t1],nil,t2)
|
146
|
+
str3 = TypeUnparser.unparse(t3)
|
147
|
+
# puts str3
|
148
|
+
assert_equal("|a| -> b",str3)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_block_type_more_args_no_blk()
|
152
|
+
t1 = NominalType.new(A)
|
153
|
+
t2 = NominalType.new(B)
|
154
|
+
t3 = NominalType.new(C)
|
155
|
+
t4 = BlockType.new([t1,t2],nil,t3)
|
156
|
+
str4 = TypeUnparser.unparse(t4)
|
157
|
+
# puts str3
|
158
|
+
assert_equal("|a, b| -> c",str4)
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_block_type_ret_self()
|
162
|
+
t1 = NominalType.new(A)
|
163
|
+
t2 = NominalType.new(B)
|
164
|
+
t3 = SelfType.new()
|
165
|
+
t4 = BlockType.new([t1,t2],nil,t3)
|
166
|
+
str4 = TypeUnparser.unparse(t4)
|
167
|
+
# puts str3
|
168
|
+
assert_equal("|a, b| -> self",str4)
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_block_type()
|
172
|
+
t1 = NominalType.new(A)
|
173
|
+
t2 = NominalType.new(B)
|
174
|
+
t3 = NominalType.new(C)
|
175
|
+
t4 = NominalType.new(D)
|
176
|
+
t5 = BlockType.new([t1],BlockType.new([t2],nil,t3),t4)
|
177
|
+
str5 = TypeUnparser.unparse(t5)
|
178
|
+
# puts str5
|
179
|
+
assert_equal("|a| {|b| -> c} -> d",str5)
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_block_type_more_args()
|
183
|
+
t1 = NominalType.new(A)
|
184
|
+
t2 = NominalType.new(B)
|
185
|
+
t3 = NominalType.new(C)
|
186
|
+
t4 = NominalType.new(D)
|
187
|
+
t5 = NominalType.new(E)
|
188
|
+
t6 = BlockType.new([t1,t2],BlockType.new([t3],nil,t4),t5)
|
189
|
+
str6 = TypeUnparser.unparse(t6)
|
190
|
+
# puts str5
|
191
|
+
assert_equal("|a, b| {|c| -> d} -> e",str6)
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_block_type_or_args()
|
195
|
+
t1 = NominalType.new(A)
|
196
|
+
t2 = NominalType.new(B)
|
197
|
+
t3 = NominalType.new(C)
|
198
|
+
t4 = NominalType.new(D)
|
199
|
+
t5 = NominalType.new(E)
|
200
|
+
t6 = BlockType.new([OrType.new([t1,t2])],BlockType.new([t3],nil,t4),t5)
|
201
|
+
str6 = TypeUnparser.unparse(t6)
|
202
|
+
# puts str5
|
203
|
+
assert_equal("|a || b| {|c| -> d} -> e",str6)
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_method_type_no_blk()
|
207
|
+
t1 = NominalType.new(A)
|
208
|
+
t2 = NominalType.new(B)
|
209
|
+
t3 = MethodType.new("m",[t1],nil,t2)
|
210
|
+
str3 = TypeUnparser.unparse(t3)
|
211
|
+
# puts str3
|
212
|
+
assert_equal("m(a) -> b", str3)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_method_type_symbolic_methname()
|
216
|
+
t1 = NominalType.new(A)
|
217
|
+
t2 = NominalType.new(B)
|
218
|
+
t3 = MethodType.new("==",[t1],nil,t2)
|
219
|
+
str3 = TypeUnparser.unparse(t3)
|
220
|
+
# puts str3
|
221
|
+
assert_equal("==(a) -> b", str3)
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_method_type_more_args_no_blk()
|
225
|
+
t1 = NominalType.new(A)
|
226
|
+
t2 = NominalType.new(B)
|
227
|
+
t3 = NominalType.new(C)
|
228
|
+
t4 = MethodType.new("m",[t1,t2],nil,t3)
|
229
|
+
str4 = TypeUnparser.unparse(t4)
|
230
|
+
# puts str3
|
231
|
+
assert_equal("m(a, b) -> c", str4)
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_method_type_ret_self()
|
235
|
+
t1 = NominalType.new(A)
|
236
|
+
t2 = NominalType.new(B)
|
237
|
+
t3 = SelfType.new()
|
238
|
+
t4 = MethodType.new("m",[t1,t2],nil,t3)
|
239
|
+
str4 = TypeUnparser.unparse(t4)
|
240
|
+
# puts str3
|
241
|
+
assert_equal("m(a, b) -> self", str4)
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_method_type_or_args_no_blk()
|
245
|
+
t1 = NominalType.new(A)
|
246
|
+
t2 = NominalType.new(B)
|
247
|
+
t3 = NominalType.new(C)
|
248
|
+
t4 = MethodType.new("m",[OrType.new([t1,t2])],nil,t3)
|
249
|
+
str4 = TypeUnparser.unparse(t4)
|
250
|
+
# puts str3
|
251
|
+
assert_equal("m(a || b) -> c", str4)
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_method_type_with_blk()
|
255
|
+
t1 = NominalType.new(A)
|
256
|
+
t2 = NominalType.new(B)
|
257
|
+
t3 = NominalType.new(C)
|
258
|
+
t4 = NominalType.new(D)
|
259
|
+
t5 = MethodType.new("m",[t1],BlockType.new([t2],nil,t3),t4)
|
260
|
+
str5 = TypeUnparser.unparse(t5)
|
261
|
+
# puts str5
|
262
|
+
assert_equal("m(a) {|b| -> c} -> d", str5)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_method_type_more_args_with_blk()
|
266
|
+
t1 = NominalType.new(A)
|
267
|
+
t2 = NominalType.new(B)
|
268
|
+
t3 = NominalType.new(C)
|
269
|
+
t4 = NominalType.new(D)
|
270
|
+
t5 = NominalType.new(E)
|
271
|
+
t6 = MethodType.new("m",[t1,t2],BlockType.new([t3],nil,t4),t5)
|
272
|
+
str6 = TypeUnparser.unparse(t6)
|
273
|
+
# puts str5
|
274
|
+
assert_equal("m(a, b) {|c| -> d} -> e", str6)
|
275
|
+
end
|
276
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
require "test/unit"
|
3
|
+
require "#{dir}/../../lib/rubybreaker/typing"
|
4
|
+
|
5
|
+
|
6
|
+
class RubyTypeTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
module M1
|
9
|
+
end
|
10
|
+
|
11
|
+
module M2
|
12
|
+
include M1
|
13
|
+
end
|
14
|
+
|
15
|
+
module M3
|
16
|
+
include M2
|
17
|
+
end
|
18
|
+
|
19
|
+
module M4
|
20
|
+
end
|
21
|
+
|
22
|
+
module M5
|
23
|
+
include M2
|
24
|
+
include M4
|
25
|
+
end
|
26
|
+
|
27
|
+
include RubyBreaker
|
28
|
+
|
29
|
+
def test_subclass_1
|
30
|
+
cls1 = Fixnum
|
31
|
+
cls2 = Numeric
|
32
|
+
assert(RubyTypeUtils.subclass_rel?(cls1,cls2))
|
33
|
+
assert(!RubyTypeUtils.subclass_rel?(cls2,cls1))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_subclass_2
|
37
|
+
cls1 = String
|
38
|
+
cls2 = Fixnum
|
39
|
+
assert(!RubyTypeUtils.subclass_rel?(cls1,cls2))
|
40
|
+
assert(!RubyTypeUtils.subclass_rel?(cls2,cls1))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_subclass_3
|
44
|
+
cls1 = Array
|
45
|
+
mod1 = Enumerable
|
46
|
+
assert(RubyTypeUtils.subclass_rel?(cls1,mod1))
|
47
|
+
assert(!RubyTypeUtils.submodule_rel?(mod1,cls1))
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_subclass_4
|
51
|
+
assert(!RubyTypeUtils.submodule_rel?(M1,M2))
|
52
|
+
assert(RubyTypeUtils.submodule_rel?(M2,M1))
|
53
|
+
assert(RubyTypeUtils.submodule_rel?(M3,M1))
|
54
|
+
assert(!RubyTypeUtils.submodule_rel?(M1,M3))
|
55
|
+
assert(RubyTypeUtils.submodule_rel?(M5,M1))
|
56
|
+
assert(RubyTypeUtils.submodule_rel?(M5,M2))
|
57
|
+
assert(!RubyTypeUtils.submodule_rel?(M5,M3))
|
58
|
+
assert(RubyTypeUtils.submodule_rel?(M5,M4))
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
require "test/unit"
|
3
|
+
require "#{dir}/../../lib/rubybreaker/type"
|
4
|
+
require "#{dir}/../../lib/rubybreaker/typing"
|
5
|
+
|
6
|
+
class TypingTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
include RubyBreaker
|
9
|
+
|
10
|
+
class A
|
11
|
+
include RubyBreaker::Broken
|
12
|
+
typesig("foo(fixnum) -> fixnum")
|
13
|
+
typesig("bar(fixnum) {|fixnum| -> string} -> string")
|
14
|
+
typesig("baz(fixnum, string?) -> fixnum")
|
15
|
+
typesig("bazz(fixnum, string*) -> fixnum")
|
16
|
+
end
|
17
|
+
|
18
|
+
# This function is a helper to compose an error message for subtyping
|
19
|
+
# test.
|
20
|
+
def msg(lhs,rhs,should_fail=false)
|
21
|
+
subtype = lhs.unparse()
|
22
|
+
supertype = rhs.unparse()
|
23
|
+
str = "#{subtype} <: #{supertype}"
|
24
|
+
if should_fail
|
25
|
+
str = str + " did not fail"
|
26
|
+
else
|
27
|
+
str = str + " failed"
|
28
|
+
end
|
29
|
+
return str
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_any()
|
33
|
+
t1 = AnyType.new
|
34
|
+
t2 = NilType.new
|
35
|
+
assert(t1.subtype_of?(t2), msg(t1,t2))
|
36
|
+
assert(!t2.subtype_of?(t1), msg(t2,t1,true))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_nil()
|
40
|
+
t1 = NilType.new
|
41
|
+
t2 = NilType.new
|
42
|
+
t3 = NominalType.new(Fixnum)
|
43
|
+
assert(t1.subtype_of?(t2), msg(t1,t2))
|
44
|
+
assert(t2.subtype_of?(t1), msg(t1,t2))
|
45
|
+
assert(!t3.subtype_of?(t2), msg(t3,t2,true))
|
46
|
+
assert(!t2.subtype_of?(t3), msg(t3,t2,true))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_nominal()
|
50
|
+
t1 = NominalType.new(Fixnum)
|
51
|
+
t2 = NominalType.new(Numeric)
|
52
|
+
t3 = NominalType.new(Object)
|
53
|
+
t4 = NominalType.new(String)
|
54
|
+
assert(t1.subtype_of?(t2), msg(t1,t2))
|
55
|
+
assert(!t2.subtype_of?(t1), msg(t2,t1,true))
|
56
|
+
assert(t1.subtype_of?(t3), msg(t1,t3))
|
57
|
+
assert(!t3.subtype_of?(t1), msg(t3,t1,true))
|
58
|
+
assert(!t1.subtype_of?(t4), msg(t1,t4,true))
|
59
|
+
assert(!t4.subtype_of?(t1), msg(t4,t1,true))
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_self()
|
63
|
+
SelfType.set_self(Fixnum)
|
64
|
+
t1 = SelfType.new()
|
65
|
+
t2 = SelfType.new()
|
66
|
+
SelfType.set_self(String)
|
67
|
+
t3 = SelfType.new()
|
68
|
+
t4 = NominalType.new(Numeric)
|
69
|
+
t5 = NominalType.new(String)
|
70
|
+
t6 = DuckType.new([:to_s])
|
71
|
+
assert(t1.subtype_of?(t2), msg(t1,t2))
|
72
|
+
assert(t2.subtype_of?(t1), msg(t2,t1))
|
73
|
+
assert(t1.subtype_of?(t3), msg(t1, t3))
|
74
|
+
assert(t3.subtype_of?(t1), msg(t3, t1))
|
75
|
+
assert(t1.subtype_of?(t4), msg(t1, t4))
|
76
|
+
assert(!t4.subtype_of?(t1), msg(t4, t1, true))
|
77
|
+
assert(!t1.subtype_of?(t5), msg(t1, t5, true))
|
78
|
+
assert(!t5.subtype_of?(t1), msg(t5, t1, true))
|
79
|
+
assert(t1.subtype_of?(t6), msg(t1, t5))
|
80
|
+
assert(!t6.subtype_of?(t1), msg(t5, t1, true))
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_duck_types_id()
|
84
|
+
t1 = DuckType.new([:foo,:baz])
|
85
|
+
t2 = DuckType.new([:baz,:foo])
|
86
|
+
assert(t1.subtype_of?(t2),msg(t1,t2))
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_duck_types()
|
90
|
+
t1 = DuckType.new([:foo,:bar,:baz])
|
91
|
+
t2 = DuckType.new([:foo,:baz])
|
92
|
+
assert(t1.subtype_of?(t2),msg(t1,t2))
|
93
|
+
assert(!t2.subtype_of?(t1),msg(t2,t1,true))
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_fusion_types()
|
97
|
+
t1 = FusionType.new(NominalType.new(Fixnum), [:to_s, :to_f])
|
98
|
+
t2 = FusionType.new(NominalType.new(Fixnum), [:to_f, :to_s])
|
99
|
+
t3 = FusionType.new(NominalType.new(String), [:to_s, :to_f])
|
100
|
+
assert(t1.subtype_of?(t2), msg(t1, t2))
|
101
|
+
assert(t2.subtype_of?(t1), msg(t1, t2))
|
102
|
+
# XXX: The following assert will succeed because Fixnum and String are
|
103
|
+
# not Broken at this point.
|
104
|
+
assert(t1.subtype_of?(t3), msg(t1, t3, true))
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_duck_fusion_types()
|
108
|
+
t1 = DuckType.new([:to_s, :to_f])
|
109
|
+
t2 = FusionType.new(NominalType.new(Fixnum), [:to_f, :to_s])
|
110
|
+
# Again, this works because Fixnum is not Broken yet
|
111
|
+
assert(t1.subtype_of?(t2), msg(t1, t2))
|
112
|
+
assert(t2.subtype_of?(t1), msg(t1, t2))
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_duck_nominal_types()
|
116
|
+
t1 = DuckType.new([:to_s, :to_f])
|
117
|
+
t2 = NominalType.new(Fixnum)
|
118
|
+
t3 = NominalType.new(Symbol)
|
119
|
+
assert(!t1.subtype_of?(t2), msg(t1, t2, true))
|
120
|
+
assert(!t1.subtype_of?(t3), msg(t1, t3, true))
|
121
|
+
assert(t2.subtype_of?(t1), msg(t2, t1))
|
122
|
+
assert(!t3.subtype_of?(t1), msg(t3, t1, true))
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_nominal_and_other_types()
|
126
|
+
t1 = NominalType.new(Fixnum)
|
127
|
+
t2 = FusionType.new(NominalType.new(Fixnum), [:to_s, :to_f])
|
128
|
+
t3 = FusionType.new(NominalType.new(String), [:to_s, :to_f])
|
129
|
+
t4 = DuckType.new([:to_s, :to_f])
|
130
|
+
t5 = DuckType.new([:to_s, :to_f, :foo])
|
131
|
+
assert(t1.subtype_of?(t2), msg(t1, t2))
|
132
|
+
assert(!t2.subtype_of?(t1), msg(t2, t1, true))
|
133
|
+
assert(t1.subtype_of?(t3), msg(t1, t3))
|
134
|
+
assert(!t3.subtype_of?(t1), msg(t3, t1, true))
|
135
|
+
assert(t1.subtype_of?(t4), msg(t1, t4))
|
136
|
+
assert(!t4.subtype_of?(t1), msg(t4, t1, true))
|
137
|
+
assert(!t1.subtype_of?(t5), msg(t1, t5, true))
|
138
|
+
assert(!t5.subtype_of?(t1), msg(t5, t1, true))
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_blk_types_id()
|
142
|
+
t1 = NominalType.new(Fixnum)
|
143
|
+
t2 = NominalType.new(String)
|
144
|
+
t3 = BlockType.new([t1],nil,t2)
|
145
|
+
t4 = BlockType.new([t1],nil,t2)
|
146
|
+
assert(t3.subtype_of?(t4),msg(t3,t4))
|
147
|
+
assert(t4.subtype_of?(t3),msg(t4,t3))
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_blk_types_no_blk_ret_type_diff()
|
151
|
+
t1 = NominalType.new(Fixnum)
|
152
|
+
t2 = NominalType.new(String)
|
153
|
+
t3 = NominalType.new(Fixnum)
|
154
|
+
t4 = NominalType.new(Object)
|
155
|
+
t5 = BlockType.new([t1],nil,t2)
|
156
|
+
t6 = BlockType.new([t3],nil,t4)
|
157
|
+
assert(t5.subtype_of?(t6),msg(t5,t6))
|
158
|
+
assert(!t6.subtype_of?(t5),msg(t6,t5,true))
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_blk_types_no_blk_one_arg()
|
162
|
+
t1 = NominalType.new(Object)
|
163
|
+
t2 = NominalType.new(String)
|
164
|
+
t3 = NominalType.new(Fixnum)
|
165
|
+
t4 = NominalType.new(Object)
|
166
|
+
t5 = BlockType.new([t1],nil,t2)
|
167
|
+
t6 = BlockType.new([t3],nil,t4)
|
168
|
+
assert(t5.subtype_of?(t6),msg(t5,t6))
|
169
|
+
assert(!t6.subtype_of?(t5),msg(t6,t5,true))
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_blk_types_no_blk_opt_arg()
|
173
|
+
t1 = OptionalType.new(NominalType.new(Object))
|
174
|
+
t2 = NominalType.new(String)
|
175
|
+
t3 = NominalType.new(Fixnum)
|
176
|
+
t4 = NominalType.new(Object)
|
177
|
+
t5 = BlockType.new([t1],nil,t2)
|
178
|
+
t6 = BlockType.new([t3],nil,t4)
|
179
|
+
assert(t5.subtype_of?(t6),msg(t5,t6))
|
180
|
+
assert(!t6.subtype_of?(t5),msg(t6,t5,true))
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_blk_types_no_blk_both_opt_arg()
|
184
|
+
t1 = OptionalType.new(NominalType.new(Object))
|
185
|
+
t2 = NominalType.new(String)
|
186
|
+
t3 = OptionalType.new(NominalType.new(Fixnum))
|
187
|
+
t4 = NominalType.new(Object)
|
188
|
+
t5 = BlockType.new([t1],nil,t2)
|
189
|
+
t6 = BlockType.new([t3],nil,t4)
|
190
|
+
assert(t5.subtype_of?(t6),msg(t5,t6))
|
191
|
+
assert(!t6.subtype_of?(t5),msg(t6,t5,true))
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_blk_types_no_blk_varlen_arg()
|
195
|
+
t1 = VarLengthType.new(NominalType.new(Object))
|
196
|
+
t2 = NominalType.new(String)
|
197
|
+
t3 = NominalType.new(Fixnum)
|
198
|
+
t4 = NominalType.new(Object)
|
199
|
+
t5 = BlockType.new([t1],nil,t2)
|
200
|
+
t6 = BlockType.new([t3],nil,t4)
|
201
|
+
assert(t5.subtype_of?(t6),msg(t5,t6))
|
202
|
+
assert(!t6.subtype_of?(t5),msg(t6,t5,true))
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_blk_types_no_blk_both_varlen_arg()
|
206
|
+
t1 = VarLengthType.new(NominalType.new(Object))
|
207
|
+
t2 = NominalType.new(String)
|
208
|
+
t3 = VarLengthType.new(NominalType.new(Fixnum))
|
209
|
+
t4 = NominalType.new(Object)
|
210
|
+
t5 = BlockType.new([t1],nil,t2)
|
211
|
+
t6 = BlockType.new([t3],nil,t4)
|
212
|
+
assert(t5.subtype_of?(t6),msg(t5,t6))
|
213
|
+
assert(!t6.subtype_of?(t5),msg(t6,t5,true))
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_broken_nominal()
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|