steep 0.28.0 → 0.29.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,63 @@
1
+ module Steep
2
+ module AST
3
+ module Types
4
+ module Logic
5
+ class Base
6
+ attr_reader :location
7
+
8
+ def subst(s)
9
+ self
10
+ end
11
+
12
+ def free_variables
13
+ @fvs ||= Set[]
14
+ end
15
+
16
+ def hash
17
+ self.class.hash
18
+ end
19
+
20
+ def ==(other)
21
+ other.class ==self.class
22
+ end
23
+
24
+ alias eql? ==
25
+
26
+ def to_s
27
+ "<% #{self.class} %>"
28
+ end
29
+ end
30
+
31
+ class Not < Base
32
+ def initialize(location: nil)
33
+ @location = location
34
+ end
35
+ end
36
+
37
+ class ReceiverIsNil < Base
38
+ def initialize(location: nil)
39
+ @location = location
40
+ end
41
+ end
42
+
43
+ class ReceiverIsNotNil < Base
44
+ def initialize(location: nil)
45
+ @location = location
46
+ end
47
+ end
48
+
49
+ class ReceiverIsArg < Base
50
+ def initialize(location: nil)
51
+ @location = location
52
+ end
53
+ end
54
+
55
+ class ArgIsReceiver < Base
56
+ def initialize(location: nil)
57
+ @location = location
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -775,13 +775,15 @@ module Steep
775
775
  attr_reader :block
776
776
  attr_reader :return_type
777
777
  attr_reader :location
778
+ attr_reader :method_def
778
779
 
779
- def initialize(type_params:, params:, block:, return_type:, location:)
780
+ def initialize(type_params:, params:, block:, return_type:, location:, method_def:)
780
781
  @type_params = type_params
781
782
  @params = params
782
783
  @block = block
783
784
  @return_type = return_type
784
785
  @location = location
786
+ @method_def = method_def
785
787
  end
786
788
 
787
789
  def ==(other)
@@ -790,6 +792,7 @@ module Steep
790
792
  other.params == params &&
791
793
  other.block == block &&
792
794
  other.return_type == return_type &&
795
+ (!other.method_def || !method_def || other.method_def == method_def) &&
793
796
  (!other.location || !location || other.location == location)
794
797
  end
795
798
 
@@ -821,6 +824,7 @@ module Steep
821
824
  params: params.subst(s_),
822
825
  block: block&.subst(s_),
823
826
  return_type: return_type.subst(s_),
827
+ method_def: method_def,
824
828
  location: location
825
829
  )
826
830
  end
@@ -843,14 +847,16 @@ module Steep
843
847
  params: params.subst(s),
844
848
  block: block&.subst(s),
845
849
  return_type: return_type.subst(s),
846
- location: location)
850
+ location: location,
851
+ method_def: method_def)
847
852
  end
848
853
 
849
- def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, location: self.location)
854
+ def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, location: self.location, method_def: self.method_def)
850
855
  self.class.new(type_params: type_params,
851
856
  params: params,
852
857
  block: block,
853
858
  return_type: return_type,
859
+ method_def: method_def,
854
860
  location: location)
855
861
  end
856
862
 
@@ -867,7 +873,8 @@ module Steep
867
873
  params: params.map_type(&block),
868
874
  block: self.block&.yield_self {|blk| blk.map_type(&block) },
869
875
  return_type: yield(return_type),
870
- location: location)
876
+ location: location,
877
+ method_def: method_def)
871
878
  end
872
879
 
873
880
  # Returns a new method type which can be used for the method implementation type of both `self` and `other`.
@@ -895,6 +902,7 @@ module Steep
895
902
  return_type: AST::Types::Union.build(
896
903
  types: [return_type.subst(s1),other.return_type.subst(s2)]
897
904
  ),
905
+ method_def: method_def,
898
906
  location: nil
899
907
  )
900
908
  end
@@ -950,6 +958,7 @@ module Steep
950
958
  block: block,
951
959
  return_type: return_type,
952
960
  type_params: type_params,
961
+ method_def: nil,
953
962
  location: nil
954
963
  )
955
964
  end
@@ -997,6 +1006,7 @@ module Steep
997
1006
  block: block,
998
1007
  return_type: return_type,
999
1008
  type_params: type_params,
1009
+ method_def: nil,
1000
1010
  location: nil
1001
1011
  )
1002
1012
  end
@@ -0,0 +1,25 @@
1
+ module Steep
2
+ module ModuleHelper
3
+ def module_name_from_node(node)
4
+ case node.type
5
+ when :const, :casgn
6
+ namespace = namespace_from_node(node.children[0]) or return
7
+ name = node.children[1]
8
+ RBS::TypeName.new(name: name, namespace: namespace)
9
+ end
10
+ end
11
+
12
+ def namespace_from_node(node)
13
+ case node&.type
14
+ when nil
15
+ RBS::Namespace.empty
16
+ when :cbase
17
+ RBS::Namespace.root
18
+ when :const
19
+ namespace_from_node(node.children[0])&.yield_self do |parent|
20
+ parent.append(node.children[1])
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -10,13 +10,9 @@ module Steep
10
10
 
11
11
  InstanceVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
12
12
  LocalVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
