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 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: