steep-activesupport-4 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) 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/Steepfile +68 -0
  9. data/bin/console +14 -0
  10. data/bin/generate-diagnostics-docs.rb +112 -0
  11. data/bin/mem_graph.rb +67 -0
  12. data/bin/mem_prof.rb +102 -0
  13. data/bin/output_rebaseline.rb +34 -0
  14. data/bin/output_test.rb +60 -0
  15. data/bin/rbs +20 -0
  16. data/bin/rbs-inline +19 -0
  17. data/bin/setup +9 -0
  18. data/bin/stackprof_test.rb +19 -0
  19. data/bin/steep +19 -0
  20. data/bin/steep-check.rb +251 -0
  21. data/bin/steep-prof +16 -0
  22. data/doc/narrowing.md +195 -0
  23. data/doc/shape.md +194 -0
  24. data/exe/steep +18 -0
  25. data/guides/README.md +5 -0
  26. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  27. data/guides/src/getting-started/getting-started.md +163 -0
  28. data/guides/src/nil-optional/nil-optional.md +195 -0
  29. data/lib/steep/annotation_parser.rb +199 -0
  30. data/lib/steep/ast/annotation/collection.rb +172 -0
  31. data/lib/steep/ast/annotation.rb +137 -0
  32. data/lib/steep/ast/builtin.rb +104 -0
  33. data/lib/steep/ast/ignore.rb +148 -0
  34. data/lib/steep/ast/node/type_application.rb +88 -0
  35. data/lib/steep/ast/node/type_assertion.rb +81 -0
  36. data/lib/steep/ast/types/any.rb +35 -0
  37. data/lib/steep/ast/types/boolean.rb +45 -0
  38. data/lib/steep/ast/types/bot.rb +35 -0
  39. data/lib/steep/ast/types/class.rb +43 -0
  40. data/lib/steep/ast/types/factory.rb +557 -0
  41. data/lib/steep/ast/types/helper.rb +40 -0
  42. data/lib/steep/ast/types/instance.rb +42 -0
  43. data/lib/steep/ast/types/intersection.rb +93 -0
  44. data/lib/steep/ast/types/literal.rb +59 -0
  45. data/lib/steep/ast/types/logic.rb +84 -0
  46. data/lib/steep/ast/types/name.rb +128 -0
  47. data/lib/steep/ast/types/nil.rb +41 -0
  48. data/lib/steep/ast/types/proc.rb +117 -0
  49. data/lib/steep/ast/types/record.rb +79 -0
  50. data/lib/steep/ast/types/self.rb +43 -0
  51. data/lib/steep/ast/types/shared_instance.rb +11 -0
  52. data/lib/steep/ast/types/top.rb +35 -0
  53. data/lib/steep/ast/types/tuple.rb +60 -0
  54. data/lib/steep/ast/types/union.rb +97 -0
  55. data/lib/steep/ast/types/var.rb +65 -0
  56. data/lib/steep/ast/types/void.rb +35 -0
  57. data/lib/steep/cli.rb +401 -0
  58. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  59. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  60. data/lib/steep/diagnostic/helper.rb +18 -0
  61. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  62. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  63. data/lib/steep/diagnostic/ruby.rb +1221 -0
  64. data/lib/steep/diagnostic/signature.rb +570 -0
  65. data/lib/steep/drivers/annotations.rb +52 -0
  66. data/lib/steep/drivers/check.rb +339 -0
  67. data/lib/steep/drivers/checkfile.rb +210 -0
  68. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  69. data/lib/steep/drivers/init.rb +66 -0
  70. data/lib/steep/drivers/langserver.rb +56 -0
  71. data/lib/steep/drivers/print_project.rb +113 -0
  72. data/lib/steep/drivers/stats.rb +203 -0
  73. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  74. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  75. data/lib/steep/drivers/vendor.rb +27 -0
  76. data/lib/steep/drivers/watch.rb +194 -0
  77. data/lib/steep/drivers/worker.rb +58 -0
  78. data/lib/steep/equatable.rb +23 -0
  79. data/lib/steep/expectations.rb +228 -0
  80. data/lib/steep/index/rbs_index.rb +350 -0
  81. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  82. data/lib/steep/index/source_index.rb +167 -0
  83. data/lib/steep/interface/block.rb +103 -0
  84. data/lib/steep/interface/builder.rb +843 -0
  85. data/lib/steep/interface/function.rb +1090 -0
  86. data/lib/steep/interface/method_type.rb +330 -0
  87. data/lib/steep/interface/shape.rb +239 -0
  88. data/lib/steep/interface/substitution.rb +159 -0
  89. data/lib/steep/interface/type_param.rb +115 -0
  90. data/lib/steep/located_value.rb +20 -0
  91. data/lib/steep/method_name.rb +42 -0
  92. data/lib/steep/module_helper.rb +24 -0
  93. data/lib/steep/node_helper.rb +273 -0
  94. data/lib/steep/path_helper.rb +30 -0
  95. data/lib/steep/project/dsl.rb +268 -0
  96. data/lib/steep/project/group.rb +31 -0
  97. data/lib/steep/project/options.rb +63 -0
  98. data/lib/steep/project/pattern.rb +59 -0
  99. data/lib/steep/project/target.rb +92 -0
  100. data/lib/steep/project.rb +78 -0
  101. data/lib/steep/rake_task.rb +132 -0
  102. data/lib/steep/range_extension.rb +29 -0
  103. data/lib/steep/server/base_worker.rb +97 -0
  104. data/lib/steep/server/change_buffer.rb +73 -0
  105. data/lib/steep/server/custom_methods.rb +77 -0
  106. data/lib/steep/server/delay_queue.rb +45 -0
  107. data/lib/steep/server/interaction_worker.rb +492 -0
  108. data/lib/steep/server/lsp_formatter.rb +455 -0
  109. data/lib/steep/server/master.rb +912 -0
  110. data/lib/steep/server/target_group_files.rb +205 -0
  111. data/lib/steep/server/type_check_controller.rb +366 -0
  112. data/lib/steep/server/type_check_worker.rb +303 -0
  113. data/lib/steep/server/work_done_progress.rb +64 -0
  114. data/lib/steep/server/worker_process.rb +176 -0
  115. data/lib/steep/services/completion_provider.rb +802 -0
  116. data/lib/steep/services/content_change.rb +61 -0
  117. data/lib/steep/services/file_loader.rb +74 -0
  118. data/lib/steep/services/goto_service.rb +441 -0
  119. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  120. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  121. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  122. data/lib/steep/services/path_assignment.rb +46 -0
  123. data/lib/steep/services/signature_help_provider.rb +202 -0
  124. data/lib/steep/services/signature_service.rb +428 -0
  125. data/lib/steep/services/stats_calculator.rb +68 -0
  126. data/lib/steep/services/type_check_service.rb +394 -0
  127. data/lib/steep/services/type_name_completion.rb +236 -0
  128. data/lib/steep/signature/validator.rb +651 -0
  129. data/lib/steep/source/ignore_ranges.rb +69 -0
  130. data/lib/steep/source.rb +691 -0
  131. data/lib/steep/subtyping/cache.rb +30 -0
  132. data/lib/steep/subtyping/check.rb +1113 -0
  133. data/lib/steep/subtyping/constraints.rb +341 -0
  134. data/lib/steep/subtyping/relation.rb +101 -0
  135. data/lib/steep/subtyping/result.rb +324 -0
  136. data/lib/steep/subtyping/variable_variance.rb +89 -0
  137. data/lib/steep/test.rb +9 -0
  138. data/lib/steep/thread_waiter.rb +43 -0
  139. data/lib/steep/type_construction.rb +5183 -0
  140. data/lib/steep/type_inference/block_params.rb +416 -0
  141. data/lib/steep/type_inference/case_when.rb +303 -0
  142. data/lib/steep/type_inference/constant_env.rb +56 -0
  143. data/lib/steep/type_inference/context.rb +195 -0
  144. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  145. data/lib/steep/type_inference/method_call.rb +193 -0
  146. data/lib/steep/type_inference/method_params.rb +531 -0
  147. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  148. data/lib/steep/type_inference/send_args.rb +712 -0
  149. data/lib/steep/type_inference/type_env.rb +341 -0
  150. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  151. data/lib/steep/typing.rb +321 -0
  152. data/lib/steep/version.rb +3 -0
  153. data/lib/steep.rb +369 -0
  154. data/manual/annotations.md +181 -0
  155. data/manual/ignore.md +20 -0
  156. data/manual/ruby-diagnostics.md +1879 -0
  157. data/sample/Steepfile +22 -0
  158. data/sample/lib/conference.rb +49 -0
  159. data/sample/lib/length.rb +35 -0
  160. data/sample/sig/conference.rbs +42 -0
  161. data/sample/sig/generics.rbs +15 -0
  162. data/sample/sig/length.rbs +34 -0
  163. data/steep-activesupport-4.gemspec +55 -0
  164. metadata +437 -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