13
- MethodNameItem = Struct.new(:identifier, :range, :definition, :def_type, :inherited_method, keyword_init: true) do
14
- def method_type
15
- def_type.type
16
- end
17
-
13
+ MethodNameItem = Struct.new(:identifier, :range, :method_def, :method_type, :inherited_method, keyword_init: true) do
18
14
  def comment
19
- def_type.comment
15
+ method_def&.comment
20
16
  end
21
17
  end
22
18
 
@@ -90,7 +86,9 @@ module Steep
90
86
  end
91
87
 
92
88
  def at_end?(pos, of:)
93
- of.last_line == pos.line && of.last_column == pos.column
89
+ if of
90
+ of.last_line == pos.line && of.last_column == pos.column
91
+ end
94
92
  end
95
93
 
96
94
  def range_for(position, prefix: "")
@@ -194,21 +192,25 @@ module Steep
194
192
  return [] unless node
195
193
 
196
194
  if at_end?(shift_pos, of: node.loc)
197
- context = typing.context_at(line: position.line, column: position.column)
198
- receiver_type = case (type = typing.type_of(node: node))
199
- when AST::Types::Self
200
- context.self_type
201
- else
202
- type
203
- end
204
-
205
- items = []
206
- method_items_for_receiver_type(receiver_type,
207
- include_private: false,
208
- prefix: "",
209
- position: position,
210
- items: items)
211
- items
195
+ begin
196
+ context = typing.context_at(line: position.line, column: position.column)
197
+ receiver_type = case (type = typing.type_of(node: node))
198
+ when AST::Types::Self
199
+ context.self_type
200
+ else
201
+ type
202
+ end
203
+
204
+ items = []
205
+ method_items_for_receiver_type(receiver_type,
206
+ include_private: false,
207
+ prefix: "",
208
+ position: position,
209
+ items: items)
210
+ items
211
+ rescue Typing::UnknownNodeError
212
+ []
213
+ end
212
214
  else
213
215
  []
214
216
  end
@@ -230,37 +232,27 @@ module Steep
230
232
 
231
233
  def method_items_for_receiver_type(type, include_private:, prefix:, position:, items:)
232
234
  range = range_for(position, prefix: prefix)
233
- definition = case type
234
- when AST::Types::Name::Instance
235
- type_name = subtyping.factory.type_name_1(type.name)
236
- subtyping.factory.definition_builder.build_instance(type_name)
237
- when AST::Types::Name::Singleton
238
- type_name = subtyping.factory.type_name_1(type.name)
239
- subtyping.factory.definition_builder.build_singleton(type_name)
240
- when AST::Types::Name::Interface
241
- type_name = subtyping.factory.type_name_1(type.name)
242
- subtyping.factory.definition_builder.build_interface(type_name)
243
- end
244
-
245
- if definition
246
- definition.methods.each do |name, method|
247
- next if disallowed_method?(name)
248
-
249
- if include_private || method.public?
250
- if name.to_s.start_with?(prefix)
251
- if word_name?(name.to_s)
252
- method.defs.each do |def_type|
253
- items << MethodNameItem.new(identifier: name,
254
- range: range,
255
- definition: method,
256
- def_type: def_type,
257
- inherited_method: inherited_method?(method, definition))
258
- end
259
- end
235
+ interface = subtyping.factory.interface(type, self_type: type, private: include_private)
236
+
237
+ interface.methods.each do |name, method_entry|
238
+ next if disallowed_method?(name)
239
+
240
+ if name.to_s.start_with?(prefix)
241
+ if word_name?(name.to_s)
242
+ method_entry.method_types.each do |method_type|
243
+ items << MethodNameItem.new(
244
+ identifier: name,
245
+ range: range,
246
+ method_def: method_type.method_def,
247
+ method_type: method_type.method_def&.type || subtyping.factory.method_type_1(method_type, self_type: type),
248
+ inherited_method: inherited_method?(method_type.method_def, type)
249
+ )
260
250
  end
261
251
  end
262
252
  end
263
253
  end
254
+ rescue
255
+ # nop
264
256
  end
265
257
 
266
258
  def word_name?(name)
@@ -304,8 +296,13 @@ module Steep
304
296
  index
305
297
  end
306
298
 
307
- def inherited_method?(method, definition)
308
- method.implemented_in != definition.type_name
299
+ def inherited_method?(method_def, type)
300
+ case type
301
+ when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
302
+ method_def.implemented_in != type.name
303
+ else
304
+ false
305
+ end
309
306
  end
310
307
 
311
308
  def disallowed_method?(name)
@@ -41,8 +41,8 @@ module Steep
41
41
  end
42
42
 
43
43
  def self.type_check(source, subtyping:)
44
- annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module: AST::Namespace.root)
45
- const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: [AST::Namespace.root])
44
+ annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module: RBS::Namespace.root)
45
+ const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: [RBS::Namespace.root])
46
46
  type_env = TypeInference::TypeEnv.build(annotations: annotations,
47
47
  subtyping: subtyping,
48
48
  const_env: const_env,
@@ -58,7 +58,7 @@ module Steep
58
58
  instance_type: nil,
59
59
  module_type: nil,
60
60
  implement_name: nil,
61
- current_namespace: AST::Namespace.root,
61
+ current_namespace: RBS::Namespace.root,
62
62
  const_env: const_env,
63
63
  class_name: nil
64
64
  ),
