steep 1.7.0.dev.2 → 1.7.0.dev.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +10 -12
  3. data/gemfile_steep/Gemfile.lock +8 -10
  4. data/lib/steep/ast/types/helper.rb +4 -0
  5. data/lib/steep/ast/types/intersection.rb +7 -0
  6. data/lib/steep/ast/types/record.rb +7 -0
  7. data/lib/steep/ast/types/tuple.rb +7 -0
  8. data/lib/steep/ast/types/union.rb +7 -0
  9. data/lib/steep/drivers/stats.rb +2 -2
  10. data/lib/steep/drivers/validate.rb +4 -2
  11. data/lib/steep/expectations.rb +2 -2
  12. data/lib/steep/interface/builder.rb +336 -360
  13. data/lib/steep/interface/function.rb +69 -6
  14. data/lib/steep/interface/method_type.rb +3 -3
  15. data/lib/steep/interface/shape.rb +69 -18
  16. data/lib/steep/interface/substitution.rb +4 -0
  17. data/lib/steep/node_helper.rb +18 -1
  18. data/lib/steep/services/completion_provider.rb +19 -17
  19. data/lib/steep/services/signature_help_provider.rb +6 -9
  20. data/lib/steep/subtyping/check.rb +4 -16
  21. data/lib/steep/test.rb +9 -0
  22. data/lib/steep/type_construction.rb +13 -9
  23. data/lib/steep/type_inference/block_params.rb +11 -3
  24. data/lib/steep/type_inference/context.rb +1 -1
  25. data/lib/steep/type_inference/logic_type_interpreter.rb +1 -1
  26. data/lib/steep/version.rb +1 -1
  27. data/lib/steep.rb +11 -7
  28. data/sig/steep/ast/types/helper.rbs +2 -0
  29. data/sig/steep/ast/types/intersection.rbs +2 -0
  30. data/sig/steep/ast/types/name.rbs +4 -0
  31. data/sig/steep/ast/types/record.rbs +2 -0
  32. data/sig/steep/ast/types/tuple.rbs +2 -0
  33. data/sig/steep/ast/types/union.rbs +2 -0
  34. data/sig/steep/expectations.rbs +1 -1
  35. data/sig/steep/interface/block.rbs +2 -2
  36. data/sig/steep/interface/builder.rbs +94 -108
  37. data/sig/steep/interface/function.rbs +34 -29
  38. data/sig/steep/interface/shape.rbs +23 -4
  39. data/sig/steep/interface/substitution.rbs +2 -0
  40. data/sig/steep/node_helper.rbs +11 -0
  41. data/sig/steep/services/signature_help_provider.rbs +2 -0
  42. data/sig/steep/subtyping/constraints.rbs +2 -2
  43. data/sig/steep/type_construction.rbs +1 -1
  44. data/sig/steep/type_inference/block_params.rbs +2 -2
  45. data/sig/steep/type_inference/context.rbs +2 -0
  46. data/sig/steep.rbs +1 -1
  47. metadata +3 -2
@@ -3,346 +3,305 @@ module Steep
3
3
  class Builder
4
4
  class Config
5
5
  attr_reader :self_type, :class_type, :instance_type, :variable_bounds
6
- attr_reader :resolve_self, :resolve_instance, :resolve_class
7
6
 
8
- def initialize(self_type:, class_type:, instance_type:, resolve_self: true, resolve_class: true, resolve_instance: true, variable_bounds:)
7
+ def initialize(self_type:, class_type: nil, instance_type: nil, variable_bounds:)
9
8
  @self_type = self_type
10
9
  @class_type = class_type
11
10
  @instance_type = instance_type
12
- @resolve_self = resolve_self
13
- @resolve_class = resolve_class
14
- @resolve_instance = resolve_instance
15
11
  @variable_bounds = variable_bounds
16
- end
17
-
18
- def update(self_type: self.self_type, class_type: self.class_type, instance_type: self.instance_type, resolve_self: self.resolve_self, resolve_class: self.resolve_class, resolve_instance: self.resolve_instance, variable_bounds: self.variable_bounds)
19
- _ = self.class.new(
20
- self_type: self_type,
21
- class_type: class_type,
22
- instance_type: instance_type,
23
- resolve_self: resolve_self,
24
- resolve_class: resolve_class,
25
- resolve_instance: resolve_instance,
26
- variable_bounds: variable_bounds
27
- )
28
- end
29
-
30
- def no_resolve
31
- if resolve?
32
- @no_resolve ||= update(resolve_self: false, resolve_class: false, resolve_instance: false)
33
- else
34
- self
35
- end
36
- end
37
-
38
- def resolve?
39
- resolve_self || resolve_class || resolve_instance
40
- end
41
12
 
