steep 0.1.0.pre2 → 0.1.0

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 (119) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/README.md +146 -33
  4. data/bin/smoke_runner.rb +43 -10
  5. data/lib/steep/ast/annotation/collection.rb +93 -0
  6. data/lib/steep/ast/annotation.rb +131 -0
  7. data/lib/steep/ast/buffer.rb +47 -0
  8. data/lib/steep/ast/location.rb +82 -0
  9. data/lib/steep/ast/method_type.rb +116 -0
  10. data/lib/steep/ast/signature/class.rb +33 -0
  11. data/lib/steep/ast/signature/const.rb +17 -0
  12. data/lib/steep/ast/signature/env.rb +123 -0
  13. data/lib/steep/ast/signature/extension.rb +21 -0
  14. data/lib/steep/ast/signature/gvar.rb +17 -0
  15. data/lib/steep/ast/signature/interface.rb +31 -0
  16. data/lib/steep/ast/signature/members.rb +71 -0
  17. data/lib/steep/ast/signature/module.rb +21 -0
  18. data/lib/steep/ast/type_params.rb +13 -0
  19. data/lib/steep/ast/types/any.rb +39 -0
  20. data/lib/steep/ast/types/bot.rb +39 -0
  21. data/lib/steep/ast/types/class.rb +35 -0
  22. data/lib/steep/ast/types/helper.rb +21 -0
  23. data/lib/steep/ast/types/instance.rb +39 -0
  24. data/lib/steep/ast/types/intersection.rb +74 -0
  25. data/lib/steep/ast/types/name.rb +124 -0
  26. data/lib/steep/ast/types/self.rb +39 -0
  27. data/lib/steep/ast/types/top.rb +39 -0
  28. data/lib/steep/ast/types/union.rb +74 -0
  29. data/lib/steep/ast/types/var.rb +57 -0
  30. data/lib/steep/ast/types/void.rb +35 -0
  31. data/lib/steep/cli.rb +28 -1
  32. data/lib/steep/drivers/annotations.rb +32 -0
  33. data/lib/steep/drivers/check.rb +53 -77
  34. data/lib/steep/drivers/scaffold.rb +303 -0
  35. data/lib/steep/drivers/utils/each_signature.rb +66 -0
  36. data/lib/steep/drivers/utils/validator.rb +115 -0
  37. data/lib/steep/drivers/validate.rb +39 -0
  38. data/lib/steep/errors.rb +291 -19
  39. data/lib/steep/interface/abstract.rb +44 -0
  40. data/lib/steep/interface/builder.rb +470 -0
  41. data/lib/steep/interface/instantiated.rb +126 -0
  42. data/lib/steep/interface/ivar_chain.rb +26 -0
  43. data/lib/steep/interface/method.rb +60 -0
  44. data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
  45. data/lib/steep/interface/substitution.rb +65 -0
  46. data/lib/steep/module_name.rb +116 -0
  47. data/lib/steep/parser.rb +1314 -814
  48. data/lib/steep/parser.y +536 -175
  49. data/lib/steep/source.rb +220 -25
  50. data/lib/steep/subtyping/check.rb +673 -0
  51. data/lib/steep/subtyping/constraints.rb +275 -0
  52. data/lib/steep/subtyping/relation.rb +41 -0
  53. data/lib/steep/subtyping/result.rb +126 -0
  54. data/lib/steep/subtyping/trace.rb +48 -0
  55. data/lib/steep/subtyping/variable_occurrence.rb +49 -0
  56. data/lib/steep/subtyping/variable_variance.rb +69 -0
  57. data/lib/steep/type_construction.rb +1630 -524
  58. data/lib/steep/type_inference/block_params.rb +100 -0
  59. data/lib/steep/type_inference/constant_env.rb +55 -0
  60. data/lib/steep/type_inference/send_args.rb +222 -0
  61. data/lib/steep/type_inference/type_env.rb +226 -0
  62. data/lib/steep/type_name.rb +27 -7
  63. data/lib/steep/typing.rb +4 -0
  64. data/lib/steep/version.rb +1 -1
  65. data/lib/steep.rb +71 -16
  66. data/smoke/and/a.rb +4 -2
  67. data/smoke/array/a.rb +4 -5
  68. data/smoke/array/b.rb +4 -4
  69. data/smoke/block/a.rb +2 -2
  70. data/smoke/block/a.rbi +2 -0
  71. data/smoke/block/b.rb +15 -0
  72. data/smoke/case/a.rb +3 -3
  73. data/smoke/class/a.rb +3 -3
  74. data/smoke/class/b.rb +0 -2
  75. data/smoke/class/d.rb +2 -2
  76. data/smoke/class/e.rb +1 -1
  77. data/smoke/class/f.rb +2 -2
  78. data/smoke/class/g.rb +8 -0
  79. data/smoke/const/a.rb +3 -3
  80. data/smoke/dstr/a.rb +1 -1
  81. data/smoke/ensure/a.rb +22 -0
  82. data/smoke/enumerator/a.rb +6 -6
  83. data/smoke/enumerator/b.rb +22 -0
  84. data/smoke/extension/a.rb +2 -2
  85. data/smoke/extension/b.rb +3 -3
  86. data/smoke/extension/c.rb +1 -1
  87. data/smoke/hello/hello.rb +2 -2
  88. data/smoke/if/a.rb +4 -2
  89. data/smoke/kwbegin/a.rb +8 -0
  90. data/smoke/literal/a.rb +5 -5
  91. data/smoke/method/a.rb +5 -5
  92. data/smoke/method/a.rbi +4 -0
  93. data/smoke/method/b.rb +29 -0
  94. data/smoke/module/a.rb +3 -3
  95. data/smoke/module/a.rbi +9 -0
  96. data/smoke/module/b.rb +2 -2
  97. data/smoke/module/c.rb +1 -1
  98. data/smoke/module/d.rb +5 -0
  99. data/smoke/module/e.rb +13 -0
  100. data/smoke/module/f.rb +13 -0
  101. data/smoke/rescue/a.rb +62 -0
  102. data/smoke/super/a.rb +2 -2
  103. data/smoke/type_case/a.rb +35 -0
  104. data/smoke/yield/a.rb +2 -2
  105. data/stdlib/builtin.rbi +463 -24
  106. data/steep.gemspec +3 -2
  107. metadata +91 -29
  108. data/lib/steep/annotation.rb +0 -223
  109. data/lib/steep/signature/class.rb +0 -450
  110. data/lib/steep/signature/extension.rb +0 -51
  111. data/lib/steep/signature/interface.rb +0 -49
  112. data/lib/steep/types/any.rb +0 -31
  113. data/lib/steep/types/class.rb +0 -27
  114. data/lib/steep/types/instance.rb +0 -27
  115. data/lib/steep/types/merge.rb +0 -32
  116. data/lib/steep/types/name.rb +0 -57
  117. data/lib/steep/types/union.rb +0 -42
  118. data/lib/steep/types/var.rb +0 -38
  119. data/lib/steep/types.rb +0 -4
@@ -1,8 +1,46 @@
1
1
  module Steep
2
2
  class TypeConstruction
3
+ module Types
4
+ module_function
5
+
6
+ def any
7
+ AST::Types::Any.new
8
+ end
9
+
10
+ def symbol_instance
11
+ AST::Types::Name.new_instance(name: "::Symbol")
12
+ end
13
+
14
+ def nil_instance
15
+ AST::Types::Name.new_instance(name: "::NilClass")
16
+ end
17
+
18
+ def string_instance
19
+ AST::Types::Name.new_instance(name: "::String")
20
+ end
21
+
22
+ def array_instance(type)
23
+ AST::Types::Name.new_instance(name: "::Array", args: [type])
24
+ end
25
+
26
+ def hash_instance(key, value)
27
+ AST::Types::Name.new_instance(name: "::Hash", args: [key, value])
28
+ end
29
+
30
+ def range_instance(type)
31
+ AST::Types::Name.new_instance(name: "::Range", args: [type])
32
+ end
33
+
34
+ def boolean?(type)
35
+ type == AST::Types::Name.new_interface(name: :_Boolean)
36
+ end
37
+ end
38
+
3
39
  class MethodContext
4
40
  attr_reader :name
5
41
  attr_reader :method
42
+ attr_reader :method_type
43
+ attr_reader :return_type
6
44
  attr_reader :constructor
7
45
 
8
46
  def initialize(name:, method:, method_type:, return_type:, constructor:)
@@ -13,30 +51,30 @@ module Steep
13
51
  @constructor = constructor
14
52
  end
15
53
 
16
- def return_type
17
- @return_type || method_type&.return_type
18
- end
19
-
20
54
  def block_type
21
55
  method_type&.block
22
56
  end
23
57
 
24
- def method_type
25
- @method_type || method&.types&.first
58
+ def super_method
59
+ method&.super_method
26
60
  end
61
+ end
62
+
63
+ class BlockContext
64
+ attr_reader :body_type
27
65
 
28
- def super_type
29
- method&.super_method&.types&.first
66
+ def initialize(body_type:)
67
+ @body_type = body_type
30
68
  end
31
69
  end
32
70
 
33
- class BlockContext
71
+ class BreakContext
34
72
  attr_reader :break_type
35
- attr_reader :body_type
73
+ attr_reader :next_type
36
74
 
37
- def initialize(break_type:, body_type:)
75
+ def initialize(break_type:, next_type:)
38
76
  @break_type = break_type
39
- @body_type = body_type
77
+ @next_type = next_type
40
78
  end
41
79
  end
42
80
 
@@ -45,726 +83,1685 @@ module Steep
45
83
  attr_reader :module_type
46
84
  attr_reader :defined_instance_methods
47
85
  attr_reader :defined_module_methods
48
- attr_reader :const_types
86
+ attr_reader :const_env
87
+ attr_reader :implement_name
88
+ attr_reader :current_namespace
49
89
 
50
- def initialize(instance_type:, module_type:, const_types:)
90
+ def initialize(instance_type:, module_type:, implement_name:, current_namespace:, const_env:)
51
91
  @instance_type = instance_type
52
92
  @module_type = module_type
53
93
  @defined_instance_methods = Set.new
54
94
  @defined_module_methods = Set.new
55
- @const_types = const_types
95
+ @implement_name = implement_name
96
+ @current_namespace = current_namespace
97
+ @const_env = const_env
56
98
  end
57
99
  end
58
100
 
59
- attr_reader :assignability
101
+ attr_reader :checker
60
102
  attr_reader :source
61
103
  attr_reader :annotations
62
- attr_reader :var_types
63
- attr_reader :ivar_types
64
104
  attr_reader :typing
65
105
  attr_reader :method_context
66
106
  attr_reader :block_context
67
107
  attr_reader :module_context
68
108
  attr_reader :self_type
109
+ attr_reader :break_context
110
+ attr_reader :type_env
69
111
 
70
- def initialize(assignability:, source:, annotations:, var_types:, ivar_types: {}, typing:, self_type:, method_context:, block_context:, module_context:)
71
- @assignability = assignability
112
+ def initialize(checker:, source:, annotations:, type_env:, typing:, self_type:, method_context:, block_context:, module_context:, break_context:)
113
+ @checker = checker
72
114
  @source = source
73
115
  @annotations = annotations
74
- @var_types = var_types
75
- @ivar_types = ivar_types
76
116
  @typing = typing
77
117
  @self_type = self_type
78
118
  @block_context = block_context
79
119
  @method_context = method_context
80
120
  @module_context = module_context
121
+ @break_context = break_context
122
+ @type_env = type_env
81
123
  end
82
124
 
83
- def method_entry(method_name, receiver_type:)
84
- if receiver_type
85
- entry = nil
86
- assignability.method_type receiver_type, method_name do |method|
87
- entry = method
88
- end
125
+ def for_new_method(method_name, node, args:, self_type:)
126
+ annots = source.annotations(block: node)
127
+ type_env = TypeInference::TypeEnv.new(subtyping: checker,
128
+ const_env: module_context&.const_env || self.type_env.const_env)
129
+
130
+ self.type_env.const_types.each do |name, type|
131
+ type_env.set(const: name, type: type)
89
132
  end
90
133
 
91
- if (type = annotations.lookup_method_type(method_name))
92
- Interface::Method.new(types: [type], super_method: entry&.super_method, attributes: [])
93
- else
94
- entry
134
+ self_type = annots.self_type || self_type
135
+
136
+ self_interface = self_type && (self_type != Types.any || nil) && checker.resolve(self_type, with_initialize: true)
137
+ interface_method = self_interface&.yield_self {|interface| interface.methods[method_name] }
138
+ annotation_method = annotations.lookup_method_type(method_name)&.yield_self do |method_type|
139
+ Interface::Method.new(type_name: nil,
140
+ name: method_name,
141
+ types: [checker.builder.method_type_to_method_type(method_type,
142
+ current: current_namespace)],
143
+ super_method: interface_method&.super_method,
144
+ attributes: [])
95
145
  end
96
- end
97
146
 
98
- def for_new_method(method_name, node, args:, self_type:)
99
- annots = source.annotations(block: node)
147
+ if interface_method && annotation_method
148
+ result = checker.check_method(method_name,
149
+ annotation_method,
150
+ interface_method,
151
+ assumption: Set.new,
152
+ trace: Subtyping::Trace.new,
153
+ constraints: Subtyping::Constraints.empty)
154
+
155
+ if result.failure?
156
+ typing.add_error Errors::IncompatibleMethodTypeAnnotation.new(
157
+ node: node,
158
+ annotation_method: annotation_method,
159
+ interface_method: interface_method,
160
+ result: result
161
+ )
162
+ end
163
+ end
100
164
 
101
- self_type = annots.self_type || self_type
165
+ method = annotation_method || interface_method
102
166
 
103
- entry = method_entry(method_name, receiver_type: self_type)
104
- method_type = entry&.types&.first
105
- if method_type
106
- var_types = TypeConstruction.parameter_types(args,
107
- method_type)
108
- unless TypeConstruction.valid_parameter_env?(var_types, args, method_type.params)
109
- typing.add_error Errors::MethodParameterTypeMismatch.new(node: node)
167
+ case
168
+ when method && method.types.size == 1
169
+ method_type = method.types.first
170
+ return_type = method_type.return_type
171
+ var_types = TypeConstruction.parameter_types(args, method_type).transform_values {|type| absolute_type(type) }
172
+ unless TypeConstruction.valid_parameter_env?(var_types, args.reject {|arg| arg.type == :blockarg }, method_type.params)
173
+ typing.add_error Errors::MethodArityMismatch.new(node: node)
110
174
  end
175
+ when method
176
+ typing.add_error Errors::MethodDefinitionWithOverloading.new(node: node, method: method)
177
+ return_type = union_type(*method.types.map(&:return_type))
178
+ var_types = {}
111
179
  else
112
180
  var_types = {}
113
181
  end
114
182
 
115
- # FIXME: reading signature directory does not look good...
116
- constructor_method = entry&.attributes&.include?(:constructor)
183
+ if annots.return_type && return_type
184
+ return_type_relation = Subtyping::Relation.new(sub_type: annots.return_type,
185
+ super_type: return_type)
186
+ checker.check(return_type_relation, constraints: Subtyping::Constraints.empty).else do |result|
187
+ typing.add_error Errors::MethodReturnTypeAnnotationMismatch.new(node: node,
188
+ method_type: return_type,
189
+ annotation_type: annots.return_type,
190
+ result: result)
191
+ end
192
+ end
193
+
194
+ constructor_method = method&.attributes&.include?(:constructor)
117
195
 
118
196
  method_context = MethodContext.new(
119
197
  name: method_name,
120
- method: entry,
121
- method_type: annotations.lookup_method_type(method_name),
122
- return_type: annots.return_type,
198
+ method: method,
199
+ method_type: method_type,
200
+ return_type: annots.return_type || return_type,
123
201
  constructor: constructor_method
124
202
  )
125
203
 
126
- ivar_types = annots.ivar_types.keys.each.with_object({}) do |var, env|
127
- env[var] = annots.ivar_types[var]
204
+ var_types.each do |name, type|
205
+ type_env.set(lvar: name, type: type)
128
206
  end
129
207
 
208
+ ivar_types = {}
209
+ ivar_types.merge!(self_interface.ivars) if self_interface
210
+ ivar_types.merge!(annots.ivar_types)
211
+
212
+ ivar_types.each do |name, type|
213
+ type_env.set(ivar: name, type: type)
214
+ end
215
+
216
+ type_env = type_env.with_annotations(
217
+ lvar_types: annots.var_types.transform_values {|annot| absolute_type(annot.type) },
218
+ ivar_types: annots.ivar_types,
219
+ const_types: annots.const_types.transform_values {|type| absolute_type(type) }
220
+ )
221
+
130
222
  self.class.new(
131
- assignability: assignability,
223
+ checker: checker,
132
224
  source: source,
133
225
  annotations: annots,
134
- var_types: var_types,
226
+ type_env: type_env,
135
227
  block_context: nil,
136
228
  self_type: self_type,
137
229
  method_context: method_context,
138
230
  typing: typing,
139
231
  module_context: module_context,
140
- ivar_types: ivar_types
232
+ break_context: nil
233
+ )
234
+ end
235
+
236
+ def for_module(node)
237
+ annots = source.annotations(block: node)
238
+ new_module_name = ModuleName.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
239
+
240
+ module_type = AST::Types::Name.new_instance(name: "::Module")
241
+
242
+ implement_module_name =
243
+ if annots.implement_module
244
+ annots.implement_module.name
245
+ else
246
+ absolute_name(new_module_name).yield_self do |module_name|
247
+ if checker.builder.signatures.module_name?(module_name)
248
+ signature = checker.builder.signatures.find_module(module_name)
249
+ AST::Annotation::Implements::Module.new(name: module_name,
250
+ args: signature.params&.variables || [])
251
+ end
252
+ end
253
+ end
254
+
255
+ if implement_module_name
256
+ module_name = implement_module_name.name
257
+ module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x) }
258
+
259
+ abstract = checker.builder.build(TypeName::Instance.new(name: module_name))
260
+
261
+ instance_type = absolute_type(
262
+ AST::Types::Name.new_instance(name: module_name, args: module_args)
263
+ )
264
+
265
+ unless abstract.supers.empty?
266
+ instance_type = AST::Types::Intersection.build(
267
+ types: [instance_type, AST::Types::Name.new_instance(name: "::Object")] + abstract.supers.map {|x| absolute_type(x) }
268
+ )
269
+ end
270
+
271
+ module_type = AST::Types::Intersection.build(types: [
272
+ AST::Types::Name.new_instance(name: "::Module"),
273
+ absolute_type(AST::Types::Name.new_module(name: module_name, args: module_args))
274
+ ])
275
+ end
276
+
277
+ if annots.instance_type
278
+ instance_type = absolute_type(annots.instance_type)
279
+ end
280
+
281
+ if annots.module_type
282
+ module_type = absolute_type(annots.module_type)
283
+ end
284
+
285
+ new_namespace = nested_namespace(new_module_name)
286
+ module_const_env = TypeInference::ConstantEnv.new(builder: checker.builder, current_namespace: new_namespace)
287
+
288
+ module_context_ = ModuleContext.new(
289
+ instance_type: instance_type,
290
+ module_type: module_type,
291
+ implement_name: implement_module_name,
292
+ current_namespace: new_namespace,
293
+ const_env: module_const_env
294
+ )
295
+
296
+ module_type_env = TypeInference::TypeEnv.build(annotations: annots,
297
+ subtyping: checker,
298
+ const_env: module_const_env,
299
+ signatures: checker.builder.signatures)
300
+
301
+ self.class.new(
302
+ checker: checker,
303
+ source: source,
304
+ annotations: annots,
305
+ type_env: module_type_env,
306
+ typing: typing,
307
+ method_context: nil,
308
+ block_context: nil,
309
+ module_context: module_context_,
310
+ self_type: module_context_.module_type,
311
+ break_context: nil
141
312
  )
142
313
  end
143
314
 
144
315
  def for_class(node)
145
316
  annots = source.annotations(block: node)
317
+ new_class_name = ModuleName.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
146
318
 
147
- if annots.implement_module
148
- signature = assignability.signatures[annots.implement_module]
149
- raise "Class implements should be an class: #{annots.instance_type}" unless signature.is_a?(Signature::Class)
319
+ implement_module_name =
320
+ if annots.implement_module
321
+ annots.implement_module.name
322
+ else
323
+ absolute_name(new_class_name).yield_self do |name|
324
+ if checker.builder.signatures.class_name?(name)
325
+ signature = checker.builder.signatures.find_class(name)
326
+ AST::Annotation::Implements::Module.new(name: name,
327
+ args: signature.params&.variables || [])
328
+ end
329
+ end
330
+ end
150
331
 
151
- instance_type = Types::Name.instance(name: annots.implement_module)
152
- module_type = Types::Name.module(name: annots.implement_module)
332
+ if implement_module_name
333
+ class_name = implement_module_name.name
334
+ class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x) }
335
+
336
+ _ = checker.builder.build(TypeName::Instance.new(name: class_name))
337
+
338
+ instance_type = AST::Types::Name.new_instance(name: class_name, args: class_args)
339
+ module_type = AST::Types::Name.new_class(name: class_name, args: [], constructor: nil)
153
340
  end
154
341
 
342
+ new_namespace = nested_namespace(new_class_name)
343
+ class_const_env = TypeInference::ConstantEnv.new(builder: checker.builder, current_namespace: new_namespace)
344
+
155
345
  module_context = ModuleContext.new(
156
346
  instance_type: annots.instance_type || instance_type,
157
347
  module_type: annots.module_type || module_type,
158
- const_types: annots.const_types
348
+ implement_name: implement_module_name,
349
+ current_namespace: new_namespace,
350
+ const_env: class_const_env
351
+ )
352
+
353
+ class_type_env = TypeInference::TypeEnv.build(
354
+ annotations: annots,
355
+ const_env: class_const_env,
356
+ signatures: checker.builder.signatures,
357
+ subtyping: checker
159
358
  )
160
359
 
161
360
  self.class.new(
162
- assignability: assignability,
361
+ checker: checker,
163
362
  source: source,
164
363
  annotations: annots,
165
- var_types: {},
364
+ type_env: class_type_env,
166
365
  typing: typing,
167
366
  method_context: nil,
168
367
  block_context: nil,
169
368
  module_context: module_context,
170
- self_type: module_context.module_type
369
+ self_type: module_context.module_type,
370
+ break_context: nil
171
371
  )
172
372
  end
173
373
 
174
- def synthesize(node)
175
- case node.type
176
- when :begin
177
- type = each_child_node(node).map do |child|
178
- synthesize(child)
179
- end.last
374
+ def for_branch(node, truthy_vars: Set.new, type_case_override: nil)
375
+ annots = source.annotations(block: node)
180
376
 
181
- typing.add_typing(node, type)
377
+ type_env = self.type_env
182
378
 
183
- when :lvasgn
184
- var = node.children[0]
185
- rhs = node.children[1]
379
+ lvar_types = self.type_env.lvar_types.each.with_object({}) do |(var, type), env|
380
+ if truthy_vars.member?(var)
381
+ env[var] = TypeConstruction.unwrap(type)
382
+ else
383
+ env[var] = type
384
+ end
385
+ end
386
+ type_env = type_env.with_annotations(lvar_types: lvar_types) do |var, relation, result|
387
+ raise "Unexpected annotate failure: #{relation}"
388
+ end
186
389
 
187
- type_assignment(var, rhs, node)
390
+ if type_case_override
391
+ type_env = type_env.with_annotations(lvar_types: type_case_override) do |var, relation, result|
392
+ typing.add_error(
393
+ Errors::IncompatibleTypeCase.new(node: node,
394
+ var_name: var,
395
+ relation: relation,
396
+ result: result)
397
+ )
398
+ end
399
+ end
188
400
 
189
- when :lvar
190
- var = node.children[0]
401
+ type_env = type_env.with_annotations(
402
+ lvar_types: annots.var_types.transform_values {|a| absolute_type(a.type) },
403
+ ivar_types: annots.ivar_types.transform_values {|ty| absolute_type(ty) },
404
+ const_types: annots.const_types.transform_values {|ty| absolute_type(ty) },
405
+ gvar_types: {}
406
+ ) do |var, relation, result|
407
+ typing.add_error(
408
+ Errors::IncompatibleAnnotation.new(node: node,
409
+ var_name: var,
410
+ relation: relation,
411
+ result: result)
412
+ )
413
+ end
191
414
 
192
- if (type = variable_type(var))
193
- typing.add_typing(node, type)
194
- else
195
- fallback_to_any node
196
- typing.add_var_type var, Types::Any.new
197
- end
415
+ with(type_env: type_env)
416
+ end
417
+
418
+ NOTHING = ::Object.new
419
+
420
+ def with(annotations: NOTHING, type_env: NOTHING, method_context: NOTHING, block_context: NOTHING, module_context: NOTHING, self_type: NOTHING, break_context: NOTHING)
421
+ self.class.new(
422
+ checker: checker,
423
+ source: source,
424
+ annotations: annotations.equal?(NOTHING) ? self.annotations : annotations,
425
+ type_env: type_env.equal?(NOTHING) ? self.type_env : type_env,
426
+ typing: typing,
427
+ method_context: method_context.equal?(NOTHING) ? self.method_context : method_context,
428
+ block_context: block_context.equal?(NOTHING) ? self.block_context : block_context,
429
+ module_context: module_context.equal?(NOTHING) ? self.module_context : module_context,
430
+ self_type: self_type.equal?(NOTHING) ? self.self_type : self_type,
431
+ break_context: break_context.equal?(NOTHING) ? self.break_context : break_context
432
+ )
433
+ end
198
434
 
199
- when :ivasgn
200
- name = node.children[0]
201
- value = node.children[1]
435
+ def synthesize(node)
436
+ Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
437
+ Steep.logger.debug node.type
438
+ case node.type
439
+ when :begin, :kwbegin
440
+ yield_self do
441
+ type = each_child_node(node).map do |child|
442
+ synthesize(child)
443
+ end.last
202
444
 
203
- if (type = ivar_types[name])
204
- check(value, type) do |_, value_type|
205
- typing.add_error(Errors::IncompatibleAssignment.new(node: node, lhs_type: type, rhs_type: value_type))
445
+ typing.add_typing(node, type)
206
446
  end
207
- typing.add_typing(node, type)
208
- else
209
- value_type = synthesize(value)
210
- typing.add_typing(node, value_type)
211
- end
212
447
 
213
- when :ivar
214
- type = ivar_types[node.children[0]]
215
- if type
216
- typing.add_typing(node, type)
217
- else
218
- fallback_to_any node
219
- end
448
+ when :lvasgn
449
+ yield_self do
450
+ var = node.children[0]
451
+ rhs = node.children[1]
220
452
 
221
- when :send
222
- if self_class?(node)
223
- module_type = module_context.module_type
224
- type = if module_type.is_a?(Types::Name)
225
- Types::Name.new(name: module_type.name.updated(constructor: method_context.constructor),
226
- params: module_type.params)
227
- else
228
- module_type
229
- end
230
- typing.add_typing(node, type)
231
- else
232
- type_send(node, with_block: false)
233
- end
453
+ if var.name == :_
454
+ typing.add_typing(node, Types.any)
455
+ else
456
+ type_assignment(var, rhs, node)
457
+ end
458
+ end
234
459
 
235
- when :super
236
- if self_type && method_context&.method
237
- if method_context.super_type
238
- ret_type = type_method_call(node: node,
239
- receiver_type: self_type,
240
- method_name: method_context.name,
241
- arguments: node.children,
242
- method_types: [method_context.super_type],
243
- with_block: false)
244
- else
245
- typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
460
+ when :lvar
461
+ yield_self do
462
+ var = node.children[0]
463
+ type = type_env.get(lvar: var.name) do
464
+ fallback_to_any node
465
+ end
466
+
467
+ typing.add_typing node, type
246
468
  end
247
- end
248
469
 
249
- if ret_type
250
- typing.add_typing node, ret_type
251
- else
252
- fallback_to_any node
253
- end
470
+ when :ivasgn
471
+ name = node.children[0]
472
+ value = node.children[1]
254
473
 
255
- when :block
256
- send_node, params, block = node.children
474
+ type_ivasgn(name, value, node)
257
475
 
258
- ret_type = type_send(send_node, with_block: true) do |recv_type, method_name, method_type|
259
- if method_type.block
260
- var_types_ = var_types.dup
261
- self.class.block_param_typing_pairs(param_types: method_type.block.params, param_nodes: params.children).each do |param_node, type|
262
- var = param_node.children[0]
263
- var_types_[var] = type
264
- typing.add_var_type(var, type)
476
+ when :ivar
477
+ yield_self do
478
+ name = node.children[0]
479
+ type = type_env.get(ivar: name) do
480
+ fallback_to_any node
265
481
  end
482
+ typing.add_typing(node, type)
483
+ end
266
484
 
267
- annots = source.annotations(block: node)
268
-
269
- block_context = BlockContext.new(body_type: annots.block_type,
270
- break_type: method_type.return_type)
271
-
272
- for_block = self.class.new(
273
- assignability: assignability,
274
- source: source,
275
- annotations: annotations + annots,
276
- var_types: var_types_,
277
- block_context: block_context,
278
- typing: typing,
279
- method_context: method_context,
280
- module_context: self.module_context,
281
- self_type: annots.self_type || self_type
282
- )
485
+ when :send
486
+ yield_self do
487
+ if self_class?(node)
488
+ module_type = module_context.module_type
489
+ type = if module_type.is_a?(AST::Types::Name) && module_type.name.is_a?(TypeName::Class)
490
+ AST::Types::Name.new(name: module_type.name.updated(constructor: method_context.constructor),
491
+ args: module_type.args)
492
+ else
493
+ module_type
494
+ end
495
+ typing.add_typing(node, type)
496
+ else
497
+ type_send(node, send_node: node, block_params: nil, block_body: nil)
498
+ end
499
+ end
283
500
 
284
- each_child_node(params) do |param|
285
- for_block.synthesize(param)
501
+ when :csend
502
+ yield_self do
503
+ type = if self_class?(node)
504
+ module_type = module_context.module_type
505
+ type = if module_type.is_a?(AST::Types::Name)
506
+ AST::Types::Name.new(name: module_type.name.updated(constructor: method_context.constructor),
507
+ args: module_type.args)
508
+ else
509
+ module_type
510
+ end
511
+ typing.add_typing(node, type)
512
+ else
513
+ type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true)
514
+ end
515
+
516
+ union_type(type, Types.nil_instance)
517
+ end
518
+
519
+ when :match_with_lvasgn
520
+ each_child_node(node) do |child|
521
+ synthesize(child)
522
+ end
523
+ typing.add_typing(node, Types.any)
524
+
525
+ when :op_asgn
526
+ yield_self do
527
+ lhs, op, rhs = node.children
528
+
529
+ synthesize(rhs)
530
+
531
+ lhs_type = case lhs.type
532
+ when :lvasgn
533
+ type_env.get(lvar: lhs.children.first.name) do
534
+ break
535
+ end
536
+ when :ivasgn
537
+ type_env.get(ivar: lhs.children.first) do
538
+ break
539
+ end
540
+ else
541
+ Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
542
+ nil
543
+ end
544
+
545
+ case
546
+ when lhs_type == Types.any
547
+ typing.add_typing(node, lhs_type)
548
+ when !lhs_type
549
+ fallback_to_any(node)
550
+ else
551
+ lhs_interface = checker.resolve(lhs_type, with_initialize: false)
552
+ op_method = lhs_interface.methods[op]
553
+
554
+ if op_method
555
+ args = TypeInference::SendArgs.from_nodes([rhs])
556
+ return_type_or_error = type_method_call(node,
557
+ receiver_type: lhs_type,
558
+ method: op_method,
559
+ args: args,
560
+ block_params: nil,
561
+ block_body: nil)
562
+
563
+ if return_type_or_error.is_a?(Errors::Base)
564
+ typing.add_error return_type_or_error
565
+ else
566
+ result = checker.check(
567
+ Subtyping::Relation.new(sub_type: return_type_or_error, super_type: lhs_type),
568
+ constraints: Subtyping::Constraints.empty
569
+ )
570
+ if result.failure?
571
+ typing.add_error(
572
+ Errors::IncompatibleAssignment.new(
573
+ node: node,
574
+ lhs_type: lhs_type,
575
+ rhs_type: return_type_or_error,
576
+ result: result
577
+ )
578
+ )
579
+ end
580
+ end
581
+ else
582
+ typing.add_error Errors::NoMethod.new(node: node, method: op, type: lhs_type)
583
+ end
584
+
585
+ typing.add_typing(node, lhs_type)
286
586
  end
587
+ end
287
588
 
288
- case method_type.block.return_type
289
- when Types::Var
290
- block_type = block ? for_block.synthesize(block) : Types::Any.new
291
- method_type_ = method_type.instantiate(subst: { method_type.block.return_type.name => block_type })
292
- method_type_.return_type
589
+ when :super
590
+ yield_self do
591
+ if self_type && method_context&.method
592
+ if method_context.super_method
593
+ each_child_node(node) do |child| synthesize(child) end
594
+
595
+ super_method = method_context.super_method
596
+ args = TypeInference::SendArgs.from_nodes(node.children.dup)
597
+
598
+ return_type_or_error = type_method_call(node,
599
+ receiver_type: self_type,
600
+ method: super_method,
601
+ args: args,
602
+ block_params: nil,
603
+ block_body: nil)
604
+
605
+ if return_type_or_error.is_a?(Errors::Base)
606
+ fallback_to_any node do
607
+ return_type_or_error
608
+ end
609
+ else
610
+ typing.add_typing node, return_type_or_error
611
+ end
612
+ else
613
+ fallback_to_any node do
614
+ Errors::UnexpectedSuper.new(node: node, method: method_context.name)
615
+ end
616
+ end
293
617
  else
294
- if block
295
- for_block.check(block, method_type.block.return_type) do |expected, actual|
296
- typing.add_error Errors::BlockTypeMismatch.new(node: node, expected: expected, actual: actual)
618
+ typing.add_typing node, Types.any
619
+ end
620
+ end
621
+
622
+ when :block
623
+ yield_self do
624
+ send_node, params, body = node.children
625
+ type_send(node, send_node: send_node, block_params: params, block_body: body)
626
+ end
627
+
628
+ when :def
629
+ new = for_new_method(node.children[0],
630
+ node,
631
+ args: node.children[1].children,
632
+ self_type: module_context&.instance_type)
633
+
634
+ each_child_node(node.children[1]) do |arg|
635
+ new.synthesize(arg)
636
+ end
637
+
638
+ if node.children[2]
639
+ return_type = new.method_context&.return_type
640
+ if return_type && !return_type.is_a?(AST::Types::Void)
641
+ new.check(node.children[2], return_type) do |_, actual_type, result|
642
+ typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
643
+ expected: return_type,
644
+ actual: actual_type,
645
+ result: result))
646
+ end
647
+ else
648
+ new.synthesize(node.children[2])
649
+ end
650
+ end
651
+
652
+ if module_context
653
+ module_context.defined_instance_methods << node.children[0]
654
+ end
655
+
656
+ typing.add_typing(node, Types.any)
657
+
658
+ when :defs
659
+ synthesize(node.children[0]).tap do |self_type|
660
+ new = for_new_method(node.children[1],
661
+ node,
662
+ args: node.children[2].children,
663
+ self_type: self_type)
664
+
665
+ each_child_node(node.children[2]) do |arg|
666
+ new.synthesize(arg)
667
+ end
668
+
669
+ if node.children[3]
670
+ return_type = new.method_context&.return_type
671
+ if return_type && !return_type.is_a?(AST::Types::Void)
672
+ new.check(node.children[3], return_type) do |return_type, actual_type, result|
673
+ typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
674
+ expected: return_type,
675
+ actual: actual_type,
676
+ result: result))
297
677
  end
