steep 1.7.0.dev.1 → 1.7.0.dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +13 -15
  3. data/Rakefile +5 -0
  4. data/gemfile_steep/Gemfile +1 -1
  5. data/gemfile_steep/Gemfile.lock +11 -13
  6. data/lib/steep/ast/types/helper.rb +4 -0
  7. data/lib/steep/ast/types/intersection.rb +7 -0
  8. data/lib/steep/ast/types/record.rb +7 -0
  9. data/lib/steep/ast/types/tuple.rb +7 -0
  10. data/lib/steep/ast/types/union.rb +7 -0
  11. data/lib/steep/drivers/stats.rb +2 -2
  12. data/lib/steep/drivers/validate.rb +4 -2
  13. data/lib/steep/expectations.rb +2 -2
  14. data/lib/steep/interface/builder.rb +336 -360
  15. data/lib/steep/interface/function.rb +69 -6
  16. data/lib/steep/interface/method_type.rb +3 -3
  17. data/lib/steep/interface/shape.rb +69 -18
  18. data/lib/steep/interface/substitution.rb +4 -0
  19. data/lib/steep/node_helper.rb +18 -1
  20. data/lib/steep/services/completion_provider.rb +19 -17
  21. data/lib/steep/services/signature_help_provider.rb +19 -20
  22. data/lib/steep/subtyping/check.rb +10 -16
  23. data/lib/steep/subtyping/result.rb +6 -0
  24. data/lib/steep/test.rb +9 -0
  25. data/lib/steep/type_construction.rb +13 -13
  26. data/lib/steep/type_inference/block_params.rb +11 -3
  27. data/lib/steep/type_inference/context.rb +1 -1
  28. data/lib/steep/type_inference/logic_type_interpreter.rb +1 -1
  29. data/lib/steep/version.rb +1 -1
  30. data/lib/steep.rb +11 -7
  31. data/sig/steep/ast/types/helper.rbs +2 -0
  32. data/sig/steep/ast/types/intersection.rbs +2 -0
  33. data/sig/steep/ast/types/name.rbs +4 -0
  34. data/sig/steep/ast/types/record.rbs +2 -0
  35. data/sig/steep/ast/types/tuple.rbs +2 -0
  36. data/sig/steep/ast/types/union.rbs +2 -0
  37. data/sig/steep/expectations.rbs +1 -1
  38. data/sig/steep/interface/block.rbs +2 -2
  39. data/sig/steep/interface/builder.rbs +94 -108
  40. data/sig/steep/interface/function.rbs +34 -29
  41. data/sig/steep/interface/shape.rbs +23 -4
  42. data/sig/steep/interface/substitution.rbs +2 -0
  43. data/sig/steep/node_helper.rbs +11 -0
  44. data/sig/steep/services/signature_help_provider.rbs +2 -0
  45. data/sig/steep/subtyping/check.rbs +2 -0
  46. data/sig/steep/subtyping/constraints.rbs +2 -2
  47. data/sig/steep/subtyping/result.rbs +5 -1
  48. data/sig/steep/type_construction.rbs +1 -1
  49. data/sig/steep/type_inference/block_params.rbs +2 -2
  50. data/sig/steep/type_inference/context.rbs +2 -0
  51. data/sig/steep.rbs +1 -1
  52. metadata +3 -3
  53. data/sig/steep/type_inference/branch.rbs +0 -15
@@ -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)