typed.rb 0.0.11
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 +7 -0
- data/Rakefile +26 -0
- data/bin/typed.rb +110 -0
- data/lib/typed/language.rb +131 -0
- data/lib/typed/model/tm_abs.rb +104 -0
- data/lib/typed/model/tm_array_literal.rb +25 -0
- data/lib/typed/model/tm_boolean.rb +15 -0
- data/lib/typed/model/tm_boolean_operator.rb +34 -0
- data/lib/typed/model/tm_break.rb +24 -0
- data/lib/typed/model/tm_case_when.rb +38 -0
- data/lib/typed/model/tm_class.rb +63 -0
- data/lib/typed/model/tm_const.rb +29 -0
- data/lib/typed/model/tm_defined.rb +19 -0
- data/lib/typed/model/tm_error.rb +16 -0
- data/lib/typed/model/tm_float.rb +15 -0
- data/lib/typed/model/tm_for.rb +42 -0
- data/lib/typed/model/tm_fun.rb +165 -0
- data/lib/typed/model/tm_global_var.rb +22 -0
- data/lib/typed/model/tm_global_var_assignment.rb +20 -0
- data/lib/typed/model/tm_hash_literal.rb +32 -0
- data/lib/typed/model/tm_if_else.rb +24 -0
- data/lib/typed/model/tm_instance_var.rb +23 -0
- data/lib/typed/model/tm_instance_var_assignment.rb +32 -0
- data/lib/typed/model/tm_int.rb +15 -0
- data/lib/typed/model/tm_local_var_asgn.rb +35 -0
- data/lib/typed/model/tm_mass_asgn.rb +60 -0
- data/lib/typed/model/tm_mlhs.rb +87 -0
- data/lib/typed/model/tm_module.rb +51 -0
- data/lib/typed/model/tm_next.rb +24 -0
- data/lib/typed/model/tm_nil.rb +14 -0
- data/lib/typed/model/tm_range_literal.rb +30 -0
- data/lib/typed/model/tm_regexp.rb +27 -0
- data/lib/typed/model/tm_rescue.rb +27 -0
- data/lib/typed/model/tm_return.rb +24 -0
- data/lib/typed/model/tm_s_class.rb +30 -0
- data/lib/typed/model/tm_self.rb +22 -0
- data/lib/typed/model/tm_send.rb +300 -0
- data/lib/typed/model/tm_sequencing.rb +53 -0
- data/lib/typed/model/tm_string.rb +15 -0
- data/lib/typed/model/tm_string_interpolation.rb +21 -0
- data/lib/typed/model/tm_super.rb +27 -0
- data/lib/typed/model/tm_symbol.rb +15 -0
- data/lib/typed/model/tm_symbol_interpolation.rb +21 -0
- data/lib/typed/model/tm_try.rb +29 -0
- data/lib/typed/model/tm_var.rb +28 -0
- data/lib/typed/model/tm_while.rb +43 -0
- data/lib/typed/model.rb +48 -0
- data/lib/typed/prelude.rb +939 -0
- data/lib/typed/prelude_existential_registry.bin +0 -0
- data/lib/typed/prelude_generic_registry.bin +0 -0
- data/lib/typed/prelude_registry.bin +0 -0
- data/lib/typed/runtime/ast_parser.rb +589 -0
- data/lib/typed/runtime/method_signature_processor.rb +72 -0
- data/lib/typed/runtime/normalization/validations.rb +47 -0
- data/lib/typed/runtime/normalization.rb +196 -0
- data/lib/typed/runtime/parser_context.rb +36 -0
- data/lib/typed/runtime/type_parser.rb +215 -0
- data/lib/typed/runtime/type_registry.rb +170 -0
- data/lib/typed/runtime/type_signature_processor.rb +34 -0
- data/lib/typed/runtime.rb +33 -0
- data/lib/typed/type_signature/parser.rb +240 -0
- data/lib/typed/types/polymorphism/existential_type_variable.rb +13 -0
- data/lib/typed/types/polymorphism/generic_comparisons.rb +134 -0
- data/lib/typed/types/polymorphism/generic_variables.rb +24 -0
- data/lib/typed/types/polymorphism/type_variable.rb +138 -0
- data/lib/typed/types/polymorphism/type_variable_register.rb +298 -0
- data/lib/typed/types/polymorphism/unification.rb +579 -0
- data/lib/typed/types/ty_boolean.rb +15 -0
- data/lib/typed/types/ty_dynamic.rb +39 -0
- data/lib/typed/types/ty_either.rb +168 -0
- data/lib/typed/types/ty_error.rb +18 -0
- data/lib/typed/types/ty_existential_type.rb +22 -0
- data/lib/typed/types/ty_function.rb +144 -0
- data/lib/typed/types/ty_generic_function.rb +115 -0
- data/lib/typed/types/ty_generic_object.rb +180 -0
- data/lib/typed/types/ty_generic_singleton_object.rb +238 -0
- data/lib/typed/types/ty_object.rb +256 -0
- data/lib/typed/types/ty_singleton_object.rb +78 -0
- data/lib/typed/types/ty_stack_jump.rb +44 -0
- data/lib/typed/types/ty_top_level_object.rb +38 -0
- data/lib/typed/types.rb +60 -0
- data/lib/typed/typing_context.rb +206 -0
- data/lib/typed/version.rb +3 -0
- data/lib/typed.rb +161 -0
- data/spec/lib/ast_parser_spec.rb +101 -0
- data/spec/lib/examples/animals.rb +44 -0
- data/spec/lib/examples/counter.rb +16 -0
- data/spec/lib/examples/if.rb +31 -0
- data/spec/lib/language_spec.rb +36 -0
- data/spec/lib/model/tm_abs_spec.rb +66 -0
- data/spec/lib/model/tm_array_literal_spec.rb +36 -0
- data/spec/lib/model/tm_case_when_spec.rb +39 -0
- data/spec/lib/model/tm_class_spec.rb +67 -0
- data/spec/lib/model/tm_defined_spec.rb +10 -0
- data/spec/lib/model/tm_for_spec.rb +150 -0
- data/spec/lib/model/tm_fun_spec.rb +11 -0
- data/spec/lib/model/tm_hash_literal_spec.rb +40 -0
- data/spec/lib/model/tm_mass_asgn_spec.rb +104 -0
- data/spec/lib/model/tm_module_spec.rb +42 -0
- data/spec/lib/model/tm_regexp_spec.rb +9 -0
- data/spec/lib/model/tm_return_spec.rb +47 -0
- data/spec/lib/model/tm_s_class_spec.rb +27 -0
- data/spec/lib/model/tm_self_spec.rb +19 -0
- data/spec/lib/model/tm_string_interpolation_spec.rb +10 -0
- data/spec/lib/model/tm_symbol_interpolation_spec.rb +10 -0
- data/spec/lib/model/tm_symbol_spec.rb +9 -0
- data/spec/lib/model/tm_while_spec.rb +141 -0
- data/spec/lib/polymorphism/type_variable_spec.rb +14 -0
- data/spec/lib/polymorphism/unification_spec.rb +328 -0
- data/spec/lib/prelude/array_spec.rb +263 -0
- data/spec/lib/prelude/class_spec.rb +12 -0
- data/spec/lib/prelude/enumerable_spec.rb +278 -0
- data/spec/lib/prelude/enumerator_spec.rb +101 -0
- data/spec/lib/prelude/hash_spec.rb +361 -0
- data/spec/lib/prelude/kernel_spec.rb +23 -0
- data/spec/lib/prelude/object_spec.rb +22 -0
- data/spec/lib/prelude/pair_spec.rb +16 -0
- data/spec/lib/prelude/showable_spec.rb +31 -0
- data/spec/lib/prelude/string_spec.rb +98 -0
- data/spec/lib/runtime/normalization_spec.rb +29 -0
- data/spec/lib/runtime/validations_spec.rb +56 -0
- data/spec/lib/runtime_spec.rb +503 -0
- data/spec/lib/type_signature/parser_spec.rb +239 -0
- data/spec/lib/types/comparisons_spec.rb +35 -0
- data/spec/lib/types/polymorphism/generic_comparisons_spec.rb +492 -0
- data/spec/lib/types/polymorphism/type_variable_register_spec.rb +128 -0
- data/spec/lib/types/ty_dynamic_spec.rb +103 -0
- data/spec/lib/types/ty_either_spec.rb +288 -0
- data/spec/lib/types/ty_error_spec.rb +18 -0
- data/spec/lib/types/ty_generic_object_spec.rb +78 -0
- data/spec/lib/types/ty_generic_singleton_object_spec.rb +288 -0
- data/spec/lib/types/typing_context_spec.rb +86 -0
- data/spec/lib/types_spec.rb +174 -0
- data/spec/lib/typing/boolean_asgn_spec.rb +134 -0
- data/spec/lib/typing/break_spec.rb +79 -0
- data/spec/lib/typing/generics_spec.rb +191 -0
- data/spec/lib/typing/instance_vars_spec.rb +103 -0
- data/spec/lib/typing/next_spec.rb +29 -0
- data/spec/lib/typing/op_asgn_spec.rb +104 -0
- data/spec/lib/typing/overriden_methods_spec.rb +31 -0
- data/spec/lib/typing/subtyping_spec.rb +112 -0
- data/spec/lib/typing/tm_boolean_operator_spec.rb +100 -0
- data/spec/lib/typing/tm_boolean_spec.rb +61 -0
- data/spec/lib/typing/tm_const_spec.rb +28 -0
- data/spec/lib/typing/tm_defined_spec.rb +12 -0
- data/spec/lib/typing/tm_fun_spec.rb +347 -0
- data/spec/lib/typing/tm_global_var_spec.rb +33 -0
- data/spec/lib/typing/tm_if_else_spec.rb +104 -0
- data/spec/lib/typing/tm_ignore_spec.rb +24 -0
- data/spec/lib/typing/tm_instance_vars_spec.rb +117 -0
- data/spec/lib/typing/tm_local_var_asgn_spec.rb +134 -0
- data/spec/lib/typing/tm_mlhs_spec.rb +164 -0
- data/spec/lib/typing/tm_module_spec.rb +89 -0
- data/spec/lib/typing/tm_raise_spec.rb +31 -0
- data/spec/lib/typing/tm_range_literal_spec.rb +25 -0
- data/spec/lib/typing/tm_regexp_spec.rb +14 -0
- data/spec/lib/typing/tm_return_spec.rb +45 -0
- data/spec/lib/typing/tm_send_casting_spec.rb +26 -0
- data/spec/lib/typing/tm_send_class_methods_spec.rb +42 -0
- data/spec/lib/typing/tm_send_generic_apply_spec.rb +103 -0
- data/spec/lib/typing/tm_send_generic_methods_spec.rb +77 -0
- data/spec/lib/typing/tm_send_initialize_spec.rb +68 -0
- data/spec/lib/typing/tm_send_lambda_spec.rb +135 -0
- data/spec/lib/typing/tm_send_spec.rb +217 -0
- data/spec/lib/typing/tm_send_yield_block_spec.rb +308 -0
- data/spec/lib/typing/tm_sequencing_spec.rb +174 -0
- data/spec/lib/typing/tm_string_interpolation_spec.rb +19 -0
- data/spec/lib/typing/tm_super_spec.rb +63 -0
- data/spec/lib/typing/tm_symbol_interpolation_spec.rb +19 -0
- data/spec/lib/typing/tm_symbol_spec.rb +14 -0
- data/spec/lib/typing/tm_try_spec.rb +73 -0
- data/spec/spec_helper.rb +140 -0
- metadata +216 -0
@@ -0,0 +1,308 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmSend do
|
4
|
+
let(:language) { TypedRb::Language.new }
|
5
|
+
|
6
|
+
context 'with a yield blocking function' do
|
7
|
+
it 'type-checks correctly the block yielding and the block passing' do
|
8
|
+
expr = <<__END
|
9
|
+
ts '#wblock1 / Integer -> &(Integer -> Integer) -> Integer'
|
10
|
+
def wblock1(x)
|
11
|
+
yield x
|
12
|
+
end
|
13
|
+
|
14
|
+
wblock1(2) { |n| n + 1 }
|
15
|
+
__END
|
16
|
+
|
17
|
+
result = language.check(expr)
|
18
|
+
expect(result).to eq(tyinteger)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'type-checks correctly errors in the block arguments application' do
|
22
|
+
expr = <<__END
|
23
|
+
ts '#wblock2 / Integer -> &(Integer -> Integer) -> Integer'
|
24
|
+
def wblock2(x)
|
25
|
+
yield x
|
26
|
+
end
|
27
|
+
lambda {
|
28
|
+
wblock2('2') { |n| n + 1 }
|
29
|
+
}
|
30
|
+
__END
|
31
|
+
|
32
|
+
expect {
|
33
|
+
language.check(expr)
|
34
|
+
}.to raise_error(TypedRb::TypeCheckError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'type-checks correctly errors in the block arguments type' do
|
38
|
+
expr = <<__END
|
39
|
+
class Integer
|
40
|
+
ts '#+ / Integer -> Integer'
|
41
|
+
end
|
42
|
+
|
43
|
+
ts '#wblock3 / Integer -> &(Integer -> Integer) -> Integer'
|
44
|
+
def wblock3(x)
|
45
|
+
yield x
|
46
|
+
end
|
47
|
+
lambda {
|
48
|
+
wblock3(2) { |n| n + '1' }
|
49
|
+
}
|
50
|
+
__END
|
51
|
+
|
52
|
+
expect {
|
53
|
+
language.check(expr)
|
54
|
+
}.to raise_error(TypedRb::TypeCheckError)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'type-checks correctly errors in the block return type' do
|
58
|
+
expr = <<__END
|
59
|
+
ts '#wblock4 / Integer -> &(Integer -> Integer) -> Integer'
|
60
|
+
def wblock4(x)
|
61
|
+
yield x
|
62
|
+
end
|
63
|
+
|
64
|
+
wblock4(2) { |n| '1' }
|
65
|
+
__END
|
66
|
+
|
67
|
+
expect {
|
68
|
+
language.check(expr)
|
69
|
+
}.to raise_error(TypedRb::TypeCheckError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'type-checks block-passing args' do
|
73
|
+
expr = <<__CODE
|
74
|
+
|
75
|
+
ts '#f / &(Integer -> String) -> String'
|
76
|
+
def f(&b)
|
77
|
+
b[1]
|
78
|
+
end
|
79
|
+
|
80
|
+
p = Proc.new { |arg| 'string' }
|
81
|
+
|
82
|
+
f(&p)
|
83
|
+
__CODE
|
84
|
+
|
85
|
+
result = language.check(expr)
|
86
|
+
|
87
|
+
expect(result.ruby_type).to eq(String)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'captures errors type-checking block-passing args' do
|
91
|
+
|
92
|
+
expr = <<__CODE
|
93
|
+
|
94
|
+
ts '#f / &(Integer -> String) -> String'
|
95
|
+
def f(&b)
|
96
|
+
b[1]
|
97
|
+
end
|
98
|
+
|
99
|
+
p = Proc.new { |arg| 0 }
|
100
|
+
|
101
|
+
f(&p)
|
102
|
+
__CODE
|
103
|
+
|
104
|
+
expect {
|
105
|
+
language.check(expr)
|
106
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'captures errors type-checking block-passing args' do
|
111
|
+
|
112
|
+
expr = <<__CODE
|
113
|
+
|
114
|
+
ts '#f / &(Integer -> String) -> Integer'
|
115
|
+
def f(&b)
|
116
|
+
b[1]
|
117
|
+
end
|
118
|
+
|
119
|
+
p = Proc.new { |arg| 'string' }
|
120
|
+
|
121
|
+
f(&p)
|
122
|
+
__CODE
|
123
|
+
|
124
|
+
expect {
|
125
|
+
language.check(expr)
|
126
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'type-checks yielded block-passing args' do
|
131
|
+
expr = <<__CODE
|
132
|
+
|
133
|
+
ts '#f / &(Integer -> String) -> String'
|
134
|
+
def f(&b)
|
135
|
+
yield 1
|
136
|
+
end
|
137
|
+
|
138
|
+
p = Proc.new { |arg| 'string' }
|
139
|
+
|
140
|
+
f(&p)
|
141
|
+
__CODE
|
142
|
+
|
143
|
+
result = language.check(expr)
|
144
|
+
|
145
|
+
expect(result.ruby_type).to eq(String)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'type-checks yielded blocks' do
|
149
|
+
expr = <<__CODE
|
150
|
+
|
151
|
+
ts '#f / &(Integer -> String) -> String'
|
152
|
+
def f(&b)
|
153
|
+
yield 1
|
154
|
+
end
|
155
|
+
|
156
|
+
f { |arg| 'string' }
|
157
|
+
__CODE
|
158
|
+
|
159
|
+
result = language.check(expr)
|
160
|
+
|
161
|
+
expect(result.ruby_type).to eq(String)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'captures errors in yielded type-checking block-passing args' do
|
165
|
+
|
166
|
+
expr = <<__CODE
|
167
|
+
|
168
|
+
ts '#f / &(Integer -> String) -> String'
|
169
|
+
def f(&b)
|
170
|
+
yield 1
|
171
|
+
end
|
172
|
+
|
173
|
+
p = Proc.new { |arg| 0 }
|
174
|
+
|
175
|
+
f(&p)
|
176
|
+
__CODE
|
177
|
+
|
178
|
+
expect {
|
179
|
+
language.check(expr)
|
180
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'captures errors in yielded type-checking blocks' do
|
185
|
+
|
186
|
+
expr = <<__CODE
|
187
|
+
|
188
|
+
ts '#f / &(Integer -> String) -> String'
|
189
|
+
def f(&b)
|
190
|
+
yield 1
|
191
|
+
end
|
192
|
+
|
193
|
+
f { |arg| 0 }
|
194
|
+
__CODE
|
195
|
+
|
196
|
+
expect {
|
197
|
+
language.check(expr)
|
198
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'captures errors yielded type-checking block-passing args' do
|
203
|
+
|
204
|
+
expr = <<__CODE
|
205
|
+
|
206
|
+
ts '#f / &(Integer -> String) -> Integer'
|
207
|
+
def f(&b)
|
208
|
+
yield 1
|
209
|
+
end
|
210
|
+
|
211
|
+
p = Proc.new { |arg| 'string' }
|
212
|
+
|
213
|
+
f(&p)
|
214
|
+
__CODE
|
215
|
+
|
216
|
+
expect {
|
217
|
+
language.check(expr)
|
218
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'type-checks symbol.to_proc converted arguments' do
|
223
|
+
expr = <<__CODE
|
224
|
+
class TStP1
|
225
|
+
ts '#test / -> String'
|
226
|
+
def test
|
227
|
+
'string'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
ts '#ftstp1 / TStP1 -> &(TStP1 -> String) -> String'
|
232
|
+
def ftstp1(obj, &b)
|
233
|
+
yield obj
|
234
|
+
end
|
235
|
+
|
236
|
+
ftstp1(TStP1.new, &:test)
|
237
|
+
__CODE
|
238
|
+
|
239
|
+
result = language.check(expr)
|
240
|
+
expect(result.ruby_type).to eq(String)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'type-checks symbol.to_proc converted arguments for generic functions' do
|
244
|
+
expr = <<__CODE
|
245
|
+
class TStP1g
|
246
|
+
ts '#test / -> String'
|
247
|
+
def test
|
248
|
+
'string'
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
ts '#ftstp1g[T] / [T] -> &([T] -> String) -> String'
|
253
|
+
def ftstp1g(obj, &b)
|
254
|
+
yield obj
|
255
|
+
end
|
256
|
+
|
257
|
+
ftstp1g(TStP1g.new, &:test)
|
258
|
+
__CODE
|
259
|
+
|
260
|
+
result = language.check(expr)
|
261
|
+
expect(result.ruby_type).to eq(String)
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'type-checks symbol.to_proc converted arguments for generic functions, negative case' do
|
265
|
+
expr = <<__CODE
|
266
|
+
class TStP1gn
|
267
|
+
ts '#test / -> Integer'
|
268
|
+
def test
|
269
|
+
1
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
ts '#ftstp1gn[T] / [T] -> &([T] -> String) -> String'
|
274
|
+
def ftstp1gn(obj, &b)
|
275
|
+
yield obj
|
276
|
+
end
|
277
|
+
|
278
|
+
ftstp1gn(TStP1gn.new, &:test)
|
279
|
+
__CODE
|
280
|
+
|
281
|
+
expect {
|
282
|
+
language.check(expr)
|
283
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'captures errors in the application of symbol.to_proc converted arguments' do
|
287
|
+
expr = <<__CODE
|
288
|
+
class TStP2
|
289
|
+
ts '#test / -> String'
|
290
|
+
def test
|
291
|
+
'string'
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
ts '#ftstp2 / TStP2 -> &(TStP2 -> Integer) -> Integer'
|
296
|
+
def ftstp2(obj, &b)
|
297
|
+
yield obj
|
298
|
+
end
|
299
|
+
|
300
|
+
ftstp2(TStP2.new, &:test)
|
301
|
+
__CODE
|
302
|
+
|
303
|
+
expect {
|
304
|
+
language.check(expr)
|
305
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmSequencing do
|
4
|
+
it 'parses sequencing instructions without return type' do
|
5
|
+
code = <<__CODE
|
6
|
+
1
|
7
|
+
2
|
8
|
+
'string'
|
9
|
+
__CODE
|
10
|
+
|
11
|
+
parsed = TypedRb::Language.new.check(code)
|
12
|
+
expect(parsed.ruby_type).to eq(String)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'parses sequencing instructions with return type' do
|
16
|
+
code = <<__CODE
|
17
|
+
ts '#st1 / -> String'
|
18
|
+
def st1
|
19
|
+
return 'string'
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
st1
|
24
|
+
__CODE
|
25
|
+
|
26
|
+
parsed = TypedRb::Language.new.check(code)
|
27
|
+
expect(parsed.ruby_type).to eq(String)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'parses sequencing instructions with multiple return types' do
|
31
|
+
code = <<__CODE
|
32
|
+
ts '#st2 / -> Numeric'
|
33
|
+
def st2
|
34
|
+
return 1
|
35
|
+
return Numeric.new
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
st2
|
40
|
+
__CODE
|
41
|
+
|
42
|
+
parsed = TypedRb::Language.new.check(code)
|
43
|
+
expect(parsed.ruby_type).to eq(Numeric)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'parses sequencing instructions with multiple return types and dynamic objects' do
|
47
|
+
code = <<__CODE
|
48
|
+
ts '#st2 / -> Numeric'
|
49
|
+
def st2
|
50
|
+
return 1
|
51
|
+
return dynamic
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
st2
|
56
|
+
__CODE
|
57
|
+
|
58
|
+
parsed = TypedRb::Language.new.check(code)
|
59
|
+
expect(parsed.ruby_type).to eq(Numeric)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'parses sequencing instructions with nested nodes' do
|
63
|
+
code = <<__CODE
|
64
|
+
ts '#st3 / -> Boolean'
|
65
|
+
def st3
|
66
|
+
if true
|
67
|
+
1
|
68
|
+
true
|
69
|
+
else
|
70
|
+
'string'
|
71
|
+
false
|
72
|
+
end
|
73
|
+
0
|
74
|
+
return true
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
st3
|
79
|
+
__CODE
|
80
|
+
|
81
|
+
parsed = TypedRb::Language.new.check(code)
|
82
|
+
expect(parsed.class).to eq(TypedRb::Types::TyBoolean)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'parses sequencing instructions with either types, positive case' do
|
86
|
+
code = <<__CODE
|
87
|
+
ts '#st3 / -> Boolean'
|
88
|
+
def st3
|
89
|
+
if true
|
90
|
+
1
|
91
|
+
return true
|
92
|
+
else
|
93
|
+
'string'
|
94
|
+
false
|
95
|
+
end
|
96
|
+
0
|
97
|
+
true
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
|
101
|
+
st3
|
102
|
+
__CODE
|
103
|
+
|
104
|
+
parsed = TypedRb::Language.new.check(code)
|
105
|
+
expect(parsed.class).to eq(TypedRb::Types::TyBoolean)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'parses sequencing instructions with either types, negative case' do
|
109
|
+
code = <<__CODE
|
110
|
+
ts '#st3 / -> Boolean'
|
111
|
+
def st3
|
112
|
+
if true
|
113
|
+
1
|
114
|
+
return 2.0
|
115
|
+
else
|
116
|
+
'string'
|
117
|
+
false
|
118
|
+
end
|
119
|
+
0
|
120
|
+
true
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
124
|
+
st3
|
125
|
+
__CODE
|
126
|
+
|
127
|
+
expect {
|
128
|
+
TypedRb::Language.new.check(code)
|
129
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'parses sequencing instructions with either types, negative case2' do
|
133
|
+
code = <<__CODE
|
134
|
+
ts '#st3 / -> Boolean'
|
135
|
+
def st3
|
136
|
+
if true
|
137
|
+
1
|
138
|
+
return 2.0
|
139
|
+
else
|
140
|
+
'string'
|
141
|
+
false
|
142
|
+
end
|
143
|
+
0
|
144
|
+
return true
|
145
|
+
nil
|
146
|
+
end
|
147
|
+
|
148
|
+
st3
|
149
|
+
__CODE
|
150
|
+
|
151
|
+
expect {
|
152
|
+
TypedRb::Language.new.check(code)
|
153
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'parses sequencing instructions with either types, negative case 3' do
|
157
|
+
code = <<__CODE
|
158
|
+
ts '#st3 / -> Boolean'
|
159
|
+
def st3
|
160
|
+
if true
|
161
|
+
1
|
162
|
+
2.0
|
163
|
+
else
|
164
|
+
'string'
|
165
|
+
return false
|
166
|
+
end
|
167
|
+
end
|
168
|
+
__CODE
|
169
|
+
|
170
|
+
expect {
|
171
|
+
TypedRb::Language.new.check(code)
|
172
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmStringInterpolation do
|
4
|
+
|
5
|
+
let(:language) { TypedRb::Language.new }
|
6
|
+
|
7
|
+
context 'with a interpolated string' do
|
8
|
+
|
9
|
+
it 'type-checks it correctly' do
|
10
|
+
code = <<__END
|
11
|
+
a = 1
|
12
|
+
b = 'interpolated'
|
13
|
+
"This is \#{a} string \#{b}"
|
14
|
+
__END
|
15
|
+
result = language.check(code)
|
16
|
+
expect(result).to eq(tystring)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmSuper do
|
4
|
+
let(:language) { TypedRb::Language.new }
|
5
|
+
|
6
|
+
it 'type checks invocations of the super keyword' do
|
7
|
+
expr = <<__CODE
|
8
|
+
class TSA
|
9
|
+
ts '#t / Integer -> Integer'
|
10
|
+
def t(x); x; end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TSB < TSA
|
14
|
+
ts '#t / Integer -> Integer'
|
15
|
+
def t(x); super; end
|
16
|
+
end
|
17
|
+
|
18
|
+
TSB.new.t(1)
|
19
|
+
__CODE
|
20
|
+
|
21
|
+
result = language.check(expr)
|
22
|
+
expect(result.ruby_type).to eq(Integer)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'type checks invocations of the super keyword and arguments' do
|
26
|
+
expr = <<__CODE
|
27
|
+
class TSA
|
28
|
+
ts '#t / Integer -> Integer -> Integer'
|
29
|
+
def t(x,y); x+y; end
|
30
|
+
end
|
31
|
+
|
32
|
+
class TSB < TSA
|
33
|
+
ts '#t / Integer -> Integer'
|
34
|
+
def t(x); super(0,x); end
|
35
|
+
end
|
36
|
+
|
37
|
+
TSB.new.t(1)
|
38
|
+
__CODE
|
39
|
+
|
40
|
+
result = language.check(expr)
|
41
|
+
expect(result.ruby_type).to eq(Integer)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'type checks invocations of the super keyword and arguments, negative case' do
|
45
|
+
expr = <<__CODE
|
46
|
+
class TSA
|
47
|
+
ts '#t / Integer -> Integer -> Integer'
|
48
|
+
def t(x,y); x.to_i+y.to_i; end
|
49
|
+
end
|
50
|
+
|
51
|
+
class TSB < TSA
|
52
|
+
ts '#t / String -> String'
|
53
|
+
def t(x); super(0,x); end
|
54
|
+
end
|
55
|
+
|
56
|
+
TSB.new.t('string')
|
57
|
+
__CODE
|
58
|
+
|
59
|
+
expect {
|
60
|
+
language.check(expr)
|
61
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmSymbolInterpolation do
|
4
|
+
|
5
|
+
let(:language) { TypedRb::Language.new }
|
6
|
+
|
7
|
+
context 'with a interpolated string' do
|
8
|
+
|
9
|
+
it 'type-checks it correctly' do
|
10
|
+
code = <<__END
|
11
|
+
a = 1
|
12
|
+
b = 'interpolated'
|
13
|
+
:"This is \#{a} string \#{b}"
|
14
|
+
__END
|
15
|
+
result = language.check(code)
|
16
|
+
expect(result).to eq(tysymbol)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmSymbol do
|
4
|
+
|
5
|
+
let(:language) { TypedRb::Language.new }
|
6
|
+
|
7
|
+
context 'with a ruby symbol' do
|
8
|
+
|
9
|
+
it 'parsed the symbol type correctly' do
|
10
|
+
result = language.check(':test')
|
11
|
+
expect(result).to eq(tysymbol)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe TypedRb::Model::TmTry do
|
4
|
+
|
5
|
+
let(:language) { TypedRb::Language.new }
|
6
|
+
|
7
|
+
context 'with no rescue term' do
|
8
|
+
it 'type-checks it correctly' do
|
9
|
+
code = <<__END
|
10
|
+
begin
|
11
|
+
2 + 2
|
12
|
+
end
|
13
|
+
__END
|
14
|
+
result = language.check(code)
|
15
|
+
expect(result.to_s).to eq('Integer')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context 'with rescue term' do
|
19
|
+
it 'type-checks it correctly, positive case' do
|
20
|
+
code = <<__END
|
21
|
+
begin
|
22
|
+
2 + 2
|
23
|
+
rescue StandardError => e
|
24
|
+
0
|
25
|
+
end
|
26
|
+
__END
|
27
|
+
result = language.check(code)
|
28
|
+
expect(result.to_s).to eq('Integer')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'type-checks it correctly, negative case' do
|
32
|
+
code = <<__END
|
33
|
+
begin
|
34
|
+
2 + 2
|
35
|
+
rescue
|
36
|
+
'string'
|
37
|
+
end
|
38
|
+
__END
|
39
|
+
expect {
|
40
|
+
language.check(code)
|
41
|
+
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with multiple rescue clauses' do
|
46
|
+
it 'type-checks it correctly' do
|
47
|
+
code = <<__END
|
48
|
+
begin
|
49
|
+
2 + 2
|
50
|
+
rescue StandardError => e
|
51
|
+
rescue
|
52
|
+
0
|
53
|
+
end
|
54
|
+
__END
|
55
|
+
result = language.check(code)
|
56
|
+
expect(result.to_s).to eq('Integer')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with a error return type' do
|
61
|
+
it 'type-checks it correctly' do
|
62
|
+
code = <<__END
|
63
|
+
begin
|
64
|
+
Object.new
|
65
|
+
rescue StandardError, Object => e
|
66
|
+
e
|
67
|
+
end
|
68
|
+
__END
|
69
|
+
result = language.check(code)
|
70
|
+
expect(result.to_s).to eq('Object')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|