typed.rb 0.0.18 → 0.0.19

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: 28e293212576b2bd00356a05305289b6e92587b7
4
- data.tar.gz: 0c91a5c37a9dbe053232db6731c14fbe97f2991e
3
+ metadata.gz: 275c43f2dc819f16b312b04476aeb6e2348b901c
4
+ data.tar.gz: a3bee9cfa379440d26e4ed53d65bda969deeaa8c
5
5
  SHA512:
6
- metadata.gz: 715899217f62a966e082d72e5686c2bc5b5ddc306861959420e71bc86f499bcec74317a109aa9fb1858ca7b7f104ef688c16ab6450e0ede990b64f4417c73663
7
- data.tar.gz: 057c49cd5749900aff35435aee86e7ccdfc3810485284d0bca548ad588492d0ef8482902781421f06dadcb2436863cb6223bfac8b70f12431015bac14a5779a1
6
+ metadata.gz: d56e1eb679fc7443cb0f85da729c1680236cea4f6bf25e6eed316cb54ed5a1b5783cebc121ce5b34843060a1f97570f6f9f82eb42e9ab8c2712591fc6d6ae3d6
7
+ data.tar.gz: d3de0f7e334161c2e99e700efe52d0492e57b464d612413c5c86f069114e9393c94d2b8356270a509de8efb69471df627d7df879ce71f1eef9f6810fb19cdc25
@@ -105,6 +105,7 @@ module TypedRb
105
105
  end
106
106
  end
107
107
  end
108
+
108
109
  top_level_errors = []
109
110
  begin
110
111
  ::BasicObject::TypeRegistry.check_super_type_annotations
Binary file
Binary file
@@ -29,21 +29,32 @@ class BasicObject
29
29
 
30
30
  ts '.register_generic_type_information / Hash[Object][Object] -> Hash[Object][Object] -> unit'
31
31
  def register_generic_type_information(generic_type_information, generic_super_types_information)
32
- unless generic_type_information.is_a?(String) # TODO: String when super annotations for non-generic types
33
- generic_type_information[:super_type] = generic_super_types_information
34
- if generic_types_parser_registry[generic_type_information[:type]]
35
- super_type = (generic_types_parser_registry[generic_type_information[:type]][:super_type] || [])
36
- generic_types_parser_registry[generic_type_information[:type]][:super_type]= super_type.concat(generic_type_information[:super_type])
37
- else
38
- generic_types_parser_registry[generic_type_information[:type]] = generic_type_information
39
- end
32
+ if generic_type_information.is_a?(String)
33
+ # concrete type with a generic super type
34
+ generic_type_information = {
35
+ :type => generic_type_information,
36
+ :parameters => [],
37
+ :kind => :generic_type
38
+ }
39
+ end
40
+ generic_type_information[:super_type] = generic_super_types_information
41
+ if generic_types_parser_registry[generic_type_information[:type]]
42
+ super_type = (generic_types_parser_registry[generic_type_information[:type]][:super_type] || [])
43
+ generic_types_parser_registry[generic_type_information[:type]][:super_type]= super_type.concat(generic_type_information[:super_type])
44
+ else
45
+ generic_types_parser_registry[generic_type_information[:type]] = generic_type_information
40
46
  end
41
47
  end
42
48
 
43
49
  def find_existential_type(type)
44
50
  existential_type = existential_types_registry[type]
45
51
  if existential_type.nil?
46
- existential_type = TypedRb::Types::TyExistentialType.new(type)
52
+ generic_existential_type = generic_types_registry[type]
53
+ existential_type = if generic_existential_type
54
+ TypedRb::Types::TyGenericExistentialType.new(type, generic_existential_type.type_vars)
55
+ else
56
+ TypedRb::Types::TyExistentialType.new(type)
57
+ end
47
58
  @existential_types_registry[type] = existential_type
48
59
  end
49
60
  existential_type