678
+ else
679
+ new.synthesize(node.children[3])
298
680
  end
681
+ end
682
+ end
299
683
 
300
- method_type.return_type
684
+ if module_context
685
+ if node.children[0].type == :self
686
+ module_context.defined_module_methods << node.children[1]
301
687
  end
688
+ end
689
+
690
+ typing.add_typing(node, Types.symbol_instance)
691
+
692
+ when :return
693
+ yield_self do
694
+ if node.children.size > 0
695
+ return_types = node.children.map do |value|
696
+ synthesize(value)
697
+ end
302
698
 
699
+ value_type = if return_types.size == 1
700
+ return_types.first
701
+ else
702
+ Types.array_instance(union_type(*return_types))
703
+ end
704
+
705
+ if method_context&.return_type && !method_context.return_type.is_a?(AST::Types::Void)
706
+ result = checker.check(
707
+ Subtyping::Relation.new(sub_type: value_type,
708
+ super_type: method_context.return_type),
709
+ constraints: Subtyping::Constraints.empty
710
+ )
711
+
712
+ if result.failure?
713
+ typing.add_error(Errors::ReturnTypeMismatch.new(node: node,
714
+ expected: method_context.return_type,
715
+ actual: value_type,
716
+ result: result))
717
+ end
718
+ end
719
+ end
720
+
721
+ typing.add_typing(node, Types.any)
722
+ end
723
+
724
+ when :break
725
+ value = node.children[0]
726
+
727
+ if break_context
728
+ case
729
+ when value && break_context.break_type
730
+ check(value, break_context.break_type) do |break_type, actual_type, result|
731
+ typing.add_error Errors::BreakTypeMismatch.new(node: node,
732
+ expected: break_type,
733
+ actual: actual_type,
734
+ result: result)
735
+ end
736
+ when !value
737
+ # ok
738
+ else
739
+ synthesize(value) if value
740
+ typing.add_error Errors::UnexpectedJumpValue.new(node: node)
741
+ end
303
742
  else
304
- typing.add_error Errors::UnexpectedBlockGiven.new(node: node, type: recv_type, method: method_name)
305
- nil
743
+ synthesize(value)
744
+ typing.add_error Errors::UnexpectedJump.new(node: node)
306
745
  end
307
- end
308
746
 
309
- typing.add_typing(node, ret_type)
747
+ typing.add_typing(node, Types.any)
310
748
 
311
- when :def
312
- new = for_new_method(node.children[0],
313
- node,
314
- args: node.children[1].children,
315
- self_type: module_context&.instance_type)
749
+ when :next
750
+ value = node.children[0]
316
751
 
317
- each_child_node(node.children[1]) do |arg|
318
- new.synthesize(arg)
319
- end
752
+ if break_context
753
+ case
754
+ when value && break_context.next_type
755
+ check(value, break_context.next_type) do |break_type, actual_type, result|
756
+ typing.add_error Errors::BreakTypeMismatch.new(node: node,
757
+ expected: break_type,
758
+ actual: actual_type,
759
+ result: result)
760
+ end
761
+ when !value
762
+ # ok
763
+ else
764
+ synthesize(value) if value
765
+ typing.add_error Errors::UnexpectedJumpValue.new(node: node)
766
+ end
767
+ else
768
+ synthesize(value)
769
+ typing.add_error Errors::UnexpectedJump.new(node: node)
770
+ end
320
771
 
321
- if node.children[2]
322
- return_type = new.method_context&.return_type
323
- if return_type
324
- new.check(node.children[2], return_type) do |_, actual_type|
325
- typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
326
- expected: return_type,
327
- actual: actual_type))
772
+ typing.add_typing(node, Types.any)
773
+
774
+ when :retry
775
+ unless break_context
776
+ typing.add_error Errors::UnexpectedJump.new(node: node)
777
+ end
778
+ typing.add_typing(node, Types.any)
779
+
780
+ when :arg, :kwarg, :procarg0
781
+ yield_self do
782
+ var = node.children[0]
783
+ type = type_env.get(lvar: var.name) do
784
+ fallback_to_any node
328
785
  end
786
+ typing.add_typing(node, type)
787
+ end
788
+
789
+ when :optarg, :kwoptarg
790
+ yield_self do
791
+ var = node.children[0]
792
+ rhs = node.children[1]
793
+ type_assignment(var, rhs, node)
794
+ end
795
+
796
+ when :restarg
797
+ yield_self do
798
+ var = node.children[0]
799
+ type = type_env.get(lvar: var.name) do
800
+ typing.add_error Errors::FallbackAny.new(node: node)
801
+ Types.array_instance(Types.any)
802
+ end
803
+
804
+ typing.add_typing(node, type)
805
+ end
806
+
807
+ when :kwrestarg
808
+ yield_self do
809
+ var = node.children[0]
810
+ type = type_env.get(lvar: var.name) do
811
+ typing.add_error Errors::FallbackAny.new(node: node)
812
+ Types.hash_instance(Types.symbol_instance, Types.any)
813
+ end
814
+
815
+ typing.add_typing(node, type)
816
+ end
817
+
818
+ when :int
819
+ typing.add_typing(node, AST::Types::Name.new_instance(name: "::Integer"))
820
+
821
+ when :float
822
+ typing.add_typing(node, AST::Types::Name.new_instance(name: "::Float"))
823
+
824
+ when :nil
825
+ typing.add_typing(node, Types.nil_instance)
826
+
827
+ when :sym
828
+ typing.add_typing(node, Types.symbol_instance)
829
+
830
+ when :str
831
+ typing.add_typing(node, Types.string_instance)
832
+
833
+ when :true, :false
834
+ typing.add_typing(node, AST::Types::Name.new_interface(name: :_Boolean))
835
+
836
+ when :hash
837
+ yield_self do
838
+ key_types = []
839
+ value_types = []
840
+
841
+ each_child_node(node) do |child|
842
+ case child.type
843
+ when :pair
844
+ key, value = child.children
845
+ key_types << synthesize(key)
846
+ value_types << synthesize(value)
847
+ when :kwsplat
848
+ splat_type = synthesize(child.children[0])
849
+
850
+ if splat_type.is_a?(AST::Types::Name) && splat_type.name == TypeName::Instance.new(name: ModuleName.parse("::Hash"))
851
+ key_types << splat_type.args[0]
852
+ value_types << splat_type.args[1]
853
+ else
854
+ typing.add_error Errors::UnexpectedSplat.new(node: child, type: splat_type)
855
+ key_types << Types.any
856
+ value_types << Types.any
857
+ end
858
+ else
859
+ raise "Unexpected non pair: #{child.inspect}" unless child.type == :pair
860
+ end
861
+ end
862
+
863
+ key_type = key_types.empty? ? Types.any : AST::Types::Union.build(types: key_types)
864
+ value_type = value_types.empty? ? Types.any : AST::Types::Union.build(types: value_types)
865
+
866
+ typing.add_typing(node, Types.hash_instance(key_type, value_type))
867
+ end
868
+
869
+ when :dstr
870
+ each_child_node(node) do |child|
871
+ synthesize(child)
872
+ end
873
+
874
+ typing.add_typing(node, Types.string_instance)
875
+
876
+ when :dsym
877
+ each_child_node(node) do |child|
878
+ synthesize(child)
879
+ end
880
+
881
+ typing.add_typing(node, Types.symbol_instance)
882
+
883
+ when :class
884
+ yield_self do
885
+ for_class(node).tap do |constructor|
886
+ constructor.synthesize(node.children[2]) if node.children[2]
887
+
888
+ if constructor.module_context&.implement_name && !namespace_module?(node)
889
+ constructor.validate_method_definitions(node, constructor.module_context.implement_name)
890
+ end
891
+ end
892
+
893
+ typing.add_typing(node, Types.nil_instance)
894
+ end
895
+
896
+ when :module
897
+ yield_self do
898
+ for_module(node).yield_self do |constructor|
899
+ constructor.synthesize(node.children[1]) if node.children[1]
900
+
901
+ if constructor.module_context&.implement_name && !namespace_module?(node)
902
+ constructor.validate_method_definitions(node, constructor.module_context.implement_name)
903
+ end
904
+ end
905
+
906
+ typing.add_typing(node, Types.nil_instance)
907
+ end
908
+
909
+ when :self
910
+ if self_type
911
+ typing.add_typing(node, self_type)
329
912
  else
330
- new.synthesize(node.children[2])
913
+ fallback_to_any node
331
914
  end
332
- end
333
915
 
334
- if module_context
335
- module_context.defined_instance_methods << node.children[0]
336
- end
916
+ when :const
917
+ const_name = ModuleName.from_node(node)
918
+ if const_name
919
+ type = type_env.get(const: const_name) do
920
+ fallback_to_any node
921
+ end
922
+ typing.add_typing node, type
923
+ else
924
+ fallback_to_any node
925
+ end
337
926
 
338
- typing.add_typing(node, Types::Any.new)
927
+ when :casgn
928
+ yield_self do
929
+ const_name = ModuleName.from_node(node)
930
+ if const_name
931
+ value_type = synthesize(node.children.last)
932
+ type = type_env.assign(const: const_name, type: value_type) do |error|
933
+ case error
934
+ when Subtyping::Result::Failure
935
+ const_type = type_env.get(const: const_name)
936
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
937
+ lhs_type: const_type,
938
+ rhs_type: value_type,
939
+ result: error))
940
+ when nil
941
+ typing.add_error(Errors::UnknownConstantAssigned.new(node: node, type: value_type))
942
+ end
943
+ end
339
944
 
340
- when :defs
341
- synthesize(node.children[0]).tap do |self_type|
342
- new = for_new_method(node.children[1],
343
- node,
344
- args: node.children[2].children,
345
- self_type: self_type)
945
+ typing.add_typing(node, type)
946
+ else
947
+ synthesize(node.children.last)
948
+ fallback_to_any(node)
949
+ end
950
+ end
346
951
 
347
- each_child_node(node.children[2]) do |arg|
348
- new.synthesize(arg)
952
+ when :yield
953
+ if method_context&.method_type
954
+ if method_context.block_type
955
+ block_type = method_context.block_type
956
+ block_type.params.flat_unnamed_params.map(&:last).zip(node.children).each do |(type, node)|
957
+ if node && type
958
+ check(node, type) do |_, rhs_type, result|
959
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
960
+ lhs_type: type,
961
+ rhs_type: rhs_type,
962
+ result: result))
963
+ end
964
+ end
965
+ end
966
+
967
+ typing.add_typing(node, block_type.return_type)
968
+ else
969
+ typing.add_error(Errors::UnexpectedYield.new(node: node))
970
+ fallback_to_any node
971
+ end
972
+ else
973
+ fallback_to_any node
349
974
  end
350
975
 
351
- if node.children[3]
352
- if new&.method_context&.method_type
353
- new.check(node.children[3], new.method_context.method_type.return_type) do |return_type, actual_type|
354
- typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
355
- expected: return_type,
356
- actual: actual_type))
976
+ when :zsuper
977
+ yield_self do
978
+ if method_context&.method
979
+ if method_context.super_method
980
+ types = method_context.super_method.types.map(&:return_type)
981
+ typing.add_typing(node, union_type(*types))
982
+ else
983
+ typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
984
+ fallback_to_any node
985
+ end
986
+ else
987
+ fallback_to_any node
988
+ end
989
+ end
990
+
991
+ when :array
992
+ yield_self do
993
+ if node.children.empty?
994
+ typing.add_typing(node, Types.array_instance(Types.any))
995
+ else
996
+ types = node.children.flat_map do |e|
997
+ if e.type == :splat
998
+ Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
999
+ synthesize(e.children.first).yield_self do |type|
1000
+ case type
1001
+ when AST::Types::Union
1002
+ type.types
1003
+ else
1004
+ [type]
1005
+ end
1006
+ end.map do |type|
1007
+ case
1008
+ when type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Instance) && type.name.name == ModuleName.new(name: "Array", absolute: true)
1009
+ type.args.first
1010
+ when type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Instance) && type.name.name == ModuleName.new(name: "Range", absolute: true)
1011
+ type.args.first
1012
+ else
1013
+ type
1014
+ end
1015
+ end
1016
+ else
1017
+ [synthesize(e)]
1018
+ end
357
1019
  end
358
- else
359
- new.synthesize(node.children[3])
1020
+
1021
+ typing.add_typing(node, Types.array_instance(AST::Types::Union.build(types: types)))
360
1022
  end
361
1023
  end
362
- end
363
1024
 
364
- if module_context
365
- if node.children[0].type == :self
366
- module_context.defined_module_methods << node.children[1]
367
- end
368
- end
1025
+ when :and
1026
+ yield_self do
1027
+ left, right = node.children
1028
+ left_type = synthesize(left)
369
1029
 
370
- typing.add_typing(node, Types::Name.instance(name: :Symbol))
1030
+ truthy_vars = TypeConstruction.truthy_variables(left)
1031
+ right_type, right_env = for_branch(right, truthy_vars: truthy_vars).yield_self do |constructor|
1032
+ type = constructor.synthesize(right)
1033
+ [type, constructor.type_env]
1034
+ end
371
1035
 
372
- when :return
373
- value = node.children[0]
1036
+ type_env.join!([right_env, TypeInference::TypeEnv.new(subtyping: checker,
1037
+ const_env: nil)])
374
1038
 
375
- if value
376
- if method_context&.return_type
377
- check(value, method_context.return_type) do |_, actual_type|
378
- typing.add_error(Errors::ReturnTypeMismatch.new(node: node,
379
- expected: method_context.return_type,
380
- actual: actual_type))
1039
+ if Types.boolean?(left_type)
1040
+ typing.add_typing(node, union_type(left_type, right_type))
1041
+ else
1042
+ typing.add_typing(node, union_type(right_type, Types.nil_instance))
381
1043
  end
382
- else
383
- synthesize(value)
384
1044
  end
385
- end
386
1045
 
387
- typing.add_typing(node, Types::Any.new)
1046
+ when :or
1047
+ types = each_child_node(node).map {|child| synthesize(child) }
1048
+ type = union_type(*types)
1049
+ typing.add_typing(node, type)
1050
+
1051
+ when :if
1052
+ cond, true_clause, false_clause = node.children
1053
+ synthesize cond
388
1054
 
389
- when :break
390
- value = node.children[0]
1055
+ truthy_vars = TypeConstruction.truthy_variables(cond)
391
1056
 
392
- if value
393
- if block_context&.break_type
394
- check(value, block_context.break_type) do |break_type, actual_type|
395
- typing.add_error Errors::BreakTypeMismatch.new(node: node,
396
- expected: break_type,
397
- actual: actual_type)
1057
+ if true_clause
1058
+ true_type, true_env = for_branch(true_clause, truthy_vars: truthy_vars).yield_self do |constructor|
1059
+ type = constructor.synthesize(true_clause)
1060
+ [type, constructor.type_env]
1061
+ end
1062
+ end
1063
+ if false_clause
1064
+ false_type, false_env = for_branch(false_clause).yield_self do |constructor|
1065
+ type = constructor.synthesize(false_clause)
1066
+ [type, constructor.type_env]
398
1067
  end
399
- else
400
- synthesize(value)
401
1068
  end
402
- end
403
-
404
- typing.add_typing(node, Types::Any.new)
405
1069
 
406
- when :arg, :kwarg, :procarg0
407
- var = node.children[0]
408
- if (type = variable_type(var))
409
- typing.add_var_type(var, type)
410
- else
411
- fallback_to_any node
412
- end
1070
+ type_env.join!([true_env, false_env].compact)
1071
+ typing.add_typing(node, union_type(true_type, false_type))
413
1072
 
414
- when :optarg, :kwoptarg
415
- var = node.children[0]
416
- rhs = node.children[1]
417
- type_assignment(var, rhs, node)
1073
+ when :case
1074
+ yield_self do
1075
+ cond, *whens = node.children
418
1076
 
419
- when :int
420
- typing.add_typing(node, Types::Name.instance(name: :Integer))
1077
+ if cond
1078
+ cond_type = synthesize(cond)
1079
+ if cond_type.is_a?(AST::Types::Union)
1080
+ var_names = TypeConstruction.value_variables(cond)
1081
+ var_types = cond_type.types.dup
1082
+ end
1083
+ end
421
1084
 
422
- when :nil
423
- typing.add_typing(node, Types::Any.new)
1085
+ pairs = whens.each.with_object([]) do |clause, pairs|
1086
+ if clause&.type == :when
1087
+ test_types = clause.children.take(clause.children.size - 1).map do |child|
1088
+ synthesize(child)
1089
+ end
424
1090
 
425
- when :sym
426
- typing.add_typing(node, Types::Name.instance(name: :Symbol))
1091
+ if (body = clause.children.last)
1092
+ if var_names && var_types && test_types.all? {|type| type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Class) && type.args.empty? }
1093
+ var_types_in_body = test_types.flat_map {|test_type|
1094
+ filtered_types = var_types.select {|var_type| var_type.name.name == test_type.name.name }
1095
+ if filtered_types.empty?
1096
+ test_type.instance_type
1097
+ else
1098
+ filtered_types
1099
+ end
1100
+ }
1101
+ var_types.reject! {|type|
1102
+ var_types_in_body.any? {|test_type|
1103
+ test_type.name.name == type.name.name
1104
+ }
1105
+ }
1106
+
1107
+ type_case_override = var_names.each.with_object({}) do |var_name, hash|
1108
+ hash[var_name] = union_type(*var_types_in_body)
1109
+ end
1110
+ else
1111
+ type_case_override = nil
1112
+ end
1113
+
1114
+ for_branch(body, type_case_override: type_case_override).yield_self do |body_construction|
1115
+ type = body_construction.synthesize(body)
1116
+ pairs << [type, body_construction.type_env]
1117
+ end
1118
+ else
1119
+ pairs << [Types.nil_instance, nil]
1120
+ end
1121
+ else
1122
+ if clause
1123
+ if var_types
1124
+ if !var_types.empty?
1125
+ type_case_override = var_names.each.with_object({}) do |var_name, hash|
1126
+ hash[var_name] = union_type(*var_types)
1127
+ end
1128
+ var_types.clear
1129
+ else
1130
+ typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1131
+ type_case_override = var_names.each.with_object({}) do |var_name, hash|
1132
+ hash[var_name] = Types.any
1133
+ end
1134
+ end
1135
+ end
1136
+
1137
+ for_branch(clause, type_case_override: type_case_override).yield_self do |body_construction|
1138
+ type = body_construction.synthesize(clause)
1139
+ pairs << [type, body_construction.type_env]
1140
+ end
1141
+ end
1142
+ end
1143
+ end
427
1144
 
428
- when :str
429
- typing.add_typing(node, Types::Name.instance(name: :String))
1145
+ types = pairs.map(&:first)
1146
+ envs = pairs.map(&:last)
430
1147
 
431
- when :true, :false
432
- typing.add_typing(node, Types::Name.interface(name: :_Boolean))
1148
+ if var_types
1149
+ unless var_types.empty? || whens.last
1150
+ types.push Types.nil_instance
1151
+ end
1152
+ end
433
1153
 
434
- when :hash
435
- each_child_node(node) do |pair|
436
- raise "Unexpected non pair: #{pair.inspect}" unless pair.type == :pair
437
- each_child_node(pair) do |e|
438
- synthesize(e)
1154
+ type_env.join!(envs.compact)
1155
+ typing.add_typing(node, union_type(*types))
439
1156
  end
440
- end
441
-
442
- typing.add_typing(node, Types::Any.new)
443
-
444
- when :dstr
445
- each_child_node(node) do |child|
446
- synthesize(child)
447
- end
448
1157
 
449
- typing.add_typing(node, Types::Name.instance(name: :String))
1158
+ when :rescue
1159
+ yield_self do
1160
+ body, *resbodies, else_node = node.children
1161
+ body_type = synthesize(body) if body
450
1162
 
451
- when :dsym
452
- each_child_node(node) do |child|
453
- synthesize(child)
454
- end
1163
+ resbody_pairs = resbodies.map do |resbody|
1164
+ exn_classes, assignment, body = resbody.children
455
1165
 
456
- typing.add_typing(node, Types::Name.instance(name: :Symbol))
1166
+ if exn_classes
1167
+ case exn_classes.type
1168
+ when :array
1169
+ exn_types = exn_classes.children.map {|child| synthesize(child) }
1170
+ else
1171
+ Steep.logger.error "Unexpected exception list: #{exn_classes.type}"
1172
+ end
1173
+ end
457
1174
 
458
- when :class
459
- for_class(node).tap do |constructor|
460
- constructor.synthesize(node.children[2])
461
- constructor.validate_method_definitions(node)
462
- end
1175
+ if assignment
1176
+ case assignment.type
1177
+ when :lvasgn
1178
+ var_name = assignment.children[0].name
1179
+ else
1180
+ Steep.logger.error "Unexpected rescue variable assignment: #{assignment.type}"
1181
+ end
1182
+ end
463
1183
 
464
- typing.add_typing(node, Types::Name.instance(name: :NilClass))
1184
+ type_override = {}
1185
+
1186
+ case
1187
+ when exn_classes && var_name
1188
+ instance_types = exn_types.map do |type|
1189
+ case
1190
+ when type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Class)
1191
+ type.instance_type
1192
+ else
1193
+ Types.any
1194
+ end
1195
+ end
1196
+ type_override[var_name] = AST::Types::Union.build(types: instance_types)
1197
+ when var_name
1198
+ type_override[var_name] = Types.any
1199
+ end
465
1200
 
466
- when :module
467
- annots = source.annotations(block: node)
1201
+ resbody_construction = for_branch(resbody, type_case_override: type_override)
468
1202
 
469
- module_type = Types::Name.instance(name: :Module)
1203
+ type = if body
1204
+ resbody_construction.synthesize(body)
1205
+ else
1206
+ Types.nil_instance
1207
+ end
1208
+ [type, resbody_construction.type_env]
1209
+ end
1210
+ resbody_types, resbody_envs = resbody_pairs.transpose
470
1211
 
471
- if annots.implement_module
472
- signature = assignability.signatures[annots.implement_module]
473
- raise "Module instance should be an module: #{annots.instance_type || annots.implment_module}" unless signature.is_a?(Signature::Module)
1212
+ if else_node
1213
+ else_construction = for_branch(else_node)
1214
+ else_type = else_construction.synthesize(else_node)
1215
+ else_env = else_construction.type_env
1216
+ end
474
1217
 
475
- ty = Types::Name.instance(name: annots.implement_module)
1218
+ type_env.join!([*resbody_envs, else_env].compact)
476
1219
 
477
- if signature.self_type
478
- instance_type = Types::Merge.new(types: [Types::Name.instance(name: :Object),
479
- signature.self_type,
480
- ty])
481
- else
482
- instance_type = Types::Merge.new(types: [Types::Name.instance(name: :Object),
483
- ty])
1220
+ types = [body_type, *resbody_types, else_type].compact
1221
+ typing.add_typing(node, union_type(*types))
484
1222
  end
485
1223
 
486
- module_type = Types::Merge.new(types: [
487
- Types::Name.instance(name: :Module),
488
- Types::Name.module(name: annots.implement_module)
489
- ])
490
- end
1224
+ when :resbody
1225
+ yield_self do
1226
+ klasses, asgn, body = node.children
1227
+ synthesize(klasses) if klasses
1228
+ synthesize(asgn) if asgn
1229
+ body_type = synthesize(body) if body
1230
+ typing.add_typing(node, body_type)
1231
+ end
491
1232
 
492
- if annots.instance_type
493
- instance_type = annots.instance_type
494
- end
1233
+ when :ensure
1234
+ yield_self do
1235
+ body, ensure_body = node.children
1236
+ body_type = synthesize(body) if body
1237
+ synthesize(ensure_body) if ensure_body
1238
+ typing.add_typing(node, union_type(body_type))
1239
+ end
495
1240
 
496
- if annots.module_type
497
- module_type = annots.module_type
498
- end
1241
+ when :masgn
1242
+ type_masgn(node)
499
1243
 
500
- module_context_ = ModuleContext.new(
501
- instance_type: instance_type,
502
- module_type: module_type,
503
- const_types: annots.const_types
504
- )
1244
+ when :while, :while_post, :until, :until_post
1245
+ yield_self do
1246
+ cond, body = node.children
505
1247
 
506
- for_class = self.class.new(
507
- assignability: assignability,
508
- source: source,
509
- annotations: annots,
510
- var_types: {},
511
- typing: typing,
512
- method_context: nil,
513
- block_context: nil,
514
- module_context: module_context_,
515
- self_type: module_context_.module_type
516
- )
1248
+ synthesize(cond)
1249
+ truthy_vars = node.type == :while ? TypeConstruction.truthy_variables(cond) : Set.new
517
1250
 
518
- for_class.synthesize(node.children[1]) if node.children[1]
519
- for_class.validate_method_definitions(node)
1251
+ if body
1252
+ for_loop = for_branch(body, truthy_vars: truthy_vars).with(break_context: BreakContext.new(break_type: nil, next_type: nil))
1253
+ for_loop.synthesize(body)
1254
+ type_env.join!([for_loop.type_env])
1255
+ end
520
1256
 
521
- typing.add_typing(node, Types::Name.instance(name: :NilClass))
1257
+ typing.add_typing(node, Types.any)
1258
+ end
522
1259
 
523
- when :self
524
- if self_type
525
- typing.add_typing(node, self_type)
526
- else
527
- fallback_to_any node
528
- end
1260
+ when :irange, :erange
1261
+ types = node.children.map {|n| synthesize(n) }
1262
+ type = Types.range_instance(union_type(*types))
1263
+ typing.add_typing(node, type)
529
1264
 
530
- when :const
531
- const_name = flatten_const_name(node)
532
- if const_name
533
- type = (module_context&.const_types || {})[const_name]
534
- end
1265
+ when :regexp
1266
+ each_child_node(node) do |child|
1267
+ synthesize(child)
1268
+ end
535
1269
 
536
- if type
537
- typing.add_typing(node, type)
538
- else
539
- fallback_to_any node
540
- end
1270
+ typing.add_typing(node, AST::Types::Name.new_instance(name: "::Regexp"))
541
1271
 
542
- when :yield
543
- if method_context&.method_type
544
- if method_context.block_type
545
- block_type = method_context.block_type
546
- block_type.params.flat_unnamed_params.map(&:last).zip(node.children).each do |(type, node)|
547
- if node && type
548
- check(node, type) do |_, rhs_type|
549
- typing.add_error(Errors::IncompatibleAssignment.new(node: node, lhs_type: type, rhs_type: rhs_type))
550
- end
551
- end
552
- end
1272
+ when :regopt
1273
+ # ignore
1274
+ typing.add_typing(node, Types.any)
553
1275
 
554
- typing.add_typing(node, block_type.return_type)
555
- else
556
- typing.add_error(Errors::UnexpectedYield.new(node: node))
557
- fallback_to_any node
558
- end
559
- else
560
- fallback_to_any node
561
- end
1276
+ when :nth_ref, :back_ref
1277
+ typing.add_typing(node, Types.string_instance)
562
1278
 
563
- when :zsuper
564
- if method_context&.method
565
- if method_context.super_type
566
- typing.add_typing(node, method_context.super_type.return_type)
567
- else
568
- typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
569
- fallback_to_any node
1279
+ when :or_asgn, :and_asgn
1280
+ yield_self do
1281
+ _, rhs = node.children
1282
+ rhs_type = synthesize(rhs)
1283
+ typing.add_typing(node, rhs_type)
570
1284
  end
571
- else
572
- fallback_to_any node
573
- end
574
1285
 
575
- when :array
576
- if node.children.empty?
577
- typing.add_typing(node, Types::Name.instance(name: :Array, params: [Types::Any.new]))
578
- else
579
- types = node.children.map {|e| synthesize(e) }
580
-
581
- if types.uniq.size == 1
582
- typing.add_typing(node, Types::Name.instance(name: :Array, params: [types.first]))
583
- else
584
- typing.add_typing(node, Types::Name.instance(name: :Array, params: [Types::Any.new]))
1286
+ when :defined?
1287
+ each_child_node(node) do |child|
1288
+ synthesize(child)
585
1289
  end
586
- end
587
1290
 
588
- when :and
589
- types = each_child_node(node).map {|child| synthesize(child) }
590
- typing.add_typing(node, types.last)
1291
+ typing.add_typing(node, Types.any)
591
1292
 
592
- when :or
593
- types = each_child_node(node).map {|child| synthesize(child) }
594
- type = union_type(*types)
595
- typing.add_typing(node, type)
1293
+ when :gvasgn
1294
+ yield_self do
1295
+ name, rhs = node.children
1296
+ type = checker.builder.signatures.find_gvar(name)&.type
596
1297
 
597
- when :if
598
- cond, true_clause, false_clause = node.children
599
- synthesize cond
600
- true_type = synthesize(true_clause) if true_clause
601
- false_type = synthesize(false_clause) if false_clause
1298
+ if type
1299
+ check(rhs, type) do |_, rhs_type, result|
1300
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1301
+ lhs_type: type,
1302
+ rhs_type: rhs_type,
1303
+ result: result))
1304
+ end
1305
+ else
1306
+ synthesize(rhs)
1307
+ fallback_to_any node
1308
+ end
1309
+ end
602
1310
 
603
- typing.add_typing(node, union_type(true_type, false_type))
1311
+ when :gvar
1312
+ yield_self do
1313
+ name = node.children.first
1314
+ type = checker.builder.signatures.find_gvar(name)&.type
604
1315
 
605
- when :case
606
- cond, *whens = node.children
1316
+ if type
1317
+ typing.add_typing(node, type)
1318
+ else
1319
+ fallback_to_any node
1320
+ end
1321
+ end
607
1322
 
608
- synthesize cond if cond
1323
+ when :splat, :block_pass, :blockarg, :sclass
1324
+ yield_self do
1325
+ Steep.logger.error "Unsupported node #{node.type}"
609
1326
 
610
- types = whens.map do |clause|
611
- if clause&.type == :when
612
- clause.children.take(clause.children.size - 1).map do |child|
1327
+ each_child_node node do |child|
613
1328
  synthesize(child)
614
1329
  end
615
1330
 
616
- if (body = clause.children.last)
617
- synthesize body
618
- else
619
- fallback_to_any body
620
- end
621
- else
622
- synthesize clause if clause
1331
+ typing.add_typing node, Types.any
623
1332
  end
624
- end
625
1333
 
626
- typing.add_typing(node, union_type(*types))
627
-
628
- else
629
- raise "Unexpected node: #{node.inspect}, #{node.location.line}"
1334
+ else
1335
+ raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
1336
+ end
630
1337
  end
631
1338
  end
632
1339
 
633
1340
  def check(node, type)
634
1341
  type_ = synthesize(node)
635
1342
 
636
- unless assignability.test(src: type_, dest: type)
637
- yield(type, type_)
1343
+ result = checker.check(
1344
+ Subtyping::Relation.new(sub_type: type_,
1345
+ super_type: type),
1346
+ constraints: Subtyping::Constraints.empty
1347
+ )
1348
+ if result.failure?
1349
+ yield(type, type_, result)
638
1350
  end
639
1351
  end
640
1352
 
641
1353
  def type_assignment(var, rhs, node)
642
- lhs_type = variable_type(var)
643
-
644
1354
  if rhs
645
- if lhs_type
646
- check(rhs, lhs_type) do |_, rhs_type|
647
- typing.add_error(Errors::IncompatibleAssignment.new(node: node, lhs_type: lhs_type, rhs_type: rhs_type))
648
- end
649
- typing.add_var_type(var, lhs_type)
650
- typing.add_typing(node, lhs_type)
651
- var_types[var] = lhs_type
652
- lhs_type
653
- else
654
- rhs_type = synthesize(rhs)
655
- typing.add_var_type(var, rhs_type)
656
- typing.add_typing(node, rhs_type)
657
- var_types[var] = rhs_type
658
- rhs_type
659
- end
1355
+ rhs_type = synthesize(rhs)
1356
+ node_type = assign_type_to_variable(var, rhs_type, node)
1357
+ typing.add_typing(node, node_type)
660
1358
  else
1359
+ raise
1360
+ lhs_type = variable_type(var)
1361
+
661
1362
  if lhs_type
662
1363
  typing.add_var_type(var, lhs_type)
663
1364
  typing.add_typing(node, lhs_type)
664
1365
  var_types[var] = lhs_type
665
1366
  else
666
- typing.add_var_type(var, Types::Any.new)
1367
+ typing.add_var_type(var, Types.any)
667
1368
  fallback_to_any node
668
- var_types[var] = Types::Any.new
1369
+ var_types[var] = Types.any
669
1370
  end
670
1371
  end
671
1372
  end
672
1373
 
673
- def type_method_call(node:, receiver_type:, method_name:, method_types:, arguments:, with_block: false)
674
- method_type = method_types.flat_map do |type|
675
- next unless with_block == !!type.block
676
-
677
- var_types_mapping = {}
1374
+ def assign_type_to_variable(var, type, node)
1375
+ name = var.name
1376
+ type_env.assign(lvar: name, type: type) do |result|
1377
+ var_type = type_env.get(lvar: name)
1378
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1379
+ lhs_type: var_type,
1380
+ rhs_type: type,
1381
+ result: result))
1382
+ end
1383
+ end
678
1384
 
679
- type.type_params.each do |param|
680
- var_types_mapping[param] = []
1385
+ def type_ivasgn(name, rhs, node)
1386
+ rhs_type = synthesize(rhs)
1387
+ ivar_type = type_env.assign(ivar: name, type: rhs_type) do |error|
1388
+ case error
1389
+ when Subtyping::Result::Failure
1390
+ type = type_env.get(ivar: name)
1391
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1392
+ lhs_type: type,
1393
+ rhs_type: rhs_type,
1394
+ result: error))
1395
+ when nil
1396
+ fallback_to_any node
681
1397
  end
1398
+ end
1399
+ typing.add_typing(node, ivar_type)
1400
+ end
682
1401
 
683
- catch :abort do
684
- pairs = test_args(params: type.params, arguments: arguments)
685
- if pairs
686
- arg_types = pairs.map {|(_, arg_node)| synthesize(arg_node) }
687
-
688
- pairs.each.with_index do |(param_type, _), index|
689
- arg_type = arg_types[index]
1402
+ def type_masgn(node)
1403
+ lhs, rhs = node.children
1404
+ rhs_type = synthesize(rhs)
1405
+
1406
+ case
1407
+ when rhs.type == :array && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn } && lhs.children.size == rhs.children.size
1408
+ pairs = lhs.children.zip(rhs.children)
1409
+ pairs.each do |(l, r)|
1410
+ case
1411
+ when l.type == :lvasgn
1412
+ type_assignment(l.children.first, r, l)
1413
+ when l.type == :ivasgn
1414
+ type_ivasgn(l.children.first, r, l)
1415
+ end
1416
+ end
690
1417
 
691
- case param_type
692
- when Types::Var
693
- var_types_mapping[param_type.name] << arg_type
694
- else
695
- unless assignability.test(src: arg_type, dest: param_type)
696
- throw :abort
1418
+ typing.add_typing(node, rhs_type)
1419
+
1420
+ when rhs_type.is_a?(AST::Types::Any)
1421
+ fallback_to_any(node)
1422
+
1423
+ when rhs_type.is_a?(AST::Types::Name) && rhs_type.name.is_a?(TypeName::Instance) && rhs_type.name.name == ModuleName.new(name: "Array", absolute: true)
1424
+ element_type = rhs_type.args.first
1425
+
1426
+ lhs.children.each do |assignment|
1427
+ case assignment.type
1428
+ when :lvasgn
1429
+ assign_type_to_variable(assignment.children.first, element_type, assignment)
1430
+ when :ivasgn
1431
+ assignment.children.first.yield_self do |ivar|
1432
+ type_env.assign(ivar: ivar, type: element_type) do |error|
1433
+ case error
1434
+ when Subtyping::Result::Failure
1435
+ type = type_env.get(ivar: ivar)
1436
+ typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
1437
+ lhs_type: type,
1438
+ rhs_type: element_type,
1439
+ result: error))
1440
+ when nil
1441
+ fallback_to_any node
697
1442
  end
698
1443
  end
699
1444
  end
1445
+ end
1446
+ end
700
1447
 
701
- subst = var_types_mapping.each.with_object({}) do |(name, types), subst|
702
- unless types.empty?
703
- compacted_types = assignability.compact(types)
1448
+ typing.add_typing node, rhs_type
704
1449
 
705
- if compacted_types.size > 1
706
- subst[name] = Types::Union.new(types: compacted_types)
707
- else
708
- subst[name] = compacted_types.first
1450
+ when rhs_type.is_a?(AST::Types::Union) &&
1451
+ rhs_type.types.all? {|type| type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Instance) && type.name.name == ModuleName.new(name: "Array", absolute: true) }
1452
+
1453
+ types = rhs_type.types.flat_map do |type|
1454
+ type.args.first
1455
+ end
1456
+
1457
+ element_type = AST::Types::Union.build(types: types)
1458
+
1459
+ lhs.children.each do |assignment|
1460
+ case assignment.type
1461
+ when :lvasgn
1462
+ assign_type_to_variable(assignment.children.first, element_type, assignment)
1463
+ when :ivasgn
1464
+ assignment.children.first.yield_self do |ivar|
1465
+ type_env.assign(ivar: ivar, type: element_type) do |error|
1466
+ case error
1467
+ when Subtyping::Result::Failure
1468
+ type = type_env.get(ivar: ivar)
1469
+ typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
1470
+ lhs_type: type,
1471
+ rhs_type: element_type,
1472
+ result: error))
1473
+ when nil
1474
+ fallback_to_any node
709
1475
  end
710
1476
  end
711
1477
  end
712
-
713
- type.instantiate(subst: subst)
714
1478
  end
715
1479
  end
716
- end.compact.first
717
1480
 
718
- if method_type
719
- if block_given?
720
- return_type = yield(receiver_type, method_name, method_type)
721
- end
722
- return_type || method_type.return_type
1481
+ typing.add_typing node, rhs_type
1482
+
723
1483
  else
724
- arguments.each do |arg|
1484
+ Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
1485
+ fallback_to_any(node)
1486
+ end
1487
+ end
1488
+
1489
+ def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
1490
+ receiver, method_name, *arguments = send_node.children
1491
+ receiver_type = receiver ? synthesize(receiver) : self_type
1492
+ arguments.each do |arg|
1493
+ if arg.type == :splat
1494
+ type = synthesize(arg.children[0])
1495
+ typing.add_typing(arg, Types.array_instance(type))
1496
+ else
725
1497
  synthesize(arg)
726
1498
  end
1499
+ end
727
1500
 
728
- typing.add_error Errors::ArgumentTypeMismatch.new(node: node, type: receiver_type, method: method_name)
729
- nil
1501
+ if unwrap
1502
+ receiver_type = TypeConstruction.unwrap(receiver_type)
730
1503
  end
731
- end
732
1504
 
733
- def type_send(node, with_block:, &block)
734
- receiver, method_name, *args = node.children
735
- receiver_type = receiver ? synthesize(receiver) : self_type
1505
+ case receiver_type
1506
+ when AST::Types::Any
1507
+ typing.add_typing node, Types.any
1508
+
1509
+ when nil
1510
+ fallback_to_any node
1511
+
1512
+ else
1513
+ begin
1514
+ interface = checker.resolve(receiver_type, with_initialize: false)
1515
+ method = interface.methods[method_name]
736
1516
 
737
- if receiver_type
738
- ret_type = assignability.method_type receiver_type, method_name do |method|
739
1517
  if method
740
- type_method_call(node: node,
741
- receiver_type: receiver_type,
742
- method_name: method_name,
743
- arguments: args,
744
- method_types: method.types,
745
- with_block: with_block,
746
- &block)
1518
+ args = TypeInference::SendArgs.from_nodes(arguments)
1519
+ return_type_or_error = type_method_call(node,
1520
+ method: method,
1521
+ args: args,
1522
+ block_params: block_params,
1523
+ block_body: block_body,
1524
+ receiver_type: receiver_type)
1525
+
1526
+ if return_type_or_error.is_a?(Errors::Base)
1527
+ fallback_to_any node do
1528
+ return_type_or_error
1529
+ end
1530
+ else
1531
+ typing.add_typing node, return_type_or_error
1532
+ end
1533
+ else
1534
+ fallback_to_any node do
1535
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1536
+ end
1537
+ end
1538
+ rescue Subtyping::Check::CannotResolveError
1539
+ fallback_to_any node do
1540
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1541
+ end
1542
+ end
1543
+ end
1544
+ end
1545
+
1546
+ def type_method_call(node, receiver_type:, method:, args:, block_params:, block_body:)
1547
+ results = method.types.map do |method_type|
1548
+ Steep.logger.tagged method_type.location&.source do
1549
+ arg_pairs = args.zip(method_type.params)
1550
+
1551
+ if arg_pairs
1552
+ try_method_type(node,
1553
+ receiver_type: receiver_type,
1554
+ method_type: method_type,
1555
+ arg_pairs: arg_pairs,
1556
+ block_params: block_params,
1557
+ block_body: block_body)
747
1558
  else
748
- args.each {|arg| synthesize(arg) }
749
- typing.add_error Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
750
- nil
1559
+ Steep.logger.debug(node.inspect)
1560
+ Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
751
1561
  end
752
1562
  end
1563
+ end
753
1564
 
754
- typing.add_typing node, ret_type
1565
+ if results.all? {|result| result.is_a?(Errors::Base) }
1566
+ results.first
755
1567
  else
756
- fallback_to_any node
1568
+ results.find do |result|
1569
+ !result.is_a?(Errors::Base)
1570
+ end
757
1571
  end
758
1572
  end
759
1573
 
760
- def variable_type(var)
761
- var_types[var] || annotations.lookup_var_type(var.name)
1574
+ def try_method_type(node, receiver_type:, method_type:, arg_pairs:, block_params:, block_body:)
1575
+ fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x) }
1576
+ fresh_vars = Set.new(fresh_types.map(&:name))
1577
+ instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
1578
+
1579
+ method_type.instantiate(instantiation).yield_self do |method_type|
1580
+ constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
1581
+ variance = Subtyping::VariableVariance.from_method_type(method_type)
1582
+ occurence = Subtyping::VariableOccurence.from_method_type(method_type)
1583
+
1584
+ arg_pairs.each do |(arg_node, param_type)|
1585
+ relation = Subtyping::Relation.new(
1586
+ sub_type: typing.type_of(node: arg_node),
1587
+ super_type: param_type.subst(instantiation)
1588
+ )
1589
+
1590
+ checker.check(relation, constraints: constraints).else do |result|
1591
+ return Errors::ArgumentTypeMismatch.new(
1592
+ node: arg_node,
1593
+ receiver_type: receiver_type,
1594
+ expected: relation.super_type,
1595
+ actual: relation.sub_type
1596
+ )
1597
+ end
1598
+ end
1599
+
1600
+ if method_type.block && block_params
1601
+ block_annotations = source.annotations(block: node)
1602
+
1603
+ params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
1604
+ block_param_pairs = params.zip(method_type.block.params)
1605
+
1606
+ unless block_param_pairs
1607
+ return Errors::IncompatibleBlockParameters.new(
1608
+ node: node,
1609
+ method_type: method_type
1610
+ )
1611
+ end
1612
+
1613
+ block_param_pairs.each do |param, type|
1614
+ if param.type
1615
+ relation = Subtyping::Relation.new(
1616
+ sub_type: type,
1617
+ super_type: absolute_type(param.type)
1618
+ )
1619
+
1620
+ checker.check(relation, constraints: constraints).else do |result|
1621
+ return Errors::BlockParameterTypeMismatch.new(
1622
+ node: param.node,
1623
+ expected: type,
1624
+ actual: param.type
1625
+ )
1626
+ end
1627
+ end
1628
+ end
1629
+
1630
+ if block_annotations.block_type
1631
+ relation = Subtyping::Relation.new(
1632
+ sub_type: absolute_type(block_annotations.block_type),
1633
+ super_type: method_type.block.return_type
1634
+ )
1635
+
1636
+ checker.check(relation, constraints: constraints).else do |result|
1637
+ typing.add_error Errors::BlockTypeMismatch.new(node: node,
1638
+ expected: method_type.block.return_type,
1639
+ actual: absolute_type(block_annotations.block_type),
1640
+ result: result)
1641
+ end
1642
+ end
1643
+ end
1644
+
1645
+ case
1646
+ when method_type.block && block_params && block_body
1647
+ Steep.logger.debug "block is okay: method_type=#{method_type}"
1648
+ Steep.logger.debug "Constraints = #{constraints}"
1649
+
1650
+ begin
1651
+ method_type.subst(constraints.solution(checker, variance: variance, variables: occurence.params)).yield_self do |method_type|
1652
+ block_annotations = source.annotations(block: node)
1653
+
1654
+ params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
1655
+ block_param_pairs = params.zip(method_type.block.params)
1656
+
1657
+ block_type_env = type_env.dup.yield_self do |env|
1658
+ block_param_pairs.each do |param, type|
1659
+ if param.type
1660
+ env.set(lvar: param.var.name, type: absolute_type(param.type))
1661
+ else
1662
+ env.set(lvar: param.var.name, type: absolute_type(type))
1663
+ end
1664
+ end
1665
+
1666
+ env.with_annotations(
1667
+ lvar_types: block_annotations.var_types.transform_values {|annot| absolute_type(annot.type) },
1668
+ ivar_types: block_annotations.ivar_types.transform_values {|type| absolute_type(type) },
1669
+ const_types: block_annotations.const_types.transform_values {|type| absolute_type(type) }
1670
+ )
1671
+ end
1672
+
1673
+ return_type = if block_annotations.break_type
1674
+ union_type(method_type.return_type, absolute_type(block_annotations.break_type))
1675
+ else
1676
+ method_type.return_type
1677
+ end
1678
+ Steep.logger.debug("return_type = #{return_type}")
1679
+
1680
+ block_context = BlockContext.new(body_type: absolute_type(block_annotations.block_type))
1681
+ Steep.logger.debug("block_context { body_type: #{block_context.body_type} }")
1682
+
1683
+ break_context = BreakContext.new(
1684
+ break_type: absolute_type(block_annotations.break_type) || method_type.return_type,
1685
+ next_type: absolute_type(block_annotations.block_type)
1686
+ )
1687
+ Steep.logger.debug("break_context { type: #{absolute_type(break_context.break_type)} }")
1688
+
1689
+ for_block = self.class.new(
1690
+ checker: checker,
1691
+ source: source,
1692
+ annotations: annotations + block_annotations,
1693
+ type_env: block_type_env,
1694
+ block_context: block_context,
1695
+ typing: typing,
1696
+ method_context: method_context,
1697
+ module_context: module_context,
1698
+ self_type: absolute_type(block_annotations.self_type) || self_type,
1699
+ break_context: break_context
1700
+ )
1701
+
1702
+ each_child_node(block_params) do |p|
1703
+ for_block.synthesize(p)
1704
+ end
1705
+
1706
+ block_body_type = for_block.synthesize(block_body)
1707
+
1708
+ unless method_type.block.return_type.is_a?(AST::Types::Void)
1709
+ result = checker.check(Subtyping::Relation.new(
1710
+ sub_type: block_annotations.block_type || block_body_type,
1711
+ super_type: method_type.block.return_type
1712
+ ), constraints: constraints)
1713
+
1714
+ if result.success?
1715
+ return_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars))
1716
+ else
1717
+ typing.add_error Errors::BlockTypeMismatch.new(node: node,
1718
+ expected: method_type.block.return_type,
1719
+ actual: block_annotations.block_type || block_body_type,
1720
+ result: result)
1721
+ return_type
1722
+ end
1723
+ else
1724
+ return_type
1725
+ end
1726
+ end
1727
+
1728
+ rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
1729
+ typing.add_error Errors::UnsatisfiableConstraint.new(node: node,
1730
+ method_type: method_type,
1731
+ var: exn.var,
1732
+ sub_type: exn.sub_type,
1733
+ super_type: exn.super_type,
1734
+ result: exn.result
1735
+ )
1736
+ fallback_any_rec node
1737
+ end
1738
+
1739
+ when !method_type.block && !block_params && !block_body
1740
+ # OK, without block
1741
+ method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars)).return_type
1742
+
1743
+ when !method_type.block && block_params && block_body
1744
+ Errors::UnexpectedBlockGiven.new(
1745
+ node: node,
1746
+ method_type: method_type
1747
+ )
1748
+
1749
+ when method_type.block && !block_params && !block_body
1750
+ Errors::RequiredBlockMissing.new(
1751
+ node: node,
1752
+ method_type: method_type
1753
+ )
1754
+
1755
+ else
1756
+ raise "Unexpected case condition"
1757
+ end
1758
+ end
762
1759
  end
763
1760
 
764
1761
  def each_child_node(node)
765
1762
  if block_given?
766
1763
  node.children.each do |child|
767
- if child.is_a?(AST::Node)
1764
+ if child.is_a?(::AST::Node)
768
1765
  yield child
769
1766
  end
770
1767
  end
@@ -919,7 +1916,7 @@ module Steep
919
1916
  if type.params.rest
920
1917
  a = nodes.first
921
1918
  if a&.type == :restarg
922
- env[a.children.first] = Types::Name.instance(name: :Array, params: [type.params.rest])
1919
+ env[a.children.first] = Types.array_instance(type.params.rest)
923
1920
  nodes.shift
924
1921
  end
925
1922
  end
@@ -940,8 +1937,7 @@ module Steep
940
1937
  if node.type == :kwrestarg
941
1938
  ty = type.params.rest_keywords
942
1939
  if ty
943
- env[node.children[0]] = Types::Name.instance(name: :Hash,
944
- params: [Types::Name.instance(name: :Symbol), ty])
1940
+ env[node.children[0]] = Types.hash_instance(Types.symbol_instance, ty)
945
1941
  end
946
1942
  end
947
1943
  end
@@ -953,46 +1949,86 @@ module Steep
953
1949
  env.size == nodes.size && env.size == params.size
954
1950
  end
955
1951
 
956
- def union_type(*types)
957
- types_ = assignability.compact(types.compact)
1952
+ def current_namespace
1953
+ module_context&.current_namespace
1954
+ end
1955
+
1956
+ def nested_namespace(new)
1957
+ case
1958
+ when !new.simple?
1959
+ current_namespace
1960
+ when current_namespace
1961
+ current_namespace + new
1962
+ else
1963
+ new.absolute!
1964
+ end
1965
+ end
958
1966
 
959
- if types_.size == 1
960
- types_.first
1967
+ def absolute_name(module_name)
1968
+ if current_namespace
1969
+ current_namespace + module_name
961
1970
  else
962
- Types::Union.new(types: types_)
1971
+ module_name.absolute!
963
1972
  end
964
1973
  end
965
1974
 
966
- def validate_method_definitions(node)
967
- implements = annotations.implement_module
968
- if implements
969
- signature = assignability.signatures[implements]
970
- signature.members.each do |member|
971
- if member.is_a?(Signature::Members::InstanceMethod) || member.is_a?(Signature::Members::ModuleInstanceMethod)
972
- unless module_context.defined_instance_methods.include?(member.name) || annotations.dynamics.member?(member.name)
1975
+ def absolute_type(type)
1976
+ if type
1977
+ checker.builder.absolute_type(type, current: current_namespace)
1978
+ end
1979
+ end
1980
+
1981
+ def union_type(*types)
1982
+ AST::Types::Union.build(types: types)
1983
+ end
1984
+
1985
+ def validate_method_definitions(node, module_name)
1986
+ signature = checker.builder.signatures.find_class_or_module(module_name.name)
1987
+
1988
+ signature.members.each do |member|
1989
+ if member.is_a?(AST::Signature::Members::Method)
1990
+ if member.instance_method?
1991
+ case
1992
+ when module_context.defined_instance_methods.include?(member.name)
1993
+ # ok
1994
+ when annotations.dynamics[member.name]&.instance_method?
1995
+ # ok
1996
+ else
973
1997
  typing.add_error Errors::MethodDefinitionMissing.new(node: node,
974
- module_name: implements,
1998
+ module_name: module_name.name,
975
1999
  kind: :instance,
976
2000
  missing_method: member.name)
977
2001
  end
978
-
979
2002
  end
980
- if member.is_a?(Signature::Members::ModuleMethod) || member.is_a?(Signature::Members::ModuleInstanceMethod)
981
- unless module_context.defined_module_methods.include?(member.name)
2003
+
2004
+ if member.module_method?
2005
+ case
2006
+ when module_context.defined_module_methods.include?(member.name)
2007
+ # ok
2008
+ when annotations.dynamics[member.name]&.module_method?
2009
+ # ok
2010
+ else
982
2011
  typing.add_error Errors::MethodDefinitionMissing.new(node: node,
983
- module_name: implements,
2012
+ module_name: module_name.name,
984
2013
  kind: :module,
985
2014
  missing_method: member.name)
986
2015
  end
987
2016
  end
988
2017
  end
2018
+ end
989
2019
 
990
- annotations.dynamics.each do |method_name|
991
- unless signature.members.any? {|sig| sig.is_a?(Signature::Members::InstanceMethod) && sig.name == method_name }
992
- typing.add_error Errors::UnexpectedDynamicMethod.new(node: node,
993
- module_name: implements,
994
- method_name: method_name)
995
- end
2020
+ annotations.dynamics.each do |method_name, annotation|
2021
+ method_signature = signature.members.find {|sig| sig.is_a?(AST::Signature::Members::Method) && sig.name == method_name }
2022
+
2023
+ case
2024
+ when annotation.module_method? && method_signature&.module_method?
2025
+ # ok
2026
+ when annotation.instance_method? && method_signature&.instance_method?
2027
+ # ok
2028
+ else
2029
+ typing.add_error Errors::UnexpectedDynamicMethod.new(node: node,
2030
+ module_name: module_name.name,
2031
+ method_name: method_name)
996
2032
  end
997
2033
  end
998
2034
  end
@@ -1002,7 +2038,7 @@ module Steep
1002
2038
 
1003
2039
  while node
1004
2040
  case node.type
1005
- when :const
2041
+ when :const, :casgn
1006
2042
  path.unshift(node.children[1])
1007
2043
  node = node.children[0]
1008
2044
  when :cbase
@@ -1017,12 +2053,82 @@ module Steep
1017
2053
  end
1018
2054
 
1019
2055
  def fallback_to_any(node)
1020
- typing.add_error Errors::FallbackAny.new(node: node)
1021
- typing.add_typing node, Types::Any.new
2056
+ if block_given?
2057
+ typing.add_error yield
2058
+ else
2059
+ typing.add_error Errors::FallbackAny.new(node: node)
2060
+ end
2061
+
2062
+ typing.add_typing node, Types.any
1022
2063
  end
1023
2064
 
1024
2065
  def self_class?(node)
1025
2066
  node.type == :send && node.children[0]&.type == :self && node.children[1] == :class
1026
2067
  end
2068
+
2069
+ def namespace_module?(node)
2070
+ nodes = case node.type
2071
+ when :class, :module
2072
+ node.children.last&.yield_self {|child|
2073
+ if child.type == :begin
2074
+ child.children
2075
+ else
2076
+ [child]
2077
+ end
2078
+ } || []
2079
+ else
2080
+ return false
2081
+ end
2082
+
2083
+ !nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module }
2084
+ end
2085
+
2086
+ def fallback_any_rec(node)
2087
+ fallback_to_any(node) unless typing.has_type?(node)
2088
+
2089
+ each_child_node(node) do |child|
2090
+ fallback_any_rec(child)
2091
+ end
2092
+
2093
+ typing.type_of(node: node)
2094
+ end
2095
+
2096
+ def self.unwrap(type)
2097
+ case
2098
+ when type.is_a?(AST::Types::Union)
2099
+ types = type.types.reject {|type| type.is_a?(AST::Types::Name) && type.name == TypeName::Instance.new(name: ModuleName.parse("::NilClass")) }
2100
+ AST::Types::Union.build(types: types)
2101
+ else
2102
+ type
2103
+ end
2104
+ end
2105
+
2106
+ def self.truthy_variables(node)
2107
+ case node&.type
2108
+ when :lvar
2109
+ Set.new([node.children.first.name])
2110
+ when :lvasgn
2111
+ Set.new([node.children.first.name]) + truthy_variables(node.children[1])
2112
+ when :and
2113
+ truthy_variables(node.children[0]) + truthy_variables(node.children[1])
2114
+ when :begin
2115
+ truthy_variables(node.children.last)
2116
+ else
2117
+ Set.new()
2118
+ end
2119
+ end
2120
+
2121
+ def self.value_variables(node)
2122
+ case node&.type
2123
+ when :lvar
2124
+ Set.new([node.children.first.name])
2125
+ when :lvasgn
2126
+ Set.new([node.children.first.name]) + value_variables(node.children[1])
2127
+ when :begin
2128
+ value_variables(node.children.last)
2129
+ else
2130
+ Set.new
2131
+ end
2132
+ end
1027
2133
  end
1028
2134
  end