steep 0.1.0.pre2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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