typed.rb 0.0.11

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.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +26 -0
  3. data/bin/typed.rb +110 -0
  4. data/lib/typed/language.rb +131 -0
  5. data/lib/typed/model/tm_abs.rb +104 -0
  6. data/lib/typed/model/tm_array_literal.rb +25 -0
  7. data/lib/typed/model/tm_boolean.rb +15 -0
  8. data/lib/typed/model/tm_boolean_operator.rb +34 -0
  9. data/lib/typed/model/tm_break.rb +24 -0
  10. data/lib/typed/model/tm_case_when.rb +38 -0
  11. data/lib/typed/model/tm_class.rb +63 -0
  12. data/lib/typed/model/tm_const.rb +29 -0
  13. data/lib/typed/model/tm_defined.rb +19 -0
  14. data/lib/typed/model/tm_error.rb +16 -0
  15. data/lib/typed/model/tm_float.rb +15 -0
  16. data/lib/typed/model/tm_for.rb +42 -0
  17. data/lib/typed/model/tm_fun.rb +165 -0
  18. data/lib/typed/model/tm_global_var.rb +22 -0
  19. data/lib/typed/model/tm_global_var_assignment.rb +20 -0
  20. data/lib/typed/model/tm_hash_literal.rb +32 -0
  21. data/lib/typed/model/tm_if_else.rb +24 -0
  22. data/lib/typed/model/tm_instance_var.rb +23 -0
  23. data/lib/typed/model/tm_instance_var_assignment.rb +32 -0
  24. data/lib/typed/model/tm_int.rb +15 -0
  25. data/lib/typed/model/tm_local_var_asgn.rb +35 -0
  26. data/lib/typed/model/tm_mass_asgn.rb +60 -0
  27. data/lib/typed/model/tm_mlhs.rb +87 -0
  28. data/lib/typed/model/tm_module.rb +51 -0
  29. data/lib/typed/model/tm_next.rb +24 -0
  30. data/lib/typed/model/tm_nil.rb +14 -0
  31. data/lib/typed/model/tm_range_literal.rb +30 -0
  32. data/lib/typed/model/tm_regexp.rb +27 -0
  33. data/lib/typed/model/tm_rescue.rb +27 -0
  34. data/lib/typed/model/tm_return.rb +24 -0
  35. data/lib/typed/model/tm_s_class.rb +30 -0
  36. data/lib/typed/model/tm_self.rb +22 -0
  37. data/lib/typed/model/tm_send.rb +300 -0
  38. data/lib/typed/model/tm_sequencing.rb +53 -0
  39. data/lib/typed/model/tm_string.rb +15 -0
  40. data/lib/typed/model/tm_string_interpolation.rb +21 -0
  41. data/lib/typed/model/tm_super.rb +27 -0
  42. data/lib/typed/model/tm_symbol.rb +15 -0
  43. data/lib/typed/model/tm_symbol_interpolation.rb +21 -0
  44. data/lib/typed/model/tm_try.rb +29 -0
  45. data/lib/typed/model/tm_var.rb +28 -0
  46. data/lib/typed/model/tm_while.rb +43 -0
  47. data/lib/typed/model.rb +48 -0
  48. data/lib/typed/prelude.rb +939 -0
  49. data/lib/typed/prelude_existential_registry.bin +0 -0
  50. data/lib/typed/prelude_generic_registry.bin +0 -0
  51. data/lib/typed/prelude_registry.bin +0 -0
  52. data/lib/typed/runtime/ast_parser.rb +589 -0
  53. data/lib/typed/runtime/method_signature_processor.rb +72 -0
  54. data/lib/typed/runtime/normalization/validations.rb +47 -0
  55. data/lib/typed/runtime/normalization.rb +196 -0
  56. data/lib/typed/runtime/parser_context.rb +36 -0
  57. data/lib/typed/runtime/type_parser.rb +215 -0
  58. data/lib/typed/runtime/type_registry.rb +170 -0
  59. data/lib/typed/runtime/type_signature_processor.rb +34 -0
  60. data/lib/typed/runtime.rb +33 -0
  61. data/lib/typed/type_signature/parser.rb +240 -0
  62. data/lib/typed/types/polymorphism/existential_type_variable.rb +13 -0
  63. data/lib/typed/types/polymorphism/generic_comparisons.rb +134 -0
  64. data/lib/typed/types/polymorphism/generic_variables.rb +24 -0
  65. data/lib/typed/types/polymorphism/type_variable.rb +138 -0
  66. data/lib/typed/types/polymorphism/type_variable_register.rb +298 -0
  67. data/lib/typed/types/polymorphism/unification.rb +579 -0
  68. data/lib/typed/types/ty_boolean.rb +15 -0
  69. data/lib/typed/types/ty_dynamic.rb +39 -0
  70. data/lib/typed/types/ty_either.rb +168 -0
  71. data/lib/typed/types/ty_error.rb +18 -0
  72. data/lib/typed/types/ty_existential_type.rb +22 -0
  73. data/lib/typed/types/ty_function.rb +144 -0
  74. data/lib/typed/types/ty_generic_function.rb +115 -0
  75. data/lib/typed/types/ty_generic_object.rb +180 -0
  76. data/lib/typed/types/ty_generic_singleton_object.rb +238 -0
  77. data/lib/typed/types/ty_object.rb +256 -0
  78. data/lib/typed/types/ty_singleton_object.rb +78 -0
  79. data/lib/typed/types/ty_stack_jump.rb +44 -0
  80. data/lib/typed/types/ty_top_level_object.rb +38 -0
  81. data/lib/typed/types.rb +60 -0
  82. data/lib/typed/typing_context.rb +206 -0
  83. data/lib/typed/version.rb +3 -0
  84. data/lib/typed.rb +161 -0
  85. data/spec/lib/ast_parser_spec.rb +101 -0
  86. data/spec/lib/examples/animals.rb +44 -0
  87. data/spec/lib/examples/counter.rb +16 -0
  88. data/spec/lib/examples/if.rb +31 -0
  89. data/spec/lib/language_spec.rb +36 -0
  90. data/spec/lib/model/tm_abs_spec.rb +66 -0
  91. data/spec/lib/model/tm_array_literal_spec.rb +36 -0
  92. data/spec/lib/model/tm_case_when_spec.rb +39 -0
  93. data/spec/lib/model/tm_class_spec.rb +67 -0
  94. data/spec/lib/model/tm_defined_spec.rb +10 -0
  95. data/spec/lib/model/tm_for_spec.rb +150 -0
  96. data/spec/lib/model/tm_fun_spec.rb +11 -0
  97. data/spec/lib/model/tm_hash_literal_spec.rb +40 -0
  98. data/spec/lib/model/tm_mass_asgn_spec.rb +104 -0
  99. data/spec/lib/model/tm_module_spec.rb +42 -0
  100. data/spec/lib/model/tm_regexp_spec.rb +9 -0
  101. data/spec/lib/model/tm_return_spec.rb +47 -0
  102. data/spec/lib/model/tm_s_class_spec.rb +27 -0
  103. data/spec/lib/model/tm_self_spec.rb +19 -0
  104. data/spec/lib/model/tm_string_interpolation_spec.rb +10 -0
  105. data/spec/lib/model/tm_symbol_interpolation_spec.rb +10 -0
  106. data/spec/lib/model/tm_symbol_spec.rb +9 -0
  107. data/spec/lib/model/tm_while_spec.rb +141 -0
  108. data/spec/lib/polymorphism/type_variable_spec.rb +14 -0
  109. data/spec/lib/polymorphism/unification_spec.rb +328 -0
  110. data/spec/lib/prelude/array_spec.rb +263 -0
  111. data/spec/lib/prelude/class_spec.rb +12 -0
  112. data/spec/lib/prelude/enumerable_spec.rb +278 -0
  113. data/spec/lib/prelude/enumerator_spec.rb +101 -0
  114. data/spec/lib/prelude/hash_spec.rb +361 -0
  115. data/spec/lib/prelude/kernel_spec.rb +23 -0
  116. data/spec/lib/prelude/object_spec.rb +22 -0
  117. data/spec/lib/prelude/pair_spec.rb +16 -0
  118. data/spec/lib/prelude/showable_spec.rb +31 -0
  119. data/spec/lib/prelude/string_spec.rb +98 -0
  120. data/spec/lib/runtime/normalization_spec.rb +29 -0
  121. data/spec/lib/runtime/validations_spec.rb +56 -0
  122. data/spec/lib/runtime_spec.rb +503 -0
  123. data/spec/lib/type_signature/parser_spec.rb +239 -0
  124. data/spec/lib/types/comparisons_spec.rb +35 -0
  125. data/spec/lib/types/polymorphism/generic_comparisons_spec.rb +492 -0
  126. data/spec/lib/types/polymorphism/type_variable_register_spec.rb +128 -0
  127. data/spec/lib/types/ty_dynamic_spec.rb +103 -0
  128. data/spec/lib/types/ty_either_spec.rb +288 -0
  129. data/spec/lib/types/ty_error_spec.rb +18 -0
  130. data/spec/lib/types/ty_generic_object_spec.rb +78 -0
  131. data/spec/lib/types/ty_generic_singleton_object_spec.rb +288 -0
  132. data/spec/lib/types/typing_context_spec.rb +86 -0
  133. data/spec/lib/types_spec.rb +174 -0
  134. data/spec/lib/typing/boolean_asgn_spec.rb +134 -0
  135. data/spec/lib/typing/break_spec.rb +79 -0
  136. data/spec/lib/typing/generics_spec.rb +191 -0
  137. data/spec/lib/typing/instance_vars_spec.rb +103 -0
  138. data/spec/lib/typing/next_spec.rb +29 -0
  139. data/spec/lib/typing/op_asgn_spec.rb +104 -0
  140. data/spec/lib/typing/overriden_methods_spec.rb +31 -0
  141. data/spec/lib/typing/subtyping_spec.rb +112 -0
  142. data/spec/lib/typing/tm_boolean_operator_spec.rb +100 -0
  143. data/spec/lib/typing/tm_boolean_spec.rb +61 -0
  144. data/spec/lib/typing/tm_const_spec.rb +28 -0
  145. data/spec/lib/typing/tm_defined_spec.rb +12 -0
  146. data/spec/lib/typing/tm_fun_spec.rb +347 -0
  147. data/spec/lib/typing/tm_global_var_spec.rb +33 -0
  148. data/spec/lib/typing/tm_if_else_spec.rb +104 -0
  149. data/spec/lib/typing/tm_ignore_spec.rb +24 -0
  150. data/spec/lib/typing/tm_instance_vars_spec.rb +117 -0
  151. data/spec/lib/typing/tm_local_var_asgn_spec.rb +134 -0
  152. data/spec/lib/typing/tm_mlhs_spec.rb +164 -0
  153. data/spec/lib/typing/tm_module_spec.rb +89 -0
  154. data/spec/lib/typing/tm_raise_spec.rb +31 -0
  155. data/spec/lib/typing/tm_range_literal_spec.rb +25 -0
  156. data/spec/lib/typing/tm_regexp_spec.rb +14 -0
  157. data/spec/lib/typing/tm_return_spec.rb +45 -0
  158. data/spec/lib/typing/tm_send_casting_spec.rb +26 -0
  159. data/spec/lib/typing/tm_send_class_methods_spec.rb +42 -0
  160. data/spec/lib/typing/tm_send_generic_apply_spec.rb +103 -0
  161. data/spec/lib/typing/tm_send_generic_methods_spec.rb +77 -0
  162. data/spec/lib/typing/tm_send_initialize_spec.rb +68 -0
  163. data/spec/lib/typing/tm_send_lambda_spec.rb +135 -0
  164. data/spec/lib/typing/tm_send_spec.rb +217 -0
  165. data/spec/lib/typing/tm_send_yield_block_spec.rb +308 -0
  166. data/spec/lib/typing/tm_sequencing_spec.rb +174 -0
  167. data/spec/lib/typing/tm_string_interpolation_spec.rb +19 -0
  168. data/spec/lib/typing/tm_super_spec.rb +63 -0
  169. data/spec/lib/typing/tm_symbol_interpolation_spec.rb +19 -0
  170. data/spec/lib/typing/tm_symbol_spec.rb +14 -0
  171. data/spec/lib/typing/tm_try_spec.rb +73 -0
  172. data/spec/spec_helper.rb +140 -0
  173. metadata +216 -0