42
- def ==(other)
43
- other.is_a?(Config) &&
44
- other.self_type == self_type &&
45
- other.class_type == class_type &&
46
- other.instance_type == instance_type &&
47
- other.resolve_self == resolve_self &&
48
- other.resolve_class == resolve_class &&
49
- other.resolve_instance == resolve_instance &&
50
- other.variable_bounds == variable_bounds
13
+ validate
51
14
  end
52
15
 
53
- alias eql? ==
54
-
55
- def hash
56
- self_type.hash ^ class_type.hash ^ instance_type.hash ^ resolve_self.hash ^ resolve_class.hash ^ resolve_instance.hash ^ variable_bounds.hash
16
+ def self.empty
17
+ new(self_type: nil, variable_bounds: {})
57
18
  end
58
19
 
59
20
  def subst
60
- @subst ||= begin
61
- Substitution.build(
62
- [],
63
- [],
64
- self_type: self_type,
65
- module_type: class_type || AST::Types::Class.instance,
66
- instance_type: instance_type || AST::Types::Instance.instance
67
- )
21
+ if self_type || class_type || instance_type
22
+ Substitution.build([], [], self_type: self_type, module_type: class_type, instance_type: instance_type)
68
23
  end
69
24
  end
70
25
 
71
- def self_type?
72
- unless self_type.is_a?(AST::Types::Self)
73
- self_type
74
- end
26
+ def validate
27
+ validate_fvs(:self_type, self_type)
28
+ validate_fvs(:instance_type, instance_type)
29
+ validate_fvs(:class_type, class_type)
30
+ self
75
31
  end
76
32
 
77
- def instance_type?
78
- unless instance_type.is_a?(AST::Types::Instance)
79
- instance_type
33
+ def validate_fvs(name, type)
34
+ if type
35
+ fvs = type.free_variables
36
+ if fvs.include?(AST::Types::Self.instance)
37
+ raise "#{name} cannot include 'self' type: #{type}"
38
+ end
39
+ if fvs.include?(AST::Types::Instance.instance)
40
+ raise "#{name} cannot include 'instance' type: #{type}"
41
+ end
42
+ if fvs.include?(AST::Types::Class.instance)
43
+ raise "#{name} cannot include 'class' type: #{type}"
44
+ end
80
45
  end
81
46
  end
82
47
 
83
- def class_type?
84
- unless class_type.is_a?(AST::Types::Class)
85
- class_type
86
- end
48
+ def upper_bound(a)
49
+ variable_bounds.fetch(a, nil)
87
50
  end
88
51
  end
89
52
 
90
- attr_reader :factory, :cache, :raw_object_cache
91
- attr_reader :raw_instance_object_shape_cache, :raw_singleton_object_shape_cache, :raw_interface_object_shape_cache
53
+ attr_reader :factory, :object_shape_cache, :union_shape_cache, :singleton_shape_cache
92
54
 
93
55
  def initialize(factory)
94
56
  @factory = factory
95
- @cache = {}
96
- @raw_instance_object_shape_cache = {}
97
- @raw_singleton_object_shape_cache = {}
98
- @raw_interface_object_shape_cache = {}
57
+ @object_shape_cache = {}
58
+ @union_shape_cache = {}
59
+ @singleton_shape_cache = {}
99
60
  end
100
61
 
101
- def include_self?(type)
102
- case type
103
- when AST::Types::Self, AST::Types::Instance, AST::Types::Class
104
- true
105
- else
106
- type.each_child.any? {|t| include_self?(t) }
62
+ def shape(type, config)
63
+ Steep.logger.tagged "shape(#{type})" do
64
+ if shape = raw_shape(type, config)
65
+ if type.free_variables.include?(AST::Types::Self.instance)
66
+ shape
67
+ else
68
+ if s = config.subst
69
+ shape.subst(s)
70
+ else
71
+ shape
72
+ end
73
+ end
74
+ end
107
75
  end
108
76
  end
109
77
 
110
- def fetch_cache(type, public_only, config)
111
- has_self = include_self?(type)
112
- fvs = type.free_variables
113
-
114
- # @type var key: cache_key
115
- key = [
116
- type,
117
- public_only,
118
- has_self ? config.self_type : nil,
119
- has_self ? config.class_type : nil,
120
- has_self ? config.instance_type : nil,
121
- config.resolve_self,
122
- config.resolve_class,
123
- config.resolve_instance,
124
- if config.variable_bounds.each_key.any? {|var| fvs.include?(var)}
125
- config.variable_bounds.select {|var, _| fvs.include?(var) }
126
- else
127
- nil
128
- end
129
- ]
130
-
78
+ def fetch_cache(cache, key)
131
79
  if cache.key?(key)
132
- cache[key]
133
- else
134
- cache[key] = yield
80
+ return cache.fetch(key)
135
81
  end
