rdl 2.0.1 → 2.1.0
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/.travis.yml +13 -0
- data/CHANGES.md +35 -0
- data/README.md +153 -116
- data/bin/rdl_query +1 -1
- data/extras/type_tests/typetests.rb +905 -0
- data/lib/rdl.rb +0 -1
- data/lib/rdl/boot.rb +108 -77
- data/lib/rdl/boot_rails.rb +2 -8
- data/lib/rdl/config.rb +44 -17
- data/lib/rdl/contracts/flat.rb +1 -1
- data/lib/rdl/info.rb +3 -3
- data/lib/rdl/query.rb +11 -11
- data/lib/rdl/typecheck.rb +399 -136
- data/lib/rdl/types/finite_hash.rb +3 -2
- data/lib/rdl/types/generic.rb +7 -6
- data/lib/rdl/types/intersection.rb +3 -2
- data/lib/rdl/types/lexer.rex +2 -3
- data/lib/rdl/types/lexer.rex.rb +1 -4
- data/lib/rdl/types/method.rb +7 -6
- data/lib/rdl/types/nominal.rb +10 -1
- data/lib/rdl/types/parser.racc +7 -8
- data/lib/rdl/types/parser.tab.rb +108 -109
- data/lib/rdl/types/structural.rb +1 -0
- data/lib/rdl/types/tuple.rb +2 -2
- data/lib/rdl/types/type.rb +8 -8
- data/lib/rdl/types/type_inferencer.rb +1 -1
- data/lib/rdl/types/union.rb +2 -1
- data/lib/rdl/util.rb +28 -3
- data/lib/rdl/wrap.rb +216 -165
- data/lib/rdl_disable.rb +22 -15
- data/lib/types/core.rb +2 -4
- data/lib/types/core/_aliases.rb +14 -0
- data/lib/types/core/abbrev.rb +3 -0
- data/lib/types/core/array.rb +139 -0
- data/lib/types/core/base64.rb +8 -0
- data/lib/types/core/basic_object.rb +12 -0
- data/lib/types/core/benchmark.rb +9 -0
- data/lib/types/core/bigdecimal.rb +223 -0
- data/lib/types/core/bigmath.rb +10 -0
- data/lib/types/core/bignum.rb +214 -0
- data/lib/types/core/class.rb +15 -0
- data/lib/types/core/complex.rb +123 -0
- data/lib/types/core/coverage.rb +4 -0
- data/lib/types/core/csv.rb +3 -0
- data/lib/types/core/date.rb +4 -0
- data/lib/types/core/dir.rb +37 -0
- data/lib/types/core/encoding.rb +21 -0
- data/lib/types/core/enumerable.rb +96 -0
- data/lib/types/core/enumerator.rb +24 -0
- data/lib/types/core/exception.rb +15 -0
- data/lib/types/core/file.rb +125 -0
- data/lib/types/core/fileutils.rb +4 -0
- data/lib/types/core/fixnum.rb +213 -0
- data/lib/types/core/float.rb +199 -0
- data/lib/types/core/gem.rb +19 -0
- data/lib/types/core/hash.rb +72 -0
- data/lib/types/core/integer.rb +194 -0
- data/lib/types/core/io.rb +101 -0
- data/lib/types/core/kernel.rb +89 -0
- data/lib/types/core/marshal.rb +3 -0
- data/lib/types/core/matchdata.rb +24 -0
- data/lib/types/core/math.rb +50 -0
- data/lib/types/core/module.rb +81 -0
- data/lib/types/core/nil.rb +11 -0
- data/lib/types/core/numeric.rb +56 -0
- data/lib/types/core/object.rb +73 -0
- data/lib/types/core/pathname.rb +104 -0
- data/lib/types/core/proc.rb +12 -0
- data/lib/types/core/process.rb +110 -0
- data/lib/types/core/random.rb +13 -0
- data/lib/types/core/range.rb +37 -0
- data/lib/types/core/rational.rb +207 -0
- data/lib/types/core/regexp.rb +28 -0
- data/lib/types/core/set.rb +56 -0
- data/lib/types/core/string.rb +140 -0
- data/lib/types/core/strscan.rb +6 -0
- data/lib/types/core/symbol.rb +27 -0
- data/lib/types/core/time.rb +66 -0
- data/lib/types/core/uri.rb +18 -0
- data/lib/types/core/yaml.rb +3 -0
- data/lib/types/devise.rb +1 -0
- data/lib/types/devise/controller_helpers.rb +3 -0
- data/lib/types/devise/parameter_sanitizer.rb +2 -0
- data/lib/types/pundit.rb +2 -0
- data/lib/types/rails/_helpers.rb +50 -0
- data/lib/types/rails/abstract_controller/translation.rb +2 -0
- data/lib/types/rails/action_controller/base.rb +3 -0
- data/lib/types/rails/action_controller/instrumentation.rb +6 -0
- data/lib/types/rails/action_controller/metal.rb +3 -0
- data/lib/types/rails/action_controller/mime_responds.rb +13 -0
- data/lib/types/rails/action_controller/parameters.rb +3 -0
- data/lib/types/{rails-5.x → rails}/action_controller/strong_parameters.rb +4 -8
- data/lib/types/rails/action_dispatch/flashhash.rb +8 -0
- data/lib/types/rails/action_dispatch/routing.rb +10 -0
- data/lib/types/rails/action_mailer/base.rb +2 -0
- data/lib/types/rails/action_mailer/message_delivery.rb +2 -0
- data/lib/types/rails/action_view/helpers_sanitizehelper.rb +2 -0
- data/lib/types/rails/action_view/helpers_urlhelper.rb +5 -0
- data/lib/types/rails/active_model/errors.rb +14 -0
- data/lib/types/rails/active_model/validations.rb +2 -0
- data/lib/types/rails/active_record/associations.rb +208 -0
- data/lib/types/rails/active_record/base.rb +2 -0
- data/lib/types/rails/active_record/core.rb +2 -0
- data/lib/types/rails/active_record/finder_methods.rb +2 -0
- data/lib/types/rails/active_record/model_schema.rb +37 -0
- data/lib/types/rails/active_record/relation.rb +11 -0
- data/lib/types/rails/active_record/schema_types.rb +51 -0
- data/lib/types/rails/active_record/validations.rb +2 -0
- data/lib/types/rails/active_support/base.rb +2 -0
- data/lib/types/rails/active_support/logger.rb +3 -0
- data/lib/types/rails/active_support/tagged_logging.rb +2 -0
- data/lib/types/rails/active_support/time_with_zone.rb +13 -0
- data/lib/types/rails/active_support/time_zone.rb +2 -0
- data/lib/types/rails/fixnum.rb +2 -0
- data/lib/types/rails/integer.rb +2 -0
- data/lib/types/rails/rack/request.rb +2 -0
- data/lib/types/rails/string.rb +3 -0
- data/lib/types/rails/time.rb +1 -0
- data/rdl.gemspec +2 -2
- data/test/disabled_test_rdoc.rb +8 -8
- data/test/test_alias.rb +1 -0
- data/test/test_dsl.rb +4 -4
- data/test/test_generic.rb +45 -38
- data/test/test_intersection.rb +10 -10
- data/test/test_le.rb +103 -102
- data/test/test_member.rb +33 -33
- data/test/test_parser.rb +101 -96
- data/test/test_query.rb +84 -84
- data/test/test_rdl.rb +87 -52
- data/test/test_rdl_type.rb +26 -9
- data/test/test_type_contract.rb +32 -31
- data/test/test_typecheck.rb +802 -436
- data/test/test_types.rb +39 -39
- data/test/test_wrap.rb +3 -2
- metadata +91 -120
- data/extras/type_tests/%.rb +0 -171
- data/extras/type_tests/&.rb +0 -159
- data/extras/type_tests/**.rb +0 -222
- data/extras/type_tests/*.rb +0 -177
- data/extras/type_tests/+.rb +0 -170
- data/extras/type_tests/-.rb +0 -171
- data/extras/type_tests/1scomp.rb +0 -157
- data/extras/type_tests/<.rb +0 -170
- data/extras/type_tests/<<.rb +0 -159
- data/extras/type_tests/>>.rb +0 -159
- data/extras/type_tests/[].rb +0 -163
- data/extras/type_tests/^.rb +0 -159
- data/extras/type_tests/abs.rb +0 -155
- data/extras/type_tests/abs2.rb +0 -164
- data/extras/type_tests/angle.rb +0 -157
- data/extras/type_tests/arg.rb +0 -157
- data/extras/type_tests/bit_length.rb +0 -157
- data/extras/type_tests/ceil.rb +0 -157
- data/extras/type_tests/ceilRational.rb +0 -160
- data/extras/type_tests/conj.rb +0 -158
- data/extras/type_tests/defwhere.rb +0 -86
- data/extras/type_tests/denominator.rb +0 -157
- data/extras/type_tests/div.rb +0 -172
- data/extras/type_tests/divslash.rb +0 -179
- data/extras/type_tests/even?.rb +0 -157
- data/extras/type_tests/fdiv.rb +0 -244
- data/extras/type_tests/finite?.rb +0 -157
- data/extras/type_tests/floor.rb +0 -157
- data/extras/type_tests/floorRational.rb +0 -161
- data/extras/type_tests/hash.rb +0 -157
- data/extras/type_tests/imag.rb +0 -158
- data/extras/type_tests/infinite?.rb +0 -157
- data/extras/type_tests/modulo.rb +0 -171
- data/extras/type_tests/nan?.rb +0 -157
- data/extras/type_tests/neg.rb +0 -155
- data/extras/type_tests/next.rb +0 -157
- data/extras/type_tests/next_float.rb +0 -157
- data/extras/type_tests/numerator.rb +0 -157
- data/extras/type_tests/phase.rb +0 -157
- data/extras/type_tests/prev_float.rb +0 -157
- data/extras/type_tests/quo.rb +0 -179
- data/extras/type_tests/rationalize.rb +0 -157
- data/extras/type_tests/rationalizeArg.rb +0 -198
- data/extras/type_tests/real.rb +0 -157
- data/extras/type_tests/real?.rb +0 -157
- data/extras/type_tests/round.rb +0 -157
- data/extras/type_tests/roundArg.rb +0 -169
- data/extras/type_tests/size.rb +0 -157
- data/extras/type_tests/to_c.rb +0 -157
- data/extras/type_tests/to_f.rb +0 -155
- data/extras/type_tests/to_i.rb +0 -157
- data/extras/type_tests/to_r.rb +0 -157
- data/extras/type_tests/to_s.rb +0 -157
- data/extras/type_tests/truncate.rb +0 -157
- data/extras/type_tests/truncateArg.rb +0 -166
- data/extras/type_tests/type tests +0 -1
- data/extras/type_tests/zero?.rb +0 -155
- data/extras/type_tests/|.rb +0 -159
- data/lib/types/core-ruby-2.x/_aliases.rb +0 -15
- data/lib/types/core-ruby-2.x/abbrev.rb +0 -5
- data/lib/types/core-ruby-2.x/array.rb +0 -137
- data/lib/types/core-ruby-2.x/base64.rb +0 -10
- data/lib/types/core-ruby-2.x/basic_object.rb +0 -14
- data/lib/types/core-ruby-2.x/benchmark.rb +0 -11
- data/lib/types/core-ruby-2.x/bigdecimal.rb +0 -224
- data/lib/types/core-ruby-2.x/bigmath.rb +0 -12
- data/lib/types/core-ruby-2.x/bignum.rb +0 -214
- data/lib/types/core-ruby-2.x/class.rb +0 -17
- data/lib/types/core-ruby-2.x/complex.rb +0 -124
- data/lib/types/core-ruby-2.x/coverage.rb +0 -6
- data/lib/types/core-ruby-2.x/csv.rb +0 -5
- data/lib/types/core-ruby-2.x/date.rb +0 -6
- data/lib/types/core-ruby-2.x/dir.rb +0 -38
- data/lib/types/core-ruby-2.x/encoding.rb +0 -23
- data/lib/types/core-ruby-2.x/enumerable.rb +0 -98
- data/lib/types/core-ruby-2.x/enumerator.rb +0 -26
- data/lib/types/core-ruby-2.x/exception.rb +0 -17
- data/lib/types/core-ruby-2.x/file.rb +0 -126
- data/lib/types/core-ruby-2.x/fileutils.rb +0 -6
- data/lib/types/core-ruby-2.x/fixnum.rb +0 -213
- data/lib/types/core-ruby-2.x/float.rb +0 -199
- data/lib/types/core-ruby-2.x/gem.rb +0 -247
- data/lib/types/core-ruby-2.x/hash.rb +0 -72
- data/lib/types/core-ruby-2.x/integer.rb +0 -197
- data/lib/types/core-ruby-2.x/io.rb +0 -103
- data/lib/types/core-ruby-2.x/kernel.rb +0 -90
- data/lib/types/core-ruby-2.x/marshal.rb +0 -5
- data/lib/types/core-ruby-2.x/matchdata.rb +0 -26
- data/lib/types/core-ruby-2.x/math.rb +0 -53
- data/lib/types/core-ruby-2.x/module.rb +0 -83
- data/lib/types/core-ruby-2.x/nil.rb +0 -12
- data/lib/types/core-ruby-2.x/numeric.rb +0 -56
- data/lib/types/core-ruby-2.x/object.rb +0 -75
- data/lib/types/core-ruby-2.x/pathname.rb +0 -106
- data/lib/types/core-ruby-2.x/proc.rb +0 -16
- data/lib/types/core-ruby-2.x/process.rb +0 -127
- data/lib/types/core-ruby-2.x/random.rb +0 -17
- data/lib/types/core-ruby-2.x/range.rb +0 -39
- data/lib/types/core-ruby-2.x/rational.rb +0 -209
- data/lib/types/core-ruby-2.x/regexp.rb +0 -30
- data/lib/types/core-ruby-2.x/set.rb +0 -58
- data/lib/types/core-ruby-2.x/string.rb +0 -143
- data/lib/types/core-ruby-2.x/strscan.rb +0 -7
- data/lib/types/core-ruby-2.x/symbol.rb +0 -29
- data/lib/types/core-ruby-2.x/time.rb +0 -68
- data/lib/types/core-ruby-2.x/uri.rb +0 -20
- data/lib/types/core-ruby-2.x/yaml.rb +0 -5
- data/lib/types/rails-5.x/_helpers.rb +0 -52
- data/lib/types/rails-5.x/action_controller/mime_responds.rb +0 -11
- data/lib/types/rails-5.x/action_dispatch/routing.rb +0 -10
- data/lib/types/rails-5.x/active_model/errors.rb +0 -15
- data/lib/types/rails-5.x/active_model/validations.rb +0 -5
- data/lib/types/rails-5.x/active_record/associations.rb +0 -190
- data/lib/types/rails-5.x/active_record/core.rb +0 -3
- data/lib/types/rails-5.x/active_record/model_schema.rb +0 -39
- data/lib/types/rails-5.x/fixnum.rb +0 -3
data/test/test_typecheck.rb
CHANGED
|
@@ -3,20 +3,146 @@ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
|
|
|
3
3
|
require 'rdl'
|
|
4
4
|
require 'types/core'
|
|
5
5
|
|
|
6
|
+
class N1
|
|
7
|
+
class N2
|
|
8
|
+
extend RDL::Annotate
|
|
9
|
+
def self.foo
|
|
10
|
+
:sym
|
|
11
|
+
end
|
|
12
|
+
type 'self.foo', '() -> :sym'
|
|
13
|
+
|
|
14
|
+
def self.foo2
|
|
15
|
+
:sym2
|
|
16
|
+
end
|
|
17
|
+
type 'self.foo2', '() -> :sym2'
|
|
18
|
+
|
|
19
|
+
def self.nf
|
|
20
|
+
N2.foo
|
|
21
|
+
end
|
|
22
|
+
type 'self.nf', '() -> :sym', typecheck: :call
|
|
23
|
+
|
|
24
|
+
def nf2
|
|
25
|
+
N2.foo2
|
|
26
|
+
end
|
|
27
|
+
type :nf2, '() -> :sym2', typecheck: :call
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class N3
|
|
31
|
+
extend RDL::Annotate
|
|
32
|
+
def nf3
|
|
33
|
+
N2.foo
|
|
34
|
+
end
|
|
35
|
+
type :nf3, '() -> :sym', typecheck: :call
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class N4
|
|
40
|
+
extend RDL::Annotate
|
|
41
|
+
class N5
|
|
42
|
+
extend RDL::Annotate
|
|
43
|
+
type :bar, '() -> :B'
|
|
44
|
+
def bar
|
|
45
|
+
:B
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class N5
|
|
51
|
+
extend RDL::Annotate
|
|
52
|
+
type :bar, '() -> :A'
|
|
53
|
+
def bar
|
|
54
|
+
:A
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class N4
|
|
59
|
+
class << self
|
|
60
|
+
extend RDL::Annotate
|
|
61
|
+
def foo
|
|
62
|
+
N5.new.bar
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
type 'self.foo', '() -> :B', typecheck: :call
|
|
66
|
+
end
|
|
67
|
+
|
|
6
68
|
class TestTypecheckC
|
|
7
|
-
|
|
69
|
+
extend RDL::Annotate
|
|
70
|
+
type 'self.bar', '() -> Integer or String ret'
|
|
8
71
|
type 'self.foo', '() -> :A'
|
|
9
|
-
type '
|
|
72
|
+
type 'foo', '() -> Integer'
|
|
73
|
+
type '(Integer) -> self'
|
|
74
|
+
def initialize(x); end
|
|
10
75
|
end
|
|
11
76
|
|
|
12
77
|
class TestTypecheckD
|
|
13
78
|
end
|
|
14
79
|
|
|
80
|
+
class TestTypecheckE
|
|
81
|
+
extend RDL::Annotate
|
|
82
|
+
type '(Integer) -> self', typecheck: :einit
|
|
83
|
+
def initialize(x)
|
|
84
|
+
x
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class TestTypecheckF
|
|
89
|
+
extend RDL::Annotate
|
|
90
|
+
type '(Integer) -> F', typecheck: :finit
|
|
91
|
+
def initialize(x)
|
|
92
|
+
x
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
15
96
|
module TestTypecheckM
|
|
97
|
+
extend RDL::Annotate
|
|
16
98
|
type 'self.foo', '() -> :B'
|
|
17
99
|
end
|
|
18
100
|
|
|
101
|
+
class TestTypecheckOuter
|
|
102
|
+
class A
|
|
103
|
+
class B
|
|
104
|
+
class C
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class X
|
|
111
|
+
extend RDL::Annotate
|
|
112
|
+
end
|
|
113
|
+
class Y
|
|
114
|
+
extend RDL::Annotate
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
class MethodMissing1
|
|
118
|
+
extend RDL::Annotate
|
|
119
|
+
type '() -> String', typecheck: :later_mm1
|
|
120
|
+
def foo()
|
|
121
|
+
bar()
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
type '(Symbol, *%any) -> String', typecheck: :later_mm1
|
|
125
|
+
def method_missing(name, *_)
|
|
126
|
+
name.to_s
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class MethodMissing2
|
|
131
|
+
extend RDL::Annotate
|
|
132
|
+
type '() -> Integer', typecheck: :later_mm2
|
|
133
|
+
def foo()
|
|
134
|
+
bar()
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
type '(Symbol, *%any) -> String', typecheck: :later_mm2
|
|
138
|
+
def method_missing(name, *_)
|
|
139
|
+
name.to_s
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
|
|
19
144
|
class TestTypecheck < Minitest::Test
|
|
145
|
+
extend RDL::Annotate
|
|
20
146
|
type :_any_object, "() -> Object" # a method that could return true or false
|
|
21
147
|
|
|
22
148
|
def setup
|
|
@@ -27,13 +153,13 @@ class TestTypecheck < Minitest::Test
|
|
|
27
153
|
@t45 = RDL::Type::UnionType.new(@t4, @t5)
|
|
28
154
|
@t35 = RDL::Type::UnionType.new(@t3, @t5)
|
|
29
155
|
@t345 = RDL::Type::UnionType.new(@t34, @t5)
|
|
30
|
-
@ts3 = RDL::Type::UnionType.new(
|
|
156
|
+
@ts3 = RDL::Type::UnionType.new(RDL::Globals.types[:string], @t3)
|
|
31
157
|
@ts34 = RDL::Type::UnionType.new(@ts3, @t4)
|
|
32
|
-
@t3n = RDL::Type::UnionType.new(@t3,
|
|
33
|
-
@t4n = RDL::Type::UnionType.new(@t4,
|
|
158
|
+
@t3n = RDL::Type::UnionType.new(@t3, RDL::Globals.types[:nil])
|
|
159
|
+
@t4n = RDL::Type::UnionType.new(@t4, RDL::Globals.types[:nil])
|
|
34
160
|
@env = RDL::Typecheck::Env.new(self: tt("TestTypecheck"))
|
|
35
|
-
@scopef = { tret:
|
|
36
|
-
@tfs = RDL::Type::UnionType.new(
|
|
161
|
+
@scopef = { tret: RDL::Globals.types[:integer] }
|
|
162
|
+
@tfs = RDL::Type::UnionType.new(RDL::Globals.types[:integer], RDL::Globals.types[:string])
|
|
37
163
|
@scopefs = { tret: @tfs, tblock: nil }
|
|
38
164
|
end
|
|
39
165
|
|
|
@@ -48,52 +174,91 @@ class TestTypecheck < Minitest::Test
|
|
|
48
174
|
|
|
49
175
|
# convert arg string to a type
|
|
50
176
|
def tt(t)
|
|
51
|
-
|
|
177
|
+
RDL::Globals.parser.scan_str('#T ' + t)
|
|
52
178
|
end
|
|
53
179
|
|
|
54
180
|
def test_def
|
|
55
181
|
self.class.class_eval {
|
|
56
|
-
type "(
|
|
182
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
57
183
|
def def_ff(x) x; end
|
|
58
184
|
}
|
|
59
185
|
|
|
60
186
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
61
187
|
self.class.class_eval {
|
|
62
|
-
type "(
|
|
188
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
63
189
|
def def_fs(x) "42"; end
|
|
64
190
|
}
|
|
65
191
|
}
|
|
66
192
|
|
|
67
193
|
self.class.class_eval {
|
|
68
|
-
type "(
|
|
194
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
69
195
|
def def_ff2(x) x; end
|
|
70
196
|
}
|
|
71
197
|
assert_equal 42, def_ff2(42)
|
|
72
198
|
|
|
73
199
|
self.class.class_eval {
|
|
74
|
-
type "(
|
|
200
|
+
type "(Integer) -> Integer", typecheck: :call
|
|
75
201
|
def def_fs2(x) "42"; end
|
|
76
202
|
}
|
|
77
203
|
assert_raises(RDL::Typecheck::StaticTypeError) { def_fs2(42) }
|
|
78
204
|
|
|
79
205
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
80
206
|
self.class.class_eval {
|
|
81
|
-
type "(
|
|
207
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
82
208
|
def def_ff3(x, y) 42; end
|
|
83
209
|
}
|
|
84
210
|
}
|
|
85
211
|
|
|
86
212
|
self.class.class_eval {
|
|
87
|
-
type "(
|
|
213
|
+
type "(Integer) -> Integer", typecheck: :later1
|
|
88
214
|
def def_ff4(x, y) 42; end
|
|
89
215
|
}
|
|
90
216
|
|
|
91
|
-
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
217
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :later1 }
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def test_def_post
|
|
221
|
+
self.class.class_eval {
|
|
222
|
+
def def_ffp(x) x; end
|
|
223
|
+
type :def_ffp, "(Integer) -> Integer", typecheck: :now, wrap: false
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
227
|
+
self.class.class_eval {
|
|
228
|
+
def def_fsp(x) "42"; end
|
|
229
|
+
type :def_fsp, "(Integer) -> Integer", typecheck: :now, wrap: false
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
self.class.class_eval {
|
|
234
|
+
def def_ff2p(x) x; end
|
|
235
|
+
type :def_ff2p, "(Integer) -> Integer", typecheck: :now, wrap: false
|
|
236
|
+
}
|
|
237
|
+
assert_equal 42, def_ff2p(42)
|
|
238
|
+
|
|
239
|
+
self.class.class_eval {
|
|
240
|
+
def def_fs2p(x) "42"; end
|
|
241
|
+
type :def_fs2p, "(Integer) -> Integer", typecheck: :call
|
|
242
|
+
}
|
|
243
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { def_fs2p(42) }
|
|
244
|
+
|
|
245
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
246
|
+
self.class.class_eval {
|
|
247
|
+
def def_ff3p(x, y) 42; end
|
|
248
|
+
type :def_ff3p, "(Integer) -> Integer", typecheck: :now, wrap: false
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
self.class.class_eval {
|
|
253
|
+
def def_ff4p(x, y) 42; end
|
|
254
|
+
type :def_ff4p, "(Integer) -> Integer", typecheck: :later2, wrap: false
|
|
255
|
+
}
|
|
256
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :later2 }
|
|
92
257
|
end
|
|
93
258
|
|
|
94
259
|
def test_defs
|
|
95
260
|
self.class.class_eval {
|
|
96
|
-
type "(
|
|
261
|
+
type "(Integer) -> Class", typecheck: :now
|
|
97
262
|
def self.defs_ff(x) self; end
|
|
98
263
|
}
|
|
99
264
|
|
|
@@ -110,25 +275,37 @@ class TestTypecheck < Minitest::Test
|
|
|
110
275
|
}
|
|
111
276
|
|
|
112
277
|
self.class.class_eval {
|
|
113
|
-
type "(
|
|
278
|
+
type "(Integer) -> Integer", typecheck: :later4
|
|
114
279
|
def self.defs_ff2(x, y) 42; end
|
|
115
280
|
}
|
|
116
281
|
|
|
117
|
-
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
282
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :later4 }
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def test_singleton_method_const
|
|
286
|
+
X.class_eval {
|
|
287
|
+
type '(Integer) -> Integer'
|
|
288
|
+
def foo(x) x; end
|
|
289
|
+
}
|
|
290
|
+
Y.class_eval {
|
|
291
|
+
type '(Integer) -> Integer', typecheck: :later5
|
|
292
|
+
def self.bar(x) a = X.new; a.foo(x); end
|
|
293
|
+
}
|
|
294
|
+
self.class.class_eval { RDL.do_typecheck :later5 }
|
|
118
295
|
end
|
|
119
296
|
|
|
120
297
|
def test_lits
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
assert do_tc("123456789123456789123456789") <=
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
298
|
+
assert do_tc("nil") <= RDL::Globals.types[:nil]
|
|
299
|
+
assert do_tc("true") <= RDL::Globals.types[:true]
|
|
300
|
+
assert do_tc("false") <= RDL::Globals.types[:false]
|
|
301
|
+
assert do_tc("42") <= tt("42")
|
|
302
|
+
assert do_tc("123456789123456789123456789") <= RDL::Globals.types[:integer]
|
|
303
|
+
assert do_tc("3.14") <= tt("3.14")
|
|
304
|
+
assert do_tc("1i") <= RDL::Globals.types[:complex]
|
|
305
|
+
assert do_tc("2.0r") <= RDL::Globals.types[:rational]
|
|
306
|
+
assert do_tc("'42'") <= RDL::Globals.types[:string]
|
|
307
|
+
assert do_tc("\"42\"") <= RDL::Globals.types[:string]
|
|
308
|
+
assert do_tc(":foo") <= tt(":foo")
|
|
132
309
|
end
|
|
133
310
|
|
|
134
311
|
def test_empty
|
|
@@ -150,7 +327,7 @@ class TestTypecheck < Minitest::Test
|
|
|
150
327
|
end
|
|
151
328
|
|
|
152
329
|
def test_seq
|
|
153
|
-
|
|
330
|
+
assert do_tc("_ = 42; _ = 43; 'foo'") <= RDL::Globals.types[:string]
|
|
154
331
|
end
|
|
155
332
|
|
|
156
333
|
def test_dsym
|
|
@@ -162,7 +339,7 @@ class TestTypecheck < Minitest::Test
|
|
|
162
339
|
end
|
|
163
340
|
|
|
164
341
|
def test_regexp
|
|
165
|
-
|
|
342
|
+
assert do_tc("/foo/") <= RDL::Globals.types[:regexp]
|
|
166
343
|
|
|
167
344
|
self.class.class_eval {
|
|
168
345
|
# Hard to read if these are inside of strings, so leave like this
|
|
@@ -172,20 +349,20 @@ class TestTypecheck < Minitest::Test
|
|
|
172
349
|
end
|
|
173
350
|
|
|
174
351
|
def test_tuple
|
|
175
|
-
|
|
176
|
-
|
|
352
|
+
assert do_tc("[true, '42']") <= tt("[TrueClass, String]")
|
|
353
|
+
assert do_tc("[42, '42']") <= tt("[42, String]")
|
|
177
354
|
end
|
|
178
355
|
|
|
179
356
|
def test_hash
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
357
|
+
assert do_tc("{x: true, y: false}") <= tt("{x: TrueClass, y: FalseClass}")
|
|
358
|
+
assert do_tc("{'a' => 1, 'b' => 2}") <= tt("Hash<String, 1 or 2>")
|
|
359
|
+
assert do_tc("{1 => 'a', 2 => 'b'}") <= tt("{1 => String, 2 => String}")
|
|
360
|
+
assert do_tc("{}") <= tt("{}")
|
|
184
361
|
end
|
|
185
362
|
|
|
186
363
|
def test_range
|
|
187
|
-
|
|
188
|
-
|
|
364
|
+
assert do_tc("1..5") <= tt("Range<Integer>")
|
|
365
|
+
assert do_tc("1...5") <= tt("Range<Integer>")
|
|
189
366
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("1..'foo'") }
|
|
190
367
|
end
|
|
191
368
|
|
|
@@ -210,63 +387,69 @@ class TestTypecheck < Minitest::Test
|
|
|
210
387
|
end
|
|
211
388
|
|
|
212
389
|
def test_nth_back
|
|
213
|
-
|
|
214
|
-
|
|
390
|
+
assert do_tc("$4") <= RDL::Globals.types[:string]
|
|
391
|
+
assert do_tc("$+") <= RDL::Globals.types[:string]
|
|
215
392
|
end
|
|
216
393
|
|
|
217
394
|
def test_const
|
|
218
|
-
|
|
219
|
-
|
|
395
|
+
assert do_tc("String", env: @env) <= tt("${String}")
|
|
396
|
+
|
|
397
|
+
t = RDL::Type::SingletonType.new(TestTypecheckOuter)
|
|
398
|
+
assert_equal t, do_tc("TestTypecheckOuter", env: @env)
|
|
399
|
+
t = RDL::Type::SingletonType.new(TestTypecheckOuter::A)
|
|
400
|
+
assert_equal t, do_tc("TestTypecheckOuter::A", env: @env)
|
|
401
|
+
t = RDL::Type::SingletonType.new(TestTypecheckOuter::A::B::C)
|
|
402
|
+
assert_equal t, do_tc("TestTypecheckOuter::A::B::C", env: @env)
|
|
220
403
|
end
|
|
221
404
|
|
|
222
405
|
def test_defined
|
|
223
|
-
|
|
406
|
+
assert do_tc("defined?(x)") <= RDL::Globals.types[:string]
|
|
224
407
|
end
|
|
225
408
|
|
|
226
409
|
def test_lvar
|
|
227
410
|
self.class.class_eval {
|
|
228
|
-
type "(
|
|
411
|
+
type "(Integer, String) -> Integer", typecheck: :now
|
|
229
412
|
def lvar1(x, y) x; end
|
|
230
413
|
}
|
|
231
414
|
|
|
232
415
|
self.class.class_eval {
|
|
233
|
-
type "(
|
|
416
|
+
type "(Integer, String) -> String", typecheck: :now
|
|
234
417
|
def lvar2(x, y) y; end
|
|
235
418
|
}
|
|
236
419
|
|
|
237
420
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
238
421
|
# really a send
|
|
239
422
|
self.class.class_eval {
|
|
240
|
-
type "(
|
|
423
|
+
type "(Integer, String) -> String", typecheck: :now
|
|
241
424
|
def lvar3(x, y) z; end
|
|
242
425
|
}
|
|
243
426
|
}
|
|
244
427
|
end
|
|
245
428
|
|
|
246
429
|
def test_lvasgn
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
430
|
+
assert do_tc("x = 42; x") <= tt("42")
|
|
431
|
+
assert do_tc("x = 42; y = x; y") <= tt("42")
|
|
432
|
+
assert do_tc("x = y = 42; x") <= tt("42")
|
|
433
|
+
assert do_tc("x = x") <= RDL::Globals.types[:nil] # weird behavior - lhs bound to nil always before assignment!
|
|
251
434
|
end
|
|
252
435
|
|
|
253
436
|
def test_lvar_type
|
|
254
437
|
# var_type arg type and formattests
|
|
255
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type :x", env: @env) }
|
|
256
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type :x, 3", env: @env) }
|
|
257
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type 'x', '
|
|
258
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type :@x, '
|
|
259
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type :x, 'Fluffy Bunny'", env: @env) }
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type :x, '
|
|
438
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.var_type :x", env: @env) }
|
|
439
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.var_type :x, 3", env: @env) }
|
|
440
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.var_type 'x', 'Integer'", env: @env) }
|
|
441
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.var_type :@x, 'Integer'", env: @env) }
|
|
442
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.var_type :x, 'Fluffy Bunny'", env: @env) }
|
|
443
|
+
|
|
444
|
+
assert do_tc("RDL.var_type :x, 'Integer'; x = 3; x", env: @env) <= RDL::Globals.types[:integer]
|
|
445
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.var_type :x, 'Integer'; x = 'three'", env: @env) }
|
|
263
446
|
self.class.class_eval {
|
|
264
|
-
type "(
|
|
447
|
+
type "(Integer) -> nil", typecheck: :now
|
|
265
448
|
def lvar_type_ff(x) x = 42; nil; end
|
|
266
449
|
}
|
|
267
450
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
268
451
|
self.class.class_eval {
|
|
269
|
-
type "(
|
|
452
|
+
type "(Integer) -> nil", typecheck: :now
|
|
270
453
|
def lvar_type_ff2(x) x = "forty-two"; nil; end
|
|
271
454
|
}
|
|
272
455
|
}
|
|
@@ -274,59 +457,62 @@ class TestTypecheck < Minitest::Test
|
|
|
274
457
|
|
|
275
458
|
def test_ivar_ivasgn
|
|
276
459
|
self.class.class_eval {
|
|
277
|
-
|
|
278
|
-
var_type
|
|
279
|
-
var_type
|
|
460
|
+
extend RDL::Annotate
|
|
461
|
+
var_type :@foo, "Integer"
|
|
462
|
+
var_type :@@foo, "Integer"
|
|
463
|
+
var_type :$test_ivar_ivasgn_global, "Integer"
|
|
280
464
|
var_type :@object, "Object"
|
|
281
465
|
}
|
|
282
466
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
467
|
+
assert do_tc("@foo", env: @env) <= RDL::Globals.types[:integer]
|
|
468
|
+
assert do_tc("@@foo", env: @env) <= RDL::Globals.types[:integer]
|
|
469
|
+
assert do_tc("$test_ivar_ivasgn_global") <= RDL::Globals.types[:integer]
|
|
286
470
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@bar", env: @env) }
|
|
287
471
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@bar", env: @env) }
|
|
288
472
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@@bar", env: @env) }
|
|
289
473
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("$_test_ivar_ivasgn_global_2") }
|
|
290
474
|
|
|
291
|
-
|
|
475
|
+
assert do_tc("@foo = 3", env: @env) <= @t3
|
|
292
476
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@foo = 'three'", env: @env) }
|
|
293
477
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@bar = 'three'", env: @env) }
|
|
294
|
-
|
|
478
|
+
assert do_tc("@@foo = 3", env: @env) <= @t3
|
|
295
479
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@@foo = 'three'", env: @env) }
|
|
296
480
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("@@bar = 'three'", env: @env) }
|
|
297
|
-
|
|
481
|
+
assert do_tc("$test_ivar_ivasgn_global = 3") <= @t3
|
|
298
482
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("$test_ivar_ivasgn_global = 'three'") }
|
|
299
483
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("$test_ivar_ivasgn_global_2 = 'three'") }
|
|
300
|
-
|
|
484
|
+
assert do_tc("@object = 3", env: @env) <= @t3 # type of assignment is type of rhs
|
|
301
485
|
end
|
|
302
486
|
|
|
303
487
|
def test_send_basic
|
|
304
488
|
self.class.class_eval {
|
|
305
|
-
type :_send_basic2, "() ->
|
|
306
|
-
type :_send_basic3, "(
|
|
307
|
-
type :_send_basic4, "(
|
|
308
|
-
type "self._send_basic5", "(
|
|
489
|
+
type :_send_basic2, "() -> Integer"
|
|
490
|
+
type :_send_basic3, "(Integer) -> Integer"
|
|
491
|
+
type :_send_basic4, "(Integer, String) -> Integer"
|
|
492
|
+
type "self._send_basic5", "(Integer) -> Integer"
|
|
309
493
|
}
|
|
310
494
|
|
|
311
495
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("z", env: @env) }
|
|
312
|
-
|
|
313
|
-
|
|
496
|
+
assert do_tc("_send_basic2", env: @env) <= RDL::Globals.types[:integer]
|
|
497
|
+
assert do_tc("_send_basic3(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
314
498
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_basic3('42')", env: @env) }
|
|
315
|
-
|
|
499
|
+
assert do_tc("_send_basic4(42, '42')", env: @env) <= RDL::Globals.types[:integer]
|
|
316
500
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_basic4(42, 43)", env: @env) }
|
|
317
501
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_basic4('42', '43')", env: @env) }
|
|
318
|
-
|
|
502
|
+
assert do_tc("TestTypecheck._send_basic5(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
319
503
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("TestTypecheck._send_basic5('42')", env: @env) }
|
|
320
|
-
|
|
504
|
+
assert do_tc("puts 42", env: @env) <= RDL::Globals.types[:nil]
|
|
321
505
|
end
|
|
322
506
|
|
|
323
507
|
class A
|
|
324
|
-
|
|
508
|
+
extend RDL::Annotate
|
|
509
|
+
type :_send_inherit1, "() -> Integer"
|
|
325
510
|
end
|
|
326
511
|
class B < A
|
|
327
512
|
end
|
|
328
513
|
|
|
329
514
|
class A1
|
|
515
|
+
extend RDL::Annotate
|
|
330
516
|
type "() -> nil"
|
|
331
517
|
def _send_inherit2; end
|
|
332
518
|
end
|
|
@@ -337,17 +523,17 @@ class TestTypecheck < Minitest::Test
|
|
|
337
523
|
end
|
|
338
524
|
|
|
339
525
|
def test_send_inherit
|
|
340
|
-
|
|
526
|
+
assert do_tc("B.new._send_inherit1", env: @env) <= RDL::Globals.types[:integer]
|
|
341
527
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("A3.new._send_inherit2", env: @env) }
|
|
342
528
|
end
|
|
343
529
|
|
|
344
530
|
def test_send_inter
|
|
345
531
|
self.class.class_eval {
|
|
346
|
-
type :_send_inter1, "(
|
|
532
|
+
type :_send_inter1, "(Integer) -> Integer"
|
|
347
533
|
type :_send_inter1, "(String) -> String"
|
|
348
534
|
}
|
|
349
|
-
|
|
350
|
-
|
|
535
|
+
assert do_tc("_send_inter1(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
536
|
+
assert do_tc("_send_inter1('42')", env: @env) <= RDL::Globals.types[:string]
|
|
351
537
|
|
|
352
538
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_inter1(:forty_two)", env: @env) }
|
|
353
539
|
end
|
|
@@ -355,57 +541,57 @@ class TestTypecheck < Minitest::Test
|
|
|
355
541
|
def test_send_opt_varargs
|
|
356
542
|
# from test_type_contract.rb
|
|
357
543
|
self.class.class_eval {
|
|
358
|
-
type :_send_opt_varargs1, "(
|
|
359
|
-
type :_send_opt_varargs2, "(
|
|
360
|
-
type :_send_opt_varargs3, "(
|
|
361
|
-
type :_send_opt_varargs4, "(?
|
|
362
|
-
type :_send_opt_varargs5, "(*
|
|
363
|
-
type :_send_opt_varargs6, "(?
|
|
364
|
-
type :_send_opt_varargs7, "(
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
|
|
544
|
+
type :_send_opt_varargs1, "(Integer, ?Integer) -> Integer"
|
|
545
|
+
type :_send_opt_varargs2, "(Integer, *Integer) -> Integer"
|
|
546
|
+
type :_send_opt_varargs3, "(Integer, ?Integer, ?Integer, *Integer) -> Integer"
|
|
547
|
+
type :_send_opt_varargs4, "(?Integer) -> Integer"
|
|
548
|
+
type :_send_opt_varargs5, "(*Integer) -> Integer"
|
|
549
|
+
type :_send_opt_varargs6, "(?Integer, String) -> Integer"
|
|
550
|
+
type :_send_opt_varargs7, "(Integer, *String, Integer) -> Integer"
|
|
551
|
+
}
|
|
552
|
+
assert do_tc("_send_opt_varargs1(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
553
|
+
assert do_tc("_send_opt_varargs1(42, 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
368
554
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs1()", env: @env) }
|
|
369
555
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs1(42, 43, 44)", env: @env) }
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
556
|
+
assert do_tc("_send_opt_varargs2(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
557
|
+
assert do_tc("_send_opt_varargs2(42, 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
558
|
+
assert do_tc("_send_opt_varargs2(42, 43, 44)", env: @env) <= RDL::Globals.types[:integer]
|
|
559
|
+
assert do_tc("_send_opt_varargs2(42, 43, 44, 45)", env: @env) <= RDL::Globals.types[:integer]
|
|
374
560
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs2()", env: @env) }
|
|
375
561
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs2('42')", env: @env) }
|
|
376
562
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs2(42, '43')", env: @env) }
|
|
377
563
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs2(42, 43, '44')", env: @env) }
|
|
378
564
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs2(42, 43, 44, '45')", env: @env) }
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
565
|
+
assert do_tc("_send_opt_varargs3(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
566
|
+
assert do_tc("_send_opt_varargs3(42, 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
567
|
+
assert do_tc("_send_opt_varargs3(42, 43, 44)", env: @env) <= RDL::Globals.types[:integer]
|
|
568
|
+
assert do_tc("_send_opt_varargs3(42, 43, 45)", env: @env) <= RDL::Globals.types[:integer]
|
|
569
|
+
assert do_tc("_send_opt_varargs3(42, 43, 46)", env: @env) <= RDL::Globals.types[:integer]
|
|
384
570
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs3()", env: @env) }
|
|
385
571
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs3('42')", env: @env) }
|
|
386
572
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs3(42, '43')", env: @env) }
|
|
387
573
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs3(42, 43, '44')", env: @env) }
|
|
388
574
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs3(42, 43, 44, '45')", env: @env) }
|
|
389
575
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs3(42, 43, 44, 45, '46')", env: @env) }
|
|
390
|
-
|
|
391
|
-
|
|
576
|
+
assert do_tc("_send_opt_varargs4()", env: @env) <= RDL::Globals.types[:integer]
|
|
577
|
+
assert do_tc("_send_opt_varargs4(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
392
578
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs4('42')", env: @env) }
|
|
393
579
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs4(42, 43)", env: @env) }
|
|
394
580
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs4(42, 43, 44)", env: @env) }
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
581
|
+
assert do_tc("_send_opt_varargs5()", env: @env) <= RDL::Globals.types[:integer]
|
|
582
|
+
assert do_tc("_send_opt_varargs5(42)", env: @env) <= RDL::Globals.types[:integer]
|
|
583
|
+
assert do_tc("_send_opt_varargs5(42, 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
584
|
+
assert do_tc("_send_opt_varargs5(42, 43, 44)", env: @env) <= RDL::Globals.types[:integer]
|
|
399
585
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs5('42')", env: @env) }
|
|
400
586
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs5(42, '43')", env: @env) }
|
|
401
587
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs5(42, 43, '44')", env: @env) }
|
|
402
|
-
|
|
403
|
-
|
|
588
|
+
assert do_tc("_send_opt_varargs6('44')", env: @env) <= RDL::Globals.types[:integer]
|
|
589
|
+
assert do_tc("_send_opt_varargs6(43, '44')", env: @env) <= RDL::Globals.types[:integer]
|
|
404
590
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs6()", env: @env) }
|
|
405
591
|
assert_raises(RDL::Typecheck::StaticTypeError) { assert do_tc("_send_opt_varargs6(43, '44', 45)", env: @env) }
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
592
|
+
assert do_tc("_send_opt_varargs7(42, 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
593
|
+
assert do_tc("_send_opt_varargs7(42, 'foo', 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
594
|
+
assert do_tc("_send_opt_varargs7(42, 'foo', 'bar', 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
409
595
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_opt_varargs7", env: @env) }
|
|
410
596
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_opt_varargs7('42')", env: @env) }
|
|
411
597
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_opt_varargs7(42)", env: @env) }
|
|
@@ -416,108 +602,108 @@ class TestTypecheck < Minitest::Test
|
|
|
416
602
|
def test_send_named_args
|
|
417
603
|
# from test_type_contract.rb
|
|
418
604
|
self.class.class_eval {
|
|
419
|
-
type :_send_named_args1, "(x:
|
|
420
|
-
type :_send_named_args2, "(x:
|
|
421
|
-
type :_send_named_args3, "(
|
|
422
|
-
type :_send_named_args4, "(
|
|
423
|
-
type :_send_named_args5, "(x:
|
|
424
|
-
type :_send_named_args6, "(x: ?
|
|
425
|
-
type :_send_named_args7, "(x: ?
|
|
426
|
-
type :_send_named_args8, "(?
|
|
427
|
-
type :_send_named_args9, "(
|
|
428
|
-
}
|
|
429
|
-
|
|
605
|
+
type :_send_named_args1, "(x: Integer) -> Integer"
|
|
606
|
+
type :_send_named_args2, "(x: Integer, y: String) -> Integer"
|
|
607
|
+
type :_send_named_args3, "(Integer, y: String) -> Integer"
|
|
608
|
+
type :_send_named_args4, "(Integer, x: Integer, y: String) -> Integer"
|
|
609
|
+
type :_send_named_args5, "(x: Integer, y: ?String) -> Integer"
|
|
610
|
+
type :_send_named_args6, "(x: ?Integer, y: String) -> Integer"
|
|
611
|
+
type :_send_named_args7, "(x: ?Integer, y: ?String) -> Integer"
|
|
612
|
+
type :_send_named_args8, "(?Integer, x: ?Symbol, y: ?String) -> Integer"
|
|
613
|
+
type :_send_named_args9, "(Integer, x: String, y: Integer, **Float) -> Integer"
|
|
614
|
+
}
|
|
615
|
+
assert do_tc("_send_named_args1(x: 42)", env: @env) <= RDL::Globals.types[:integer]
|
|
430
616
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args1(x: '42')", env: @env) }
|
|
431
617
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args1()", env: @env) }
|
|
432
618
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args1(x: 42, y: 42)", env: @env) }
|
|
433
619
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args1(y: 42)", env: @env) }
|
|
434
620
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args1(42)", env: @env) }
|
|
435
621
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args1(42, x: '42')", env: @env) }
|
|
436
|
-
|
|
622
|
+
assert do_tc("_send_named_args2(x: 42, y: '43')", env: @env) <= RDL::Globals.types[:integer]
|
|
437
623
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args2()", env: @env) }
|
|
438
624
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args2(x: 42)", env: @env) }
|
|
439
625
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args2(x: '42', y: '43')", env: @env) }
|
|
440
626
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args2(42, '43')", env: @env) }
|
|
441
627
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args2(42, x: 42, y: '43')", env: @env) }
|
|
442
628
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args2(x: 42, y: '43', z: 44)", env: @env) }
|
|
443
|
-
|
|
629
|
+
assert do_tc("_send_named_args3(42, y: '43')", env: @env) <= RDL::Globals.types[:integer]
|
|
444
630
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args3(42, y: 43)", env: @env) }
|
|
445
631
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args3()", env: @env) }
|
|
446
632
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args3(42, 43, y: 44)", env: @env) }
|
|
447
633
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args3(42, y: 43, z: 44)", env: @env) }
|
|
448
|
-
|
|
634
|
+
assert do_tc("_send_named_args4(42, x: 43, y: '44')", env: @env) <= RDL::Globals.types[:integer]
|
|
449
635
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args4(42, x: 43)", env: @env) }
|
|
450
636
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args4(42, y: '43')", env: @env) }
|
|
451
637
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args4()", env: @env) }
|
|
452
638
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args4(42, 43, x: 44, y: '45')", env: @env) }
|
|
453
639
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args4(42, x: 43, y: '44', z: 45)", env: @env) }
|
|
454
|
-
|
|
455
|
-
|
|
640
|
+
assert do_tc("_send_named_args5(x: 42, y: '43')", env: @env) <= RDL::Globals.types[:integer]
|
|
641
|
+
assert do_tc("_send_named_args5(x: 42)", env: @env) <= RDL::Globals.types[:integer]
|
|
456
642
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args5()", env: @env) }
|
|
457
643
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args5(x: 42, y: 43)", env: @env) }
|
|
458
644
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args5(x: 42, y: 43, z: 44)", env: @env) }
|
|
459
645
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args5(3, x: 42, y: 43)", env: @env) }
|
|
460
646
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args5(3, x: 42)", env: @env) }
|
|
461
|
-
|
|
462
|
-
|
|
647
|
+
assert do_tc("_send_named_args6(x: 43, y: '44')", env: @env) <= RDL::Globals.types[:integer]
|
|
648
|
+
assert do_tc("_send_named_args6(y: '44')", env: @env) <= RDL::Globals.types[:integer]
|
|
463
649
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args6()", env: @env) }
|
|
464
650
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args6(x: '43', y: '44')", env: @env) }
|
|
465
651
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args6(42, x: 43, y: '44')", env: @env) }
|
|
466
652
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args6(x: 43, y: '44', z: 45)", env: @env) }
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
653
|
+
assert do_tc("_send_named_args7()", env: @env) <= RDL::Globals.types[:integer]
|
|
654
|
+
assert do_tc("_send_named_args7(x: 43)", env: @env) <= RDL::Globals.types[:integer]
|
|
655
|
+
assert do_tc("_send_named_args7(y: '44')", env: @env) <= RDL::Globals.types[:integer]
|
|
656
|
+
assert do_tc("_send_named_args7(x: 43, y: '44')", env: @env) <= RDL::Globals.types[:integer]
|
|
471
657
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args7(x: '43', y: '44')", env: @env) }
|
|
472
658
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args7(41, x: 43, y: '44')", env: @env) }
|
|
473
659
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args7(x: 43, y: '44', z: 45)", env: @env) }
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
660
|
+
assert do_tc("_send_named_args8()", env: @env) <= RDL::Globals.types[:integer]
|
|
661
|
+
assert do_tc("_send_named_args8(43)", env: @env) <= RDL::Globals.types[:integer]
|
|
662
|
+
assert do_tc("_send_named_args8(x: :foo)", env: @env) <= RDL::Globals.types[:integer]
|
|
663
|
+
assert do_tc("_send_named_args8(43, x: :foo)", env: @env) <= RDL::Globals.types[:integer]
|
|
664
|
+
assert do_tc("_send_named_args8(y: 'foo')", env: @env) <= RDL::Globals.types[:integer]
|
|
665
|
+
assert do_tc("_send_named_args8(43, y: 'foo')", env: @env) <= RDL::Globals.types[:integer]
|
|
666
|
+
assert do_tc("_send_named_args8(x: :foo, y: 'foo')", env: @env) <= RDL::Globals.types[:integer]
|
|
667
|
+
assert do_tc("_send_named_args8(43, x: :foo, y: 'foo')", env: @env) <= RDL::Globals.types[:integer]
|
|
482
668
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args8(43, 44, x: :foo, y: 'foo')", env: @env) }
|
|
483
669
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args8(43, x: 'foo', y: 'foo')", env: @env) }
|
|
484
670
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args8(43, x: :foo, y: 'foo', z: 44)", env: @env) }
|
|
485
671
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args9", env: @env) }
|
|
486
672
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args9(43)", env: @env) }
|
|
487
673
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args9(43, x: 'foo')", env: @env) }
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
674
|
+
assert do_tc("_send_named_args9(43, x:'foo', y: 44)", env: @env) <= RDL::Globals.types[:integer]
|
|
675
|
+
assert do_tc("_send_named_args9(43, x:'foo', y: 44, pi: 3.14)", env: @env) <= RDL::Globals.types[:integer]
|
|
676
|
+
assert do_tc("_send_named_args9(43, x:'foo', y: 44, pi: 3.14, e: 2.72)", env: @env) <= RDL::Globals.types[:integer]
|
|
491
677
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args9(43, x: 'foo', y: 44, pi: 3)", env: @env) }
|
|
492
678
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_named_args9(43, x: 'foo', y: 44, pi: 3.14, e: 3)", env: @env) }
|
|
493
679
|
end
|
|
494
680
|
|
|
495
681
|
def test_send_singleton
|
|
496
|
-
type
|
|
497
|
-
|
|
682
|
+
RDL.type Integer, :_send_singleton, "() -> String"
|
|
683
|
+
assert do_tc("3._send_singleton", env: @env) <= RDL::Globals.types[:string]
|
|
498
684
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("3._send_singleton_nexists", env: @env) }
|
|
499
685
|
end
|
|
500
686
|
|
|
501
687
|
def test_send_generic
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
688
|
+
assert do_tc("[1,2,3].length", env: @env) <= RDL::Globals.types[:integer]
|
|
689
|
+
assert do_tc("{a:1, b:2}.length", env: @env) <= RDL::Globals.types[:integer]
|
|
690
|
+
assert do_tc("String.new.clone", env: @env) <= RDL::Globals.types[:string]
|
|
505
691
|
# TODO test case with other generic
|
|
506
692
|
end
|
|
507
693
|
|
|
508
694
|
def test_send_alias
|
|
509
|
-
|
|
695
|
+
assert do_tc("[1,2,3].size", env: @env) <= RDL::Globals.types[:integer]
|
|
510
696
|
end
|
|
511
697
|
|
|
512
698
|
def test_send_block
|
|
513
699
|
self.class.class_eval {
|
|
514
|
-
type :_send_block1, "(
|
|
515
|
-
type :_send_block2, "(
|
|
700
|
+
type :_send_block1, "(Integer) { (Integer) -> Integer } -> Integer"
|
|
701
|
+
type :_send_block2, "(Integer) -> Integer"
|
|
516
702
|
}
|
|
517
703
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_block1(42)", env: @env) }
|
|
518
704
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_block2(42) { |x| x + 1 }", env: @env) }
|
|
519
705
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_block1(42) { |x, y| x + y }", env: @env) }
|
|
520
|
-
|
|
706
|
+
assert do_tc("_send_block1(42) { |x| x }", env: @env) <= RDL::Globals.types[:integer]
|
|
521
707
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_send_block1(42) { |x| 'forty-two' }", env: @env) }
|
|
522
708
|
self.class.class_eval {
|
|
523
709
|
type "() -> 1", typecheck: :now
|
|
@@ -532,7 +718,7 @@ class TestTypecheck < Minitest::Test
|
|
|
532
718
|
end
|
|
533
719
|
}
|
|
534
720
|
self.class.class_eval {
|
|
535
|
-
type "() ->
|
|
721
|
+
type "() -> Integer or String", typecheck: :now
|
|
536
722
|
def _send_blockd3
|
|
537
723
|
x = 'one'; _send_block1(42) { |y| for x in 1..5 do end; y }; x
|
|
538
724
|
end
|
|
@@ -543,50 +729,49 @@ class TestTypecheck < Minitest::Test
|
|
|
543
729
|
self.class.class_eval {
|
|
544
730
|
type :_send_method_generic1, '(t) -> t'
|
|
545
731
|
type :_send_method_generic2, '(t, u) -> t or u'
|
|
546
|
-
type :_send_method_generic3, '() { (u) ->
|
|
732
|
+
type :_send_method_generic3, '() { (u) -> Integer } -> Integer'
|
|
547
733
|
type :_send_method_generic4, '(t) { (t) -> t } -> t'
|
|
548
734
|
type :_send_method_generic5, '() { (u) -> u } -> u'
|
|
549
|
-
type :_send_method_generic6, '() { (
|
|
735
|
+
type :_send_method_generic6, '() { (Integer) -> u } -> u'
|
|
550
736
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
737
|
+
assert do_tc('_send_method_generic1 3', env: @env) <= @t3
|
|
738
|
+
assert do_tc('_send_method_generic1 "foo"', env: @env) <= RDL::Globals.types[:string]
|
|
739
|
+
assert do_tc('_send_method_generic2 3, "foo"', env: @env) <= tt("3 or String")
|
|
740
|
+
assert do_tc('_send_method_generic3 { |x| 42 }', env: @env) <= RDL::Globals.types[:integer]
|
|
741
|
+
assert do_tc('_send_method_generic4(42) { |x| x }', env: @env) <= tt("42")
|
|
556
742
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc('_send_method_generic4(42) { |x| "foo" }', env: @env) }
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
assert_equal tt("Array<String>"), do_tc('[1, 2, 3].map { |y| y.to_s }', env: @env)
|
|
743
|
+
assert do_tc('_send_method_generic5 { |x| x }', env: @env) <= tt("u") # not possible to implement _send_method_generic5!
|
|
744
|
+
assert do_tc('_send_method_generic5 { |x| 3 }', env: @env) <= tt("3") # weird example, but can pick u=3
|
|
745
|
+
assert do_tc('_send_method_generic6 { |x| "foo" }', env: @env) <= RDL::Globals.types[:string]
|
|
746
|
+
assert do_tc('[1,2,3].index(Object.new)', env: @env) <= tt("Integer")
|
|
747
|
+
assert do_tc('[1, 2, 3].map { |y| y.to_s }', env: @env) <= tt("Array<String>")
|
|
563
748
|
end
|
|
564
749
|
|
|
565
750
|
def test_send_union
|
|
566
751
|
self.class.class_eval {
|
|
567
|
-
type :_send_union1, "(
|
|
752
|
+
type :_send_union1, "(Integer) -> Float"
|
|
568
753
|
type :_send_union1, "(String) -> Rational"
|
|
569
754
|
}
|
|
570
|
-
|
|
571
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("(if _any_object then Object.new else
|
|
572
|
-
|
|
755
|
+
assert do_tc("(if _any_object then Integer.new else String.new end) * 2", env: @env) <= RDL::Type::UnionType.new(@tfs, RDL::Globals.types[:integer])
|
|
756
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("(if _any_object then Object.new else Integer.new end) + 2", env: @env) }
|
|
757
|
+
assert do_tc("if _any_object then x = Integer.new else x = String.new end; _send_union1(x)", env: @env) <= tt("Float or Rational")
|
|
573
758
|
end
|
|
574
759
|
|
|
575
760
|
def test_send_splat
|
|
576
761
|
self.class.class_eval {
|
|
577
|
-
type :_send_splat1, "(
|
|
578
|
-
type :_send_splat2, "(String, *
|
|
579
|
-
type :_send_splat_fa, "() -> Array<
|
|
762
|
+
type :_send_splat1, "(Integer, String, Integer, String) -> Integer"
|
|
763
|
+
type :_send_splat2, "(String, *Integer, Float) -> Integer"
|
|
764
|
+
type :_send_splat_fa, "() -> Array<Integer>"
|
|
580
765
|
}
|
|
581
|
-
|
|
582
|
-
|
|
766
|
+
assert do_tc("x = ['foo', 42]; _send_splat1(1, *x, 'bar')", env: @env) <= RDL::Globals.types[:integer]
|
|
767
|
+
assert do_tc("x = _send_splat_fa; _send_splat2('foo', *x, 3.14)", env: @env) <= RDL::Globals.types[:integer]
|
|
583
768
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = _send_splat_fa; _send_splat1(*x, 'foo', 2, 'bar')", env: @env) }
|
|
584
769
|
end
|
|
585
770
|
|
|
586
771
|
|
|
587
772
|
def test_yield
|
|
588
773
|
self.class.class_eval {
|
|
589
|
-
type "(
|
|
774
|
+
type "(Integer) { (Integer) -> Integer } -> Integer", typecheck: :now
|
|
590
775
|
def _yield1(x)
|
|
591
776
|
yield x
|
|
592
777
|
end
|
|
@@ -594,7 +779,7 @@ class TestTypecheck < Minitest::Test
|
|
|
594
779
|
|
|
595
780
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
596
781
|
self.class.class_eval {
|
|
597
|
-
type "(
|
|
782
|
+
type "(Integer) { (Integer) -> Integer } -> Integer", typecheck: :now
|
|
598
783
|
def _yield2(x)
|
|
599
784
|
yield 'forty-two'
|
|
600
785
|
end
|
|
@@ -603,7 +788,7 @@ class TestTypecheck < Minitest::Test
|
|
|
603
788
|
|
|
604
789
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
605
790
|
self.class.class_eval {
|
|
606
|
-
type "(
|
|
791
|
+
type "(Integer) { (Integer) -> String } -> Integer", typecheck: :now
|
|
607
792
|
def _yield3(x)
|
|
608
793
|
yield 42
|
|
609
794
|
end
|
|
@@ -612,7 +797,7 @@ class TestTypecheck < Minitest::Test
|
|
|
612
797
|
|
|
613
798
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
614
799
|
self.class.class_eval {
|
|
615
|
-
type "(
|
|
800
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
616
801
|
def _yield4(x)
|
|
617
802
|
yield 42
|
|
618
803
|
end
|
|
@@ -621,7 +806,7 @@ class TestTypecheck < Minitest::Test
|
|
|
621
806
|
|
|
622
807
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
623
808
|
self.class.class_eval {
|
|
624
|
-
type "(
|
|
809
|
+
type "(Integer) { (Integer) { (Integer) -> Integer } -> Integer } -> Integer", typecheck: :now
|
|
625
810
|
def _yield5(x)
|
|
626
811
|
yield 42
|
|
627
812
|
end
|
|
@@ -631,7 +816,7 @@ class TestTypecheck < Minitest::Test
|
|
|
631
816
|
|
|
632
817
|
def test_block_arg
|
|
633
818
|
self.class.class_eval {
|
|
634
|
-
type "(
|
|
819
|
+
type "(Integer) { (Integer) -> Integer } -> Integer", typecheck: :now
|
|
635
820
|
def _block_arg1(x, &blk)
|
|
636
821
|
blk.call x
|
|
637
822
|
end
|
|
@@ -639,7 +824,7 @@ class TestTypecheck < Minitest::Test
|
|
|
639
824
|
|
|
640
825
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
641
826
|
self.class.class_eval {
|
|
642
|
-
type "(
|
|
827
|
+
type "(Integer) { (Integer) -> Integer } -> Integer", typecheck: :now
|
|
643
828
|
def _block_arg2(x, &blk)
|
|
644
829
|
blk.call 'forty-two'
|
|
645
830
|
end
|
|
@@ -648,7 +833,7 @@ class TestTypecheck < Minitest::Test
|
|
|
648
833
|
|
|
649
834
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
650
835
|
self.class.class_eval {
|
|
651
|
-
type "(
|
|
836
|
+
type "(Integer) { (Integer) -> String } -> Integer", typecheck: :now
|
|
652
837
|
def _block_arg3(x, &foo)
|
|
653
838
|
foo.call 42
|
|
654
839
|
end
|
|
@@ -657,7 +842,7 @@ class TestTypecheck < Minitest::Test
|
|
|
657
842
|
|
|
658
843
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
659
844
|
self.class.class_eval {
|
|
660
|
-
type "(
|
|
845
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
661
846
|
def _block_arg4(x, &blk)
|
|
662
847
|
blk.call 42
|
|
663
848
|
end
|
|
@@ -666,7 +851,7 @@ class TestTypecheck < Minitest::Test
|
|
|
666
851
|
|
|
667
852
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
668
853
|
self.class.class_eval {
|
|
669
|
-
type "(
|
|
854
|
+
type "(Integer) { (Integer) { (Integer) -> Integer } -> Integer } -> Integer", typecheck: :now
|
|
670
855
|
def _block_arg5(x, &blk)
|
|
671
856
|
blk.call 42
|
|
672
857
|
end
|
|
@@ -674,8 +859,8 @@ class TestTypecheck < Minitest::Test
|
|
|
674
859
|
}
|
|
675
860
|
|
|
676
861
|
self.class.class_eval {
|
|
677
|
-
type :_block_arg6, "(
|
|
678
|
-
type "() { (
|
|
862
|
+
type :_block_arg6, "(Integer) { (Integer) -> Integer } -> Integer"
|
|
863
|
+
type "() { (Integer) -> Integer } -> Integer", typecheck: :now
|
|
679
864
|
def _block_arg7(&blk)
|
|
680
865
|
_block_arg6(42, &blk)
|
|
681
866
|
end
|
|
@@ -683,7 +868,7 @@ class TestTypecheck < Minitest::Test
|
|
|
683
868
|
|
|
684
869
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
685
870
|
self.class.class_eval {
|
|
686
|
-
type "() { (
|
|
871
|
+
type "() { (Integer) -> String } -> Integer", typecheck: :now
|
|
687
872
|
def _block_arg8(&blk)
|
|
688
873
|
_block_arg6(42, &blk)
|
|
689
874
|
end
|
|
@@ -692,7 +877,7 @@ class TestTypecheck < Minitest::Test
|
|
|
692
877
|
|
|
693
878
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
694
879
|
self.class.class_eval {
|
|
695
|
-
type "() ->
|
|
880
|
+
type "() -> Integer", typecheck: :now
|
|
696
881
|
def _block_arg9()
|
|
697
882
|
_block_arg6(42, &(1+2))
|
|
698
883
|
end
|
|
@@ -700,23 +885,23 @@ class TestTypecheck < Minitest::Test
|
|
|
700
885
|
}
|
|
701
886
|
|
|
702
887
|
self.class.class_eval {
|
|
703
|
-
type :_block_arg10, "(
|
|
704
|
-
type :_block_arg11, "(
|
|
888
|
+
type :_block_arg10, "(Integer) -> Integer"
|
|
889
|
+
type :_block_arg11, "(Integer) -> String"
|
|
705
890
|
}
|
|
706
|
-
|
|
891
|
+
assert do_tc("_block_arg6(42, &:_block_arg10)", env: @env) <= RDL::Globals.types[:integer]
|
|
707
892
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_block_arg6(42, &:_block_arg11)", env: @env) }
|
|
708
893
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("_block_arg6(42, &:_block_arg_does_not_exist)", env: @env) }
|
|
709
894
|
end
|
|
710
895
|
|
|
711
896
|
# class Sup1
|
|
712
|
-
# type '(
|
|
897
|
+
# type '(Integer) -> Integer', typecheck: :call
|
|
713
898
|
# def foo(y)
|
|
714
899
|
# return y
|
|
715
900
|
# end
|
|
716
901
|
# end
|
|
717
902
|
#
|
|
718
903
|
# class Sup2 < Sup1
|
|
719
|
-
# type '(
|
|
904
|
+
# type '(Integer) -> Integer', typecheck: :call
|
|
720
905
|
# def foo(x)
|
|
721
906
|
# super(x+1)
|
|
722
907
|
# end
|
|
@@ -727,130 +912,132 @@ class TestTypecheck < Minitest::Test
|
|
|
727
912
|
# end
|
|
728
913
|
|
|
729
914
|
def test_new
|
|
730
|
-
|
|
915
|
+
assert do_tc("B.new", env: @env) <= RDL::Type::NominalType.new(B)
|
|
731
916
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("B.new(3)", env: @env) }
|
|
732
917
|
end
|
|
733
918
|
|
|
734
919
|
def test_if
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
920
|
+
assert do_tc("if _any_object then 3 end", env: @env) <= @t3n
|
|
921
|
+
assert do_tc("unless _any_object then 3 end", env: @env) <= @t3n
|
|
922
|
+
assert do_tc("if _any_object then 3 else 4 end", env: @env) <= @t34
|
|
923
|
+
assert do_tc("unless _any_object then 3 else 4 end", env: @env) <= @t34
|
|
924
|
+
assert do_tc("if _any_object then 3 else 'three' end", env: @env) <= @ts3
|
|
925
|
+
assert do_tc("unless _any_object then 3 else 'three' end", env: @env) <= @ts3
|
|
926
|
+
assert do_tc("3 if _any_object", env: @env) <= @t3n
|
|
927
|
+
assert do_tc("3 unless _any_object", env: @env) <= @t3n
|
|
928
|
+
assert do_tc("if true then 3 else 'three' end", env: @env) <= @t3
|
|
929
|
+
assert do_tc("if :foo then 3 else 'three' end", env: @env) <= @t3
|
|
930
|
+
assert do_tc("if false then 3 else 'three' end", env: @env) <= RDL::Globals.types[:string]
|
|
931
|
+
assert do_tc("if nil then 3 else 'three' end", env: @env) <= RDL::Globals.types[:string]
|
|
932
|
+
|
|
933
|
+
assert do_tc("x = 'three'; if _any_object then x = 4 else x = 5 end; x", env: @env) <= @t45
|
|
934
|
+
assert do_tc("x = 'three'; if _any_object then x = 3 end; x", env: @env) <= @ts3
|
|
935
|
+
assert do_tc("x = 'three'; unless _any_object then x = 3 end; x", env: @env) <= @ts3
|
|
936
|
+
assert do_tc("if _any_object then y = 4 end; y", env: @env) # vars are nil if not defined on branch <= @t4n
|
|
937
|
+
assert do_tc("if _any_object then x = 3; y = 4 else x = 5 end; x", env: @env) <= @t35
|
|
938
|
+
assert do_tc("if _any_object then x = 3; y = 4 else x = 5 end; y", env: @env) <= @t4n
|
|
754
939
|
end
|
|
755
940
|
|
|
756
941
|
def test_and_or
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
942
|
+
assert do_tc("'foo' and 3") <= @ts3
|
|
943
|
+
assert do_tc("'foo' && 3") <= @ts3
|
|
944
|
+
assert do_tc("3 and 'foo'") <= RDL::Globals.types[:string]
|
|
945
|
+
assert do_tc("nil and 'foo'") <= RDL::Globals.types[:nil]
|
|
946
|
+
assert do_tc("false and 'foo'") <= RDL::Globals.types[:false]
|
|
947
|
+
assert do_tc("(x = 'foo') and (x = 3); x") <= @ts3
|
|
948
|
+
assert do_tc("(x = 3) and (x = 'foo'); x") <= RDL::Globals.types[:string]
|
|
949
|
+
assert do_tc("(x = nil) and (x = 'foo'); x") <= RDL::Globals.types[:nil]
|
|
950
|
+
assert do_tc("(x = false) and (x = 'foo'); x") <= RDL::Globals.types[:false]
|
|
951
|
+
|
|
952
|
+
assert do_tc("'foo' or 3") <= @ts3
|
|
953
|
+
assert do_tc("'foo' || 3") <= @ts3
|
|
954
|
+
assert do_tc("3 or 'foo'") <= @t3
|
|
955
|
+
assert do_tc("nil or 3") <= @t3
|
|
956
|
+
assert do_tc("false or 3") <= @t3
|
|
957
|
+
assert do_tc("(x = 'foo') or (x = 3); x") <= @ts3
|
|
958
|
+
assert do_tc("(x = 3) or (x = 'foo'); x") <= @t3
|
|
959
|
+
assert do_tc("(x = nil) or (x = 3); x") <= @t3
|
|
960
|
+
assert do_tc("(x = false) or (x = 3); x") <= @t3
|
|
776
961
|
end
|
|
777
962
|
|
|
778
963
|
class C
|
|
964
|
+
extend RDL::Annotate
|
|
779
965
|
type :===, "(Object) -> %bool"
|
|
780
966
|
end
|
|
781
967
|
|
|
782
968
|
class D
|
|
969
|
+
extend RDL::Annotate
|
|
783
970
|
type :===, "(String) -> %bool"
|
|
784
971
|
end
|
|
785
972
|
|
|
786
973
|
def test_when
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
974
|
+
assert do_tc("case when C.new then 3 end", env: @env) <= @t3
|
|
975
|
+
assert do_tc("x = 4; case when _any_object then x = 3 end; x", env: @env) <= @t34
|
|
976
|
+
assert do_tc("case when _any_object then 3 else 'foo' end", env: @env) <= @ts3
|
|
977
|
+
assert do_tc("x = 4; case when _any_object then x = 3 else x = 'foo' end; x", env: @env) <= @ts3
|
|
791
978
|
|
|
792
|
-
|
|
793
|
-
|
|
979
|
+
assert do_tc("case _any_object when C.new then 'foo' end", env: @env) <= RDL::Globals.types[:string]
|
|
980
|
+
assert do_tc("x = 3; case _any_object when C.new then x = 'foo' end; x", env: @env) <= @ts3
|
|
794
981
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("case _any_object when D.new then 'foo' end", env: @env) }
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
982
|
+
assert do_tc("case _any_object when C.new then 'foo' else 3 end", env: @env) <= @ts3
|
|
983
|
+
assert do_tc("x = 4; case _any_object when C.new then x = 'foo' else x = 3 end; x", env: @env) <= @ts3
|
|
984
|
+
assert do_tc("case _any_object when C.new then 'foo' when C.new then 4 else 3 end", env: @env) <= @ts34
|
|
985
|
+
assert do_tc("x = 5; case _any_object when C.new then x = 'foo' when C.new then x = 4 else x = 3 end; x", env: @env) <= @ts34
|
|
799
986
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
987
|
+
assert do_tc("case when (x = 3) then 'foo' end; x", env: @env) <= @t3
|
|
988
|
+
assert do_tc("case when (x = 3), (x = 4) then 'foo' end; x", env: @env) <= @t34
|
|
989
|
+
assert do_tc("case when (x = 3), (x = 4) then 'foo' end; x", env: @env) <= @t34
|
|
990
|
+
assert do_tc("case when (x = 4) then x = 3 end; x", env: @env) <= @t34
|
|
991
|
+
assert do_tc("x = 5; case when (x = 3) then 'foo' when (x = 4) then 'foo' end; x", env: @env) # first guard always executed! <= @t34
|
|
992
|
+
assert do_tc("x = 6; case when (x = 3) then 'foo' when (x = 4) then 'foo' else x = 5 end; x", env: @env) <= @t345
|
|
806
993
|
end
|
|
807
994
|
|
|
808
995
|
def test_while_until
|
|
809
996
|
# TODO these don't do a great job checking control flow
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
997
|
+
assert do_tc("while true do end") <= RDL::Globals.types[:nil]
|
|
998
|
+
assert do_tc("until false do end") <= RDL::Globals.types[:nil]
|
|
999
|
+
assert do_tc("begin end while true") <= RDL::Globals.types[:nil]
|
|
1000
|
+
assert do_tc("begin end until false") <= RDL::Globals.types[:nil]
|
|
1001
|
+
assert do_tc("i = 0; while i < 5 do i = 1 + i end; i") <= RDL::Globals.types[:integer]
|
|
1002
|
+
assert do_tc("i = 0; while i < 5 do i = i + 1 end; i") <= RDL::Globals.types[:integer]
|
|
1003
|
+
assert do_tc("i = 0; until i >= 5 do i = 1 + i end; i") <= RDL::Globals.types[:integer]
|
|
1004
|
+
assert do_tc("i = 0; until i >= 5 do i = i + 1 end; i") <= RDL::Globals.types[:integer]
|
|
1005
|
+
assert do_tc("i = 0; begin i = 1 + i end while i < 5; i") <= RDL::Globals.types[:integer]
|
|
1006
|
+
assert do_tc("i = 0; begin i = i + 1 end while i < 5; i") <= RDL::Globals.types[:integer]
|
|
1007
|
+
assert do_tc("i = 0; begin i = 1 + i end until i >= 5; i") <= RDL::Globals.types[:integer]
|
|
1008
|
+
assert do_tc("i = 0; begin i = i + 1 end until i >= 5; i") <= RDL::Globals.types[:integer]
|
|
822
1009
|
|
|
823
1010
|
# break, redo, next, no args
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
1011
|
+
assert do_tc("i = 0; while i < 5 do if i > 2 then break end; i = 1 + i end; i") <= RDL::Globals.types[:integer]
|
|
1012
|
+
assert do_tc("i = 0; while i < 5 do break end; i") <= tt("0")
|
|
1013
|
+
assert do_tc("i = 0; while i < 5 do redo end; i") # infinite loop, ok for typing <= tt("0")
|
|
1014
|
+
assert do_tc("i = 0; while i < 5 do next end; i") # infinite loop, ok for typing <= tt("0")
|
|
828
1015
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("i = 0; while i < 5 do retry end; i") }
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1016
|
+
assert do_tc("i = 0; begin i = i + 1; break if i > 2; end while i < 5; i") <= RDL::Globals.types[:integer]
|
|
1017
|
+
assert do_tc("i = 0; begin i = i + 1; redo if i > 2; end while i < 5; i") <= RDL::Globals.types[:integer]
|
|
1018
|
+
assert do_tc("i = 0; begin i = i + 1; next if i > 2; end while i < 5; i") <= RDL::Globals.types[:integer]
|
|
832
1019
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("i = 0; begin i = i + 1; retry if i > 2; end while i < 5; i") }
|
|
833
1020
|
|
|
834
1021
|
# break w/arg, next can't take arg
|
|
835
|
-
|
|
1022
|
+
assert do_tc("while _any_object do break 3 end", env: @env) <= @t3n
|
|
836
1023
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("while _any_object do next 3 end", env: @env) }
|
|
837
|
-
|
|
1024
|
+
assert do_tc("begin break 3 end while _any_object", env: @env) <= @t3n
|
|
838
1025
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("begin next 3 end while _any_object", env: @env) }
|
|
839
1026
|
end
|
|
840
1027
|
|
|
841
1028
|
def test_for
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1029
|
+
assert do_tc("for i in 1..5 do end; i") <= RDL::Globals.types[:integer]
|
|
1030
|
+
assert do_tc("for i in [1,2,3,4,5] do end; i") <= tt("1 or 2 or 3 or 4 or 5")
|
|
1031
|
+
assert do_tc("for i in 1..5 do break end", env: @env) <= tt("Range<Integer>")
|
|
1032
|
+
assert do_tc("for i in 1..5 do next end", env: @env) <= tt("Range<Integer>")
|
|
1033
|
+
assert do_tc("for i in 1..5 do redo end", env: @env) <= tt("Range<Integer>") #infinite loop, ok for typing
|
|
1034
|
+
assert do_tc("for i in 1..5 do break 3 end", env: @env) <= tt("Range<Integer> or 3")
|
|
1035
|
+
assert do_tc("for i in 1..5 do next 'three' end; i", env: @env) <= @tfs
|
|
849
1036
|
end
|
|
850
1037
|
|
|
851
1038
|
def test_return
|
|
852
1039
|
assert self.class.class_eval {
|
|
853
|
-
type "(
|
|
1040
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
854
1041
|
def return_ff(x)
|
|
855
1042
|
return 42
|
|
856
1043
|
end
|
|
@@ -858,129 +1045,177 @@ class TestTypecheck < Minitest::Test
|
|
|
858
1045
|
|
|
859
1046
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
860
1047
|
self.class.class_eval {
|
|
861
|
-
type "(
|
|
1048
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
862
1049
|
def return_ff2(x)
|
|
863
1050
|
return "forty-two"
|
|
864
1051
|
end
|
|
865
1052
|
}
|
|
866
1053
|
}
|
|
867
1054
|
|
|
868
|
-
|
|
869
|
-
|
|
1055
|
+
assert do_tc("return 42", scope: @scopefs) <= RDL::Globals.types[:bot]
|
|
1056
|
+
assert do_tc("if _any_object then return 42 else return 'forty-two' end", env: @env, scope: @scopefs) <= RDL::Globals.types[:bot]
|
|
870
1057
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("if _any_object then return 42 else return 'forty-two' end", env: @env, scope: @scopef) }
|
|
871
|
-
|
|
1058
|
+
assert do_tc("return 42 if _any_object; 'forty-two'", env: @env, scope: @scopef) <= RDL::Globals.types[:string]
|
|
872
1059
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("return 'forty-two' if _any_object; 42", env: @env, scope: @scopef) }
|
|
873
1060
|
end
|
|
874
1061
|
|
|
875
1062
|
class E
|
|
876
|
-
|
|
877
|
-
type :f
|
|
1063
|
+
extend RDL::Annotate
|
|
1064
|
+
type :f, '() -> Integer'
|
|
1065
|
+
type :f=, '(Integer) -> nil'
|
|
878
1066
|
end
|
|
879
1067
|
|
|
880
1068
|
def test_op_asgn
|
|
881
|
-
assert
|
|
1069
|
+
assert RDL::Globals.types[:integer], do_tc("x = 0; x += 1")
|
|
882
1070
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x += 1") }
|
|
883
1071
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = Object.new; x += 1", env: @env) }
|
|
884
|
-
|
|
885
|
-
|
|
1072
|
+
assert do_tc("e = E.new; e.f += 1", env: @env) <= RDL::Globals.types[:nil] # return type of f=
|
|
1073
|
+
assert do_tc("x &= false") <= RDL::Globals.types[:false] # weird
|
|
1074
|
+
assert do_tc("h = {}; h = RDL.type_cast(h, 'Hash<Symbol, String>', force: true); h[:a] = ''; h[:a] += 's'", env: @env) <= RDL::Globals.types[:string]
|
|
886
1075
|
end
|
|
887
1076
|
|
|
888
1077
|
def test_and_or_asgn
|
|
889
1078
|
self.class.class_eval {
|
|
890
|
-
var_type :@f_and_or_asgn, "
|
|
1079
|
+
var_type :@f_and_or_asgn, "Integer"
|
|
891
1080
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1081
|
+
assert do_tc("x ||= 3") <= @t3 # weird
|
|
1082
|
+
assert do_tc("x &&= 3") <= RDL::Globals.types[:nil] # weirder
|
|
1083
|
+
assert do_tc("@f_and_or_asgn &&= 4", env: @env) <= RDL::Globals.types[:integer]
|
|
1084
|
+
assert do_tc("x = 3; x ||= 'three'") <= @t3
|
|
1085
|
+
assert do_tc("x = 'three'; x ||= 3") <= @ts3
|
|
1086
|
+
assert do_tc("e = E.new; e.f ||= 3", env: @env) <= RDL::Globals.types[:nil] # return type of f=
|
|
1087
|
+
assert do_tc("e = E.new; e.f &&= 3", env: @env) <= RDL::Globals.types[:nil] # return type of f=
|
|
899
1088
|
end
|
|
900
1089
|
|
|
901
1090
|
def test_masgn
|
|
902
1091
|
self.class.class_eval {
|
|
903
|
-
var_type :@f_masgn, "Array<
|
|
1092
|
+
var_type :@f_masgn, "Array<Integer>"
|
|
904
1093
|
}
|
|
905
1094
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x, y = 3") } # allowed in Ruby but probably has surprising behavior
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
1095
|
+
assert do_tc("a, b = @f_masgn", env: @env) <= tt("Array<Integer>")
|
|
1096
|
+
assert do_tc("a, b = @f_masgn; a", env: @env) <= RDL::Globals.types[:integer]
|
|
1097
|
+
assert do_tc("a, b = @f_masgn; b", env: @env) <= RDL::Globals.types[:integer]
|
|
909
1098
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("var_type :a, 'String'; a, b = @f_masgn", env: @env) }
|
|
910
1099
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("a, b = 1, 2, 3") }
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
1100
|
+
assert do_tc("a, b = 3, 'two'; a") <= @t3
|
|
1101
|
+
assert do_tc("a, b = 3, 'two'; b") <= RDL::Globals.types[:string]
|
|
1102
|
+
assert do_tc("a = [3, 'two']; x, y = a; x") <= @t3
|
|
1103
|
+
assert do_tc("a = [3, 'two']; x, y = a; y") <= RDL::Globals.types[:string]
|
|
915
1104
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("a = [3, 'two']; x, y = a; a.length", env: @env) }
|
|
916
1105
|
|
|
917
1106
|
# w/send
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1107
|
+
assert do_tc("e = E.new; e.f, b = 1, 2; b", env: @env) <= tt("2")
|
|
1108
|
+
assert do_tc("e = E.new; e.f, b = @f_masgn; b", env: @env) <= RDL::Globals.types[:integer]
|
|
1109
|
+
assert do_tc("@f_masgn[3], y = 1, 2", env: @env) <= tt("[1, 2]")
|
|
921
1110
|
|
|
922
1111
|
# w/splat
|
|
923
|
-
|
|
1112
|
+
assert do_tc("*x = [1, 2, 3]") <= tt("[1, 2, 3]")
|
|
924
1113
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("*x = 1") } # allowed in Ruby, but why would you write this code?
|
|
925
1114
|
|
|
926
1115
|
# w/splat on right
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1116
|
+
assert do_tc("x, *y = [1, 2, 3]; x") <= tt("1")
|
|
1117
|
+
assert do_tc("x, *y = [1, 2, 3]; y") <= tt("[2, 3]")
|
|
1118
|
+
assert do_tc("x, *y = [1]; x") <= tt("1")
|
|
1119
|
+
assert do_tc("x, *y = [1]; y") <= tt("[]")
|
|
931
1120
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x, *y = 1") } # allowed in Ruby, but hard to justify, so RDL error
|
|
932
|
-
|
|
933
|
-
|
|
1121
|
+
assert do_tc("x, *y = @f_masgn; x", env: @env) <= RDL::Globals.types[:integer]
|
|
1122
|
+
assert do_tc("x, *y = @f_masgn; y", env: @env) <= tt("Array<Integer>")
|
|
934
1123
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x, y, *z = [1]") } # works in Ruby, but confusing so RDL reports error
|
|
935
1124
|
|
|
936
1125
|
# w/splat on left
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1126
|
+
assert do_tc("*x, y = [1, 2, 3]; x") <= tt("[1, 2]")
|
|
1127
|
+
assert do_tc("*x, y = [1, 2, 3]; y") <= tt("3")
|
|
1128
|
+
assert do_tc("*x, y = [1]; x") <= tt("[]")
|
|
1129
|
+
assert do_tc("*x, y = [1]; y") <= tt("1")
|
|
941
1130
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("*x, y = 1") } # as above
|
|
942
|
-
|
|
943
|
-
|
|
1131
|
+
assert do_tc("*x, y = @f_masgn; x", env: @env) <= tt("Array<Integer>")
|
|
1132
|
+
assert do_tc("*x, y = @f_masgn; y", env: @env) <= RDL::Globals.types[:integer]
|
|
944
1133
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("*x, y, z = [1]") } # as above
|
|
945
1134
|
|
|
946
1135
|
# w/splat in middle
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
1136
|
+
assert do_tc("x, *y, z = [1, 2]; x") <= tt("1")
|
|
1137
|
+
assert do_tc("x, *y, z = [1, 2]; y") <= tt("[]")
|
|
1138
|
+
assert do_tc("x, *y, z = [1, 2]; z") <= tt("2")
|
|
1139
|
+
assert do_tc("x, *y, z = [1, 2, 3, 4]; x") <= tt("1")
|
|
1140
|
+
assert do_tc("x, *y, z = [1, 2, 3, 4]; y") <= tt("[2, 3]")
|
|
1141
|
+
assert do_tc("x, *y, z = [1, 2, 3, 4]; z") <= tt("4")
|
|
953
1142
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x, *y, z = 1") } # as above
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1143
|
+
assert do_tc("x, *y, z = @f_masgn; x", env: @env) <= RDL::Globals.types[:integer]
|
|
1144
|
+
assert do_tc("x, *y, z = @f_masgn; y", env: @env) <= tt("Array<Integer>")
|
|
1145
|
+
assert do_tc("x, *y, z = @f_masgn; z", env: @env) <= RDL::Globals.types[:integer]
|
|
957
1146
|
end
|
|
958
1147
|
|
|
959
1148
|
def test_cast
|
|
960
|
-
|
|
961
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("
|
|
962
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("(1 + 2
|
|
967
|
-
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("(1 + 2
|
|
1149
|
+
assert do_tc("RDL.type_cast(1 + 2, 'Integer')", env: @env) <= RDL::Globals.types[:integer]
|
|
1150
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.type_cast(1, 'Integer', 42)", env: @env) }
|
|
1151
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.type_cast(1, Integer)", env: @env) }
|
|
1152
|
+
assert do_tc("RDL.type_cast(1 + 2, 'Integer', force: true)", env: @env) <= RDL::Globals.types[:integer]
|
|
1153
|
+
assert do_tc("RDL.type_cast(1 + 2, 'Integer', force: false)", env: @env) <= RDL::Globals.types[:integer]
|
|
1154
|
+
assert do_tc("RDL.type_cast(1 + 2, 'Integer', force: :blah)", env: @env) <= RDL::Globals.types[:integer]
|
|
1155
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.type_cast(1 + 2, 'Integer', forc: true)", env: @env) }
|
|
1156
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("RDL.type_cast(1 + 2, 'Fluffy Bunny')") }
|
|
1157
|
+
end
|
|
1158
|
+
|
|
1159
|
+
def test_instantiate
|
|
1160
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1161
|
+
self.class.class_eval {
|
|
1162
|
+
type "(Integer, Integer) -> Array<Integer>", typecheck: :now
|
|
1163
|
+
def def_inst_fail(x, y) a = Array.new(x,y); a; end
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
assert (
|
|
1167
|
+
self.class.class_eval {
|
|
1168
|
+
type "(Integer, Integer) -> Array<Integer>", typecheck: :now
|
|
1169
|
+
def def_inst_pass(x, y) a = Array.new(x,y); RDL.instantiate!(a, "Integer"); a; end
|
|
1170
|
+
}
|
|
1171
|
+
)
|
|
1172
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1173
|
+
self.class.class_eval {
|
|
1174
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
1175
|
+
def def_inst_hash_fail(x) hash = {}; hash["test"] = x; hash["test"]; end
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1179
|
+
self.class.class_eval {
|
|
1180
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
1181
|
+
def def_inst_hash_fail2(x) hash = {}; hash.instantiate("Integer", "String") ; hash["test"] = x; hash["test"]; end
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
assert(
|
|
1185
|
+
self.class.class_eval {
|
|
1186
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
1187
|
+
def def_inst_hash_pass(x) hash = {}; RDL.instantiate!(hash, String, Integer); hash["test"] = x; hash["test"]; end
|
|
1188
|
+
}
|
|
1189
|
+
)
|
|
1190
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1191
|
+
self.class.class_eval {
|
|
1192
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
1193
|
+
def def_inst_no_param(x) RDL.instantiate!(x, Integer); end
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1198
|
+
self.class.class_eval {
|
|
1199
|
+
type "(Integer) -> Integer", typecheck: :now
|
|
1200
|
+
def def_inst_num_args(x) a = Array.new(x, x); RDL.instatntiate!(a, Integer, Integer, Integer); end
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
968
1203
|
end
|
|
969
1204
|
|
|
970
1205
|
def test_rescue_ensure
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1206
|
+
assert do_tc("begin 3; rescue; 4; end") <= @t3 # rescue clause can never be executed
|
|
1207
|
+
assert do_tc("begin puts 'foo'; 3; rescue; 4; end", env: @env) <= @t34
|
|
1208
|
+
assert do_tc("begin puts 'foo'; 3; rescue => e; e; end", env: @env) <= tt("StandardError or 3")
|
|
1209
|
+
assert do_tc("begin puts 'foo'; 3; rescue RuntimeError => e; e; end", env: @env) <= tt("RuntimeError or 3")
|
|
1210
|
+
assert do_tc("begin puts 'foo'; 3; else; 4; end", env: @env) <= tt("4") # parser discards else clause!
|
|
1211
|
+
assert do_tc("begin puts 'foo'; 3; rescue RuntimeError => e; e; rescue ArgumentError => x; x; end", env: @env) <= tt("RuntimeError or ArgumentError or 3")
|
|
1212
|
+
assert do_tc("begin puts 'foo'; 3; rescue RuntimeError => e; e; rescue ArgumentError => x; x; else 42; end", env: @env) <= tt("RuntimeError or ArgumentError or 42 or 3")
|
|
1213
|
+
assert do_tc("begin puts 'foo'; 3; rescue RuntimeError, ArgumentError => e; e; end", env: @env) <= tt("RuntimeError or ArgumentError or 3")
|
|
1214
|
+
assert do_tc("tries = 0; begin puts 'foo'; x = 1; rescue; tries = tries + 1; retry unless tries > 5; x = 'one'; end; x", env: @env) <= tt("1 or String")
|
|
1215
|
+
assert do_tc("begin 3; ensure 4; end", env: @env) <= @t3
|
|
1216
|
+
assert do_tc("begin x = 3; ensure x = 4; end; x", env: @env) <= @t4
|
|
1217
|
+
assert do_tc("begin puts 'foo'; x = 3; rescue; x = 4; ensure x = 5; end; x", env: @env) <= @t5
|
|
1218
|
+
assert do_tc("begin puts 'foo'; 3; rescue; 4; ensure 5; end", env: @env) <= @t34
|
|
984
1219
|
end
|
|
985
1220
|
|
|
986
1221
|
class SubArray < Array
|
|
@@ -991,108 +1226,108 @@ class TestTypecheck < Minitest::Test
|
|
|
991
1226
|
|
|
992
1227
|
def test_array_splat
|
|
993
1228
|
self.class.class_eval {
|
|
994
|
-
type :_splataf, "() -> Array<
|
|
1229
|
+
type :_splataf, "() -> Array<Integer>"
|
|
995
1230
|
type :_splatas, "() -> Array<String>"
|
|
996
|
-
type :_splathsf, "() -> Hash<Symbol,
|
|
1231
|
+
type :_splathsf, "() -> Hash<Symbol, Integer>"
|
|
997
1232
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1233
|
+
assert do_tc("x = *1") <= tt("[1]")
|
|
1234
|
+
assert do_tc("x = [1, *2, 3]") <= tt("[1, 2, 3]")
|
|
1000
1235
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = [1, *Object.new, 3]", env: @env) } # the Object might or might not be an array...
|
|
1001
1236
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = [1, *SubArray.new, 3]", env: @env) } # the SubArray is an Array, but unclear how to splat
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1237
|
+
assert do_tc("x = *[1]") <= tt("[1]")
|
|
1238
|
+
assert do_tc("x = *[1, 2, 3]") <= tt("[1, 2, 3]")
|
|
1239
|
+
assert do_tc("x = [1, *[2], 3]") <= tt("[1, 2, 3]")
|
|
1240
|
+
assert do_tc("x = [1, *[2, 3], 4]") <= tt("[1, 2, 3, 4]")
|
|
1241
|
+
assert do_tc("x = [1, *[2, *[3]], 4]") <= tt("[1, 2, 3, 4]")
|
|
1242
|
+
assert do_tc("x = [1, [2, *[3]], 4]") <= tt("[1, [2, 3], 4]")
|
|
1243
|
+
assert do_tc("x = [*[1,2], *[3,4]]") <= tt("[1, 2, 3, 4]")
|
|
1244
|
+
assert do_tc("x = *nil") <= tt("[]")
|
|
1245
|
+
assert do_tc("x = [1, *nil, 2]") <= tt("[1, 2]")
|
|
1246
|
+
assert do_tc("x = *{a: 1}") <= tt("[[:a, 1]]")
|
|
1012
1247
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = [1, *SubHash.new, 3]", env: @env) } # the SubHash is an Hash, but unclear how to splat
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1248
|
+
assert do_tc("x = *{a: 1, b: 2, c: 3}") <= tt("[[:a, 1], [:b, 2], [:c, 3]]")
|
|
1249
|
+
assert do_tc("x = [1, *{a: 2}, 3]") <= tt("[1, [:a, 2], 3]")
|
|
1250
|
+
assert do_tc("y = [2]; x = [1, *y, 3]; ") <= tt("[1, 2, 3]")
|
|
1016
1251
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("y = [2]; x = [1, *y, 3]; y.length") }
|
|
1017
|
-
|
|
1252
|
+
assert do_tc("y = {a: 2}; x = [1, *y, 3]") <= tt("[1, [:a, 2], 3]")
|
|
1018
1253
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("y = {a: 2}; x = [1, *y, 3]; y.length") }
|
|
1019
1254
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1255
|
+
assert do_tc("x = *_splataf", env: @env) <= tt("Array<Integer>")
|
|
1256
|
+
assert do_tc("x = [1, *_splataf, 2]", env: @env) <= tt("Array<Integer>")
|
|
1257
|
+
assert do_tc("x = [*_splataf, *_splataf]", env: @env) <= tt("Array<Integer>")
|
|
1258
|
+
assert do_tc("x = [*_splataf, *_splatas]", env: @env) <= tt("Array<Integer or String>")
|
|
1259
|
+
assert do_tc("x = [1, *_splataf, 2, *_splatas, 3]", env: @env) <= tt("Array<Integer or String>")
|
|
1260
|
+
assert do_tc("x = [1, *_splataf, 2, *_splatas, 3.0]", env: @env) <= tt("Array<Integer or String or 3.0>")
|
|
1261
|
+
assert do_tc("x = *_splathsf", env: @env) <= tt("Array<[Symbol, Integer]>")
|
|
1262
|
+
assert do_tc("x = [1, *_splathsf, 3]", env: @env) <= tt("Array<1 or 3 or [Symbol, Integer]>")
|
|
1028
1263
|
end
|
|
1029
1264
|
|
|
1030
1265
|
def test_hash_kwsplat
|
|
1031
1266
|
self.class.class_eval {
|
|
1032
|
-
type :_kwsplathsf, "() -> Hash<Symbol,
|
|
1267
|
+
type :_kwsplathsf, "() -> Hash<Symbol, Integer>"
|
|
1033
1268
|
type :_kwsplathos, "() -> Hash<Float, String>"
|
|
1034
1269
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1270
|
+
assert do_tc("x = {a: 1, **{b: 2}}") <= tt("{a: 1, b: 2}")
|
|
1271
|
+
assert do_tc("x = {a: 1, **{}}") <= tt("{a: 1}")
|
|
1272
|
+
assert do_tc("x = {a: 1, **{b: 2}, c: 3}") <= tt("{a: 1, b: 2, c: 3}")
|
|
1273
|
+
assert do_tc("x = {a: 1, **{b: 2}, **{c: 3}}") <= tt("{a: 1, b: 2, c: 3}")
|
|
1274
|
+
assert do_tc("x = {a: 1, **{b: 2, c: 3}}") <= tt("{a: 1, b: 2, c: 3}")
|
|
1275
|
+
assert do_tc("x = {**{a: 1}, b: 2, **{c: 3}}") <= tt("{a: 1, b: 2, c: 3}")
|
|
1041
1276
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = {a: 1, **Object.new}", env: @env) } # may or may not be hash
|
|
1042
1277
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("x = {a: 1, **SubHash.new}", env: @env) } # is a how, but unclear how to splat
|
|
1043
1278
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("y = {b: 2}; x = {a: 1, **y}; y.length") }
|
|
1044
1279
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1280
|
+
assert do_tc("x = {**_kwsplathsf}", env: @env) <= tt("Hash<Symbol, Integer>")
|
|
1281
|
+
assert do_tc("x = {**_kwsplathsf, **_kwsplathos}", env: @env) <= tt("Hash<Symbol or Float, Integer or String>")
|
|
1282
|
+
assert do_tc("x = {a: 1, **_kwsplathsf, b: 2}", env: @env) <= tt("Hash<Symbol, Integer>")
|
|
1283
|
+
assert do_tc("x = {'a' => 1, **_kwsplathsf, b: 'two'}", env: @env) <= tt("Hash<Symbol or String, Integer or String>")
|
|
1049
1284
|
end
|
|
1050
1285
|
|
|
1051
1286
|
def test_attr_etc
|
|
1052
1287
|
self.class.class_eval {
|
|
1053
|
-
attr_reader_type :f_attr_reader, "
|
|
1054
|
-
attr_writer_type :f_attr_writer, "
|
|
1055
|
-
attr_type :f_attr, "
|
|
1056
|
-
attr_accessor_type :f_attr_accessor, "
|
|
1288
|
+
attr_reader_type :f_attr_reader, "Integer", :f_attr_reader2, "String"
|
|
1289
|
+
attr_writer_type :f_attr_writer, "Integer"
|
|
1290
|
+
attr_type :f_attr, "Integer"
|
|
1291
|
+
attr_accessor_type :f_attr_accessor, "Integer"
|
|
1057
1292
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1293
|
+
assert do_tc("@f_attr_reader", env: @env) <= RDL::Globals.types[:integer]
|
|
1294
|
+
assert do_tc("TestTypecheck.new.f_attr_reader", env: @env) <= RDL::Globals.types[:integer]
|
|
1060
1295
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("TestTypecheck.new.f_attr_reader = 4", env: @env) }
|
|
1061
|
-
|
|
1062
|
-
|
|
1296
|
+
assert do_tc("@f_attr_reader2", env: @env) <= RDL::Globals.types[:string]
|
|
1297
|
+
assert do_tc("TestTypecheck.new.f_attr_reader2", env: @env) <= RDL::Globals.types[:string]
|
|
1063
1298
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1299
|
+
assert do_tc("@f_attr", env: @env) # same as attr_reader <= RDL::Globals.types[:integer]
|
|
1300
|
+
assert do_tc("TestTypecheck.new.f_attr", env: @env) <= RDL::Globals.types[:integer]
|
|
1066
1301
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("TestTypecheck.new.f_attr = 42", env: @env) }
|
|
1067
1302
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1303
|
+
assert do_tc("@f_attr_writer = 3", env: @env) <= @t3
|
|
1304
|
+
assert do_tc("TestTypecheck.new.f_attr_writer = 3", env: @env) <= RDL::Globals.types[:integer]
|
|
1070
1305
|
assert_raises(RDL::Typecheck::StaticTypeError) { do_tc("TestTypecheck.new.f_attr_writer", env: @env) }
|
|
1071
1306
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1307
|
+
assert do_tc("@f_attr_accessor", env: @env) <= RDL::Globals.types[:integer]
|
|
1308
|
+
assert do_tc("TestTypecheck.new.f_attr_accessor", env: @env) <= RDL::Globals.types[:integer]
|
|
1309
|
+
assert do_tc("TestTypecheck.new.f_attr_accessor = 42", env: @env) <= RDL::Globals.types[:integer]
|
|
1075
1310
|
end
|
|
1076
1311
|
|
|
1077
1312
|
# test code where we know different stuff about types on difference branches
|
|
1078
1313
|
def test_typeful_branches
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1314
|
+
assert do_tc("x = Object.new; case x when String; x.length; end", env: @env) <= RDL::Globals.types[:integer]
|
|
1315
|
+
assert do_tc("x = Object.new; case x when String, Array; x.length; end", env: @env) <= RDL::Globals.types[:integer]
|
|
1316
|
+
assert do_tc("x = String.new; case x when String; 3; when Integer; 4; end", env: @env) <= @t3
|
|
1082
1317
|
end
|
|
1083
1318
|
|
|
1084
1319
|
def test_context_typecheck
|
|
1085
1320
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1086
1321
|
self.class.class_eval {
|
|
1087
|
-
type '() ->
|
|
1322
|
+
type '() -> Integer', typecheck: :now
|
|
1088
1323
|
def context_typecheck1
|
|
1089
1324
|
context_tc_in_context1 # should fail
|
|
1090
1325
|
end
|
|
1091
1326
|
}
|
|
1092
1327
|
}
|
|
1093
|
-
|
|
1328
|
+
RDL::Globals.info.add(self.class, :context_typecheck2, :context_types, [self.class, :context_tc_in_context2, RDL::Globals.parser.scan_str('() -> Integer')])
|
|
1094
1329
|
self.class.class_eval {
|
|
1095
|
-
type '() ->
|
|
1330
|
+
type '() -> Integer', typecheck: :now
|
|
1096
1331
|
def context_typecheck2
|
|
1097
1332
|
context_tc_in_context2 # should not fail since method defined in context
|
|
1098
1333
|
end
|
|
@@ -1102,7 +1337,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1102
1337
|
def test_optional_varargs_mapping
|
|
1103
1338
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1104
1339
|
self.class.class_eval {
|
|
1105
|
-
type '(?
|
|
1340
|
+
type '(?Integer) -> Integer', typecheck: :now
|
|
1106
1341
|
def _optional_varargs_mapping1(x)
|
|
1107
1342
|
42
|
|
1108
1343
|
end
|
|
@@ -1111,7 +1346,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1111
1346
|
|
|
1112
1347
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1113
1348
|
self.class.class_eval {
|
|
1114
|
-
type '(
|
|
1349
|
+
type '(Integer) -> Integer', typecheck: :now
|
|
1115
1350
|
def _optional_varargs_mapping2(x=42)
|
|
1116
1351
|
x
|
|
1117
1352
|
end
|
|
@@ -1120,7 +1355,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1120
1355
|
|
|
1121
1356
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1122
1357
|
self.class.class_eval {
|
|
1123
|
-
type '(*
|
|
1358
|
+
type '(*Integer) -> Integer', typecheck: :now
|
|
1124
1359
|
def _optional_varargs_mapping3(x=42)
|
|
1125
1360
|
x
|
|
1126
1361
|
end
|
|
@@ -1128,7 +1363,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1128
1363
|
}
|
|
1129
1364
|
|
|
1130
1365
|
self.class.class_eval {
|
|
1131
|
-
type '(?
|
|
1366
|
+
type '(?Integer) -> Integer', typecheck: :now
|
|
1132
1367
|
def _optional_varargs_mapping4(x=42)
|
|
1133
1368
|
x
|
|
1134
1369
|
end
|
|
@@ -1136,7 +1371,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1136
1371
|
|
|
1137
1372
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1138
1373
|
self.class.class_eval {
|
|
1139
|
-
type '(?
|
|
1374
|
+
type '(?Integer) -> Integer', typecheck: :now
|
|
1140
1375
|
def _optional_varargs_mapping5(x='forty-two')
|
|
1141
1376
|
42
|
|
1142
1377
|
end
|
|
@@ -1145,7 +1380,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1145
1380
|
|
|
1146
1381
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1147
1382
|
self.class.class_eval {
|
|
1148
|
-
type '(
|
|
1383
|
+
type '(Integer) -> Integer', typecheck: :now
|
|
1149
1384
|
def _optional_varargs_mapping6(*x)
|
|
1150
1385
|
42
|
|
1151
1386
|
end
|
|
@@ -1154,7 +1389,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1154
1389
|
|
|
1155
1390
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1156
1391
|
self.class.class_eval {
|
|
1157
|
-
type '(?
|
|
1392
|
+
type '(?Integer) -> Integer', typecheck: :now
|
|
1158
1393
|
def _optional_varargs_mapping7(*x)
|
|
1159
1394
|
42
|
|
1160
1395
|
end
|
|
@@ -1162,7 +1397,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1162
1397
|
}
|
|
1163
1398
|
|
|
1164
1399
|
self.class.class_eval {
|
|
1165
|
-
type '(*
|
|
1400
|
+
type '(*Integer) -> Array<Integer>', typecheck: :now
|
|
1166
1401
|
def _optional_varargs_mapping8(*x)
|
|
1167
1402
|
x
|
|
1168
1403
|
end
|
|
@@ -1172,7 +1407,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1172
1407
|
|
|
1173
1408
|
def test_kw_mapping
|
|
1174
1409
|
self.class.class_eval {
|
|
1175
|
-
type '(kw:
|
|
1410
|
+
type '(kw: Integer) -> Integer', typecheck: :now
|
|
1176
1411
|
def _kw_mapping1(kw:)
|
|
1177
1412
|
kw
|
|
1178
1413
|
end
|
|
@@ -1180,7 +1415,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1180
1415
|
|
|
1181
1416
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1182
1417
|
self.class.class_eval {
|
|
1183
|
-
type '(
|
|
1418
|
+
type '(Integer) -> Integer', typecheck: :now
|
|
1184
1419
|
def _kw_mapping2(kw:)
|
|
1185
1420
|
kw
|
|
1186
1421
|
end
|
|
@@ -1188,7 +1423,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1188
1423
|
}
|
|
1189
1424
|
|
|
1190
1425
|
self.class.class_eval {
|
|
1191
|
-
type '(kw:
|
|
1426
|
+
type '(kw: Integer) -> Integer', typecheck: :now
|
|
1192
1427
|
def _kw_mapping3(kw_args) # slightly awkward example
|
|
1193
1428
|
kw_args[:kw]
|
|
1194
1429
|
end
|
|
@@ -1196,7 +1431,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1196
1431
|
|
|
1197
1432
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1198
1433
|
self.class.class_eval {
|
|
1199
|
-
type '(kw:
|
|
1434
|
+
type '(kw: Integer) -> Integer', typecheck: :now
|
|
1200
1435
|
def _kw_mapping4(kw: 42)
|
|
1201
1436
|
kw
|
|
1202
1437
|
end
|
|
@@ -1205,7 +1440,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1205
1440
|
|
|
1206
1441
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1207
1442
|
self.class.class_eval {
|
|
1208
|
-
type '(kw: ?
|
|
1443
|
+
type '(kw: ?Integer) -> Integer', typecheck: :now
|
|
1209
1444
|
def _kw_mapping5(kw:)
|
|
1210
1445
|
kw
|
|
1211
1446
|
end
|
|
@@ -1213,7 +1448,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1213
1448
|
}
|
|
1214
1449
|
|
|
1215
1450
|
self.class.class_eval {
|
|
1216
|
-
type '(kw: ?
|
|
1451
|
+
type '(kw: ?Integer) -> Integer', typecheck: :now
|
|
1217
1452
|
def _kw_mapping6(kw: 42)
|
|
1218
1453
|
kw
|
|
1219
1454
|
end
|
|
@@ -1221,7 +1456,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1221
1456
|
|
|
1222
1457
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1223
1458
|
self.class.class_eval {
|
|
1224
|
-
type '(kw: ?
|
|
1459
|
+
type '(kw: ?Integer) -> Integer', typecheck: :now
|
|
1225
1460
|
def _kw_mapping7(kw: 'forty-two')
|
|
1226
1461
|
kw
|
|
1227
1462
|
end
|
|
@@ -1229,7 +1464,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1229
1464
|
}
|
|
1230
1465
|
|
|
1231
1466
|
self.class.class_eval {
|
|
1232
|
-
type '(kw1:
|
|
1467
|
+
type '(kw1: Integer, kw2: Integer) -> Integer', typecheck: :now
|
|
1233
1468
|
def _kw_mapping8(kw1:, kw2:)
|
|
1234
1469
|
kw1
|
|
1235
1470
|
end
|
|
@@ -1237,7 +1472,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1237
1472
|
|
|
1238
1473
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1239
1474
|
self.class.class_eval {
|
|
1240
|
-
type '(kw1:
|
|
1475
|
+
type '(kw1: Integer, kw2: Integer, kw3: Integer) -> Integer', typecheck: :now
|
|
1241
1476
|
def _kw_mapping9(kw2:)
|
|
1242
1477
|
kw1
|
|
1243
1478
|
end
|
|
@@ -1245,7 +1480,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1245
1480
|
}
|
|
1246
1481
|
|
|
1247
1482
|
self.class.class_eval {
|
|
1248
|
-
type '(kw1:
|
|
1483
|
+
type '(kw1: Integer, kw2: Integer, **String) -> String', typecheck: :now
|
|
1249
1484
|
def _kw_mapping10(kw1:, kw2:, **kws)
|
|
1250
1485
|
kws[:foo]
|
|
1251
1486
|
end
|
|
@@ -1253,7 +1488,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1253
1488
|
|
|
1254
1489
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1255
1490
|
self.class.class_eval {
|
|
1256
|
-
type '(kw1:
|
|
1491
|
+
type '(kw1: Integer, kw2: Integer) -> String', typecheck: :now
|
|
1257
1492
|
def _kw_mapping11(kw1:, kw2:, **kws)
|
|
1258
1493
|
kws[:foo]
|
|
1259
1494
|
end
|
|
@@ -1262,7 +1497,7 @@ class TestTypecheck < Minitest::Test
|
|
|
1262
1497
|
|
|
1263
1498
|
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1264
1499
|
self.class.class_eval {
|
|
1265
|
-
type '(kw1:
|
|
1500
|
+
type '(kw1: Integer, kw2: Integer, **String) -> Integer', typecheck: :now
|
|
1266
1501
|
def _kw_mapping12(kw1:, kw2:)
|
|
1267
1502
|
kw1
|
|
1268
1503
|
end
|
|
@@ -1271,22 +1506,153 @@ class TestTypecheck < Minitest::Test
|
|
|
1271
1506
|
|
|
1272
1507
|
end
|
|
1273
1508
|
|
|
1509
|
+
def test_class_call
|
|
1510
|
+
TestTypecheckE.class_eval {
|
|
1511
|
+
type '(Integer) -> Class', typecheck: :now
|
|
1512
|
+
def call_class1(x)
|
|
1513
|
+
x.class
|
|
1514
|
+
end
|
|
1515
|
+
type '() -> TestTypecheckE', typecheck: :now
|
|
1516
|
+
def call_class2
|
|
1517
|
+
self.class.new(1)
|
|
1518
|
+
end
|
|
1519
|
+
}
|
|
1520
|
+
t = do_tc("3.14.class", env: @env)
|
|
1521
|
+
assert t <= RDL::Type::SingletonType.new(Float)
|
|
1522
|
+
t2 = do_tc("TestTypecheckE.class", env: @env)
|
|
1523
|
+
assert t2 <= RDL::Type::SingletonType.new(Class)
|
|
1524
|
+
t3 = do_tc("[1,2,3].class", env: @env)
|
|
1525
|
+
assert t3 <= RDL::Type::SingletonType.new(Array)
|
|
1526
|
+
end
|
|
1527
|
+
|
|
1274
1528
|
def test_singleton
|
|
1275
1529
|
assert_equal ':A', do_tc("TestTypecheckC.foo", env: @env).to_s
|
|
1276
1530
|
assert_equal ':B', do_tc("TestTypecheckM.foo", env: @env).to_s
|
|
1277
1531
|
end
|
|
1278
1532
|
|
|
1279
1533
|
def test_annotated_ret
|
|
1280
|
-
|
|
1281
|
-
assert_equal t, do_tc("TestTypecheckC.bar", env: @env)
|
|
1534
|
+
assert do_tc("TestTypecheckC.bar", env: @env) <= tt('Integer or String')
|
|
1282
1535
|
end
|
|
1283
1536
|
|
|
1284
1537
|
def test_constructor
|
|
1285
|
-
t = do_tc("TestTypecheckC.new(
|
|
1286
|
-
assert_equal '
|
|
1538
|
+
t = do_tc("TestTypecheckC.new(1)", env: @env)
|
|
1539
|
+
assert_equal 'TestTypecheckC', t.to_s
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
assert_raises(RDL::Typecheck::StaticTypeError) {
|
|
1543
|
+
self.class.class_eval {
|
|
1544
|
+
type '(Integer) -> Integer', typecheck: :now
|
|
1545
|
+
def self.def_bad_new_call(x)
|
|
1546
|
+
TestTypecheckC.new()
|
|
1547
|
+
x
|
|
1548
|
+
end
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
RDL.do_typecheck :einit
|
|
1553
|
+
|
|
1554
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :finit }
|
|
1287
1555
|
|
|
1288
1556
|
t = do_tc("TestTypecheckD.new", env: @env)
|
|
1289
1557
|
t2 = RDL::Type::NominalType.new TestTypecheckD
|
|
1290
1558
|
assert_equal t2, t
|
|
1559
|
+
|
|
1560
|
+
self.class.class_eval {
|
|
1561
|
+
type '(Integer) -> Integer', typecheck: :now
|
|
1562
|
+
def self.def_call_to_initialize(x)
|
|
1563
|
+
c = TestTypecheckC.new(x)
|
|
1564
|
+
c.foo
|
|
1565
|
+
end
|
|
1566
|
+
}
|
|
1567
|
+
end
|
|
1568
|
+
|
|
1569
|
+
def test_nil_return
|
|
1570
|
+
self.class.class_eval {
|
|
1571
|
+
type "(%any) -> NilClass", typecheck: :now
|
|
1572
|
+
def self.def_nil_ret(x) return; end
|
|
1573
|
+
}
|
|
1574
|
+
self.class.class_eval {
|
|
1575
|
+
type "(Integer) -> :A or NilClass", typecheck: :now
|
|
1576
|
+
def self.def_nil_ret_2(x)
|
|
1577
|
+
if x > 0
|
|
1578
|
+
:A
|
|
1579
|
+
else
|
|
1580
|
+
return
|
|
1581
|
+
end
|
|
1582
|
+
end
|
|
1583
|
+
}
|
|
1584
|
+
end
|
|
1585
|
+
|
|
1586
|
+
def test_method_missing
|
|
1587
|
+
skip "method_missing not supported yet"
|
|
1588
|
+
RDL.do_typecheck :later_mm1
|
|
1589
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :later_mm2 }
|
|
1590
|
+
end
|
|
1591
|
+
|
|
1592
|
+
def test_nested
|
|
1593
|
+
r = N1::N2.foo
|
|
1594
|
+
assert_equal :sym, r
|
|
1595
|
+
|
|
1596
|
+
r = N1::N2.nf
|
|
1597
|
+
assert_equal :sym, r
|
|
1598
|
+
|
|
1599
|
+
r = N1::N2.foo2
|
|
1600
|
+
assert_equal :sym2, r
|
|
1601
|
+
|
|
1602
|
+
r = N1::N3.new.nf3
|
|
1603
|
+
assert_equal :sym, r
|
|
1604
|
+
|
|
1605
|
+
r = N4.foo
|
|
1606
|
+
assert_equal :B, r
|
|
1607
|
+
end
|
|
1608
|
+
|
|
1609
|
+
def test_super
|
|
1610
|
+
self.class.class_eval "class SA0; end"
|
|
1611
|
+
self.class.class_eval "class SA1 < SA0; end"
|
|
1612
|
+
|
|
1613
|
+
TestTypecheck::SA0.class_eval do
|
|
1614
|
+
extend RDL::Annotate
|
|
1615
|
+
def self.foo; :a0; end
|
|
1616
|
+
def bar(x); 1 + x; end
|
|
1617
|
+
def baz(x); 1 + x; end
|
|
1618
|
+
type 'self.foo', '() -> :a0'
|
|
1619
|
+
type 'bar', '(Fixnum) -> Fixnum'
|
|
1620
|
+
type 'baz', '(Fixnum) -> Fixnum'
|
|
1621
|
+
end
|
|
1622
|
+
TestTypecheck::SA1.class_eval do
|
|
1623
|
+
extend RDL::Annotate
|
|
1624
|
+
def self.foo; super; end
|
|
1625
|
+
def bar(x); super(x); end
|
|
1626
|
+
def baz(x); super; end
|
|
1627
|
+
type 'self.foo', '() -> :a0', typecheck: :call
|
|
1628
|
+
type :bar, '(Fixnum) -> Fixnum', typecheck: :call
|
|
1629
|
+
type :baz, '(Fixnum) -> Fixnum', typecheck: :call
|
|
1630
|
+
end
|
|
1631
|
+
|
|
1632
|
+
r = TestTypecheck::SA1.foo
|
|
1633
|
+
assert_equal :a0, r
|
|
1634
|
+
|
|
1635
|
+
r = TestTypecheck::SA1.new.bar 1
|
|
1636
|
+
assert_equal 2, r
|
|
1637
|
+
|
|
1638
|
+
r = TestTypecheck::SA1.new.baz 1
|
|
1639
|
+
assert_equal 2, r
|
|
1640
|
+
end
|
|
1641
|
+
|
|
1642
|
+
|
|
1643
|
+
def test_case_when_nil_body
|
|
1644
|
+
self.class.class_eval "class A5; end"
|
|
1645
|
+
TestTypecheck::A5.class_eval do
|
|
1646
|
+
extend RDL::Annotate
|
|
1647
|
+
def foo(x)
|
|
1648
|
+
case x
|
|
1649
|
+
when :a
|
|
1650
|
+
when :b
|
|
1651
|
+
end
|
|
1652
|
+
end
|
|
1653
|
+
type(:foo, '(Symbol) -> NilClass', {:typecheck => :call})
|
|
1654
|
+
end
|
|
1655
|
+
|
|
1656
|
+
assert_nil TestTypecheck::A5.new.foo(:a)
|
|
1291
1657
|
end
|
|
1292
1658
|
end
|