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

Sign up to get free protection for your applications and to get access to all the features.
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)