136
- end
137
-
138
- def shape(type, public_only:, config:)
139
- fetch_cache(type, public_only, config) do
140
- case type
141
- when AST::Types::Self
142
- if self_type = config.self_type?
143
- self_type = self_type.subst(config.subst)
144
- shape(self_type, public_only: public_only, config: config.update(resolve_self: false))
145
- end
146
- when AST::Types::Instance
147
- if instance_type = config.instance_type?
148
- instance_type = instance_type.subst(config.subst)
149
- shape(instance_type, public_only: public_only, config: config.update(resolve_instance: false))
150
- end
151
- when AST::Types::Class
152
- if class_type = config.class_type?
153
- class_type = class_type.subst(config.subst)
154
- shape(class_type, public_only: public_only, config: config.update(resolve_class: false))
155
- end
156
- when AST::Types::Name::Instance, AST::Types::Name::Interface, AST::Types::Name::Singleton
157
- object_shape(
158
- type.subst(config.subst),
159
- public_only,
160
- !config.resolve_self,
161
- !config.resolve_instance,
162
- !config.resolve_class
163
- )
164
- when AST::Types::Name::Alias
165
- if expanded = factory.deep_expand_alias(type)
166
- shape(expanded, public_only: public_only, config: config)&.update(type: type)
167
- end
168
- when AST::Types::Any, AST::Types::Bot, AST::Types::Void, AST::Types::Top
169
- nil
170
- when AST::Types::Var
171
- if bound = config.variable_bounds[type.name]
172
- shape(bound, public_only: public_only, config: config)&.update(type: type)
173
- end
174
- when AST::Types::Union
175
- if include_self?(type)
176
- self_var = AST::Types::Var.fresh(:SELF)
177
- class_var = AST::Types::Var.fresh(:CLASS)
178
- instance_var = AST::Types::Var.fresh(:INSTANCE)
179
82
 
180
- bounds = config.variable_bounds.merge({ self_var.name => config.self_type, instance_var.name => config.instance_type, class_var.name => config.class_type })
181
- type_ = type.subst(Substitution.build([], [], self_type: self_var, instance_type: instance_var, module_type: class_var)) #: AST::Types::Union
182
-
183
- config_ = config.update(resolve_self: false, resolve_class: true, resolve_instance: true, variable_bounds: bounds)
184
-
185
- shapes = type_.types.map do |type|
186
- shape(type, public_only: public_only, config: config_) or return
187
- end
83
+ cache[key] = yield
84
+ end
188
85
 
189
- if shape = union_shape(type, shapes, public_only)
190
- shape.subst(
191
- Substitution.build(
192
- [self_var.name, class_var.name, instance_var.name],
193
- [AST::Types::Self.instance, AST::Types::Class.instance, AST::Types::Instance.instance],
194
- self_type: type,
195
- instance_type: AST::Builtin.any_type,
196
- module_type: AST::Builtin.any_type
197
- ),
198
- type: type.subst(config.subst)
199
- )
200
- end
86
+ def raw_shape(type, config)
87
+ case type
88
+ when AST::Types::Self
89
+ self_type = config.self_type or raise
90
+ self_shape(self_type, config)
91
+ when AST::Types::Instance
92
+ instance_type = config.instance_type or raise
93
+ raw_shape(instance_type, config)
94
+ when AST::Types::Class
95
+ klass_type = config.class_type or raise
96
+ raw_shape(klass_type, config)
97
+ when AST::Types::Name::Singleton
98
+ singleton_shape(type.name).subst(class_subst(type))
99
+ when AST::Types::Name::Instance
100
+ object_shape(type.name).subst(class_subst(type).merge(app_subst(type)), type: type)
101
+ when AST::Types::Name::Interface
102
+ object_shape(type.name).subst(interface_subst(type).merge(app_subst(type)), type: type)
103
+ when AST::Types::Union
104
+ groups = type.types.group_by do |type|
105
+ if type.is_a?(AST::Types::Literal)
106
+ type.back_type
201
107
  else
202
- config_ = config.update(resolve_self: false)
203
-
204
- shapes = type.types.map do |type|
205
- shape(type, public_only: public_only, config: config_) or return
206
- end
207
-
208
- if shape = union_shape(type, shapes, public_only)
209
- shape.subst(
210
- Substitution.build(
211
- [], [],
212
- self_type: type,
213
- instance_type: AST::Builtin.any_type,
214
- module_type: AST::Builtin.any_type
215
- )
216
- )
217
- end
218
- end
219
- when AST::Types::Intersection
220
- self_var = AST::Types::Var.fresh(:SELF)
221
- class_var = AST::Types::Var.fresh(:CLASS)
222
- instance_var = AST::Types::Var.fresh(:INSTANCE)
223
-
224
- bounds = config.variable_bounds.merge({ self_var.name => config.self_type, instance_var.name => config.instance_type, class_var.name => config.class_type })
225
- type_ = type.subst(Substitution.build([], [], self_type: self_var, instance_type: instance_var, module_type: class_var)) #: AST::Types::Intersection
226
-
227
- config_ = config.update(resolve_self: false, resolve_class: true, resolve_instance: true, variable_bounds: bounds)
228
-
229
- shapes = type_.types.map do |type|
230
- shape(type, public_only: public_only, config: config_) or return
108
+ nil
231
109
  end
110
+ end
232
111
 
233
- if shape = intersection_shape(type, shapes, public_only)
234
- shape.subst(
235
- Substitution.build(
236
- [self_var.name, class_var.name, instance_var.name],
237
- [AST::Types::Self.instance, AST::Types::Class.instance, AST::Types::Instance.instance],
238
- self_type: type,
239
- instance_type: AST::Builtin.any_type,
240
- module_type: AST::Builtin.any_type
241
- ),
242
- type: type.subst(config.subst)
243
- )
112
+ shapes = [] #: Array[Shape]
113
+ groups.each do |name, types|
114
+ if name
115
+ union = AST::Types::Union.build(types: types)
116
+ subst = class_subst(name).update(self_type: union)
117
+ shapes << object_shape(name.name).subst(subst, type: union)
118
+ else
119
+ shapes.concat(types.map {|ty| raw_shape(ty, config) or return })
244
120
  end
121
+ end
245
122
 
246
- when AST::Types::Tuple
247
- tuple_shape(type, public_only, config)
248
- when AST::Types::Record
249
- record_shape(type, public_only, config)
250
- when AST::Types::Literal
251
- if shape = shape(type.back_type, public_only: public_only, config: config.update(resolve_self: false))
252
- shape.subst(Substitution.build([], [], self_type: type), type: type)
253
- end
254
- when AST::Types::Boolean, AST::Types::Logic::Base
255
- shape = union_shape(
256
- type,
257
- [
258
- object_shape(AST::Builtin::TrueClass.instance_type, public_only, true, true, true),
259
- object_shape(AST::Builtin::FalseClass.instance_type, public_only, true, true, true)
260
- ],
261
- public_only
123
+ fetch_cache(union_shape_cache, type) do
124
+ union_shape(type, shapes)
125
+ end
126
+ when AST::Types::Intersection
127
+ shapes = type.types.map do |type|
128
+ raw_shape(type, config) or return
129
+ end
130
+ intersection_shape(type, shapes)
131
+ when AST::Types::Name::Alias
132
+ expanded = factory.expand_alias(type)
133
+ if shape = raw_shape(expanded, config)
134
+ shape.update(type: type)
135
+ end
136
+ when AST::Types::Literal
137
+ instance_type = type.back_type
138
+ subst = class_subst(instance_type).update(self_type: type)
139
+ object_shape(instance_type.name).subst(subst, type: type)
140
+ when AST::Types::Boolean
141
+ true_shape =
142
+ (object_shape(RBS::BuiltinNames::TrueClass.name)).
143
+ subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: type))
144
+ false_shape =
145
+ (object_shape(RBS::BuiltinNames::FalseClass.name)).
146
+ subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: type))
147
+ union_shape(type, [true_shape, false_shape])
148
+ when AST::Types::Proc
149
+ shape = object_shape(AST::Builtin::Proc.module_name).subst(class_subst(AST::Builtin::Proc.instance_type).update(self_type: type))
150
+ proc_shape(type, shape)
151
+ when AST::Types::Tuple
152
+ tuple_shape(type) do |array|
153
+ object_shape(array.name).subst(
154
+ class_subst(array).update(self_type: type).merge(app_subst(array))
262
155
  )
263
-
264
- if shape
265
- shape.subst(Substitution.build([], [], self_type: type))
266
- end
267
- when AST::Types::Nil
268
- if shape = object_shape(AST::Builtin::NilClass.instance_type, public_only, true, !config.resolve_instance, !config.resolve_class)
269
- if config.resolve_self
270
- shape.subst(Substitution.build([], [], self_type: type), type: type)
271
- else
272
- shape.update(type: type)
273
- end
274
- end
275
- when AST::Types::Proc
276
- proc_shape(type, public_only, config)
277
- else
278
- raise "Unknown type is given: #{type}"
279
156
  end
157
+ when AST::Types::Record
158
+ record_shape(type) do |hash|
159
+ object_shape(hash.name).subst(
160
+ class_subst(hash).update(self_type: type).merge(app_subst(hash))
161
+ )
162
+ end
163
+ when AST::Types::Var
164
+ if bound = config.upper_bound(type.name)
165
+ new_config = Config.new(self_type: bound, variable_bounds: config.variable_bounds)
166
+ sub = Substitution.build([], self_type: type)
167
+ # We have to use `self_shape` insead of `raw_shape` here.
168
+ # Keep the `self` types included in the `bound`'s shape, and replace it to the type variable.
169
+ self_shape(bound, new_config)&.subst(sub, type: type)
170
+ end
171
+ when AST::Types::Nil
172
+ subst = class_subst(AST::Builtin::NilClass.instance_type).update(self_type: type)
173
+ object_shape(AST::Builtin::NilClass.module_name).subst(subst, type: type)
174
+ when AST::Types::Logic::Base
175
+ true_shape =
176
+ (object_shape(RBS::BuiltinNames::TrueClass.name)).
177
+ subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: type))
178
+ false_shape =
179
+ (object_shape(RBS::BuiltinNames::FalseClass.name)).
180
+ subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: type))
181
+ union_shape(type, [true_shape, false_shape])
182
+ else
183
+ nil
280
184
  end
281
185
  end
282
186
 
283
- def definition_builder
284
- factory.definition_builder
285
- end
286
-
287
- def object_shape(type, public_only, keep_self, keep_instance, keep_singleton)
187
+ def self_shape(type, config)
288
188
  case type
189
+ when AST::Types::Self, AST::Types::Instance, AST::Types::Class
190
+ raise
191
+ when AST::Types::Name::Singleton
192
+ singleton_shape(type.name).subst(class_subst(type).update(self_type: nil))
289
193
  when AST::Types::Name::Instance
290
- definition = definition_builder.build_instance(type.name)
291
- subst = Interface::Substitution.build(
292
- definition.type_params,
293
- type.args,
294
- self_type: keep_self ? AST::Types::Self.instance : type,
295
- module_type: keep_singleton ? AST::Types::Class.instance : AST::Types::Name::Singleton.new(name: type.name),
296
- instance_type: keep_instance ? AST::Types::Instance.instance : factory.instance_type(type.name)
297
- )
194
+ object_shape(type.name)
195
+ .subst(
196
+ class_subst(type).update(self_type: nil).merge(app_subst(type)),
197
+ type: type
198
+ )
298
199
  when AST::Types::Name::Interface
299
- definition = definition_builder.build_interface(type.name)
300
- subst = Interface::Substitution.build(
301
- definition.type_params,
302
- type.args,
303
- self_type: keep_self ? AST::Types::Self.instance : type
304
- )
305
- when AST::Types::Name::Singleton
306
- subst = Interface::Substitution.build(
307
- [],
308
- [],
309
- self_type: keep_self ? AST::Types::Self.instance : type,
310
- module_type: keep_singleton ? AST::Types::Class.instance : AST::Types::Name::Singleton.new(name: type.name),
311
- instance_type: keep_instance ? AST::Types::Instance.instance : factory.instance_type(type.name)
312
- )
200
+ object_shape(type.name).subst(app_subst(type), type: type)
201
+ when AST::Types::Literal
202
+ instance_type = type.back_type
203
+ subst = class_subst(instance_type).update(self_type: nil)
204
+ object_shape(instance_type.name).subst(subst, type: type)
205
+ when AST::Types::Boolean
206
+ true_shape =
207
+ (object_shape(RBS::BuiltinNames::TrueClass.name)).
208
+ subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: nil))
209
+ false_shape =
210
+ (object_shape(RBS::BuiltinNames::FalseClass.name)).
211
+ subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: nil))
212
+ union_shape(type, [true_shape, false_shape])
213
+ when AST::Types::Proc
214
+ shape = object_shape(AST::Builtin::Proc.module_name).subst(class_subst(AST::Builtin::Proc.instance_type).update(self_type: nil))
215
+ proc_shape(type, shape)
216
+ when AST::Types::Var
217
+ if bound = config.upper_bound(type.name)
218
+ self_shape(bound, config)&.update(type: type)
219
+ end
220
+ else
221
+ raw_shape(type, config)
313
222
  end
314
-
315
- raw_object_shape(type, public_only, subst)
316
223
  end
317
224
 
318
- def raw_object_shape(type, public_only, subst)
319
- cache =
225
+ def app_subst(type)
226
+ if type.args.empty?
227
+ return Substitution.empty
228
+ end
229
+
230
+ vars =
320
231
  case type
321
232
  when AST::Types::Name::Instance
322
- raw_instance_object_shape_cache
233
+ entry = factory.env.normalized_module_class_entry(type.name) or raise
234
+ entry.primary.decl.type_params.map { _1.name }
323
235
  when AST::Types::Name::Interface
324
- raw_interface_object_shape_cache
325
- when AST::Types::Name::Singleton
326
- raw_singleton_object_shape_cache
236
+ entry = factory.env.interface_decls.fetch(type.name)
237
+ entry.decl.type_params.map { _1.name }
238
+ when AST::Types::Name::Alias
239
+ entry = factory.env.type_alias_decls.fetch(type.name)
240
+ entry.decl.type_params.map { _1.name }
327
241
  end
328
242
 
329
- raw_shape = cache[[type.name, public_only]] ||= begin
330
- shape = Interface::Shape.new(type: AST::Builtin.bottom_type, private: !public_only)
243
+ Substitution.build(vars, type.args)
244
+ end
331
245
 
332
- case type
333
- when AST::Types::Name::Instance
334
- definition = definition_builder.build_instance(type.name)
335
- when AST::Types::Name::Interface
336
- definition = definition_builder.build_interface(type.name)
337
- when AST::Types::Name::Singleton
338
- definition = definition_builder.build_singleton(type.name)
339
- end
246
+ def class_subst(type)
247
+ case type
248
+ when AST::Types::Name::Singleton
249
+ self_type = type
250
+ singleton_type = type
251
+ instance_type = factory.instance_type(type.name)
252
+ when AST::Types::Name::Instance
253
+ self_type = type
254
+ singleton_type = type.to_module
255
+ instance_type = factory.instance_type(type.name)
256
+ end
257
+
258
+ Substitution.build([], self_type: self_type, module_type: singleton_type, instance_type: instance_type)
259
+ end
260
+
261
+ def interface_subst(type)
262
+ Substitution.build([], self_type: type)
263
+ end
264
+
265
+ def singleton_shape(type_name)
266
+ singleton_shape_cache[type_name] ||= begin
267
+ shape = Interface::Shape.new(type: AST::Types::Name::Singleton.new(name: type_name), private: true)
268
+ definition = factory.definition_builder.build_singleton(type_name)
340
269
 
341
270
  definition.methods.each do |name, method|
342
- next if method.private? && public_only
271
+ Steep.logger.tagged "method = #{type_name}.#{name}" do
272
+ shape.methods[name] = Interface::Shape::Entry.new(
273
+ private_method: method.private?,
274
+ method_types: method.defs.map do |type_def|
275
+ method_name = method_name_for(type_def, name)
276
+ decl = TypeInference::MethodCall::MethodDecl.new(method_name: method_name, method_def: type_def)
277
+ method_type = factory.method_type(type_def.type, method_decls: Set[decl])
278
+ replace_primitive_method(method_name, type_def, method_type)
279
+ end
280
+ )
281
+ end
282
+ end
283
+
284
+ shape
285
+ end
286
+ end
287
+
288
+ def object_shape(type_name)
289
+ object_shape_cache[type_name] ||= begin
290
+ shape = Interface::Shape.new(type: AST::Builtin.bottom_type, private: true)
291
+
292
+ case
293
+ when type_name.class?
294
+ definition = factory.definition_builder.build_instance(type_name)
295
+ when type_name.interface?
296
+ definition = factory.definition_builder.build_interface(type_name)
297
+ end
343
298
 
344
- Steep.logger.tagged "method = #{type}##{name}" do
299
+ definition or raise
300
+
301
+ definition.methods.each do |name, method|
302
+ Steep.logger.tagged "method = #{type_name}##{name}" do
345
303
  shape.methods[name] = Interface::Shape::Entry.new(
304
+ private_method: method.private?,
346
305
  method_types: method.defs.map do |type_def|
347
306
  method_name = method_name_for(type_def, name)
348
307
  decl = TypeInference::MethodCall::MethodDecl.new(method_name: method_name, method_def: type_def)
@@ -355,8 +314,84 @@ module Steep
355
314
 
356
315
  shape
357
316
  end
317
+ end
318
+
319
+ def union_shape(shape_type, shapes)
320
+ s0, *sx = shapes
321
+ s0 or raise
322
+ all_common_methods = Set.new(s0.methods.each_name)
323
+ sx.each do |shape|
324
+ all_common_methods &= shape.methods.each_name
325
+ end
326
+
327
+ shape = Interface::Shape.new(type: shape_type, private: true)
328
+ all_common_methods.each do |method_name|
329
+ method_typess = [] #: Array[Array[MethodType]]
330
+ private_method = false
331
+ shapes.each do |shape|
332
+ entry = shape.methods[method_name] || raise
333
+ method_typess << entry.method_types
334
+ private_method ||= entry.private_method?
335
+ end
336
+
337
+ shape.methods[method_name] = Interface::Shape::Entry.new(private_method: private_method) do
338
+ method_typess.inject do |types1, types2|
339
+ # @type break: nil
340
+
341
+ if types1 == types2
342
+ decl_array1 = types1.map(&:method_decls)
343
+ decl_array2 = types2.map(&:method_decls)
344
+
345
+ if decl_array1 == decl_array2
346
+ next types1
347
+ end
348
+
349
+ decls1 = decl_array1.each.with_object(Set[]) {|array, decls| decls.merge(array) } #$ Set[TypeInference::MethodCall::MethodDecl]
350
+ decls2 = decl_array2.each.with_object(Set[]) {|array, decls| decls.merge(array) } #$ Set[TypeInference::MethodCall::MethodDecl]
351
+
352
+ if decls1 == decls2
353
+ next types1
354
+ end
355
+ end
356
+
357
+ method_types = {} #: Hash[MethodType, bool]
358
+
359
+ types1.each do |type1|
360
+ types2.each do |type2|
361
+ if type1 == type2
362
+ method_types[type1.with(method_decls: type1.method_decls + type2.method_decls)] = true
363
+ else
364
+ if type = MethodType.union(type1, type2, subtyping)
365
+ method_types[type] = true
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ break nil if method_types.empty?
372
+
373
+ method_types.keys
374
+ end
375
+ end
376
+ end
377
+
378
+ shape
379
+ end
380
+
381
+ def intersection_shape(type, shapes)
382
+ shape = Interface::Shape.new(type: type, private: true)
383
+
384
+ shapes.each do |s|
385
+ shape.methods.merge!(s.methods) do |name, old_entry, new_entry|
386
+ if old_entry.public_method? && new_entry.private_method?
387
+ old_entry
388
+ else
389
+ new_entry
390
+ end
391
+ end
392
+ end
358
393
 
359
- raw_shape.subst(subst, type: type)
394
+ shape
360
395
  end
361
396
 
362
397
  def method_name_for(type_def, name)
@@ -383,63 +418,19 @@ module Steep
383
418
  @subtyping ||= Subtyping::Check.new(builder: self)
384
419
  end
385
420
 
386
- def union_shape(shape_type, shapes, public_only)
387
- shapes.inject do |shape1, shape2|
388
- Interface::Shape.new(type: shape_type, private: !public_only).tap do |shape|
389
- common_methods = Set.new(shape1.methods.each_name) & Set.new(shape2.methods.each_name)
390
- common_methods.each do |name|
391
- Steep.logger.tagged(name.to_s) do
392
- types1 = shape1.methods[name]&.method_types or raise
393
- types2 = shape2.methods[name]&.method_types or raise
394
-
395
- if types1 == types2 && types1.map {|type| type.method_decls.to_a }.to_set == types2.map {|type| type.method_decls.to_a }.to_set
396
- shape.methods[name] = (shape1.methods[name] or raise)
397
- else
398
- method_types = {} #: Hash[MethodType, true]
399
-
400
- types1.each do |type1|
401
- types2.each do |type2|
402
- if type1 == type2
403
- method_types[type1.with(method_decls: type1.method_decls + type2.method_decls)] = true
404
- else
405
- if type = MethodType.union(type1, type2, subtyping)
406
- method_types[type] = true
407
- end
408
- end
409
- end
410
- end
411
-
412
- unless method_types.empty?
413
- shape.methods[name] = Interface::Shape::Entry.new(method_types: method_types.keys)
414
- end
415
- end
416
- end
417
- end
418
- end
419
- end
420
- end
421
-
422
- def intersection_shape(type, shapes, public_only)
423
- shapes.inject do |shape1, shape2|
424
- Interface::Shape.new(type: type, private: !public_only).tap do |shape|
425
- shape.methods.merge!(shape1.methods)
426
- shape.methods.merge!(shape2.methods)
427
- end
428
- end
429
- end
430
-
431
- def tuple_shape(tuple, public_only, config)
421
+ def tuple_shape(tuple)
432
422
  element_type = AST::Types::Union.build(types: tuple.types, location: nil)
433
423
  array_type = AST::Builtin::Array.instance_type(element_type)
434
424
 
435
- array_shape = shape(array_type, public_only: public_only, config: config.no_resolve) or raise
436
- shape = Shape.new(type: tuple, private: !public_only)
425
+ array_shape = yield(array_type) or raise
426
+ shape = Shape.new(type: tuple, private: true)
437
427
  shape.methods.merge!(array_shape.methods)
438
428
 
439
429
  aref_entry = array_shape.methods[:[]].yield_self do |aref|
440
430
  raise unless aref
441
431
 
442
432
  Shape::Entry.new(
433
+ private_method: false,
443
434
  method_types: tuple.types.map.with_index {|elem_type, index|
444
435
  MethodType.new(
445
436
  type_params: [],
@@ -459,6 +450,7 @@ module Steep
459
450
  raise unless update
460
451
 
461
452
  Shape::Entry.new(
453
+ private_method: false,
462
454
  method_types: tuple.types.map.with_index {|elem_type, index|
463
455
  MethodType.new(
464
456
  type_params: [],
@@ -478,6 +470,7 @@ module Steep
478
470
  raise unless fetch
479
471
 
480
472
  Shape::Entry.new(
473
+ private_method: false,
481
474
  method_types: tuple.types.flat_map.with_index {|elem_type, index|
482
475
  [
483
476
  MethodType.new(
@@ -530,6 +523,7 @@ module Steep
530
523
 
531
524
  first_entry = array_shape.methods[:first].yield_self do |first|
532
525
  Shape::Entry.new(
526
+ private_method: false,
533
527
  method_types: [
534
528
  MethodType.new(
535
529
  type_params: [],
@@ -547,6 +541,7 @@ module Steep
547
541
 
548
542
  last_entry = array_shape.methods[:last].yield_self do |last|
549
543
  Shape::Entry.new(
544
+ private_method: false,
550
545
  method_types: [
551
546
  MethodType.new(
552
547
  type_params: [],
@@ -568,17 +563,10 @@ module Steep
568
563
  shape.methods[:first] = first_entry
569
564
  shape.methods[:last] = last_entry
570
565
 
571
- shape.subst(
572
- Substitution.build(
573
- [], [],
574
- self_type: config.resolve_self ? tuple : AST::Types::Self.instance,
575
- instance_type: AST::Builtin::Array.instance_type(fill_untyped: true),
576
- module_type: AST::Builtin::Array.module_type
577
- )
578
- )
566
+ shape
579
567
  end
580
568
 
581
- def record_shape(record, public_only, config)
569
+ def record_shape(record)
582
570
  all_key_type = AST::Types::Union.build(
583
571
  types: record.elements.each_key.map {|value| AST::Types::Literal.new(value: value, location: nil) },
584
572
  location: nil
@@ -586,13 +574,14 @@ module Steep
586
574
  all_value_type = AST::Types::Union.build(types: record.elements.values, location: nil)
587
575
  hash_type = AST::Builtin::Hash.instance_type(all_key_type, all_value_type)
588
576
 
589
- hash_shape = shape(hash_type, public_only: public_only, config: config.no_resolve) or raise
590
- shape = Shape.new(type: record, private: !public_only)
577
+ hash_shape = yield(hash_type) or raise
578
+ shape = Shape.new(type: record, private: true)
591
579
  shape.methods.merge!(hash_shape.methods)
592
580
 
593
581
  shape.methods[:[]] = hash_shape.methods[:[]].yield_self do |aref|
594
582
  aref or raise
595
583
  Shape::Entry.new(
584
+ private_method: false,
596
585
  method_types: record.elements.map do |key_value, value_type|
597
586
  key_type = AST::Types::Literal.new(value: key_value, location: nil)
598
587
 
@@ -614,6 +603,7 @@ module Steep
614
603
  update or raise
615
604
 
616
605
  Shape::Entry.new(
606
+ private_method: false,
617
607
  method_types: record.elements.map do |key_value, value_type|
618
608
  key_type = AST::Types::Literal.new(value: key_value, location: nil)
619
609
  MethodType.new(
@@ -633,6 +623,7 @@ module Steep
633
623
  update or raise
634
624
 
635
625
  Shape::Entry.new(
626
+ private_method: false,
636
627
  method_types: record.elements.flat_map {|key_value, value_type|
637
628
  key_type = AST::Types::Literal.new(value: key_value, location: nil)
638
629
 
@@ -680,34 +671,19 @@ module Steep
680
671
  )
681
672
  end
682
673
 
683
- shape.subst(
684
- Substitution.build(
685
- [], [],
686
- self_type: config.resolve_self ? record : AST::Types::Self.instance,
687
- instance_type: AST::Builtin::Hash.instance_type(fill_untyped: true),
688
- module_type: AST::Builtin::Hash.module_type
689
- )
690
- )
674
+ shape
691
675
  end
692
676
 
693
- def proc_shape(proc, public_only, config)
694
- proc_shape = shape(AST::Builtin::Proc.instance_type, public_only: public_only, config: config.no_resolve) or raise
695
-
696
- shape = Shape.new(type: proc, private: !public_only)
677
+ def proc_shape(proc, proc_shape)
678
+ shape = Shape.new(type: proc, private: true)
697
679
  shape.methods.merge!(proc_shape.methods)
698
680
 
699
681
  shape.methods[:[]] = shape.methods[:call] = Shape::Entry.new(
682
+ private_method: false,
700
683
  method_types: [MethodType.new(type_params: [], type: proc.type, block: proc.block, method_decls: Set[])]
701
684
  )
702
685
 
703
- shape.subst(
704
- Substitution.build(
705
- [], [],
706
- self_type: config.resolve_self ? proc : AST::Types::Self.instance,
707
- instance_type: AST::Builtin::Proc.instance_type(fill_untyped: true),
708
- module_type: AST::Builtin::Proc.module_type
709
- )
710
- )
686
+ shape
711
687
  end
712
688
 
713
689
  def replace_primitive_method(method_name, method_def, method_type)