typed.rb 0.0.18 → 0.0.19

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