@@ -31,8 +31,8 @@ module TypedRb
31
31
  def compatible?(other_type, relation = :lt)
32
32
  if other_type.is_a?(TyDynamic) || other_type.is_a?(TyError)
33
33
  true
34
- elsif other_type.is_a?(TyGenericObject) || other_type.is_a?(TyGenericSingletonObject)
35
- if check_generic_type_relation(other_type.ruby_type, relation)
34
+ elsif other_type.is_a?(TyGenericObject) || other_type.is_a?(TyGenericSingletonObject) || other_type.is_a?(TyGenericExistentialType)
35
+ if check_generic_type_relation(other_type, relation)
36
36
  type_vars.each_with_index do |type_var, i|
37
37
  other_type_var = other_type.type_vars[i]
38
38
  compatible = if incompatible_free_type_vars?(type_var, other_type_var)
@@ -49,7 +49,7 @@ module TypedRb
49
49
  false
50
50
  end
51
51
  elsif other_type.is_a?(TyObject)
52
- check_generic_type_relation(other_type.ruby_type, relation)
52
+ check_generic_type_relation(other_type, relation)
53
53
  else
54
54
  other_type.compatible?(self, relation == :lt ? :gt : :lt)
55
55
  end
@@ -79,14 +79,25 @@ module TypedRb
79
79
  TypingContext.bound_generic_type_var?(right_var))
80
80
  end
81
81
 
82
- def check_generic_type_relation(other_ruby_type, relation)
82
+ def check_generic_type_relation(other_type, relation)
83
83
  if relation == :gt
84
- TyObject.new(ruby_type) >= TyObject.new(other_ruby_type)
84
+ to_ty_object(self) >= to_ty_object(other_type)
85
85
  else
86
- TyObject.new(ruby_type) <= TyObject.new(other_ruby_type)
86
+ to_ty_object(self) <= to_ty_object(other_type)
87
87
  end
88
88
  end
89
89
 
90
+ def to_ty_object(type)
91
+ ty_object = TyObject.new(type.ruby_type)
92
+ if type.is_a?(Types::TySingletonObject) ||
93
+ type.is_a?(Types::TyGenericSingletonObject) ||
94
+ type.is_a?(Types::TyExistentialType) ||
95
+ type.is_a?(Types::TyGenericExistentialType)
96
+ ty_object.hierarchy = type.ruby_type.meta_ancestors
97
+ end
98
+ ty_object
99
+ end
100
+
90
101
  def check_type_var_inclusion(type_var, other_type_var, relation)
91
102
  if (!type_var.wildcard? && !type_var.fully_bound?) ||
92
103
  (!other_type_var.wildcard? && !other_type_var.fully_bound?)
@@ -107,6 +107,19 @@ module TypedRb
107
107
  i && type_vars[i]
108
108
  end
109
109
 
110
+ def to_s
111
+ base_string = super
112
+ var_types_strings = @type_vars.map do |var_type|
113
+ if var_type.respond_to?(:bound) && var_type.bound
114
+ # "[#{var_type.variable} <= #{var_type.bound}]"
115
+ "[#{var_type.bound}]"
116
+ else
117
+ "[#{var_type}]"
118
+ end
119
+ end
120
+ "#{base_string}#{var_types_strings.join}"
121
+ end
122
+
110
123
  end
111
124
  end
112
125
  end
@@ -163,10 +163,17 @@ module TypedRb
163
163
  end
164
164
 
165
165
  def [](var)
166
- if var.is_a?(TypeVariable)
167
- groups[var]
166
+ found = if var.is_a?(TypeVariable)
167
+ groups[var]
168
+ else
169
+ var
170
+ end
171
+ if found.nil?
172
+ var_key = groups.keys.detect{ |key| key.name == var.name }
173
+ found = groups[var_key]
174
+ found || raise(TypedRb::Types::Polymorphism::UnificationError.new("Unification error, cannot find type variable #{var}"))
168
175
  else
