typed.rb 0.0.19 → 0.0.20
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/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:
|