@@ -21,9 +21,7 @@ module Steep
21
21
  @project = project
22
22
  end
23
23
 
24
- def method_definition_for(factory, module_name, singleton_method: nil, instance_method: nil)
25
- type_name = factory.type_name_1(module_name)
26
-
24
+ def method_definition_for(factory, type_name, singleton_method: nil, instance_method: nil)
27
25
  case
28
26
  when instance_method
29
27
  factory.definition_builder.build_instance(type_name).methods[instance_method]
@@ -86,7 +84,7 @@ module Steep
86
84
  when AST::Types::Name::Instance
87
85
  method_definition = method_definition_for(factory, receiver_type.name, instance_method: method_name)
88
86
  if method_definition&.defined_in
89
- owner_name = factory.type_name(method_definition.defined_in)
87
+ owner_name = method_definition.defined_in
90
88
  [
91
89
  InstanceMethodName.new(owner_name, method_name),
92
90
  method_definition
@@ -95,7 +93,7 @@ module Steep
95
93
  when AST::Types::Name::Singleton
96
94
  method_definition = method_definition_for(factory, receiver_type.name, singleton_method: method_name)
97
95
  if method_definition&.defined_in
98
- owner_name = factory.type_name(method_definition.defined_in)
96
+ owner_name = method_definition.defined_in
99
97
  [
100
98
  SingletonMethodName.new(owner_name, method_name),
101
99
  method_definition
@@ -130,19 +130,19 @@ module Steep
130
130
  yield
131
131
  rescue RBS::InvalidTypeApplicationError => exn
132
132
  @errors << Errors::InvalidTypeApplicationError.new(
133
- name: factory.type_name(exn.type_name),
133
+ name: exn.type_name,
134
134
  args: exn.args.map {|ty| factory.type(ty) },
135
135
  params: exn.params,
136
136
  location: exn.location
137
137
  )
138
138
  rescue RBS::NoTypeFoundError, RBS::NoSuperclassFoundError, RBS::NoMixinFoundError => exn
139
139
  @errors << Errors::UnknownTypeNameError.new(
140
- name: factory.type_name(exn.type_name),
140
+ name: exn.type_name,
141
141
  location: exn.location
142
142
  )
143
143
  rescue RBS::InvalidOverloadMethodError => exn
144
144
  @errors << Errors::InvalidMethodOverloadError.new(
145
- class_name: factory.type_name(exn.type_name),
145
+ class_name: exn.type_name,
146
146
  method_name: exn.method_name,
147
147
  location: exn.members[0].location
148
148
  )
@@ -10,8 +10,7 @@ module Steep
10
10
  end
11
11
 
12
12
  def instance_super_types(type_name, args:)
13
- type_name_1 = factory.type_name_1(type_name)
14
- ancestors = factory.definition_builder.one_instance_ancestors(type_name_1)
13
+ ancestors = factory.definition_builder.one_instance_ancestors(type_name)
15
14
 
16
15
  subst = unless args.empty?
17
16
  args_ = args.map {|type| factory.type_1(type) }
@@ -19,7 +18,7 @@ module Steep
19
18
  end
20
19
 
21
20
  ancestors.each_ancestor.map do |ancestor|
22
- name = factory.type_name(ancestor.name)
21
+ name = ancestor.name
23
22
 
24
23
  case ancestor
25
24
  when RBS::Definition::Ancestor::Instance
@@ -51,11 +50,10 @@ module Steep
51
50
  end
52
51
 
53
52
  def singleton_super_types(type_name)
54
- type_name_1 = factory.type_name_1(type_name)
55
- ancestors = factory.definition_builder.one_singleton_ancestors(type_name_1)
53
+ ancestors = factory.definition_builder.one_singleton_ancestors(type_name)
56
54
 
57
55
  ancestors.each_ancestor.map do |ancestor|
58
- name = factory.type_name(ancestor.name)
56
+ name = ancestor.name
59
57
 
60
58
  case ancestor
61
59
  when RBS::Definition::Ancestor::Instance
@@ -392,7 +390,7 @@ module Steep
392
390
  end
393
391
 
394
392
  def definition_for_type(type)
395
- type_name = factory.type_name_1(type.name)
393
+ type_name = type.name
396
394
 
397
395
  case type
398
396
  when AST::Types::Name::Instance
@@ -104,6 +104,14 @@ module Steep
104
104
  def add(var, sub_type: nil, super_type: nil)
105
105
  subs, supers = dictionary[var]
106
106
 
107
+ if sub_type.is_a?(AST::Types::Logic::Base)
108
+ sub_type = AST::Builtin.bool_type
109
+ end
110
+
111
+ if super_type.is_a?(AST::Types::Logic::Base)
112
+ super_type = AST::Builtin.bool_type
113
+ end
114
+
107
115
  if super_type && !super_type.is_a?(AST::Types::Top)
108
116
  supers << eliminate_variable(super_type, to: AST::Types::Top.new)
109
117
  end
@@ -33,6 +33,8 @@ module Steep
33
33
  end
34
34
  end
35
35
 
36
+ include ModuleHelper
37
+
36
38
  attr_reader :checker
37
39
  attr_reader :source
38
40
  attr_reader :annotations
@@ -169,7 +171,7 @@ module Steep
169
171
 
170
172
  super_method = if definition
171
173
  if (this_method = definition.methods[method_name])
172
- if module_context&.class_name == checker.factory.type_name(this_method.defined_in)
174
+ if module_context&.class_name == this_method.defined_in
173
175
  this_method.super_method
174
176
  else
175
177
  this_method
@@ -254,7 +256,7 @@ module Steep
254
256
  end
255
257
 
256
258
  if name
257
- absolute_name_ = checker.factory.type_name_1(name)
259
+ absolute_name_ = name
258
260
  entry = checker.factory.env.class_decls[absolute_name_]
259
261
  AST::Annotation::Implements::Module.new(
260
262
  name: name,
@@ -265,7 +267,7 @@ module Steep
265
267
  end
266
268
 
267
269
  def for_module(node)
268
- new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
270
+ new_module_name = module_name_from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
269
271
  new_namespace = nested_namespace_for_module(new_module_name)
270
272
 
271
273
  const_context = [new_namespace] + self.module_context.const_env.context
@@ -280,7 +282,7 @@ module Steep
280
282
  module_name = implement_module_name.name
281
283
  module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
282
284
 
283
- type_name_ = checker.factory.type_name_1(implement_module_name.name)
285
+ type_name_ = implement_module_name.name
284
286
  module_entry = checker.factory.definition_builder.env.class_decls[type_name_]
285
287
  instance_def = checker.factory.definition_builder.build_instance(type_name_)
286
288
  module_def = checker.factory.definition_builder.build_singleton(type_name_)
@@ -359,8 +361,8 @@ module Steep
359
361
  end
360
362
 
361
363
  def for_class(node)
362
- new_class_name = Names::Module.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
363
- super_class_name = node.children[1] && Names::Module.from_node(node.children[1])
364
+ new_class_name = module_name_from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
365
+ super_class_name = node.children[1] && module_name_from_node(node.children[1])
364
366
  new_namespace = nested_namespace_for_module(new_class_name)
365
367
 
366
368
  annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
@@ -375,7 +377,7 @@ module Steep
375
377
  class_name = implement_module_name.name
376
378
  class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
377
379
 
378
- type_name_ = checker.factory.type_name_1(implement_module_name.name)
380
+ type_name_ = implement_module_name.name
379
381
  instance_def = checker.factory.definition_builder.build_instance(type_name_)
380
382
  module_def = checker.factory.definition_builder.build_singleton(type_name_)
381
383
 
@@ -445,7 +447,7 @@ module Steep
445
447
 
446
448
  module_type = case instance_type
447
449
  when AST::Types::Name::Singleton
448
- type_name = checker.factory.type_name_1(instance_type.name)
450
+ type_name = instance_type.name
449
451
 
450
452
  case checker.factory.env.class_decls[type_name]
451
453
  when RBS::Environment::ModuleEntry
@@ -464,16 +466,16 @@ module Steep
464
466
 
465
467
  instance_definition = case instance_type
466
468
  when AST::Types::Name::Singleton
467
- type_name = checker.factory.type_name_1(instance_type.name)
469
+ type_name = instance_type.name
468
470
  checker.factory.definition_builder.build_singleton(type_name)
469
471
  when AST::Types::Name::Instance
470
- type_name = checker.factory.type_name_1(instance_type.name)
472
+ type_name = instance_type.name
471
473
  checker.factory.definition_builder.build_instance(type_name)
472
474
  end
473
475
 
474
476
  module_definition = case module_type
475
477
  when AST::Types::Name::Singleton
476
- type_name = checker.factory.type_name_1(instance_type.name)
478
+ type_name = instance_type.name
477
479
  checker.factory.definition_builder.build_singleton(type_name)
478
480
  else
479
481
  nil
@@ -888,10 +890,10 @@ module Steep
888
890
  self_type = expand_self(self_type)
889
891
  definition = case self_type
890
892
  when AST::Types::Name::Instance
891
- name = checker.factory.type_name_1(self_type.name)
893
+ name = self_type.name
892
894
  checker.factory.definition_builder.build_singleton(name)
893
895
  when AST::Types::Name::Singleton
894
- name = checker.factory.type_name_1(self_type.name)
896
+ name = self_type.name
895
897
  checker.factory.definition_builder.build_singleton(name)
896
898
  end
897
899
 
@@ -1270,7 +1272,7 @@ module Steep
1270
1272
  add_typing node, type: AST::Types::Self.new
1271
1273
 
1272
1274
  when :const
1273
- const_name = Names::Module.from_node(node)
1275
+ const_name = module_name_from_node(node)
1274
1276
 
1275
1277
  if const_name
1276
1278
  type = type_env.get(const: const_name) do
@@ -1283,7 +1285,7 @@ module Steep
1283
1285
 
1284
1286
  when :casgn
1285
1287
  yield_self do
1286
- const_name = Names::Module.from_node(node)
1288
+ const_name = module_name_from_node(node)
1287
1289
  if const_name
1288
1290
  const_type = type_env.get(const: const_name) {}
1289
1291
  value_type = synthesize(node.children.last, hint: const_type).type
@@ -1396,15 +1398,17 @@ module Steep
1396
1398
  when :and
1397
1399
  yield_self do
1398
1400
  left, right = node.children
1399
- logic = TypeInference::Logic.new(subtyping: checker)
1400
- truthy, falsey = logic.nodes(node: left)
1401
1401
 
1402
1402
  left_type, constr = synthesize(left)
1403
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1404
- falsey_vars: falsey.vars,
1405
- lvar_env: constr.context.lvar_env)
1406
1403
 
1407
- right_type, constr = constr.update_lvar_env { truthy_env }.for_branch(right).synthesize(right)
1404
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1405
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
1406
+
1407
+ right_type, constr = constr
1408
+ .update_lvar_env { truthy_env }
1409
+ .tap {|constr| typing.add_context_for_node(right, context: constr.context) }
1410
+ .for_branch(right)
1411
+ .synthesize(right)
1408
1412
 
1409
1413
  type = if left_type.is_a?(AST::Types::Boolean)
1410
1414
  union_type(left_type, right_type)
@@ -1426,16 +1430,18 @@ module Steep
1426
1430
  when :or
1427
1431
  yield_self do
1428
1432
  left, right = node.children
1429
- logic = TypeInference::Logic.new(subtyping: checker)
1430
- truthy, falsey = logic.nodes(node: left)
1431
1433
 
1432
1434
  left_type, constr = synthesize(left, hint: hint)
1433
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1434
- falsey_vars: falsey.vars,
1435
- lvar_env: constr.context.lvar_env)
1436
- left_type_t, _ = logic.partition_union(left_type)
1437
1435
 
1438
- right_type, constr = constr.update_lvar_env { falsey_env }.for_branch(right).synthesize(right, hint: left_type_t)
1436
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1437
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
1438
+
1439
+ left_type_t, _ = checker.factory.unwrap_optional(left_type)
1440
+ right_type, constr = constr
1441
+ .update_lvar_env { falsey_env }
1442
+ .tap {|constr| typing.add_context_for_node(right, context: constr.context) }
1443
+ .for_branch(right)
1444
+ .synthesize(right, hint: left_type_t)
1439
1445
 
1440
1446
  type = union_type(left_type_t, right_type)
1441
1447
 
@@ -1454,12 +1460,8 @@ module Steep
1454
1460
  cond, true_clause, false_clause = node.children
1455
1461
 
1456
1462
  cond_type, constr = synthesize(cond)
1457
- logic = TypeInference::Logic.new(subtyping: checker)
1458
-
1459
- truthys, falseys = logic.nodes(node: cond)
1460
- truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
1461
- falsey_vars: falseys.vars,
1462
- lvar_env: constr.context.lvar_env)
1463
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
1464
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: cond_type, node: cond)
1463
1465
 
1464
1466
  if true_clause
1465
1467
  true_pair = constr
@@ -1509,70 +1511,91 @@ module Steep
1509
1511
  cond, *whens, els = node.children
1510
1512
 
1511
1513
  constr = self
1514
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1512
1515
 
1513
1516
  if cond
1514
- cond_type, constr = synthesize(cond)
1515
- cond_type = expand_alias(cond_type)
1516
- if cond_type.is_a?(AST::Types::Union)
1517
- var_names = TypeConstruction.value_variables(cond)
1518
- var_types = cond_type.types.dup
1519
- end
1520
- end
1517
+ branch_pairs = []
1521
1518
 
1522
- branch_pairs = []
1519
+ cond_type, constr = constr.synthesize(cond)
1520
+ _, cond_vars = interpreter.decompose_value(cond)
1523
1521
 
1524
- whens.each do |clause|
1525
- *tests, body = clause.children
1522
+ when_constr = constr
1523
+ whens.each do |clause|
1524
+ *tests, body = clause.children
1526
1525
 
1527
- test_types = []
1528
- clause_constr = constr
1526
+ test_constr = when_constr
1527
+ test_envs = []
1529
1528
 
1530
- tests.each do |test|
1531
- type, clause_constr = synthesize(test)
1532
- test_types << expand_alias(type)
1533
- end
1534
-
1535
- if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Singleton) }
1536
- var_types_in_body = test_types.flat_map do |test_type|
1537
- filtered_types = var_types.select do |var_type|
1538
- var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
1539
- end
1540
- if filtered_types.empty?
1541
- to_instance_type(test_type)
1542
- else
1543
- filtered_types
1544
- end
1529
+ tests.each do |test|
1530
+ test_node = test.updated(:send, [test, :===, cond.dup])
1531
+ test_type, test_constr = test_constr.synthesize(test_node)
1532
+ truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
1533
+ test_envs << truthy_env
1534
+ test_constr = test_constr.update_lvar_env { falsy_env }
1545
1535
  end