169
- var
176
+ found
170
177
  end
171
178
  end
172
179
 
@@ -0,0 +1,92 @@
1
+ module TypedRb
2
+ module Types
3
+ module SingletonObject
4
+ def apply_type_arguments(fresh_vars_generic_type, actual_arguments)
5
+ fresh_vars_generic_type.type_vars.each_with_index do |type_var, i|
6
+ if type_var.bound.is_a?(TyGenericSingletonObject)
7
+ type_var.bind(apply_type_arguments_recursively(type_var.bound, actual_arguments))
8
+ else
9
+ apply_type_argument(actual_arguments[i], type_var)
10
+ end
11
+ end
12
+ end
13
+
14
+ def clone_with_substitutions(substitutions)
15
+ materialized_type_vars = type_vars(recursive: false).map do |type_var|
16
+ if type_var.is_a?(Polymorphism::TypeVariable) && type_var.bound_to_generic?
17
+ new_type_var = Polymorphism::TypeVariable.new(type_var.variable, node: type_var.node, gen_name: false)
18
+ new_type_var.to_wildcard! if type_var.wildcard?
19
+ bound = type_var.bound.clone_with_substitutions(substitutions)
20
+ new_type_var.bind(bound)
21
+ new_type_var.upper_bound = bound if type_var.upper_bound
22
+ new_type_var.lower_bound = bound if type_var.lower_bound
23
+ new_type_var
24
+ elsif type_var.is_a?(Polymorphism::TypeVariable)
25
+ substitutions[type_var.variable] || type_var.clone
26
+ elsif type_var.is_a?(TyGenericSingletonObject) || type_var.is_a?(TyGenericObject)
27
+ type_var.clone_with_substitutions(substitutions)
28
+ else
29
+ type_var
30
+ end
31
+ end
32
+ self.class.new(ruby_type, materialized_type_vars, node)
33
+ end
34
+
35
+ def apply_type_argument(argument, type_var)
36
+ if argument.is_a?(Polymorphism::TypeVariable)
37
+ if argument.wildcard?
38
+ # Wild card type
39
+ # If the type is T =:= E < Type1 or E > Type1 only that constraint should be added
40
+ { :lt => :upper_bound, :gt => :lower_bound }.each do |relation, bound|
41
+ if argument.send(bound)
42
+ value = if argument.send(bound).is_a?(TyGenericSingletonObject)
43
+ argument.send(bound).clone # .self_materialize
44
+ else
45
+ argument.send(bound)
46
+ end
47
+ type_var.compatible?(value, relation)
48
+ end
49
+ end
50
+ type_var.to_wildcard! # WILD CARD
51
+ elsif argument.bound # var type with a particular value
52
+ argument = argument.bound
53
+ if argument.is_a?(TyGenericSingletonObject)
54
+ argument = argument.clone # .self_materialize
55
+ end
56
+ # This is only for matches T =:= Type1 -> T < Type1, T > Type1
57
+ fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :lt)
58
+ fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :gt)
59
+ else
60
+ # Type variable
61
+ type_var.bound = argument
62
+ type_var.lower_bound = argument
63
+ type_var.upper_bound = argument
64
+ end
65
+ else
66
+ if argument.is_a?(TyGenericSingletonObject)
67
+ argument = argument.clone # .self_materialize
68
+ end
69
+ # This is only for matches T =:= Type1 -> T < Type1, T > Type1
70
+ fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :lt)
71
+ fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :gt)
72
+ end
73
+ end
74
+
75
+ def apply_type_arguments_recursively(generic_type_bound, actual_arguments)
76
+ arg_names = actual_arguments_hash(actual_arguments)
77
+ recursive_actual_arguments = generic_type_bound.type_vars.map do |type_var|
78
+ arg_names[type_var.variable] || fail("Unbound type variable #{type_var.variable} for recursive generic type #{generic_type_bound}")
79
+ end
80
+ generic_type_bound.materialize(recursive_actual_arguments)
81
+ end
82
+
83
+ def actual_arguments_hash(actual_arguments)
84
+ acc = {}
85
+ type_vars.each_with_index do |type_var, i|
86
+ acc[type_var.variable] = actual_arguments[i]
87
+ end
88
+ acc
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'ty_object'
2
+ require_relative 'singleton_object'
3
+
4
+ module TypedRb
5
+ module Types
6
+ class TyGenericExistentialType < TyExistentialType
7
+ include Polymorphism::GenericObject
8
+ include Polymorphism::GenericComparisons
9
+ include Polymorphism::GenericVariables
10
+ include SingletonObject
11
+
12
+ attr_accessor :local_typing_context, :self_variable
13
+
14
+ def initialize(ruby_type, type_vars, node = nil)
15
+ super(ruby_type, node)
16
+ @type_vars = type_vars
17
+ end
18
+
19
+ def check_inclusion(self_type)
20
+ if self_type.generic?
21
+ if ancestor_of_super_type?(self_type.super_type, ruby_type)
22
+ super_type = ancestor_of_super_type?(self_type.super_type, ruby_type)
23
+ materialize(self_type, super_type.type_vars)
24
+ else
25
+ materialize(self_type, self_type.type_vars)
26
+ end
27
+ else
28
+ # not generic extending a generic type
29
+ raise StandardError, "Extending generic module type #{ruby_type} in #{self_type} without matching super annotation"
30
+ end
31
+ end
32
+
33
+ def materialize(self_type, actual_arguments)
34
+ TypedRb.log binding, :debug, "Materialising generic existential type '#{self}' with args [#{actual_arguments.map(&:to_s).join(',')}]"
35
+ compute_minimal_typing_context if @local_typing_context.nil?
36
+
37
+ applied_typing_context, substitutions = @local_typing_context.clone(:module_self)
38
+ fresh_vars_generic_type = clone_with_substitutions(substitutions)
39
+ TypingContext.with_context(applied_typing_context) do
40
+ apply_type_arguments(fresh_vars_generic_type, actual_arguments)
41
+ context_self_type = Types::TypingContext.type_variable_for(ruby_type, :module_self, [ruby_type])
42
+ context_self_type.compatible?(self_type, :lt)
43
+ end
44
+ Polymorphism::Unification.new(applied_typing_context.all_constraints).run(false)
45
+ applied_typing_context.unlink # these constraints have already been satisfied
46
+ end
47
+ end
48
+ end
49
+ end
@@ -37,19 +37,6 @@ module TypedRb
37
37
  end
38
38
  end
39
39
 
40
- def to_s
41
- base_string = super
42
- var_types_strings = @type_vars.map do |var_type|
43
- if var_type.respond_to?(:bound) && var_type.bound
44
- # "[#{var_type.variable} <= #{var_type.bound}]"
45
- "[#{var_type.bound}]"
46
- else
47
- "[#{var_type}]"
48
- end
49
- end
50
- "#{base_string}#{var_types_strings.join}"
51
- end
52
-
53
40
  def clone_with_substitutions(substitutions)
54
41
  materialized_type_vars = type_vars(recursive: false).map do |type_var|
55
42
  if type_var.is_a?(Polymorphism::TypeVariable)
@@ -74,7 +61,6 @@ module TypedRb
74
61
  end
75
62
  self
76
63
  end
77
-
78
64
  end
79
65
  end
80
66
  end
@@ -2,6 +2,7 @@ require_relative 'ty_singleton_object'
2
2
  require_relative 'polymorphism/generic_comparisons'
3
3
  require_relative 'polymorphism/generic_variables'
4
4
  require_relative 'polymorphism/generic_object'
5
+ require_relative 'singleton_object'
5
6
 
6
7
  module TypedRb
7
8
  module Types
@@ -9,6 +10,7 @@ module TypedRb
9
10
  include Polymorphism::GenericObject
10
11
  include Polymorphism::GenericComparisons
11
12
  include Polymorphism::GenericVariables
13
+ include SingletonObject
12
14
 
13
15
  attr_accessor :local_typing_context, :super_type
14
16
 
@@ -82,26 +84,6 @@ module TypedRb
82
84
  fresh_vars_generic_type.apply_bindings(unification.bindings_map)
83
85
  end
84
86
 
85
- # TODO: We do need this for cases like Array.(Int).class_method
86
-
87
- # def find_function_type(message)
88
- # function_type = BasicObject::TypeRegistry.find(:class, ruby_type, message)
89
- # replace_bound_type_vars(function_type, type_vars)
90
- # end
91
-
92
- # def find_function_type(message)
93
- # BasicObject::TypeRegistry.find(:class, ruby_type, message)
94
- # end
95
- #
96
- # def find_var_type(var)
97
- # var_type = BasicObject::TypeRegistry.find(:class_variable, ruby_type, var)
98
- # if var_type
99
- # var_type
100
- # else
101
- # Types::TypingContext.type_variable_for(:class_variable, var, hierarchy)
102
- # end
103
- # end
104
-
105
87
  def as_object_type
106
88
  # this should only be used to check the body type of this
107
89
  # class. The variables are going to be unbound.
@@ -131,41 +113,6 @@ module TypedRb
131
113
  TyGenericSingletonObject.new(ruby_type, cloned_type_vars, super_type, node)
132
114
  end
133
115
 
134
- def to_s
135
- base_string = super
136
- var_types_strings = @type_vars.map do |var_type|
137
- if !var_type.is_a?(Polymorphism::TypeVariable)
138
- "[#{var_type}]"
139
- elsif var_type.bound && var_type.bound.is_a?(Polymorphism::TypeVariable)
140
- "[#{var_type.variable} <= #{var_type.bound.bound || var_type.bound.variable}]"
141
- else
142
- "[#{var_type.bound || var_type.variable}]"
143
- end
144
- end
145
- "#{base_string}#{var_types_strings.join}"
146
- end
147
-
148
- def clone_with_substitutions(substitutions)
149
- materialized_type_vars = type_vars(recursive: false).map do |type_var|
150
- if type_var.is_a?(Polymorphism::TypeVariable) && type_var.bound_to_generic?
151
- new_type_var = Polymorphism::TypeVariable.new(type_var.variable, node: type_var.node, gen_name: false)
152
- new_type_var.to_wildcard! if type_var.wildcard?
153
- bound = type_var.bound.clone_with_substitutions(substitutions)
154
- new_type_var.bind(bound)
155
- new_type_var.upper_bound = bound if type_var.upper_bound
156
- new_type_var.lower_bound = bound if type_var.lower_bound
157
- new_type_var
158
- elsif type_var.is_a?(Polymorphism::TypeVariable)
159
- substitutions[type_var.variable] || type_var.clone
160
- elsif type_var.is_a?(TyGenericSingletonObject) || type_var.is_a?(TyGenericObject)
161
- type_var.clone_with_substitutions(substitutions)
162
- else
163
- type_var
164
- end
165
- end
166
- self.class.new(ruby_type, materialized_type_vars, super_type, node)
167
- end
168
-
169
116
  # This object has concrete type parameters
170
117
  # The generic Function we retrieve from the registry might be generic
171
118
  # If it is generic we apply the bound parameters and we obtain a concrete function type
@@ -188,73 +135,6 @@ module TypedRb
188
135
  end
189
136
  end
190
137
 
