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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 275c43f2dc819f16b312b04476aeb6e2348b901c
4
- data.tar.gz: a3bee9cfa379440d26e4ed53d65bda969deeaa8c
3
+ metadata.gz: 3e1e422526418b9f47944538620729fa863861a4
4
+ data.tar.gz: bf8d5cd5f765212d7a28c4da99fbc5b7d76a5e6c
5
5
  SHA512:
6
- metadata.gz: d56e1eb679fc7443cb0f85da729c1680236cea4f6bf25e6eed316cb54ed5a1b5783cebc121ce5b34843060a1f97570f6f9f82eb42e9ab8c2712591fc6d6ae3d6
7
- data.tar.gz: d3de0f7e334161c2e99e700efe52d0492e57b464d612413c5c86f069114e9393c94d2b8356270a509de8efb69471df627d7df879ce71f1eef9f6810fb19cdc25
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
@@ -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
- if maybe_generic_method_var || maybe_generic_class_var
129
- maybe_generic_method_var || maybe_generic_class_var
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
- unless actual_argument.check_type(context).compatible?(formal_parameter_type, :lt)
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
@@ -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
- (arg.respond_to?(:generic?) && arg.generic?)
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
- type = compatible_lt_type?(graph[arg][:lower_type], fn_arg)
123
- graph[arg][:lower_type] = type
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
@@ -1,5 +1,5 @@
1
1
  module TypedRb
2
2
  unless defined?(VERSION)
3
- VERSION = '0.0.19'
3
+ VERSION = '0.0.20'
4
4
  end
5
5
  end
@@ -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
@@ -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::UncomparableTypes,
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::UncomparableTypes,
190
- /Cannot compare types Object with.*Integer/)
188
+ end.to raise_error(TypedRb::Types::Polymorphism::UnificationError)
191
189
  end
192
190
 
193
191
  end
@@ -27,7 +27,7 @@ __END
27
27
 
28
28
  expect {
29
29
  language.check(expr)
30
- }.to raise_error(TypedRb::Types::UncomparableTypes)
30
+ }.to raise_error(TypedRb::Types::Polymorphism::UnificationError)
31
31
  end
32
32
  end
33
33
  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.19
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-01-31 00:00:00.000000000 Z
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.6
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: