typed.rb 0.0.19 → 0.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/typed/model/tm_module.rb +18 -1
- data/lib/typed/model/tm_send.rb +5 -3
- data/lib/typed/prelude_existential_registry.bin +0 -0
- data/lib/typed/prelude_registry.bin +0 -0
- data/lib/typed/types/polymorphism/generic_object.rb +5 -2
- data/lib/typed/types/polymorphism/generic_variables.rb +12 -0
- data/lib/typed/types/polymorphism/type_variable.rb +13 -0
- data/lib/typed/types/polymorphism/type_variable_register.rb +18 -1
- data/lib/typed/types/polymorphism/unification.rb +9 -3
- data/lib/typed/types/ty_generic_existential_type.rb +7 -0
- data/lib/typed/version.rb +1 -1
- data/spec/lib/examples/enum.rb +40 -0
- data/spec/lib/examples/enum/enum_error1.rb +39 -0
- data/spec/lib/examples/equality.rb +17 -0
- data/spec/lib/language_spec.rb +36 -0
- data/spec/lib/typing/generics_spec.rb +2 -4
- data/spec/lib/typing/tm_global_var_spec.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e1e422526418b9f47944538620729fa863861a4
|
4
|
+
data.tar.gz: bf8d5cd5f765212d7a28c4da99fbc5b7d76a5e6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e1dc72ba7ff3932c5809e598667c2845235ae866364b84db98659bf1680f9701098d95db748055378aecd91f2ee20b3d6085c719aa0430c26c84180033639e2
|
7
|
+
data.tar.gz: b66faa42ec89f9f7bafac169ef736b55bde2156b2c977a24052d35707f6fb0403a10fdfe9f1f697d22ffbf2b7990b773ed1a805811dcdbc34492873018addef5
|
@@ -27,7 +27,9 @@ module TypedRb
|
|
27
27
|
unification = Types::Polymorphism::Unification.new(module_type.local_typing_context.all_constraints,
|
28
28
|
:allow_unbound_receivers => true)
|
29
29
|
unification.run
|
30
|
-
|
30
|
+
if(module_type.is_a?(TypedRb::Types::TyGenericExistentialType))
|
31
|
+
module_type.clean_dynamic_bindings
|
32
|
+
end
|
31
33
|
module_type
|
32
34
|
end
|
33
35
|
|
@@ -38,6 +40,21 @@ module TypedRb
|
|
38
40
|
module_self_variable.node = node
|
39
41
|
module_self_variable.module_type = module_type
|
40
42
|
module_type.self_variable = module_self_variable
|
43
|
+
|
44
|
+
if(module_type.is_a?(TypedRb::Types::TyGenericExistentialType))
|
45
|
+
module_type.type_vars.each do |type_var|
|
46
|
+
type_var = Types::TypingContext.type_variable_for_generic_type(type_var)
|
47
|
+
type_var.node = node
|
48
|
+
|
49
|
+
if type_var.upper_bound
|
50
|
+
type_var.compatible?(type_var.upper_bound, :lt)
|
51
|
+
end
|
52
|
+
|
53
|
+
if type_var.lower_bound
|
54
|
+
type_var.compatible?(type_var.lower_bound, :gt)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
41
58
|
yield(module_self_variable)
|
42
59
|
|
43
60
|
# Since every single time we find the generic type the same instance
|
data/lib/typed/model/tm_send.rb
CHANGED
@@ -125,8 +125,9 @@ module TypedRb
|
|
125
125
|
type_var_signature = argument.node.children.first
|
126
126
|
maybe_generic_method_var = Types::TypingContext.vars_info(:method)[type_var_signature]
|
127
127
|
maybe_generic_class_var = Types::TypingContext.vars_info(:class)[type_var_signature]
|
128
|
-
|
129
|
-
|
128
|
+
maybe_generic_module_var = Types::TypingContext.vars_info(:module)[type_var_signature]
|
129
|
+
if maybe_generic_method_var || maybe_generic_class_var || maybe_generic_module_var
|
130
|
+
maybe_generic_method_var || maybe_generic_class_var || maybe_generic_module_var
|
130
131
|
else
|
131
132
|
parsed_types = TypeSignature::Parser.parse(type_var_signature)
|
132
133
|
if parsed_types.is_a?(Array)
|
@@ -236,7 +237,8 @@ module TypedRb
|
|
236
237
|
rest_type
|
237
238
|
end
|
238
239
|
actual_arguments[index..-1].each do |actual_argument|
|
239
|
-
|
240
|
+
actual_argument_type = actual_argument.check_type(context)
|
241
|
+
unless actual_argument_type.compatible?(formal_parameter_type, :lt)
|
240
242
|
error_message = "Error type checking message sent '#{message}': #{formal_parameter_type} expected, #{actual_argument_type} found"
|
241
243
|
fail TypeCheckError.new(error_message, node)
|
242
244
|
end
|
Binary file
|
Binary file
|
@@ -63,8 +63,11 @@ module TypedRb
|
|
63
63
|
end
|
64
64
|
|
65
65
|
generic_function = (from_args + [to_arg, materialized_block_type]).any? do |arg|
|
66
|
-
arg.is_a?(Polymorphism::TypeVariable)
|
67
|
-
|
66
|
+
next arg.bound.nil? if arg.is_a?(Polymorphism::TypeVariable)
|
67
|
+
next false if !arg.respond_to?(:generic?) || !arg.generic?
|
68
|
+
next true if arg.is_a?(Types::TyGenericFunction)
|
69
|
+
unbound_vars = arg.unbound_vars
|
70
|
+
unbound_vars.count > 0
|
68
71
|
end
|
69
72
|
|
70
73
|
if generic_function
|
@@ -18,6 +18,18 @@ module TypedRb
|
|
18
18
|
# acc[type_var.variable] = type_var
|
19
19
|
#end.values
|
20
20
|
end
|
21
|
+
|
22
|
+
def unbound_vars
|
23
|
+
@type_vars.map do |type_var|
|
24
|
+
if type_var.is_a?(Polymorphism::TypeVariable) && type_var.bound_to_generic?
|
25
|
+
type_var.bound.unbound_vars
|
26
|
+
elsif type_var.is_a?(Polymorphism::TypeVariable)
|
27
|
+
type_var if type_var.bound.nil?
|
28
|
+
else
|
29
|
+
type_var.unbound_vars
|
30
|
+
end
|
31
|
+
end.flatten.reject(&:nil?)
|
32
|
+
end
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
@@ -115,6 +115,19 @@ module TypedRb
|
|
115
115
|
def bound_to_generic?
|
116
116
|
bound && bound.respond_to?(:generic?) && bound.generic?
|
117
117
|
end
|
118
|
+
|
119
|
+
def clean_dynamic_bindings
|
120
|
+
if @bound.is_a?(TypedRb::Types::TyDynamic)
|
121
|
+
@bound = nil
|
122
|
+
end
|
123
|
+
if @lower_bound.is_a?(TypedRb::Types::TyDynamic)
|
124
|
+
@lower_bound = nil
|
125
|
+
end
|
126
|
+
if @upper_bound.is_a?(TypedRb::Types::TyDynamic)
|
127
|
+
@upper_bound = nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
118
131
|
end
|
119
132
|
end
|
120
133
|
end
|
@@ -166,7 +166,7 @@ module TypedRb
|
|
166
166
|
else
|
167
167
|
key = [:local, nil, variable_name]
|
168
168
|
type_variables_register[key] = TypeVariable.new(variable_name, gen_name: false)
|
169
|
-
@constraints[variable_name] = [relation_type, type]
|
169
|
+
@constraints[variable_name] = [[relation_type, type]]
|
170
170
|
# fail StandardError, "Cannot find variable #{variable_name} to add a constraint"
|
171
171
|
end
|
172
172
|
end
|
@@ -200,6 +200,23 @@ module TypedRb
|
|
200
200
|
[apply_type(parent, substitutions), substitutions]
|
201
201
|
end
|
202
202
|
|
203
|
+
def clean_dynamic_bindings
|
204
|
+
constraints.values.each do |constraint|
|
205
|
+
constraint.each do |type, value|
|
206
|
+
if type == :lt || type == :gt
|
207
|
+
if value.is_a?(TypedRb::Types::Polymorphism::TypeVariable)
|
208
|
+
value.clean_dynamic_bindings
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
type_variables_register.values.each do |type_var|
|
214
|
+
if type_var.is_a?(TypedRb::Types::Polymorphism::TypeVariable)
|
215
|
+
type_var.clean_dynamic_bindings
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
203
220
|
protected
|
204
221
|
|
205
222
|
def method_var_types
|
@@ -119,8 +119,14 @@ module TypedRb
|
|
119
119
|
fn_arg = fn.from[i]
|
120
120
|
if arg.is_a?(TypeVariable)
|
121
121
|
if graph[arg][:lower_type]
|
122
|
-
|
123
|
-
|
122
|
+
begin
|
123
|
+
type = [graph[arg][:lower_type], fn_arg].min
|
124
|
+
graph[arg][:lower_type] = type
|
125
|
+
rescue TypedRb::Types::Polymorphism::UnificationError
|
126
|
+
value_l = graph[arg][:lower_type]
|
127
|
+
value_r = fn_arg
|
128
|
+
raise TypedRb::Types::UncomparableTypes.new(value_l, value_r, nil, ", #{value_l} cannot be compared to #{value_r}")
|
129
|
+
end
|
124
130
|
else
|
125
131
|
graph[arg][:lower_type] = fn_arg
|
126
132
|
end
|
@@ -402,6 +408,7 @@ module TypedRb
|
|
402
408
|
# in the remaining @lt constraints
|
403
409
|
@lt_constraints = graph.replace_groups(@lt_constraints)
|
404
410
|
unify(@lt_constraints)
|
411
|
+
graph.check_bindings
|
405
412
|
unify(@send_constraints)
|
406
413
|
graph.check_bindings
|
407
414
|
graph.print_groups
|
@@ -462,7 +469,6 @@ module TypedRb
|
|
462
469
|
end
|
463
470
|
text << "#{l} :send #{message}[ #{arg_types.join(',')} -> #{return_type}]\n"
|
464
471
|
end
|
465
|
-
|
466
472
|
TypedRb.log binding, :debug, text.string
|
467
473
|
end
|
468
474
|
|
@@ -44,6 +44,13 @@ module TypedRb
|
|
44
44
|
Polymorphism::Unification.new(applied_typing_context.all_constraints).run(false)
|
45
45
|
applied_typing_context.unlink # these constraints have already been satisfied
|
46
46
|
end
|
47
|
+
|
48
|
+
def clean_dynamic_bindings
|
49
|
+
type_vars.each do |type_var|
|
50
|
+
type_var.clean_dynamic_bindings
|
51
|
+
end
|
52
|
+
local_typing_context.clean_dynamic_bindings
|
53
|
+
end
|
47
54
|
end
|
48
55
|
end
|
49
56
|
end
|
data/lib/typed/version.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Categories
|
2
|
+
ts 'type Categories::Enum[T]'
|
3
|
+
module Enum
|
4
|
+
ts '#succ / -> [T]'
|
5
|
+
abstract(:succ)
|
6
|
+
|
7
|
+
ts '#pred / -> [T]'
|
8
|
+
abstract(:pred)
|
9
|
+
|
10
|
+
ts '#to / [T] -> Array[T]'
|
11
|
+
def to(x)
|
12
|
+
xs = Array.('[T]').new
|
13
|
+
next_val = self
|
14
|
+
while(next_val != x)
|
15
|
+
xs.push(next_val)
|
16
|
+
next_val = next_val.succ
|
17
|
+
end
|
18
|
+
xs.push(next_val)
|
19
|
+
xs
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
ts 'type Integer super Categories::Enum[Integer]'
|
26
|
+
class Integer
|
27
|
+
include Categories::Enum
|
28
|
+
|
29
|
+
def succ
|
30
|
+
self + 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def pred
|
34
|
+
self - 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
3.to(10)
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Categories
|
2
|
+
ts 'type Categories::Enum[T]'
|
3
|
+
module Enum
|
4
|
+
ts '#succ / -> [T]'
|
5
|
+
abstract(:succ)
|
6
|
+
|
7
|
+
ts '#pred / -> [T]'
|
8
|
+
abstract(:pred)
|
9
|
+
|
10
|
+
ts '#to / [T] -> Array[T]'
|
11
|
+
def to(x)
|
12
|
+
xs = Array.('[T]').new
|
13
|
+
next_val = self
|
14
|
+
while(next_val != x)
|
15
|
+
xs.push(next_val)
|
16
|
+
next_val = next_val.succ
|
17
|
+
end
|
18
|
+
xs.push(next_val)
|
19
|
+
xs.push(true)
|
20
|
+
xs
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
ts 'type Integer super Categories::Enum[Integer]'
|
27
|
+
class Integer
|
28
|
+
include Categories::Enum
|
29
|
+
|
30
|
+
def succ
|
31
|
+
self + 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def pred
|
35
|
+
self - 1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
3.to(10)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Categories
|
2
|
+
ts 'type Categories::Equal[T]'
|
3
|
+
module Equal
|
4
|
+
|
5
|
+
ts '#eq? / [T] -> Boolean'
|
6
|
+
def eq?(o); self.eql?(o); end
|
7
|
+
|
8
|
+
ts '#not_eq? / [T] -> Boolean'
|
9
|
+
def not_eq?(o); ! self.eq?(o); end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
ts 'type Integer super Categories::Equal[Integer]'
|
15
|
+
class Integer
|
16
|
+
include Categories::Equal
|
17
|
+
end
|
data/spec/lib/language_spec.rb
CHANGED
@@ -133,4 +133,40 @@ describe TypedRb::Language do
|
|
133
133
|
}.to raise_error(TypedRb::Types::UncomparableTypes)
|
134
134
|
end
|
135
135
|
end
|
136
|
+
|
137
|
+
context 'with equality example, type checks correctly' do
|
138
|
+
let(:example) { 'equality.rb' }
|
139
|
+
|
140
|
+
it 'should be possible to type check the example correctly' do
|
141
|
+
expect {
|
142
|
+
silence_stream(STDOUT) do
|
143
|
+
language.check_file(file, true)
|
144
|
+
end
|
145
|
+
}.to_not raise_error
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'with enum example, type checks correctly' do
|
150
|
+
let(:example) { 'enum.rb' }
|
151
|
+
|
152
|
+
it 'should be possible to type check the example correctly' do
|
153
|
+
expect {
|
154
|
+
expr = File.new(file, 'r').read
|
155
|
+
result = language.check(expr)
|
156
|
+
expect(result.to_s).to eq('Array[Integer]')
|
157
|
+
}.to_not raise_error
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'with enum example error1, type checks correctly' do
|
162
|
+
let(:example) { 'enum/enum_error1.rb' }
|
163
|
+
|
164
|
+
it 'should be possible to type check the example correctly' do
|
165
|
+
expect {
|
166
|
+
expr = File.new(file, 'r').read
|
167
|
+
language.check(expr)
|
168
|
+
}.to raise_error(TypedRb::Types::Polymorphism::UnificationError)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
136
172
|
end
|
@@ -158,8 +158,7 @@ __END
|
|
158
158
|
|
159
159
|
expect do
|
160
160
|
language.check(code)
|
161
|
-
end.to raise_error(TypedRb::Types::
|
162
|
-
/Cannot compare types Object with.*Integer/)
|
161
|
+
end.to raise_error(TypedRb::Types::Polymorphism::UnificationError)
|
163
162
|
end
|
164
163
|
|
165
164
|
it 'type-checks correctly super type generics detecting type errors based on the super-type parameter on type instantiation' do
|
@@ -186,8 +185,7 @@ __END
|
|
186
185
|
|
187
186
|
expect do
|
188
187
|
language.check(code)
|
189
|
-
end.to raise_error(TypedRb::Types::
|
190
|
-
/Cannot compare types Object with.*Integer/)
|
188
|
+
end.to raise_error(TypedRb::Types::Polymorphism::UnificationError)
|
191
189
|
end
|
192
190
|
|
193
191
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typed.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antonio Garrote
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -150,6 +150,9 @@ files:
|
|
150
150
|
- spec/lib/ast_parser_spec.rb
|
151
151
|
- spec/lib/examples/animals.rb
|
152
152
|
- spec/lib/examples/counter.rb
|
153
|
+
- spec/lib/examples/enum.rb
|
154
|
+
- spec/lib/examples/enum/enum_error1.rb
|
155
|
+
- spec/lib/examples/equality.rb
|
153
156
|
- spec/lib/examples/if.rb
|
154
157
|
- spec/lib/examples/monoid.rb
|
155
158
|
- spec/lib/examples/monoid/monoid_error1.rb
|
@@ -263,9 +266,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
263
266
|
version: '0'
|
264
267
|
requirements: []
|
265
268
|
rubyforge_project:
|
266
|
-
rubygems_version: 2.4.
|
269
|
+
rubygems_version: 2.4.7
|
267
270
|
signing_key:
|
268
271
|
specification_version: 4
|
269
272
|
summary: Gradual type checker for Ruby
|
270
273
|
test_files: []
|
271
|
-
has_rdoc:
|