steep 1.7.0.dev.2 → 1.7.0.dev.4

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