@@ -0,0 +1,298 @@
1
+ module TypedRb
2
+ module Types
3
+ # Polymorphic additions to Featherweight Ruby
4
+ module Polymorphism
5
+ class TypeVariableRegister
6
+ attr_accessor :parent, :constraints, :children, :type_variables_register, :kind
7
+
8
+ class << self
9
+ def local_var_counter
10
+ @local_var_counter ||= 0
11
+ @local_var_counter += 1
12
+ end
13
+ end
14
+
15
+ def initialize(parent = nil, kind)
16
+ @kind = kind
17
+ @parent = parent
18
+ if @parent
19
+ @parent.children << self
20
+ @parent.children.uniq!
21
+ end
22
+ @children = []
23
+ @constraints = {}
24
+ @type_variables_register = {}
25
+ end
26
+
27
+ def unlink
28
+ return if @parent.nil?
29
+ @parent.children.delete(self)
30
+ end
31
+
32
+ def type_variable_for(type, variable, hierarchy)
33
+ ensure_string(variable)
34
+ upper_level = upper_class_register # we need to get a class register
35
+ key = hierarchy.map do |ruby_type|
36
+ [type, ruby_type, variable]
37
+ end.detect do |constructed_key|
38
+ upper_level.type_variables_register[constructed_key]
39
+ end
40
+ if key.nil?
41
+ type_var = upper_level.type_variables_register[[type, hierarchy.first, variable]]
42
+ if type_var.nil?
43
+ new_var_name = "#{hierarchy.first}:#{variable}"
44
+ type_var = if variable == :module_self
45
+ ExistentialTypeVariable.new(new_var_name, :gen_name => false)
46
+ else
47
+ TypeVariable.new(new_var_name, :gen_name => false)
48
+ end
49
+ upper_level.type_variables_register[[type, hierarchy.first, variable]] = type_var
50
+ type_var
51
+ else
52
+ type_var
53
+ end
54
+ else
55
+ upper_level.type_variables_register[key]
56
+ end
57
+ end
58
+
59
+ def type_variable_for_global(variable)
60
+ ensure_string(variable)
61
+ upper_level = top_level_register
62
+ key = [:global, nil, variable]
63
+ type_var = upper_level.type_variables_register[key]
64
+ if type_var.nil?
65
+ type_var = TypeVariable.new(variable, :gen_name => false)
66
+ upper_level.type_variables_register[key] = type_var
67
+ end
68
+ type_var
69
+ end
70
+
71
+ def type_variable_for_message(variable, message)
72
+ ensure_string(variable)
73
+ key = [:return, message, variable]
74
+ type_var = recursive_constraint_search(key)
75
+ if type_var.nil?
76
+ new_var_name = "#{variable}:#{message}"
77
+ type_var = TypeVariable.new(new_var_name)
78
+ type_variables_register[key] = type_var
79
+ end
80
+ type_var
81
+ end
82
+
83
+ def type_variable_for_abstraction(abs_kind, variable, context)
84
+ variable = Model::GenSym.next("#{abs_kind}_ret}") if variable.nil?
85
+ ensure_string(variable)
86
+ key = [abs_kind.to_sym, context.context_name, variable]
87
+ type_var = recursive_constraint_search(key)
88
+ if type_var.nil?
89
+ # don't gnerate a random fresh name for the var, use the one we're
90
+ # providing
91
+ new_var_name = "TV_#{context.context_name}:#{abs_kind}:#{variable}"
92
+ type_var = TypeVariable.new(new_var_name, gen_name: false)
93
+ type_variables_register[key] = type_var
94
+ end
95
+ type_var
96
+ end
97
+
98
+ def type_variable_for_generic_type(type_var, method = false)
99
+ key = [:generic, method, type_var.variable]
100
+ type_var_in_registry = type_variables_register[key]
101
+ if type_var_in_registry
102
+ type_var_in_registry
103
+ else
104
+ type_var_in_registry = type_var.clone
105
+ type_variables_register[key] = type_var_in_registry
106
+ type_var_in_registry
107
+ end
108
+ end
109
+
110
+ def local_type_variable
111
+ var_name = "local_var_#{TypeVariableRegister.local_var_counter}"
112
+ key = [:local, nil, var_name]
113
+ type_var_in_registry = TypeVariable.new(var_name)
114
+ type_variables_register[key] = type_var_in_registry
115
+ type_var_in_registry
116
+ end
117
+
118
+ def bound_generic_type_var?(type_variable)
119
+ found = type_variables_register[[:generic, false, type_variable.name]] ||
120
+ type_variables_register[[:generic, true, type_variable.name]]
121
+
122
+ if found
123
+ kind == :method || kind == :class
124
+ elsif !parent.nil?
125
+ parent.bound_generic_type_var?(type_variable)
126
+ else
127
+ false
128
+ end
129
+ end
130
+
131
+ def constraints_for(variable)
132
+ found = constraints[variable]
133
+ children_found = children.map { |child_context| child_context.constraints_for(variable) }.reduce(&:+)
134
+ (found || []) + (children_found || [])
135
+ end
136
+
137
+ # @type_variables_register
138
+ # code_name => type_var
139
+ # @constraints
140
+ # type_var => constraint
141
+ def all_constraints
142
+ self_variables_constraints = @type_variables_register.values.reduce([]) do |constraints_acc, type_var|
143
+ constraints_acc + type_var.constraints(self)
144
+ end
145
+ self_variables_constraints + (children.reject{ |r| r.kind == :module }.map(&:all_constraints).reduce(&:+) || [])
146
+ end
147
+
148
+ def all_variables
149
+ @type_variables_register.values
150
+ end
151
+
152
+ def clear
153
+ @parent = nil
154
+ @constraints.clear
155
+ type_variables_register.clear
156
+ end
157
+
158
+ def add_constraint(variable_name, relation_type, type)
159
+ TypedRb.log(binding, :debug, "Adding constraint #{variable_name} #{relation_type} #{type}")
160
+ if type_variables_register.values.detect { |variable| variable.variable == variable_name }
161
+ var_constraints = @constraints[variable_name] || []
162
+ var_constraints << [relation_type, type]
163
+ @constraints[variable_name] = var_constraints
164
+ elsif parent
165
+ parent.add_constraint(variable_name, relation_type, type)
166
+ else
167
+ fail StandardError, "Cannot find variable #{variable_name} to add a constraint"
168
+ end
169
+ end
170
+
171
+ def include?(variable)
172
+ found = @type_variables_register.values.detect do |var|
173
+ var.variable == variable
174
+ end
175
+ return true if found
176
+ return false if parent.nil?
177
+ parent.include?(variable)
178
+ end
179
+
180
+ def print_constraints
181
+ constraints.each do |(variable_name, constraints)|
182
+ constraints.each do |(rel, val)|
183
+ if rel == :send
184
+ puts "#{variable_name} #{rel} #{val[:message]}#{val[:args].map(&:to_s).join(',')}"
185
+ else
186
+ puts "#{variable_name} #{rel} #{val}"
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ def clone(scope)
193
+ vars = (scope == :method) ? method_var_types : class_var_types
194
+ substitutions = vars.each_with_object({}) do |var_type, acc|
195
+ acc[var_type.variable] = var_type.clone
196
+ end
197
+ [apply_type(parent, substitutions), substitutions]
198
+ end
199
+
200
+ protected
201
+
202
+ def method_var_types
203
+ @type_variables_register.map do |(key, value)|
204
+ type = key.first
205
+ value if type != :instance_variable && type != :class_variable
206
+ end.compact
207
+ end
208
+
209
+ def class_var_types
210
+ @type_variables_register.map do |(key, value)|
211
+ type = key.first
212
+ if type == :instance_variable || type == :class_variable || type == :generic
213
+ value
214
+ end
215
+ end.compact
216
+ end
217
+
218
+ def apply_type(parent, type_variable_mapping)
219
+ register = TypeVariableRegister.new(parent, kind)
220
+ apply_type_to_register(register, type_variable_mapping)
221
+ end
222
+
223
+ def apply_type_to_register(register, type_variable_mapping)
224
+ register.type_variables_register = type_variables_register.each_with_object({}) do |((k, i, v), var), acc|
225
+ acc[[k, i, v]] = type_variable_mapping[var.variable] || var
226
+ end
227
+ register.constraints = rename_constraints(constraints, type_variable_mapping)
228
+ register.children = children.map { |child_register| child_register.apply_type(register, type_variable_mapping) }
229
+ register
230
+ end
231
+
232
+ def rename_constraints(constraints, type_variable_mapping)
233
+ constraints.each_with_object({}) do |(variable_name, values), acc|
234
+ new_variable_name = type_variable_mapping[variable_name] ? type_variable_mapping[variable_name].variable : variable_name
235
+ new_values = values.map do |(rel, type)|
236
+ if (rel == :send)
237
+ old_return_type = type[:return]
238
+ new_return_type = if old_return_type.is_a?(TypeVariable)
239
+ type_variable_mapping[old_return_type.variable] ? type_variable_mapping[old_return_type.variable] : old_return_type
240
+ else
241
+ old_return_type
242
+ end
243
+ new_args = type[:args].map do |arg|
244
+ if arg.is_a?(TypeVariable)
245
+ type_variable_mapping[arg.variable] ? type_variable_mapping[arg.variable] : arg
246
+ else
247
+ arg
248
+ end
249
+ end
250
+ [:send, { args: new_args, return: new_return_type, message: type[:message] }]
251
+ else
252
+ if type.is_a?(TypeVariable) && type_variable_mapping[type.variable]
253
+ [rel, type_variable_mapping[type.variable]]
254
+ else
255
+ [rel, type]
256
+ end
257
+ end
258
+ end
259
+ acc[new_variable_name] = new_values
260
+ end
261
+ end
262
+
263
+ def recursive_constraint_search(key)
264
+ current = self
265
+ found = nil
266
+ while found.nil? && !current.nil?
267
+ found = current.type_variables_register[key]
268
+ current = current.parent unless current.nil?
269
+ end
270
+ found
271
+ end
272
+
273
+ # We find the first registry that has been created
274
+ # in the context of a generic class or the top level
275
+ # registry if none is found.
276
+ # The registry can be the current one.
277
+ def upper_class_register
278
+ current = self
279
+ while current.kind != :top_level && current.kind != :class && current.kind != :module && current.kind != :sclass
280
+ current = current.parent
281
+ end
282
+ current
283
+ end
284
+
285
+ def top_level_register
286
+ current = self
287
+ current = current.parent while current.kind != :top_level
288
+ current
289
+ end
290
+
291
+ def ensure_string(variable)
292
+ variable = variable.to_s if variable.is_a?(Symbol)
293
+ fail StandardError, 'Variable name must be a String for register' unless variable.is_a?(String)
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end