1546
1536
 
1547
- var_types.reject! do |type|
1548
- var_types_in_body.any? do |test_type|
1549
- type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1550
- end
1551
- end
1552
-
1553
- var_type_in_body = union_type(*var_types_in_body)
1554
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1555
- hash[var_name] = var_type_in_body
1556
- end
1537
+ body_constr = when_constr.update_lvar_env {|env| env.except(cond_vars).join(*test_envs) }
1557
1538
 
1558
1539
  if body
1559
- branch_pairs << clause_constr
1560
- .for_branch(body, type_case_override: type_case_override)
1540
+ branch_pairs << body_constr
1541
+ .for_branch(body)
1542
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1561
1543
  .synthesize(body, hint: hint)
1562
1544
  else
1563
- branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1545
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
1546
+ end
1547
+
1548
+ when_constr = test_constr
1549
+ end
1550
+
1551
+ if els
1552
+ begin_pos = node.loc.else.end_pos
1553
+ end_pos = node.loc.end.begin_pos
1554
+ typing.add_context(begin_pos..end_pos, context: when_constr.context)
1555
+
1556
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1557
+ end
1558
+
1559
+ types = branch_pairs.map(&:type)
1560
+ constrs = branch_pairs.map(&:constr)
1561
+
1562
+ unless els
1563
+ constrs << when_constr
1564
+ end
1565
+
1566
+ if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
1567
+ # Exhaustive
1568
+ if els
1569
+ typing.add_error Errors::ElseOnExhaustiveCase.new(node: els, type: cond_type)
1564
1570
  end
1565
1571
  else
1566
- logic = TypeInference::Logic.new(subtyping: checker)
1572
+ unless els
1573
+ types << AST::Builtin.nil_type
1574
+ end
1575
+ end
1576
+ else
1577
+ branch_pairs = []
1578
+
1579
+ when_constr = constr
1580
+
1581
+ whens.each do |clause|
1582
+ *tests, body = clause.children
1567
1583
 
1568
- truthys, falseys = logic.nodes(node: ::AST::Node.new(:begin, tests))
1569
- truthy_env, _ = logic.environments(truthy_vars: truthys.vars,
1570
- falsey_vars: falseys.vars,
1571
- lvar_env: clause_constr.context.lvar_env)
1584
+ test_constr = when_constr
1585
+ test_envs = []
1586
+
1587
+ tests.each do |test|
1588
+ test_type, test_constr = test_constr.synthesize(test)
1589
+ truthy_env, falsy_env = interpreter.eval(env: test_constr.context.lvar_env, type: test_type, node: test)
1590
+ test_envs << truthy_env
1591
+ test_constr = test_constr.update_lvar_env { falsy_env }
1592
+ end
1593
+
1594
+ clause_constr = when_constr.update_lvar_env {|env| env.join(*test_envs) }
1595
+ when_constr = test_constr
1572
1596
 
1573
1597
  if body
1574
- branch_pairs << constr
1575
- .update_lvar_env { truthy_env }
1598
+ branch_pairs << clause_constr
1576
1599
  .for_branch(body)
1577
1600
  .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1578
1601
  .synthesize(body, hint: hint)
@@ -1580,34 +1603,17 @@ module Steep
1580
1603
  branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1581
1604
  end
1582
1605
  end
1583
- end
1584
1606
 
1585
- if els
1586
- if var_names && var_types
1587
- if var_types.empty?
1588
- typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1589
- end
1590
-
1591
- else_override = var_names.each.with_object({}) do |var_name, hash|
1592
- hash[var_name] = unless var_types.empty?
1593
- union_type(*var_types)
1594
- else
1595
- AST::Builtin.any_type
1596
- end
1597
- end
1598
- branch_pairs << constr
1599
- .for_branch(els, type_case_override: else_override)
1600
- .synthesize(els, hint: hint)
1601
- else
1602
- branch_pairs << constr.synthesize(els, hint: hint)
1607
+ if els
1608
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1603
1609
  end
1604
- end
1605
1610
 
1606
- types = branch_pairs.map(&:type)
1607
- constrs = branch_pairs.map(&:constr)
1611
+ types = branch_pairs.map(&:type)
1612
+ constrs = branch_pairs.map(&:constr)
1608
1613
 
1609
- unless var_types&.empty? || els
1610
- types.push AST::Builtin.nil_type
1614
+ unless els
1615
+ types << AST::Builtin.nil_type
1616
+ end
1611
1617
  end
1612
1618
 
1613
1619
  constr = constr.update_lvar_env do |env|
@@ -1620,7 +1626,7 @@ module Steep
1620
1626
  when :rescue
1621
1627
  yield_self do
1622
1628
  body, *resbodies, else_node = node.children
1623
- body_pair = synthesize(body) if body
1629
+ body_pair = synthesize(body, hint: hint) if body
1624
1630
 
1625
1631
  body_constr = if body_pair
1626
1632
  self.update_lvar_env do |env|
@@ -1672,7 +1678,7 @@ module Steep
1672
1678
  resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
1673
1679
 
1674
1680
  if body
1675
- resbody_construction.synthesize(body)
1681
+ resbody_construction.synthesize(body, hint: hint)
1676
1682
  else
1677
1683
  Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
1678
1684
  end
@@ -1682,7 +1688,7 @@ module Steep
1682
1688
  resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
1683
1689
 
1684
1690
  if else_node
1685
- else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
1691
+ else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node, hint: hint)
1686
1692
  add_typing(node,
1687
1693
  type: union_type(*[else_pair.type, *resbody_types].compact),
1688
1694
  constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
@@ -1698,7 +1704,7 @@ module Steep
1698
1704
  klasses, asgn, body = node.children
1699
1705
  synthesize(klasses) if klasses
1700
1706
  synthesize(asgn) if asgn
1701
- body_type = synthesize(body).type if body
1707
+ body_type = synthesize(body, hint: hint).type if body
1702
1708
  add_typing(node, type: body_type)
1703
1709
  end
1704
1710
 
@@ -1759,16 +1765,16 @@ module Steep
1759
1765
  when :while, :until
1760
1766
  yield_self do
1761
1767
  cond, body = node.children
1762
- _, constr = synthesize(cond)
1768
+ cond_type, constr = synthesize(cond)
1763
1769
 
1764
- logic = TypeInference::Logic.new(subtyping: checker)
1765
- truthy, falsey = logic.nodes(node: cond)
1770
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1771
+ truthy_env, falsy_env = interpreter.eval(env: constr.context.lvar_env, node: cond, type: cond_type)
1766
1772
 
1767
1773
  case node.type
1768
1774
  when :while
1769
- body_env, exit_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1775
+ body_env, exit_env = truthy_env, falsy_env
1770
1776
  when :until
1771
- exit_env, body_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1777
+ exit_env, body_env = truthy_env, falsy_env
1772
1778
  end
1773
1779
 
1774
1780
  if body
@@ -2007,8 +2013,18 @@ module Steep
2007
2013
  add_typing node, type: AST::Builtin.any_type
2008
2014
  end
2009
2015
 
2016
+ when :args
2017
+ constr = self
2018
+
2019
+ each_child_node(node) do |child|
2020
+ _, constr = constr.synthesize(child)
2021
+ end
2022
+
2023
+ add_typing node, type: AST::Builtin.any_type, constr: constr
2024
+
2010
2025
  else
2011
2026
  raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
2027
+
2012
2028
  end.tap do |pair|
2013
2029
  unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
2014
2030
  # Steep.logger.error { "result = #{pair.inspect}" }
@@ -2271,7 +2287,7 @@ module Steep
2271
2287
 
2272
2288
  def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2273
2289
  receiver, method_name, *arguments = send_node.children
2274
- receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
2290
+ receiver_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2275
2291
 
2276
2292
  if unwrap
2277
2293
  receiver_type = unwrap(receiver_type)
@@ -2279,74 +2295,80 @@ module Steep
2279
2295
 
2280
2296
  receiver_type = expand_alias(receiver_type)
2281
2297
 
2282
- pair = case receiver_type
2283
- when AST::Types::Any
2284
- add_typing node, type: AST::Builtin.any_type
2298
+ type, constr = case receiver_type
2299
+ when AST::Types::Any
2300
+ each_child_node(send_node) do |child|
2301
+ unless child.equal?(receiver)
2302
+ _, constr = constr.synthesize(child)
2303
+ end
2304
+ end
2285
2305
 
2286
- when nil
2287
- fallback_to_any node
2306
+ add_typing node, type: AST::Builtin.any_type
2288
2307
 
2289
- when AST::Types::Void, AST::Types::Bot, AST::Types::Top
2290
- fallback_to_any node do
2291
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2292
- end
2308
+ when nil
2309
+ fallback_to_any node
2293
2310
 
2294
- else
2295
- case expanded_receiver_type = expand_self(receiver_type)
2296
- when AST::Types::Self
2297
- Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
2298
- fallback_to_any node do
2299
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2300
- end
2301
- else
2302
- begin
2303
- interface = checker.factory.interface(receiver_type,
2304
- private: !receiver,
2305
- self_type: expanded_receiver_type)
2306
-
2307
- method = interface.methods[method_name]
2308
-
2309
- if method
2310
- args = TypeInference::SendArgs.from_nodes(arguments)
2311
- return_type, constr, _ = type_method_call(node,
2312
- method: method,
2313
- method_name: method_name,
2314
- args: args,
2315
- block_params: block_params,
2316
- block_body: block_body,
2317
- receiver_type: receiver_type,
2318
- topdown_hint: true)
2319
-
2320
- add_typing node, type: return_type, constr: constr
2321
- else
2322
- fallback_to_any node do
2323
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2324
- end
2325
- end
2326
- rescue => exn
2327
- case exn
2328
- when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2329
- # ignore known RBS errors.
2330
- else
2331
- Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2332
- end
2311
+ when AST::Types::Void, AST::Types::Bot, AST::Types::Top
2312
+ fallback_to_any node do
2313
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2314
+ end
2333
2315
 
2334
- fallback_to_any node do
2335
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2336
- end
2337
- end
2338
- end
2339
- end
2316
+ else
2317
+ case expanded_receiver_type = expand_self(receiver_type)
2318
+ when AST::Types::Self
2319
+ Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
2320
+ fallback_to_any node do
2321
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2322
+ end
2323
+ else
2324
+ begin
2325
+ interface = checker.factory.interface(receiver_type,
2326
+ private: !receiver,
2327
+ self_type: expanded_receiver_type)
2328
+
2329
+ method = interface.methods[method_name]
2330
+
2331
+ if method
2332
+ args = TypeInference::SendArgs.from_nodes(arguments)
2333
+ return_type, constr, _ = constr.type_method_call(node,
2334
+ method: method,
2335
+ method_name: method_name,
2336
+ args: args,
2337
+ block_params: block_params,
2338
+ block_body: block_body,
2339
+ receiver_type: receiver_type,
2340
+ topdown_hint: true)
2341
+
2342
+ add_typing node, type: return_type, constr: constr
2343
+ else
2344
+ fallback_to_any node do
2345
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2346
+ end
2347
+ end
2348
+ rescue => exn
2349
+ case exn
2350
+ when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2351
+ # ignore known RBS errors.
2352
+ else
2353
+ Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2354
+ end
2340
2355
 
2341
- case pair.type
2356
+ fallback_to_any node do
2357
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2358
+ end
2359
+ end
2360
+ end
2361
+ end
2362
+
2363
+ case type
2342
2364
  when nil, Errors::Base
2343
2365
  arguments.each do |arg|
2344
2366
  unless typing.has_type?(arg)
2345
2367
  if arg.type == :splat
2346
- type = synthesize(arg.children[0]).type
2368
+ type, constr = constr.synthesize(arg.children[0])
2347
2369
  add_typing(arg, type: AST::Builtin::Array.instance_type(type))
2348
2370
  else
2349
- synthesize(arg)
2371
+ _, constr = constr.synthesize(arg)
2350
2372
  end
2351
2373
  end
2352
2374
  end
@@ -2368,7 +2390,7 @@ module Steep
2368
2390
  end
2369
2391
  end
2370
2392
  else
2371
- pair
2393
+ Pair.new(type: type, constr: constr)
2372
2394
  end
2373
2395
  end
2374
2396
 
@@ -2867,7 +2889,7 @@ module Steep
2867
2889
  decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2868
2890
  hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2869
2891
  end
2870
- env.update(declared_types: env.declared_types.merge(decls))
2892
+ env.except(decls.keys).update(assigned_types: decls)
2871
2893
  end.annotate(block_annotations)
2872
2894
 
2873
2895
  break_type = if block_annotations.break_type
@@ -3010,7 +3032,7 @@ module Steep
3010
3032
  end
3011
3033
 
3012
3034
  def nested_namespace_for_module(module_name)
3013
- if module_name.relative?
3035
+ if module_name.namespace.relative?
3014
3036
  (current_namespace + module_name.namespace).append(module_name.name)
3015
3037
  else
3016
3038
  module_name
@@ -3019,7 +3041,7 @@ module Steep
3019
3041
 
3020
3042
  def absolute_name(module_name)
3021
3043
  if current_namespace
3022
- module_name.in_namespace(current_namespace)
3044
+ module_name.with_prefix(current_namespace)
3023
3045
  else
3024
3046
  module_name.absolute!
3025
3047
  end
@@ -3037,7 +3059,7 @@ module Steep
3037
3059
  end
3038
3060
 
3039
3061
  def validate_method_definitions(node, module_name)
3040
- module_name_1 = checker.factory.type_name_1(module_name.name)
3062
+ module_name_1 = module_name.name
3041
3063
  member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
3042
3064
 
3043
3065
  return unless member_decl_count == 1
@@ -3185,37 +3207,12 @@ module Steep
3185
3207
  end
3186
3208
  end
3187
3209
 
3188
- def deep_expand_alias(type, recursive: Set.new, &block)
3189
- raise "Recursive type definition: #{type}" if recursive.member?(type)
3190
-
3191
- ty = case type
3192
- when AST::Types::Name::Alias
3193
- deep_expand_alias(expand_alias(type), recursive: recursive.union([type]))
3194
- when AST::Types::Union
3195
- AST::Types::Union.build(
3196
- types: type.types.map {|ty| deep_expand_alias(ty, recursive: recursive, &block) },
3197
- location: type.location
3198
- )
3199
- else
3200
- type
3201
- end
3202
-
3203
- if block_given?
3204
- yield ty
3205
- else
3206
- ty
3207
- end
3210
+ def deep_expand_alias(type, &block)
3211
+ checker.factory.deep_expand_alias(type, &block)
3208
3212
  end
3209
3213
 
3210
- def flatten_union(type, acc = [])
3211
- case type
3212
- when AST::Types::Union
3213
- type.types.each {|ty| flatten_union(ty, acc) }
3214
- else
3215
- acc << type
3216
- end
3217
-
3218
- acc
3214
+ def flatten_union(type)
3215
+ checker.factory.flatten_union(type)
3219
3216
  end
3220
3217
 
3221
3218
  def select_flatten_types(type, &block)
@@ -3277,7 +3274,7 @@ module Steep
3277
3274
  def to_instance_type(type, args: nil)
3278
3275
  args = args || case type
3279
3276
  when AST::Types::Name::Singleton
3280
- checker.factory.env.class_decls[checker.factory.type_name_1(type.name)].type_params.each.map { AST::Builtin.any_type }
3277
+ checker.factory.env.class_decls[type.name].type_params.each.map { AST::Builtin.any_type }
3281
3278
  else
3282
3279
  raise "unexpected type to to_instance_type: #{type}"
3283
3280
  end