191
- protected
192
-
193
- def apply_type_arguments(fresh_vars_generic_type, actual_arguments)
194
- fresh_vars_generic_type.type_vars.each_with_index do |type_var, i|
195
- if type_var.bound.is_a?(TyGenericSingletonObject)
196
- type_var.bind(apply_type_arguments_recursively(type_var.bound, actual_arguments))
197
- else
198
- apply_type_argument(actual_arguments[i], type_var)
199
- end
200
- end
201
- end
202
-
203
- def apply_type_argument(argument, type_var)
204
- if argument.is_a?(Polymorphism::TypeVariable)
205
- if argument.wildcard?
206
- # Wild card type
207
- # If the type is T =:= E < Type1 or E > Type1 only that constraint should be added
208
- { :lt => :upper_bound, :gt => :lower_bound }.each do |relation, bound|
209
- if argument.send(bound)
210
- value = if argument.send(bound).is_a?(TyGenericSingletonObject)
211
- argument.send(bound).clone # .self_materialize
212
- else
213
- argument.send(bound)
214
- end
215
- type_var.compatible?(value, relation)
216
- end
217
- end
218
- type_var.to_wildcard! # WILD CARD
219
- elsif argument.bound # var type with a particular value
220
- argument = argument.bound
221
- if argument.is_a?(TyGenericSingletonObject)
222
- argument = argument.clone # .self_materialize
223
- end
224
- # This is only for matches T =:= Type1 -> T < Type1, T > Type1
225
- fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :lt)
226
- fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :gt)
227
- else
228
- # Type variable
229
- type_var.bound = argument
230
- type_var.lower_bound = argument
231
- type_var.upper_bound = argument
232
- end
233
- else
234
- if argument.is_a?(TyGenericSingletonObject)
235
- argument = argument.clone # .self_materialize
236
- end
237
- # This is only for matches T =:= Type1 -> T < Type1, T > Type1
238
- fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :lt)
239
- fail Types::UncomparableTypes.new(type_var, argument) unless type_var.compatible?(argument, :gt)
240
- end
241
- end
242
-
243
- def apply_type_arguments_recursively(generic_type_bound, actual_arguments)
244
- arg_names = actual_arguments_hash(actual_arguments)
245
- recursive_actual_arguments = generic_type_bound.type_vars.map do |type_var|
246
- arg_names[type_var.variable] || fail("Unbound type variable #{type_var.variable} for recursive generic type #{generic_type_bound}")
247
- end
248
- generic_type_bound.materialize(recursive_actual_arguments)
249
- end
250
-
251
- def actual_arguments_hash(actual_arguments)
252
- acc = {}
253
- type_vars.each_with_index do |type_var, i|
254
- acc[type_var.variable] = actual_arguments[i]
255
- end
256
- acc
257
- end
258
138
  end
259
139
  end
260
140
  end
@@ -19,7 +19,8 @@ module TypedRb
19
19
  class TyObject < Type
20
20
  include Comparable
21
21
 
22
- attr_reader :hierarchy, :classes, :modules, :ruby_type, :with_ruby_type
22
+ attr_reader :classes, :modules, :ruby_type, :with_ruby_type
23
+ attr_accessor :hierarchy
23
24
 
24
25
  def initialize(ruby_type, node = nil, classes = [], modules = [])
25
26
  super(node)
data/lib/typed/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module TypedRb
2
2
  unless defined?(VERSION)
3
- VERSION = '0.0.18'
3
+ VERSION = '0.0.19'
4
4
  end
5
5
  end
@@ -86,4 +86,107 @@ __CODE
86
86
  result = language.check(code)
87
87
  expect(result.ruby_type).to eq(Integer)
88
88
  end
