steep-relaxed 1.9.3.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 (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGELOG.md +1032 -0
  5. data/LICENSE +21 -0
  6. data/README.md +260 -0
  7. data/Rakefile +227 -0
  8. data/STDGEM_DEPENDENCIES.txt +59 -0
  9. data/Steepfile +68 -0
  10. data/bin/console +14 -0
  11. data/bin/generate-diagnostics-docs.rb +112 -0
  12. data/bin/mem_graph.rb +67 -0
  13. data/bin/mem_prof.rb +102 -0
  14. data/bin/output_rebaseline.rb +34 -0
  15. data/bin/output_test.rb +60 -0
  16. data/bin/rbs +20 -0
  17. data/bin/rbs-inline +19 -0
  18. data/bin/setup +9 -0
  19. data/bin/stackprof_test.rb +19 -0
  20. data/bin/steep +19 -0
  21. data/bin/steep-check.rb +251 -0
  22. data/bin/steep-prof +16 -0
  23. data/doc/narrowing.md +195 -0
  24. data/doc/shape.md +194 -0
  25. data/exe/steep +18 -0
  26. data/guides/README.md +5 -0
  27. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  28. data/guides/src/getting-started/getting-started.md +163 -0
  29. data/guides/src/nil-optional/nil-optional.md +195 -0
  30. data/lib/steep/annotation_parser.rb +199 -0
  31. data/lib/steep/ast/annotation/collection.rb +172 -0
  32. data/lib/steep/ast/annotation.rb +137 -0
  33. data/lib/steep/ast/builtin.rb +104 -0
  34. data/lib/steep/ast/ignore.rb +148 -0
  35. data/lib/steep/ast/node/type_application.rb +88 -0
  36. data/lib/steep/ast/node/type_assertion.rb +81 -0
  37. data/lib/steep/ast/types/any.rb +35 -0
  38. data/lib/steep/ast/types/boolean.rb +45 -0
  39. data/lib/steep/ast/types/bot.rb +35 -0
  40. data/lib/steep/ast/types/class.rb +43 -0
  41. data/lib/steep/ast/types/factory.rb +557 -0
  42. data/lib/steep/ast/types/helper.rb +40 -0
  43. data/lib/steep/ast/types/instance.rb +42 -0
  44. data/lib/steep/ast/types/intersection.rb +93 -0
  45. data/lib/steep/ast/types/literal.rb +59 -0
  46. data/lib/steep/ast/types/logic.rb +84 -0
  47. data/lib/steep/ast/types/name.rb +128 -0
  48. data/lib/steep/ast/types/nil.rb +41 -0
  49. data/lib/steep/ast/types/proc.rb +117 -0
  50. data/lib/steep/ast/types/record.rb +79 -0
  51. data/lib/steep/ast/types/self.rb +43 -0
  52. data/lib/steep/ast/types/shared_instance.rb +11 -0
  53. data/lib/steep/ast/types/top.rb +35 -0
  54. data/lib/steep/ast/types/tuple.rb +60 -0
  55. data/lib/steep/ast/types/union.rb +97 -0
  56. data/lib/steep/ast/types/var.rb +65 -0
  57. data/lib/steep/ast/types/void.rb +35 -0
  58. data/lib/steep/cli.rb +401 -0
  59. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  60. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  61. data/lib/steep/diagnostic/helper.rb +18 -0
  62. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  63. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  64. data/lib/steep/diagnostic/ruby.rb +1221 -0
  65. data/lib/steep/diagnostic/signature.rb +570 -0
  66. data/lib/steep/drivers/annotations.rb +52 -0
  67. data/lib/steep/drivers/check.rb +339 -0
  68. data/lib/steep/drivers/checkfile.rb +210 -0
  69. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  70. data/lib/steep/drivers/init.rb +66 -0
  71. data/lib/steep/drivers/langserver.rb +56 -0
  72. data/lib/steep/drivers/print_project.rb +113 -0
  73. data/lib/steep/drivers/stats.rb +203 -0
  74. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  75. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  76. data/lib/steep/drivers/vendor.rb +27 -0
  77. data/lib/steep/drivers/watch.rb +194 -0
  78. data/lib/steep/drivers/worker.rb +58 -0
  79. data/lib/steep/equatable.rb +23 -0
  80. data/lib/steep/expectations.rb +228 -0
  81. data/lib/steep/index/rbs_index.rb +350 -0
  82. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  83. data/lib/steep/index/source_index.rb +167 -0
  84. data/lib/steep/interface/block.rb +103 -0
  85. data/lib/steep/interface/builder.rb +843 -0
  86. data/lib/steep/interface/function.rb +1090 -0
  87. data/lib/steep/interface/method_type.rb +330 -0
  88. data/lib/steep/interface/shape.rb +239 -0
  89. data/lib/steep/interface/substitution.rb +159 -0
  90. data/lib/steep/interface/type_param.rb +115 -0
  91. data/lib/steep/located_value.rb +20 -0
  92. data/lib/steep/method_name.rb +42 -0
  93. data/lib/steep/module_helper.rb +24 -0
  94. data/lib/steep/node_helper.rb +273 -0
  95. data/lib/steep/path_helper.rb +30 -0
  96. data/lib/steep/project/dsl.rb +268 -0
  97. data/lib/steep/project/group.rb +31 -0
  98. data/lib/steep/project/options.rb +63 -0
  99. data/lib/steep/project/pattern.rb +59 -0
  100. data/lib/steep/project/target.rb +92 -0
  101. data/lib/steep/project.rb +78 -0
  102. data/lib/steep/rake_task.rb +132 -0
  103. data/lib/steep/range_extension.rb +29 -0
  104. data/lib/steep/server/base_worker.rb +97 -0
  105. data/lib/steep/server/change_buffer.rb +73 -0
  106. data/lib/steep/server/custom_methods.rb +77 -0
  107. data/lib/steep/server/delay_queue.rb +45 -0
  108. data/lib/steep/server/interaction_worker.rb +492 -0
  109. data/lib/steep/server/lsp_formatter.rb +455 -0
  110. data/lib/steep/server/master.rb +922 -0
  111. data/lib/steep/server/target_group_files.rb +205 -0
  112. data/lib/steep/server/type_check_controller.rb +366 -0
  113. data/lib/steep/server/type_check_worker.rb +303 -0
  114. data/lib/steep/server/work_done_progress.rb +64 -0
  115. data/lib/steep/server/worker_process.rb +176 -0
  116. data/lib/steep/services/completion_provider.rb +802 -0
  117. data/lib/steep/services/content_change.rb +61 -0
  118. data/lib/steep/services/file_loader.rb +74 -0
  119. data/lib/steep/services/goto_service.rb +441 -0
  120. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  121. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  122. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  123. data/lib/steep/services/path_assignment.rb +46 -0
  124. data/lib/steep/services/signature_help_provider.rb +202 -0
  125. data/lib/steep/services/signature_service.rb +428 -0
  126. data/lib/steep/services/stats_calculator.rb +68 -0
  127. data/lib/steep/services/type_check_service.rb +394 -0
  128. data/lib/steep/services/type_name_completion.rb +236 -0
  129. data/lib/steep/signature/validator.rb +651 -0
  130. data/lib/steep/source/ignore_ranges.rb +69 -0
  131. data/lib/steep/source.rb +691 -0
  132. data/lib/steep/subtyping/cache.rb +30 -0
  133. data/lib/steep/subtyping/check.rb +1113 -0
  134. data/lib/steep/subtyping/constraints.rb +341 -0
  135. data/lib/steep/subtyping/relation.rb +101 -0
  136. data/lib/steep/subtyping/result.rb +324 -0
  137. data/lib/steep/subtyping/variable_variance.rb +89 -0
  138. data/lib/steep/test.rb +9 -0
  139. data/lib/steep/thread_waiter.rb +43 -0
  140. data/lib/steep/type_construction.rb +5183 -0
  141. data/lib/steep/type_inference/block_params.rb +416 -0
  142. data/lib/steep/type_inference/case_when.rb +303 -0
  143. data/lib/steep/type_inference/constant_env.rb +56 -0
  144. data/lib/steep/type_inference/context.rb +195 -0
  145. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  146. data/lib/steep/type_inference/method_call.rb +193 -0
  147. data/lib/steep/type_inference/method_params.rb +531 -0
  148. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  149. data/lib/steep/type_inference/send_args.rb +712 -0
  150. data/lib/steep/type_inference/type_env.rb +341 -0
  151. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  152. data/lib/steep/typing.rb +321 -0
  153. data/lib/steep/version.rb +3 -0
  154. data/lib/steep.rb +369 -0
  155. data/manual/annotations.md +181 -0
  156. data/manual/ignore.md +20 -0
  157. data/manual/ruby-diagnostics.md +1879 -0
  158. data/sample/Steepfile +22 -0
  159. data/sample/lib/conference.rb +49 -0
  160. data/sample/lib/length.rb +35 -0
  161. data/sample/sig/conference.rbs +42 -0
  162. data/sample/sig/generics.rbs +15 -0
  163. data/sample/sig/length.rbs +34 -0
  164. data/steep-relaxed.gemspec +56 -0
  165. metadata +340 -0
@@ -0,0 +1,843 @@
1
+ module Steep
2
+ module Interface
3
+ class Builder
4
+ class Config
5
+ attr_reader :self_type, :class_type, :instance_type, :variable_bounds
6
+
7
+ def initialize(self_type:, class_type: nil, instance_type: nil, variable_bounds:)
8
+ @self_type = self_type
9
+ @class_type = class_type
10
+ @instance_type = instance_type
11
+ @variable_bounds = variable_bounds
12
+ end
13
+
14
+ def self.empty
15
+ new(self_type: nil, variable_bounds: {})
16
+ end
17
+
18
+ def subst
19
+ if self_type || class_type || instance_type
20
+ Substitution.build([], [], self_type: self_type, module_type: class_type, instance_type: instance_type)
21
+ end
22
+ end
23
+
24
+ def validate_self_type
25
+ validate_fvs(:self_type, self_type)
26
+ end
27
+
28
+ def validate_instance_type
29
+ validate_fvs(:instance_type, instance_type)
30
+ end
31
+
32
+ def validate_class_type
33
+ validate_fvs(:class_type, class_type)
34
+ end
35
+
36
+ def validate_fvs(name, type)
37
+ if type
38
+ fvs = type.free_variables
39
+ if fvs.include?(AST::Types::Self.instance)
40
+ raise "#{name} cannot include 'self' type: #{type}"
41
+ end
42
+ if fvs.include?(AST::Types::Instance.instance)
43
+ Steep.logger.fatal { "#{name} cannot include 'instance' type: #{type}" }
44
+ raise "#{name} cannot include 'instance' type: #{type}"
45
+ end
46
+ if fvs.include?(AST::Types::Class.instance)
47
+ raise "#{name} cannot include 'class' type: #{type}"
48
+ end
49
+ end
50
+ end
51
+
52
+ def upper_bound(a)
53
+ variable_bounds.fetch(a, nil)
54
+ end
55
+ end
56
+
57
+ attr_reader :factory, :object_shape_cache, :union_shape_cache, :singleton_shape_cache, :implicitly_returns_nil
58
+
59
+ def initialize(factory, implicitly_returns_nil:)
60
+ @factory = factory
61
+ @object_shape_cache = {}
62
+ @union_shape_cache = {}
63
+ @singleton_shape_cache = {}
64
+ @implicitly_returns_nil = implicitly_returns_nil
65
+ end
66
+
67
+ def shape(type, config)
68
+ Steep.logger.tagged "shape(#{type})" do
69
+ if shape = raw_shape(type, config)
70
+ # Optimization that skips unnecessary substitution
71
+ if type.free_variables.include?(AST::Types::Self.instance)
72
+ shape
73
+ else
74
+ if s = config.subst
75
+ shape.subst(s)
76
+ else
77
+ shape
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def fetch_cache(cache, key)
85
+ if cache.key?(key)
86
+ return cache.fetch(key)
87
+ end
88
+
89
+ cache[key] = yield
90
+ end
91
+
92
+ def raw_shape(type, config)
93
+ case type
94
+ when AST::Types::Self
95
+ config.validate_self_type
96
+ self_type = config.self_type or raise
97
+ self_shape(self_type, config)
98
+ when AST::Types::Instance
99
+ config.validate_instance_type
100
+ instance_type = config.instance_type or raise
101
+ raw_shape(instance_type, config)
102
+ when AST::Types::Class
103
+ config.validate_class_type
104
+ klass_type = config.class_type or raise
105
+ raw_shape(klass_type, config)
106
+ when AST::Types::Name::Singleton
107
+ singleton_shape(type.name).subst(class_subst(type))
108
+ when AST::Types::Name::Instance
109
+ object_shape(type.name).subst(class_subst(type).merge(app_subst(type)), type: type)
110
+ when AST::Types::Name::Interface
111
+ object_shape(type.name).subst(interface_subst(type).merge(app_subst(type)), type: type)
112
+ when AST::Types::Union
113
+ groups = type.types.group_by do |type|
114
+ if type.is_a?(AST::Types::Literal)
115
+ type.back_type
116
+ else
117
+ nil
118
+ end
119
+ end
120
+
121
+ shapes = [] #: Array[Shape]
122
+ groups.each do |name, types|
123
+ if name
124
+ union = AST::Types::Union.build(types: types)
125
+ subst = class_subst(name).update(self_type: union)
126
+ shapes << object_shape(name.name).subst(subst, type: union)
127
+ else
128
+ shapes.concat(types.map {|ty| raw_shape(ty, config) or return })
129
+ end
130
+ end
131
+
132
+ fetch_cache(union_shape_cache, type) do
133
+ union_shape(type, shapes)
134
+ end
135
+ when AST::Types::Intersection
136
+ shapes = type.types.map do |type|
137
+ raw_shape(type, config) or return
138
+ end
139
+ intersection_shape(type, shapes)
140
+ when AST::Types::Name::Alias
141
+ expanded = factory.expand_alias(type)
142
+ if shape = raw_shape(expanded, config)
143
+ shape.update(type: type)
144
+ end
145
+ when AST::Types::Literal
146
+ instance_type = type.back_type
147
+ subst = class_subst(instance_type).update(self_type: type)
148
+ object_shape(instance_type.name).subst(subst, type: type)
149
+ when AST::Types::Boolean
150
+ true_shape =
151
+ (object_shape(RBS::BuiltinNames::TrueClass.name)).
152
+ subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: type))
153
+ false_shape =
154
+ (object_shape(RBS::BuiltinNames::FalseClass.name)).
155
+ subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: type))
156
+ union_shape(type, [true_shape, false_shape])
157
+ when AST::Types::Proc
158
+ shape = object_shape(AST::Builtin::Proc.module_name).subst(class_subst(AST::Builtin::Proc.instance_type).update(self_type: type))
159
+ proc_shape(type, shape)
160
+ when AST::Types::Tuple
161
+ tuple_shape(type) do |array|
162
+ object_shape(array.name).subst(
163
+ class_subst(array).update(self_type: type).merge(app_subst(array))
164
+ )
165
+ end
166
+ when AST::Types::Record
167
+ record_shape(type) do |hash|
168
+ object_shape(hash.name).subst(
169
+ class_subst(hash).update(self_type: type).merge(app_subst(hash))
170
+ )
171
+ end
172
+ when AST::Types::Var
173
+ if bound = config.upper_bound(type.name)
174
+ new_config = Config.new(self_type: bound, variable_bounds: config.variable_bounds)
175
+ sub = Substitution.build([], self_type: type)
176
+ # We have to use `self_shape` instead of `raw_shape` here.
177
+ # Keep the `self` types included in the `bound`'s shape, and replace it to the type variable.
178
+ self_shape(bound, new_config)&.subst(sub, type: type)
179
+ end
180
+ when AST::Types::Nil
181
+ subst = class_subst(AST::Builtin::NilClass.instance_type).update(self_type: type)
182
+ object_shape(AST::Builtin::NilClass.module_name).subst(subst, type: type)
183
+ when AST::Types::Logic::Base
184
+ true_shape =
185
+ (object_shape(RBS::BuiltinNames::TrueClass.name)).
186
+ subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: type))
187
+ false_shape =
188
+ (object_shape(RBS::BuiltinNames::FalseClass.name)).
189
+ subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: type))
190
+ union_shape(type, [true_shape, false_shape])
191
+ else
192
+ nil
193
+ end
194
+ end
195
+
196
+ def self_shape(type, config)
197
+ case type
198
+ when AST::Types::Self, AST::Types::Instance, AST::Types::Class
199
+ raise
200
+ when AST::Types::Name::Singleton
201
+ singleton_shape(type.name).subst(class_subst(type).update(self_type: nil))
202
+ when AST::Types::Name::Instance
203
+ object_shape(type.name)
204
+ .subst(
205
+ class_subst(type).update(self_type: nil).merge(app_subst(type)),
206
+ type: type
207
+ )
208
+ when AST::Types::Name::Interface
209
+ object_shape(type.name).subst(app_subst(type), type: type)
210
+ when AST::Types::Literal
211
+ instance_type = type.back_type
212
+ subst = class_subst(instance_type).update(self_type: nil)
213
+ object_shape(instance_type.name).subst(subst, type: type)
214
+ when AST::Types::Boolean
215
+ true_shape =
216
+ (object_shape(RBS::BuiltinNames::TrueClass.name)).
217
+ subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: nil))
218
+ false_shape =
219
+ (object_shape(RBS::BuiltinNames::FalseClass.name)).
220
+ subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: nil))
221
+ union_shape(type, [true_shape, false_shape])
222
+ when AST::Types::Proc
223
+ shape = object_shape(AST::Builtin::Proc.module_name).subst(class_subst(AST::Builtin::Proc.instance_type).update(self_type: nil))
224
+ proc_shape(type, shape)
225
+ when AST::Types::Var
226
+ if bound = config.upper_bound(type.name)
227
+ self_shape(bound, config)&.update(type: type)
228
+ end
229
+ else
230
+ raw_shape(type, config)
231
+ end
232
+ end
233
+
234
+ def app_subst(type)
235
+ if type.args.empty?
236
+ return Substitution.empty
237
+ end
238
+
239
+ vars =
240
+ case type
241
+ when AST::Types::Name::Instance
242
+ entry = factory.env.normalized_module_class_entry(type.name) or raise
243
+ entry.primary.decl.type_params.map { _1.name }
244
+ when AST::Types::Name::Interface
245
+ entry = factory.env.interface_decls.fetch(type.name)
246
+ entry.decl.type_params.map { _1.name }
247
+ when AST::Types::Name::Alias
248
+ entry = factory.env.type_alias_decls.fetch(type.name)
249
+ entry.decl.type_params.map { _1.name }
250
+ end
251
+
252
+ Substitution.build(vars, type.args)
253
+ end
254
+
255
+ def class_subst(type)
256
+ case type
257
+ when AST::Types::Name::Singleton
258
+ self_type = type
259
+ singleton_type = type
260
+ instance_type = factory.instance_type(type.name)
261
+ when AST::Types::Name::Instance
262
+ self_type = type
263
+ singleton_type = type.to_module
264
+ instance_type = factory.instance_type(type.name)
265
+ end
266
+
267
+ Substitution.build([], self_type: self_type, module_type: singleton_type, instance_type: instance_type)
268
+ end
269
+
270
+ def interface_subst(type)
271
+ Substitution.build([], self_type: type)
272
+ end
273
+
274
+ def singleton_shape(type_name)
275
+ singleton_shape_cache[type_name] ||= begin
276
+ shape = Interface::Shape.new(type: AST::Types::Name::Singleton.new(name: type_name), private: true)
277
+ definition = factory.definition_builder.build_singleton(type_name)
278
+
279
+ definition.methods.each do |name, method|
280
+ Steep.logger.tagged "method = #{type_name}.#{name}" do
281
+ overloads = method.defs.map do |type_def|
282
+ method_name = method_name_for(type_def, name)
283
+ method_type = factory.method_type(type_def.type)
284
+ method_type = replace_primitive_method(method_name, type_def, method_type)
285
+ method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Builtin::Class.instance_type }
286
+ method_type = add_implicitly_returns_nil(type_def.annotations, method_type)
287
+ Shape::MethodOverload.new(method_type, [type_def])
288
+ end
289
+
290
+ shape.methods[name] = Interface::Shape::Entry.new(method_name: name, private_method: method.private?, overloads: overloads)
291
+ end
292
+ end
293
+
294
+ shape
295
+ end
296
+ end
297
+
298
+ def object_shape(type_name)
299
+ object_shape_cache[type_name] ||= begin
300
+ shape = Interface::Shape.new(type: AST::Builtin.bottom_type, private: true)
301
+
302
+ case
303
+ when type_name.class?
304
+ definition = factory.definition_builder.build_instance(type_name)
305
+ when type_name.interface?
306
+ definition = factory.definition_builder.build_interface(type_name)
307
+ end
308
+
309
+ definition or raise
310
+
311
+ definition.methods.each do |name, method|
312
+ Steep.logger.tagged "method = #{type_name}##{name}" do
313
+ overloads = method.defs.map do |type_def|
314
+ method_name = method_name_for(type_def, name)
315
+ method_type = factory.method_type(type_def.type)
316
+ method_type = replace_primitive_method(method_name, type_def, method_type)
317
+ if type_name.class?
318
+ method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Types::Name::Singleton.new(name: type_name) }
319
+ end
320
+ method_type = add_implicitly_returns_nil(type_def.annotations, method_type)
321
+ Shape::MethodOverload.new(method_type, [type_def])
322
+ end
323
+
324
+ shape.methods[name] = Interface::Shape::Entry.new(method_name: name, private_method: method.private?, overloads: overloads)
325
+ end
326
+ end
327
+
328
+ shape
329
+ end
330
+ end
331
+
332
+ def union_shape(shape_type, shapes)
333
+ s0, *sx = shapes
334
+ s0 or raise
335
+ all_common_methods = Set.new(s0.methods.each_name)
336
+ sx.each do |shape|
337
+ all_common_methods &= shape.methods.each_name
338
+ end
339
+
340
+ shape = Interface::Shape.new(type: shape_type, private: true)
341
+ all_common_methods.each do |method_name|
342
+ overloadss = [] #: Array[Array[Shape::MethodOverload]]
343
+ private_method = false
344
+ shapes.each do |shape|
345
+ entry = shape.methods[method_name] || raise
346
+ overloadss << entry.overloads
347
+ private_method ||= entry.private_method?
348
+ end
349
+
350
+ shape.methods[method_name] = Interface::Shape::Entry.new(method_name: method_name, private_method: private_method) do
351
+ overloadss.inject do |overloads1, overloads2|
352
+ # @type break: nil
353
+
354
+ types1 = overloads1.map(&:method_type)
355
+ types2 = overloads2.map(&:method_type)
356
+
357
+ if types1 == types2
358
+ defs1 = overloads1.flat_map(&:method_defs)
359
+ defs2 = overloads2.flat_map(&:method_defs)
360
+
361
+ if defs1 == defs2
362
+ next overloads1
363
+ end
364
+ end
365
+
366
+ method_overloads = {} #: Hash[Shape::MethodOverload, bool]
367
+
368
+ overloads1.each do |overload1|
369
+ overloads2.each do |overload2|
370
+ if overload1.method_type == overload2.method_type
371
+ overload = Shape::MethodOverload.new(overload1.method_type, overload1.method_defs + overload2.method_defs)
372
+ method_overloads[overload] = true
373
+ else
374
+ if type = MethodType.union(overload1.method_type, overload2.method_type, subtyping)
375
+ overload = Shape::MethodOverload.new(type, overload1.method_defs + overload2.method_defs)
376
+ method_overloads[overload] = true
377
+ end
378
+ end
379
+ end
380
+ end
381
+
382
+ break nil if method_overloads.empty?
383
+
384
+ method_overloads.keys
385
+ end
386
+ end
387
+ end
388
+
389
+ shape
390
+ end
391
+
392
+ def intersection_shape(type, shapes)
393
+ shape = Interface::Shape.new(type: type, private: true)
394
+
395
+ shapes.each do |s|
396
+ shape.methods.merge!(s.methods) do |name, old_entry, new_entry|
397
+ if old_entry.public_method? && new_entry.private_method?
398
+ old_entry
399
+ else
400
+ new_entry
401
+ end
402
+ end
403
+ end
404
+
405
+ shape
406
+ end
407
+
408
+ def method_name_for(type_def, name)
409
+ type_name = type_def.implemented_in || type_def.defined_in
410
+
411
+ if name == :new && type_def.member.is_a?(RBS::AST::Members::MethodDefinition) && type_def.member.name == :initialize
412
+ return SingletonMethodName.new(type_name: type_name, method_name: name)
413
+ end
414
+
415
+ case type_def.member.kind
416
+ when :instance
417
+ InstanceMethodName.new(type_name: type_name, method_name: name)
418
+ when :singleton
419
+ SingletonMethodName.new(type_name: type_name, method_name: name)
420
+ when :singleton_instance
421
+ # Assume it a instance method, because `module_function` methods are typically defined with `def`
422
+ InstanceMethodName.new(type_name: type_name, method_name: name)
423
+ else
424
+ raise
425
+ end
426
+ end
427
+
428
+ def subtyping
429
+ @subtyping ||= Subtyping::Check.new(builder: self)
430
+ end
431
+
432
+ def tuple_shape(tuple)
433
+ element_type = AST::Types::Union.build(types: tuple.types)
434
+ array_type = AST::Builtin::Array.instance_type(element_type)
435
+
436
+ array_shape = yield(array_type) or raise
437
+ shape = Shape.new(type: tuple, private: true)
438
+ shape.methods.merge!(array_shape.methods)
439
+
440
+ aref_entry = array_shape.methods[:[]].yield_self do |aref|
441
+ raise unless aref
442
+
443
+ Shape::Entry.new(
444
+ method_name: :[],
445
+ private_method: false,
446
+ overloads: tuple.types.map.with_index {|elem_type, index|
447
+ Shape::MethodOverload.new(
448
+ MethodType.new(
449
+ type_params: [],
450
+ type: Function.new(
451
+ params: Function::Params.build(required: [AST::Types::Literal.new(value: index)]),
452
+ return_type: elem_type,
453
+ location: nil
454
+ ),
455
+ block: nil
456
+ ),
457
+ []
458
+ )
459
+ } + aref.overloads
460
+ )
461
+ end
462
+
463
+ aref_update_entry = array_shape.methods[:[]=].yield_self do |update|
464
+ raise unless update
465
+
466
+ Shape::Entry.new(
467
+ method_name: :[]=,
468
+ private_method: false,
469
+ overloads: tuple.types.map.with_index {|elem_type, index|
470
+ Shape::MethodOverload.new(
471
+ MethodType.new(
472
+ type_params: [],
473
+ type: Function.new(
474
+ params: Function::Params.build(required: [AST::Types::Literal.new(value: index), elem_type]),
475
+ return_type: elem_type,
476
+ location: nil
477
+ ),
478
+ block: nil
479
+ ),
480
+ []
481
+ )
482
+ } + update.overloads
483
+ )
484
+ end
485
+
486
+ fetch_entry = array_shape.methods[:fetch].yield_self do |fetch|
487
+ raise unless fetch
488
+
489
+ Shape::Entry.new(
490
+ method_name: :fetch,
491
+ private_method: false,
492
+ overloads: tuple.types.flat_map.with_index {|elem_type, index|
493
+ [
494
+ MethodType.new(
495
+ type_params: [],
496
+ type: Function.new(
497
+ params: Function::Params.build(required: [AST::Types::Literal.new(value: index)]),
498
+ return_type: elem_type,
499
+ location: nil
500
+ ),
501
+ block: nil
502
+ ),
503
+ MethodType.new(
504
+ type_params: [TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false, default_type: nil)],
505
+ type: Function.new(
506
+ params: Function::Params.build(
507
+ required: [
508
+ AST::Types::Literal.new(value: index),
509
+ AST::Types::Var.new(name: :T)
510
+ ]
511
+ ),
512
+ return_type: AST::Types::Union.build(types: [elem_type, AST::Types::Var.new(name: :T)]),
513
+ location: nil
514
+ ),
515
+ block: nil
516
+ ),
517
+ MethodType.new(
518
+ type_params: [TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false, default_type: nil)],
519
+ type: Function.new(
520
+ params: Function::Params.build(required: [AST::Types::Literal.new(value: index)]),
521
+ return_type: AST::Types::Union.build(types: [elem_type, AST::Types::Var.new(name: :T)]),
522
+ location: nil
523
+ ),
524
+ block: Block.new(
525
+ type: Function.new(
526
+ params: Function::Params.build(required: [AST::Builtin::Integer.instance_type]),
527
+ return_type: AST::Types::Var.new(name: :T),
528
+ location: nil
529
+ ),
530
+ optional: false,
531
+ self_type: nil
532
+ )
533
+ )
534
+ ].map { Shape::MethodOverload.new(_1, []) }
535
+ } + fetch.overloads
536
+ )
537
+ end
538
+
539
+ first_entry = array_shape.methods[:first].yield_self do |first|
540
+ Shape::Entry.new(
541
+ method_name: :first,
542
+ private_method: false,
543
+ overloads: [
544
+ Shape::MethodOverload.new(
545
+ MethodType.new(
546
+ type_params: [],
547
+ type: Function.new(
548
+ params: Function::Params.empty,
549
+ return_type: tuple.types[0] || AST::Builtin.nil_type,
550
+ location: nil
551
+ ),
552
+ block: nil
553
+ ),
554
+ []
555
+ )
556
+ ]
557
+ )
558
+ end
559
+
560
+ last_entry = array_shape.methods[:last].yield_self do |last|
561
+ Shape::Entry.new(
562
+ method_name: :last,
563
+ private_method: false,
564
+ overloads: [
565
+ Shape::MethodOverload.new(
566
+ MethodType.new(
567
+ type_params: [],
568
+ type: Function.new(
569
+ params: Function::Params.empty,
570
+ return_type: tuple.types.last || AST::Builtin.nil_type,
571
+ location: nil
572
+ ),
573
+ block: nil
574
+ ),
575
+ []
576
+ )
577
+ ]
578
+ )
579
+ end
580
+
581
+ shape.methods[:[]] = aref_entry
582
+ shape.methods[:[]=] = aref_update_entry
583
+ shape.methods[:fetch] = fetch_entry
584
+ shape.methods[:first] = first_entry
585
+ shape.methods[:last] = last_entry
586
+
587
+ shape
588
+ end
589
+
590
+ def record_shape(record)
591
+ all_key_type = AST::Types::Union.build(
592
+ types: record.elements.each_key.map {|value| AST::Types::Literal.new(value: value).back_type }
593
+ )
594
+ all_value_type = AST::Types::Union.build(types: record.elements.values)
595
+ hash_type = AST::Builtin::Hash.instance_type(all_key_type, all_value_type)
596
+
597
+ hash_shape = yield(hash_type) or raise
598
+ shape = Shape.new(type: record, private: true)
599
+ shape.methods.merge!(hash_shape.methods)
600
+
601
+ shape.methods[:[]] = hash_shape.methods[:[]].yield_self do |aref|
602
+ aref or raise
603
+ Shape::Entry.new(
604
+ method_name: :[],
605
+ private_method: false,
606
+ overloads: record.elements.map do |key_value, value_type|
607
+ key_type = AST::Types::Literal.new(value: key_value)
608
+
609
+ if record.optional?(key_value)
610
+ value_type = AST::Builtin.optional(value_type)
611
+ end
612
+
613
+ Shape::MethodOverload.new(
614
+ MethodType.new(
615
+ type_params: [],
616
+ type: Function.new(
617
+ params: Function::Params.build(required: [key_type]),
618
+ return_type: value_type,
619
+ location: nil
620
+ ),
621
+ block: nil
622
+ ),
623
+ []
624
+ )
625
+ end + aref.overloads
626
+ )
627
+ end
628
+
629
+ shape.methods[:[]=] = hash_shape.methods[:[]=].yield_self do |update|
630
+ update or raise
631
+
632
+ Shape::Entry.new(
633
+ method_name: :[]=,
634
+ private_method: false,
635
+ overloads: record.elements.map do |key_value, value_type|
636
+ key_type = AST::Types::Literal.new(value: key_value)
637
+ Shape::MethodOverload.new(
638
+ MethodType.new(
639
+ type_params: [],
640
+ type: Function.new(
641
+ params: Function::Params.build(required: [key_type, value_type]),
642
+ return_type: value_type,
643
+ location: nil),
644
+ block: nil
645
+ ),
646
+ []
647
+ )
648
+ end + update.overloads
649
+ )
650
+ end
651
+
652
+ shape.methods[:fetch] = hash_shape.methods[:fetch].yield_self do |update|
653
+ update or raise
654
+
655
+ Shape::Entry.new(
656
+ method_name: :fetch,
657
+ private_method: false,
658
+ overloads: record.elements.flat_map {|key_value, value_type|
659
+ key_type = AST::Types::Literal.new(value: key_value)
660
+
661
+ [
662
+ MethodType.new(
663
+ type_params: [],
664
+ type: Function.new(
665
+ params: Function::Params.build(required: [key_type]),
666
+ return_type: value_type,
667
+ location: nil
668
+ ),
669
+ block: nil
670
+ ),
671
+ MethodType.new(
672
+ type_params: [TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false, default_type: nil)],
673
+ type: Function.new(
674
+ params: Function::Params.build(required: [key_type, AST::Types::Var.new(name: :T)]),
675
+ return_type: AST::Types::Union.build(types: [value_type, AST::Types::Var.new(name: :T)]),
676
+ location: nil
677
+ ),
678
+ block: nil
679
+ ),
680
+ MethodType.new(
681
+ type_params: [TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false, default_type: nil)],
682
+ type: Function.new(
683
+ params: Function::Params.build(required: [key_type]),
684
+ return_type: AST::Types::Union.build(types: [value_type, AST::Types::Var.new(name: :T)]),
685
+ location: nil
686
+ ),
687
+ block: Block.new(
688
+ type: Function.new(
689
+ params: Function::Params.build(required: [all_key_type]),
690
+ return_type: AST::Types::Var.new(name: :T),
691
+ location: nil
692
+ ),
693
+ optional: false,
694
+ self_type: nil
695
+ )
696
+ )
697
+ ].map { Shape::MethodOverload.new(_1, []) }
698
+ } + update.overloads
699
+ )
700
+ end
701
+
702
+ shape
703
+ end
704
+
705
+ def proc_shape(proc, proc_shape)
706
+ shape = Shape.new(type: proc, private: true)
707
+ shape.methods.merge!(proc_shape.methods)
708
+
709
+ overload = Shape::MethodOverload.new(
710
+ MethodType.new(type_params: [], type: proc.type, block: proc.block),
711
+ []
712
+ )
713
+
714
+ shape.methods[:[]] = Shape::Entry.new(
715
+ method_name: :[],
716
+ private_method: false,
717
+ overloads: [overload]
718
+ )
719
+ shape.methods[:call] = Shape::Entry.new(
720
+ method_name: :call,
721
+ private_method: false,
722
+ overloads: [overload]
723
+ )
724
+
725
+ shape
726
+ end
727
+
728
+ def replace_primitive_method(method_name, method_def, method_type)
729
+ defined_in = method_def.defined_in
730
+ member = method_def.member
731
+
732
+ if member.is_a?(RBS::AST::Members::MethodDefinition)
733
+ case method_name.method_name
734
+ when :is_a?, :kind_of?, :instance_of?
735
+ case
736
+ when RBS::BuiltinNames::Object.name,
737
+ RBS::BuiltinNames::Kernel.name
738
+ if member.instance?
739
+ return method_type.with(
740
+ type: method_type.type.with(
741
+ return_type: AST::Types::Logic::ReceiverIsArg.instance()
742
+ )
743
+ )
744
+ end
745
+ end
746
+
747
+ when :nil?
748
+ case defined_in
749
+ when RBS::BuiltinNames::Object.name,
750
+ AST::Builtin::NilClass.module_name,
751
+ RBS::BuiltinNames::Kernel.name
752
+ if member.instance?
753
+ return method_type.with(
754
+ type: method_type.type.with(
755
+ return_type: AST::Types::Logic::ReceiverIsNil.instance()
756
+ )
757
+ )
758
+ end
759
+ end
760
+
761
+ when :!
762
+ case defined_in
763
+ when RBS::BuiltinNames::BasicObject.name,
764
+ RBS::BuiltinNames::TrueClass.name,
765
+ RBS::BuiltinNames::FalseClass.name,
766
+ AST::Builtin::NilClass.module_name
767
+ return method_type.with(
768
+ type: method_type.type.with(
769
+ return_type: AST::Types::Logic::Not.instance()
770
+ )
771
+ )
772
+ end
773
+
774
+ when :===
775
+ case defined_in
776
+ when RBS::BuiltinNames::Module.name
777
+ return method_type.with(
778
+ type: method_type.type.with(
779
+ return_type: AST::Types::Logic::ArgIsReceiver.instance()
780
+ )
781
+ )
782
+ when RBS::BuiltinNames::Object.name,
783
+ RBS::BuiltinNames::Kernel.name,
784
+ RBS::BuiltinNames::String.name,
785
+ RBS::BuiltinNames::Integer.name,
786
+ RBS::BuiltinNames::Symbol.name,
787
+ RBS::BuiltinNames::TrueClass.name,
788
+ RBS::BuiltinNames::FalseClass.name,
789
+ RBS::TypeName.parse("::NilClass")
790
+ # Value based type-case works on literal types which is available for String, Integer, Symbol, TrueClass, FalseClass, and NilClass
791
+ return method_type.with(
792
+ type: method_type.type.with(
793
+ return_type: AST::Types::Logic::ArgEqualsReceiver.instance()
794
+ )
795
+ )
796
+ end
797
+ when :<, :<=
798
+ case defined_in
799
+ when RBS::BuiltinNames::Module.name
800
+ return method_type.with(
801
+ type: method_type.type.with(
802
+ return_type: AST::Types::Logic::ArgIsAncestor.instance()
803
+ )
804
+ )
805
+ end
806
+ end
807
+ end
808
+
809
+ method_type
810
+ end
811
+
812
+ def replace_kernel_class(method_name, method_def, method_type)
813
+ defined_in = method_def.defined_in
814
+ member = method_def.member
815
+
816
+ if member.is_a?(RBS::AST::Members::MethodDefinition)
817
+ case method_name.method_name
818
+ when :class
819
+ case defined_in
820
+ when AST::Builtin::Kernel.module_name
821
+ return method_type.with(type: method_type.type.with(return_type: yield))
822
+ end
823
+ end
824
+ end
825
+
826
+ method_type
827
+ end
828
+
829
+ def add_implicitly_returns_nil(annotations, method_type)
830
+ return method_type unless implicitly_returns_nil
831
+
832
+ if annotations.find { _1.string == "implicitly-returns-nil" }
833
+ return_type = method_type.type.return_type
834
+ method_type = method_type.with(
835
+ type: method_type.type.with(return_type: AST::Types::Union.build(types: [return_type, AST::Builtin.nil_type]))
836
+ )
837
+ else
838
+ method_type
839
+ end
840
+ end
841
+ end
842
+ end
843
+ end