steep 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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