89
+
90
+ it 'typechecks the inclusion of a polymorphic module into a class' do
91
+ code = <<__CODE
92
+ module TMod5
93
+ ts '#head[T] / Array[T] -> [T]'
94
+ def head(xs); xs.first; end
95
+ end
96
+
97
+ class TMod5C
98
+ include TMod5
99
+ end
100
+
101
+ TMod5C.new.head([1,2,3])
102
+ __CODE
103
+
104
+ result = language.check(code)
105
+ expect(result.ruby_type).to eq(Integer)
106
+ end
107
+
108
+ it 'typechecks the inclusion of a polymorphic nested module into a class' do
109
+ code = <<__CODE
110
+ module Categories
111
+ module Polymorphism
112
+
113
+ ts '#head[A] / Array[A] -> [A]'
114
+ def head(xs)
115
+ xs.first
116
+ end
117
+
118
+ end
119
+ end
120
+
121
+ include Categories::Polymorphism
122
+
123
+ head([1,2,3])
124
+ __CODE
125
+
126
+ result = language.check(code)
127
+ expect(result.ruby_type).to eq(Integer)
128
+ end
129
+
130
+ it 'typechecks the inclusion of a polymorphic module into the top level object' do
131
+ code = <<__CODE
132
+ module TMod5
133
+ ts '#head[T] / Array[T] -> [T]'
134
+ def head(xs); xs.first; end
135
+ end
136
+
137
+ include TMod5
138
+
139
+ head([1,2,3])
140
+ __CODE
141
+
142
+ result = language.check(code)
143
+ expect(result.ruby_type).to eq(Integer)
144
+ end
145
+
146
+ it 'typechecks modules with generic parameters' do
147
+ code = <<__CODE
148
+ ts 'type TMod6[T]'
149
+ module TMod6
150
+ ts '#test1 / Array[T] -> [T]'
151
+ def test1(x); x.first; end
152
+ end
153
+
154
+ ts 'type TestTMod6 super TMod6[String]'
155
+ class TestTMod6
156
+ include TMod6
157
+ end
158
+
159
+ TestTMod6.new.test1(['a','b','c'])
160
+ __CODE
161
+
162
+ result = language.check(code)
163
+ expect(result.ruby_type).to eq(String)
164
+ end
165
+
166
+ it 'typechecks modules with generic parameters 2' do
167
+ code = <<__CODE
168
+ module Categories
169
+ ts 'type Categories::Equal[T]'
170
+ module Equal
171
+
172
+ ts '#eq? / [T] -> Boolean'
173
+ def eq?(o); self.eql?(o); end
174
+
175
+ ts '#not_eq? / [T] -> Boolean'
176
+ def not_eq?(o); ! self.eq?(o); end
177
+
178
+ end
179
+ end
180
+
181
+ ts 'type String super Categories::Equal[String]'
182
+ class String
183
+ include Categories::Equal
184
+ end
185
+
186
+ "test".eq? "other"
187
+ __CODE
188
+
189
+ result = language.check(code)
190
+ expect(result.to_s).to eq('Boolean')
191
+ end
89
192
  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.18
4
+ version: 0.0.19
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-29 00:00:00.000000000 Z
11
+ date: 2016-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -130,12 +130,14 @@ files:
130
130
  - lib/typed/types/polymorphism/type_variable.rb
131
131
  - lib/typed/types/polymorphism/type_variable_register.rb
132
132
  - lib/typed/types/polymorphism/unification.rb
133
+ - lib/typed/types/singleton_object.rb
133
134
  - lib/typed/types/ty_boolean.rb
134
135
  - lib/typed/types/ty_dynamic.rb
135
136
  - lib/typed/types/ty_either.rb
136
137
  - lib/typed/types/ty_error.rb
137
138
  - lib/typed/types/ty_existential_type.rb
138
139
  - lib/typed/types/ty_function.rb
140
+ - lib/typed/types/ty_generic_existential_type.rb
139
141
  - lib/typed/types/ty_generic_function.rb
140
142
  - lib/typed/types/ty_generic_object.rb
141
143
  - lib/typed/types/ty_generic_singleton_object.rb
@@ -261,8 +263,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
261
263
  version: '0'
262
264
  requirements: []
263
265
  rubyforge_project:
264
- rubygems_version: 2.4.5.1
266
+ rubygems_version: 2.4.6
265
267
  signing_key:
266
268
  specification_version: 4
267
269
  summary: Gradual type checker for Ruby
268
270
  test_files: []
271
+ has_rdoc: