rbs 2.8.1 → 3.0.0.dev.1

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +1 -1
  3. data/.github/workflows/ruby.yml +9 -6
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +16 -16
  6. data/ext/rbs_extension/constants.c +2 -0
  7. data/ext/rbs_extension/constants.h +1 -0
  8. data/ext/rbs_extension/parser.c +23 -13
  9. data/ext/rbs_extension/ruby_objs.c +15 -3
  10. data/ext/rbs_extension/ruby_objs.h +2 -1
  11. data/lib/rbs/ast/members.rb +49 -15
  12. data/lib/rbs/cli.rb +6 -1
  13. data/lib/rbs/collection/config/lockfile.rb +115 -0
  14. data/lib/rbs/collection/config/lockfile_generator.rb +89 -48
  15. data/lib/rbs/collection/config.rb +11 -39
  16. data/lib/rbs/collection/installer.rb +9 -13
  17. data/lib/rbs/collection/sources/base.rb +2 -2
  18. data/lib/rbs/collection/sources/git.rb +135 -62
  19. data/lib/rbs/collection/sources/rubygems.rb +10 -12
  20. data/lib/rbs/collection/sources/stdlib.rb +10 -13
  21. data/lib/rbs/collection/sources.rb +7 -1
  22. data/lib/rbs/collection.rb +1 -0
  23. data/lib/rbs/definition.rb +1 -1
  24. data/lib/rbs/definition_builder/method_builder.rb +3 -3
  25. data/lib/rbs/definition_builder.rb +449 -572
  26. data/lib/rbs/environment.rb +5 -3
  27. data/lib/rbs/environment_loader.rb +11 -10
  28. data/lib/rbs/locator.rb +2 -2
  29. data/lib/rbs/prototype/helpers.rb +29 -13
  30. data/lib/rbs/prototype/node_usage.rb +99 -0
  31. data/lib/rbs/prototype/rb.rb +3 -2
  32. data/lib/rbs/prototype/rbi.rb +6 -4
  33. data/lib/rbs/prototype/runtime.rb +25 -12
  34. data/lib/rbs/substitution.rb +19 -0
  35. data/lib/rbs/types.rb +1 -5
  36. data/lib/rbs/validator.rb +2 -1
  37. data/lib/rbs/version.rb +1 -1
  38. data/lib/rbs/writer.rb +26 -17
  39. data/lib/rbs.rb +1 -0
  40. data/lib/rdoc_plugin/parser.rb +1 -1
  41. data/schema/members.json +15 -10
  42. data/sig/collection/config/lockfile.rbs +80 -0
  43. data/sig/collection/config/lockfile_generator.rbs +55 -0
  44. data/sig/collection/config.rbs +5 -48
  45. data/sig/collection/installer.rbs +1 -1
  46. data/sig/collection/sources.rbs +66 -29
  47. data/sig/definition_builder.rbs +94 -81
  48. data/sig/environment_loader.rbs +1 -1
  49. data/sig/errors.rbs +21 -0
  50. data/sig/members.rbs +31 -7
  51. data/sig/prototype/node_usage.rbs +20 -0
  52. data/sig/shims/bundler.rbs +13 -0
  53. data/sig/shims/rubygems.rbs +9 -0
  54. data/sig/shims.rbs +0 -22
  55. data/sig/substitution.rbs +6 -0
  56. data/sig/writer.rbs +2 -0
  57. data/stdlib/yaml/0/yaml.rbs +1 -1
  58. metadata +11 -4
@@ -32,243 +32,177 @@ module RBS
32
32
  end
33
33
  end
34
34
 
35
+ def define_interface(definition, type_name, subst)
36
+ included_interfaces = ancestor_builder.one_interface_ancestors(type_name).included_interfaces or raise
37
+ interface_methods = interface_methods(included_interfaces)
38
+
39
+ methods = method_builder.build_interface(type_name)
40
+
41
+ import_methods(definition, type_name, methods, interface_methods, subst)
42
+ end
43
+
35
44
  def build_interface(type_name)
36
45
  try_cache(type_name, cache: interface_cache) do
37
46
  entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
38
47
  declaration = entry.decl
39
48
  ensure_namespace!(type_name.namespace, location: declaration.location)
40
49
 
41
- self_type = Types::Interface.new(
42
- name: type_name,
43
- args: Types::Variable.build(declaration.type_params.each.map(&:name)),
44
- location: nil
45
- )
50
+ type_params = declaration.type_params.each.map(&:name)
51
+ type_args = Types::Variable.build(type_params)
52
+ self_type = Types::Interface.new(name: type_name, args: type_args, location: nil)
53
+
54
+ subst = Substitution.build(type_params, type_args)
46
55
 
47
56
  ancestors = ancestor_builder.interface_ancestors(type_name)
48
57
  Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
49
- included_interfaces = ancestor_builder.one_interface_ancestors(type_name).included_interfaces or raise
50
- included_interfaces.each do |mod|
51
- defn = build_interface(mod.name)
52
- subst = Substitution.build(defn.type_params, mod.args)
53
-
54
- defn.methods.each do |name, method|
55
- definition.methods[name] = method.sub(subst)
56
- end
57
- end
58
-
59
58
  methods = method_builder.build_interface(type_name)
60
59
  one_ancestors = ancestor_builder.one_interface_ancestors(type_name)
61
60
 
62
61
  validate_type_params(definition, methods: methods, ancestors: one_ancestors)
63
62
 
64
- methods.each do |defn|
65
- method = case original = defn.original
66
- when AST::Members::MethodDefinition
67
- defs = original.types.map do |method_type|
68
- Definition::Method::TypeDef.new(
69
- type: method_type,
70
- member: original,
71
- defined_in: type_name,
72
- implemented_in: nil
73
- )
74
- end
63
+ define_interface(definition, type_name, subst)
64
+ end
65
+ end
66
+ end
75
67
 
76
- Definition::Method.new(
77
- super_method: nil,
78
- defs: defs,
79
- accessibility: :public,
80
- alias_of: nil
81
- )
82
- when AST::Members::Alias
83
- unless definition.methods.key?(original.old_name)
84
- raise UnknownMethodAliasError.new(
85
- type_name: type_name,
86
- original_name: original.old_name,
87
- aliased_name: original.new_name,
88
- location: original.location
89
- )
90
- end
68
+ def tapp_subst(name, args)
69
+ params =
70
+ case
71
+ when name.interface?
72
+ entry = env.interface_decls[name] or raise "Unknown interface name: #{name}"
73
+ entry.decl.type_params
74
+ when name.alias?
75
+ entry = env.alias_decls[name] or raise "Unknown alias name: #{name}"
76
+ entry.decl.type_params
77
+ when name.class?
78
+ entry = env.class_decls[name] or raise "Unknown module name: #{name}"
79
+ entry.type_params
80
+ else
81
+ raise
82
+ end
91
83
 
92
- original_method = definition.methods[original.old_name]
93
- Definition::Method.new(
94
- super_method: nil,
95
- defs: original_method.defs.map do |defn|
96
- defn.update(implemented_in: nil, defined_in: type_name)
97
- end,
98
- accessibility: :public,
99
- alias_of: original_method
100
- )
101
- when nil
102
- unless definition.methods.key?(defn.name)
103
- raise InvalidOverloadMethodError.new(
104
- type_name: type_name,
105
- method_name: defn.name,
106
- kind: :instance,
107
- members: defn.overloads
108
- )
109
- end
84
+ Substitution.build(params.map(&:name), args)
85
+ end
86
+
87
+ def define_instance(definition, type_name, subst)
88
+ one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
89
+ methods = method_builder.build_instance(type_name)
90
+
91
+ one_ancestors.each_included_module do |mod|
92
+ mod.args.each do |arg|
93
+ validate_type_presence(arg)
94
+ end
95
+
96
+ define_instance(definition, mod.name, subst + tapp_subst(mod.name, mod.args))
97
+ end
98
+
99
+ interface_methods = interface_methods(one_ancestors.each_included_interface.to_a)
100
+ import_methods(definition, type_name, methods, interface_methods, subst)
101
+
102
+ one_ancestors.each_prepended_module do |mod|
103
+ mod.args.each do |arg|
104
+ validate_type_presence(arg)
105
+ end
110
106
 
111
- definition.methods[defn.name]
107
+ define_instance(definition, mod.name, subst + tapp_subst(mod.name, mod.args))
108
+ end
112
109
 
113
- when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
114
- raise
110
+ entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
111
+ args = entry.type_params.map {|param| Types::Variable.new(name: param.name, location: param.location) }
115
112
 
116
- end
113
+ entry.decls.each do |d|
114
+ subst_ = subst + Substitution.build(d.decl.type_params.each.map(&:name), args)
117
115
 
118
- defn.overloads.each do |overload|
119
- overload_defs = overload.types.map do |method_type|
120
- Definition::Method::TypeDef.new(
121
- type: method_type,
122
- member: overload,
123
- defined_in: type_name,
124
- implemented_in: nil
116
+ d.decl.members.each do |member|
117
+ case member
118
+ when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
119
+ if member.kind == :instance
120
+ ivar_name = case member.ivar_name
121
+ when false
122
+ nil
123
+ else
124
+ member.ivar_name || :"@#{member.name}"
125
+ end
126
+
127
+ if ivar_name
128
+ insert_variable(
129
+ type_name,
130
+ definition.instance_variables,
131
+ name: ivar_name,
132
+ type: member.type.sub(subst_)
125
133
  )
126
134
  end
127
-
128
- method.defs.unshift(*overload_defs)
129
135
  end
130
136
 
131
- definition.methods[defn.name] = method
137
+ when AST::Members::InstanceVariable
138
+ insert_variable(
139
+ type_name,
140
+ definition.instance_variables,
141
+ name: member.name,
142
+ type: member.type.sub(subst_)
143
+ )
144
+
145
+ when AST::Members::ClassVariable
146
+ insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
132
147
  end
133
148
  end
134
149
  end
135
150
  end
136
151
 
137
- def build_instance(type_name, no_self_types: false)
138
- try_cache(type_name, cache: instance_cache, key: [type_name, no_self_types]) do
152
+ def build_instance(type_name)
153
+ try_cache(type_name, cache: instance_cache) do
139
154
  entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
140
155
  ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
141
156
 
142
- case entry
143
- when Environment::ClassEntry, Environment::ModuleEntry
144
- ancestors = ancestor_builder.instance_ancestors(type_name)
145
- args = entry.type_params.map {|param| Types::Variable.new(name: param.name, location: param.location) }
146
- self_type = Types::ClassInstance.new(name: type_name, args: args, location: nil)
157
+ ancestors = ancestor_builder.instance_ancestors(type_name)
158
+ args = entry.type_params.map {|param| Types::Variable.new(name: param.name, location: param.location) }
159
+ self_type = Types::ClassInstance.new(name: type_name, args: args, location: nil)
147
160
 
148
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
149
- one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
150
- methods = method_builder.build_instance(type_name)
161
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
162
+ one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
163
+ methods = method_builder.build_instance(type_name)
151
164
 
152
- validate_type_params definition, methods: methods, ancestors: one_ancestors
165
+ validate_type_params definition, methods: methods, ancestors: one_ancestors
153
166
 
167
+ if entry.is_a?(Environment::ClassEntry)
154
168
  if super_class = one_ancestors.super_class
155
- case super_class
156
- when Definition::Ancestor::Instance
157
- build_instance(super_class.name).yield_self do |defn|
158
- merge_definition(src: defn,
159
- dest: definition,
160
- subst: Substitution.build(defn.type_params, super_class.args),
161
- keep_super: true)
162
- end
163
- else
164
- raise
165
- end
166
- end
167
-
168
- if self_types = one_ancestors.self_types
169
- unless no_self_types
170
- self_types.each do |ans|
171
- defn = if ans.name.interface?
172
- build_interface(ans.name)
173
- else
174
- build_instance(ans.name)
175
- end
176
-
177
- # Successor interface method overwrites.
178
- merge_definition(
179
- src: defn,
180
- dest: definition,
181
- subst: Substitution.build(defn.type_params, ans.args),
182
- keep_super: true
183
- )
184
- end
185
- else
186
- methods_with_self = build_instance(type_name, no_self_types: false).methods
187
- end
188
- end
189
-
190
- one_ancestors.each_included_module do |mod|
191
- defn = build_instance(mod.name, no_self_types: true)
192
- merge_definition(src: defn,
193
- dest: definition,
194
- subst: Substitution.build(defn.type_params, mod.args))
195
- end
196
-
197
- interface_methods = {}
198
-
199
- one_ancestors.each_included_interface do |mod|
200
- defn = build_interface(mod.name)
201
- subst = Substitution.build(defn.type_params, mod.args)
202
-
203
- defn.methods.each do |name, method|
204
- if interface_methods.key?(name)
205
- include_member = mod.source
169
+ super_class.is_a?(Definition::Ancestor::Instance) or raise
206
170
 
207
- raise unless include_member.is_a?(AST::Members::Include)
171
+ build_instance(super_class.name).tap do |defn|
172
+ unless super_class.args.empty?
173
+ super_class.args.each do |arg|
174
+ validate_type_presence(arg)
175
+ end
208
176
 
209
- raise DuplicatedInterfaceMethodDefinitionError.new(
210
- type: self_type,
211
- method_name: name,
212
- member: include_member
213
- )
177
+ subst = tapp_subst(super_class.name, super_class.args)
178
+ defn = defn.sub(subst)
214
179
  end
215
180
 
216
- merge_method(type_name, interface_methods, name, method, subst, implemented_in: type_name)
181
+ definition.methods.merge!(defn.methods)
182
+ definition.instance_variables.merge!(defn.instance_variables)
183
+ definition.class_variables.merge!(defn.class_variables)
217
184
  end
218
185
  end
186
+ end
219
187
 
220
- if entry.is_a?(Environment::ModuleEntry)
221
- define_methods_module_instance(
222
- definition,
223
- methods: methods,
224
- interface_methods: interface_methods,
225
- module_self_methods: methods_with_self
226
- )
227
- else
228
- define_methods_instance(definition, methods: methods, interface_methods: interface_methods)
229
- end
230
-
231
- entry.decls.each do |d|
232
- subst = Substitution.build(d.decl.type_params.each.map(&:name), args)
233
-
234
- d.decl.members.each do |member|
235
- case member
236
- when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
237
- if member.kind == :instance
238
- ivar_name = case member.ivar_name
239
- when false
240
- nil
241
- else
242
- member.ivar_name || :"@#{member.name}"
243
- end
244
-
245
- if ivar_name
246
- insert_variable(type_name,
247
- definition.instance_variables,
248
- name: ivar_name,
249
- type: member.type.sub(subst))
250
- end
251
- end
252
-
253
- when AST::Members::InstanceVariable
254
- insert_variable(type_name,
255
- definition.instance_variables,
256
- name: member.name,
257
- type: member.type.sub(subst))
188
+ if entry.is_a?(Environment::ModuleEntry)
189
+ if self_types = one_ancestors.self_types
190
+ self_types.each do |ans|
191
+ ans.args.each do |arg|
192
+ validate_type_presence(arg)
193
+ end
258
194
 
259
- when AST::Members::ClassVariable
260
- insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
195
+ subst = tapp_subst(ans.name, ans.args)
196
+ if ans.name.interface?
197
+ define_interface(definition, ans.name, subst)
198
+ else
199
+ define_instance(definition, ans.name, subst)
261
200
  end
262
201
  end
263
202
  end
264
-
265
- one_ancestors.each_prepended_module do |mod|
266
- defn = build_instance(mod.name)
267
- merge_definition(src: defn,
268
- dest: definition,
269
- subst: Substitution.build(defn.type_params, mod.args))
270
- end
271
203
  end
204
+
205
+ define_instance(definition, type_name, Substitution.new)
272
206
  end
273
207
  end
274
208
  end
@@ -280,91 +214,62 @@ module RBS
280
214
  entry = env.class_decls[type_name] or raise "Unknown name for build_singleton0: #{type_name}"
281
215
  ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
282
216
 
283
- case entry
284
- when Environment::ClassEntry, Environment::ModuleEntry
285
- ancestors = ancestor_builder.singleton_ancestors(type_name)
286
- self_type = Types::ClassSingleton.new(name: type_name, location: nil)
287
-
288
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
289
- one_ancestors = ancestor_builder.one_singleton_ancestors(type_name)
217
+ ancestors = ancestor_builder.singleton_ancestors(type_name)
218
+ self_type = Types::ClassSingleton.new(name: type_name, location: nil)
290
219
 
291
- if super_class = one_ancestors.super_class
292
- case super_class
293
- when Definition::Ancestor::Instance
294
- defn = build_instance(super_class.name)
295
- merge_definition(src: defn,
296
- dest: definition,
297
- subst: Substitution.build(defn.type_params, super_class.args),
298
- keep_super: true)
299
- when Definition::Ancestor::Singleton
300
- defn = build_singleton0(super_class.name)
301
- merge_definition(src: defn, dest: definition, subst: Substitution.new, keep_super: true)
302
- end
303
- end
304
-
305
- one_ancestors.each_extended_module do |mod|
306
- mod.args.each do |arg|
307
- validate_type_presence(arg)
308
- end
309
-
310
- mod_defn = build_instance(mod.name, no_self_types: true)
311
- merge_definition(src: mod_defn,
312
- dest: definition,
313
- subst: Substitution.build(mod_defn.type_params, mod.args))
220
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
221
+ one_ancestors = ancestor_builder.one_singleton_ancestors(type_name)
222
+
223
+ if super_class = one_ancestors.super_class
224
+ case super_class
225
+ when Definition::Ancestor::Instance
226
+ defn = build_instance(super_class.name)
227
+ when Definition::Ancestor::Singleton
228
+ defn = build_singleton0(super_class.name)
314
229
  end
315
230
 
316
- interface_methods = {}
317
- one_ancestors.each_extended_interface do |mod|
318
- mod.args.each do |arg|
319
- validate_type_presence(arg)
320
- end
231
+ definition.methods.merge!(defn.methods)
232
+ definition.instance_variables.merge!(defn.instance_variables)
233
+ definition.class_variables.merge!(defn.class_variables)
234
+ end
321
235
 
322
- mod_defn = build_interface(mod.name)
323
- subst = Substitution.build(mod_defn.type_params, mod.args)
236
+ one_ancestors = ancestor_builder.one_singleton_ancestors(type_name)
237
+ methods = method_builder.build_singleton(type_name)
324
238
 
325
- mod_defn.methods.each do |name, method|
326
- if interface_methods.key?(name)
327
- src_member = mod.source
239
+ one_ancestors.each_extended_module do |mod|
240
+ mod.args.each do |arg|
241
+ validate_type_presence(arg)
242
+ end
328
243
 
329
- raise unless src_member.is_a?(AST::Members::Extend)
244
+ subst = tapp_subst(mod.name, mod.args)
245
+ define_instance(definition, mod.name, subst)
246
+ end
330
247
 
331
- raise DuplicatedInterfaceMethodDefinitionError.new(
332
- type: self_type,
333
- method_name: name,
334
- member: src_member
335
- )
336
- end
248
+ interface_methods = interface_methods(one_ancestors.each_extended_interface.to_a)
249
+ import_methods(definition, type_name, methods, interface_methods, Substitution.new)
337
250
 
338
- merge_method(type_name, interface_methods, name, method, subst, implemented_in: type_name)
339
- end
340
- end
251
+ entry.decls.each do |d|
252
+ d.decl.members.each do |member|
253
+ case member
254
+ when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
255
+ if member.kind == :singleton
256
+ ivar_name = case member.ivar_name
257
+ when false
258
+ nil
259
+ else
260
+ member.ivar_name || :"@#{member.name}"
261
+ end
341
262
 
342
- methods = method_builder.build_singleton(type_name)
343
- define_methods_singleton(definition, methods: methods, interface_methods: interface_methods)
344
-
345
- entry.decls.each do |d|
346
- d.decl.members.each do |member|
347
- case member
348
- when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
349
- if member.kind == :singleton
350
- ivar_name = case member.ivar_name
351
- when false
352
- nil
353
- else
354
- member.ivar_name || :"@#{member.name}"
355
- end
356
-
357
- if ivar_name
358
- insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
359
- end
263
+ if ivar_name
264
+ insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
360
265
  end
266
+ end
361
267
 
362
- when AST::Members::ClassInstanceVariable
363
- insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
268
+ when AST::Members::ClassInstanceVariable
269
+ insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
364
270
 
365
- when AST::Members::ClassVariable
366
- insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
367
- end
271
+ when AST::Members::ClassVariable
272
+ insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
368
273
  end
369
274
  end
370
275
  end
@@ -377,104 +282,101 @@ module RBS
377
282
  entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
378
283
  ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
379
284
 
380
- case entry
381
- when Environment::ClassEntry, Environment::ModuleEntry
382
- ancestors = ancestor_builder.singleton_ancestors(type_name)
383
- self_type = Types::ClassSingleton.new(name: type_name, location: nil)
384
-
385
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
386
- def0 = build_singleton0(type_name)
387
- subst = Substitution.new
388
-
389
- merge_definition(src: def0, dest: definition, subst: subst, keep_super: true)
390
-
391
- if entry.is_a?(Environment::ClassEntry)
392
- new_method = definition.methods[:new]
393
- if new_method.defs.all? {|d| d.defined_in == BuiltinNames::Class.name }
394
- alias_methods = definition.methods.each.with_object([]) do |entry, array|
395
- # @type var method: Definition::Method?
396
- name, method = entry
397
- while method
398
- if method.alias_of == new_method
399
- array << name
400
- break
401
- end
402
- method = method.alias_of
285
+ ancestors = ancestor_builder.singleton_ancestors(type_name)
286
+ self_type = Types::ClassSingleton.new(name: type_name, location: nil)
287
+
288
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
289
+ definition0 = build_singleton0(type_name)
290
+ definition.methods.merge!(definition0.methods)
291
+ definition.instance_variables.merge!(definition0.instance_variables)
292
+ definition.class_variables.merge!(definition0.class_variables)
293
+
294
+ if entry.is_a?(Environment::ClassEntry)
295
+ new_method = definition.methods[:new]
296
+
297
+ if new_method.defs.all? {|d| d.defined_in == BuiltinNames::Class.name }
298
+ # The method is _untyped new_.
299
+
300
+ alias_methods = definition.methods.each.with_object([]) do |entry, array|
301
+ # @type var method: Definition::Method?
302
+ name, method = entry
303
+ while method
304
+ if method.alias_of == new_method
305
+ array << name
306
+ break
403
307
  end
308
+ method = method.alias_of
404
309
  end
310
+ end
405
311
 
406
- # The method is _untyped new_.
407
-
408
- instance = build_instance(type_name)
409
- initialize = instance.methods[:initialize]
312
+ instance = build_instance(type_name)
313
+ initialize = instance.methods[:initialize]
410
314
 
411
- if initialize
412
- class_params = entry.type_params
315
+ if initialize
316
+ class_params = entry.type_params
413
317
 
414
- # Inject a virtual _typed new_.
415
- initialize_defs = initialize.defs
416
- typed_new = Definition::Method.new(
417
- super_method: new_method,
418
- defs: initialize_defs.map do |initialize_def|
419
- method_type = initialize_def.type
318
+ # Inject a virtual _typed new_.
319
+ initialize_defs = initialize.defs
320
+ typed_new = Definition::Method.new(
321
+ super_method: new_method,
322
+ defs: initialize_defs.map do |initialize_def|
323
+ method_type = initialize_def.type
420
324
 
421
- class_type_param_vars = Set.new(class_params.map(&:name))
422
- method_type_param_vars = Set.new(method_type.type_params.map(&:name))
325
+ class_type_param_vars = Set.new(class_params.map(&:name))
326
+ method_type_param_vars = Set.new(method_type.type_params.map(&:name))
423
327
 
424
- if class_type_param_vars.intersect?(method_type_param_vars)
425
- new_method_param_names = method_type.type_params.map do |method_param|
426
- if class_type_param_vars.include?(method_param.name)
427
- Types::Variable.fresh(method_param.name).name
428
- else
429
- method_param.name
430
- end
328
+ if class_type_param_vars.intersect?(method_type_param_vars)
329
+ new_method_param_names = method_type.type_params.map do |method_param|
330
+ if class_type_param_vars.include?(method_param.name)
331
+ Types::Variable.fresh(method_param.name).name
332
+ else
333
+ method_param.name
431
334
  end
335
+ end
432
336
 
433
- sub = Substitution.build(
434
- method_type.type_params.map(&:name),
435
- Types::Variable.build(new_method_param_names)
436
- )
337
+ sub = Substitution.build(
338
+ method_type.type_params.map(&:name),
339
+ Types::Variable.build(new_method_param_names)
340
+ )
437
341
 
438
- method_params = class_params + AST::TypeParam.rename(method_type.type_params, new_names: new_method_param_names)
439
- method_type = method_type
440
- .update(type_params: [])
441
- .sub(sub)
442
- .update(type_params: method_params)
443
- else
444
- method_type = method_type
445
- .update(type_params: class_params + method_type.type_params)
446
- end
342
+ method_params = class_params + AST::TypeParam.rename(method_type.type_params, new_names: new_method_param_names)
343
+ method_type = method_type
344
+ .update(type_params: [])
345
+ .sub(sub)
346
+ .update(type_params: method_params)
347
+ else
348
+ method_type = method_type
349
+ .update(type_params: class_params + method_type.type_params)
350
+ end
447
351
 
448
- method_type = method_type.update(
449
- type: method_type.type.with_return_type(
450
- Types::ClassInstance.new(
451
- name: type_name,
452
- args: entry.type_params.map {|param| Types::Variable.new(name: param.name, location: param.location) },
453
- location: nil
454
- )
352
+ method_type = method_type.update(
353
+ type: method_type.type.with_return_type(
354
+ Types::ClassInstance.new(
355
+ name: type_name,
356
+ args: entry.type_params.map {|param| Types::Variable.new(name: param.name, location: param.location) },
357
+ location: nil
455
358
  )
456
359
  )
360
+ )
457
361
 
458
- Definition::Method::TypeDef.new(
459
- type: method_type,
460
- member: initialize_def.member,
461
- defined_in: initialize_def.defined_in,
462
- implemented_in: initialize_def.implemented_in
463
- )
464
- end,
465
- accessibility: :public,
466
- annotations: [],
467
- alias_of: nil
468
- )
362
+ Definition::Method::TypeDef.new(
363
+ type: method_type,
364
+ member: initialize_def.member,
365
+ defined_in: initialize_def.defined_in,
366
+ implemented_in: initialize_def.implemented_in
367
+ )
368
+ end,
369
+ accessibility: :public,
370
+ alias_of: nil
371
+ )
469
372
 
470
- definition.methods[:new] = typed_new
373
+ definition.methods[:new] = typed_new
471
374
 
472
- alias_methods.each do |alias_name|
473
- definition.methods[alias_name] = definition.methods[alias_name].update(
474
- alias_of: typed_new,
475
- defs: typed_new.defs
476
- )
477
- end
375
+ alias_methods.each do |alias_name|
376
+ definition.methods[alias_name] = definition.methods[alias_name].update(
377
+ alias_of: typed_new,
378
+ defs: typed_new.defs
379
+ )
478
380
  end
479
381
  end
480
382
  end
@@ -483,6 +385,26 @@ module RBS
483
385
  end
484
386
  end
485
387
 
388
+ def interface_methods(interface_ancestors)
389
+ interface_methods = {} #: interface_methods
390
+
391
+ interface_ancestors.each do |mod|
392
+ source =
393
+ case mod.source
394
+ when AST::Members::Include, AST::Members::Extend
395
+ mod.source
396
+ else
397
+ raise "Interface mixin must be include/extend: #{mod.source.inspect}"
398
+ end
399
+
400
+ methods = method_builder.build_interface(mod.name)
401
+
402
+ interface_methods[mod] = [methods, source]
403
+ end
404
+
405
+ interface_methods
406
+ end
407
+
486
408
  def validate_params_with(type_params, result:)
487
409
  type_params.each do |param|
488
410
  unless param.unchecked?
@@ -539,7 +461,7 @@ module RBS
539
461
 
540
462
  method_types = case original = defn.original
541
463
  when AST::Members::MethodDefinition
542
- original.types
464
+ original.overloads.map(&:method_type)
543
465
  when AST::Members::AttrWriter, AST::Members::AttrReader, AST::Members::AttrAccessor
544
466
  if defn.name.to_s.end_with?("=")
545
467
  [
@@ -597,267 +519,223 @@ module RBS
597
519
  )
598
520
  end
599
521
 
600
- def define_methods_instance(definition, methods:, interface_methods:)
601
- define_methods(
602
- definition,
603
- methods: methods,
604
- interface_methods: interface_methods,
605
- methods_with_self: nil,
606
- super_interface_method: false
607
- )
608
- end
522
+ def import_methods(definition, module_name, module_methods, interfaces_methods, subst)
523
+ new_methods = {} #: Hash[Symbol, Definition::Method]
524
+ interface_method_duplicates = Set[] #: Set[Symbol]
609
525
 
610
- def define_methods_module_instance(definition, methods:, interface_methods:, module_self_methods:)
611
- define_methods(definition, methods: methods, interface_methods: interface_methods, methods_with_self: module_self_methods, super_interface_method: true)
612
- end
526
+ interfaces_methods.each do |interface, (methods, member)|
527
+ unless interface.args.empty?
528
+ methods.type.is_a?(Types::Interface) or raise
529
+ params = methods.type.args.map do |arg|
530
+ arg.is_a?(Types::Variable) or raise
531
+ arg.name
532
+ end
613
533
 
614
- def define_methods_singleton(definition, methods:, interface_methods:)
615
- define_methods(
616
- definition,
617
- methods: methods,
618
- interface_methods: interface_methods,
619
- methods_with_self: nil,
620
- super_interface_method: false
621
- )
622
- end
534
+ interface.args.each do |arg|
535
+ validate_type_presence(arg)
536
+ end
623
537
 
624
- def define_methods(definition, methods:, interface_methods:, methods_with_self:, super_interface_method:)
625
- methods.each do |method_def|
626
- method_name = method_def.name
627
- original = method_def.original
538
+ subst_ = subst + Substitution.build(params, interface.args)
539
+ else
540
+ subst_ = subst
541
+ end
628
542
 
629
- if original.is_a?(AST::Members::Alias)
630
- existing_method = interface_methods[method_name] || definition.methods[method_name]
631
- original_method =
632
- interface_methods[original.old_name] ||
633
- methods_with_self&.[](original.old_name) ||
634
- definition.methods[original.old_name]
543
+ methods.each do |method|
544
+ if interface_method_duplicates.include?(method.name)
545
+ member.is_a?(AST::Members::Include) || member.is_a?(AST::Members::Extend) or raise
635
546
 
636
- unless original_method
637
- raise UnknownMethodAliasError.new(
638
- type_name: definition.type_name,
639
- original_name: original.old_name,
640
- aliased_name: original.new_name,
641
- location: original.location
547
+ raise DuplicatedInterfaceMethodDefinitionError.new(
548
+ type: definition.self_type,
549
+ method_name: method.name,
550
+ member: member
642
551
  )
643
552
  end
644
553
 
645
- method = Definition::Method.new(
646
- super_method: existing_method,
647
- defs: original_method.defs.map do |defn|
648
- defn.update(defined_in: definition.type_name, implemented_in: definition.type_name)
649
- end,
650
- accessibility: original_method.accessibility,
651
- alias_of: original_method
554
+ interface_method_duplicates << method.name
555
+ define_method(
556
+ new_methods,
557
+ definition,
558
+ method,
559
+ subst_,
560
+ defined_in: interface.name,
561
+ implemented_in: module_name
652
562
  )
653
- else
654
- if interface_methods.key?(method_name)
655
- interface_method = interface_methods[method_name]
656
-
657
- if original = method_def.original
658
- raise DuplicatedMethodDefinitionError.new(
659
- type: definition.self_type,
660
- method_name: method_name,
661
- members: [original]
662
- )
663
- end
563
+ end
564
+ end
664
565
 
665
- definition.methods[method_name] = interface_method
666
- end
566
+ module_methods.each do |method|
567
+ define_method(
568
+ new_methods,
569
+ definition,
570
+ method,
571
+ subst,
572
+ defined_in: module_name,
573
+ implemented_in: module_name.interface? ? nil : module_name
574
+ )
575
+ end
667
576
 
668
- existing_method = definition.methods[method_name]
577
+ definition.methods.merge!(new_methods)
578
+ end
669
579
 
670
- case original
671
- when AST::Members::MethodDefinition
672
- defs = original.types.map do |method_type|
673
- Definition::Method::TypeDef.new(
674
- type: method_type,
675
- member: original,
676
- defined_in: definition.type_name,
677
- implemented_in: definition.type_name
678
- )
679
- end
580
+ def define_method(methods, definition, method, subst, defined_in:, implemented_in: defined_in)
581
+ existing_method = methods[method.name] || definition.methods[method.name]
680
582
 
681
- # @type var accessibility: RBS::Definition::accessibility
682
- accessibility = if method_name == :initialize
683
- :private
684
- else
685
- method_def.accessibility
686
- end
687
-
688
- method = Definition::Method.new(
689
- super_method: existing_method,
690
- defs: defs,
691
- accessibility: accessibility,
692
- alias_of: nil
693
- )
583
+ case original = method.original
584
+ when AST::Members::Alias
585
+ original_method = methods[original.old_name] || definition.methods[original.old_name]
694
586
 
695
- when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
696
- method_type = if method_name.to_s.end_with?("=")
697
- # setter
698
- MethodType.new(
699
- type_params: [],
700
- type: Types::Function.empty(original.type).update(
701
- required_positionals: [
702
- Types::Function::Param.new(type: original.type, name: original.name)
703
- ]
704
- ),
705
- block: nil,
706
- location: nil
707
- )
708
- else
709
- # getter
710
- MethodType.new(
711
- type_params: [],
712
- type: Types::Function.empty(original.type),
713
- block: nil,
714
- location: nil
715
- )
716
- end
717
- defs = [
718
- Definition::Method::TypeDef.new(
719
- type: method_type,
720
- member: original,
721
- defined_in: definition.type_name,
722
- implemented_in: definition.type_name
723
- )
724
- ]
587
+ unless original_method
588
+ raise UnknownMethodAliasError.new(
589
+ type_name: definition.type_name,
590
+ original_name: original.old_name,
591
+ aliased_name: original.new_name,
592
+ location: original.location
593
+ )
594
+ end
725
595
 
726
- method = Definition::Method.new(
727
- super_method: existing_method,
728
- defs: defs,
729
- accessibility: method_def.accessibility,
730
- alias_of: nil
731
- )
596
+ method_definition = Definition::Method.new(
597
+ super_method: existing_method,
598
+ defs: original_method.defs.map do |defn|
599
+ defn.update(defined_in: defined_in, implemented_in: implemented_in)
600
+ end,
601
+ accessibility: original_method.accessibility,
602
+ alias_of: original_method
603
+ )
604
+ when AST::Members::MethodDefinition
605
+ if duplicated_method = methods[method.name]
606
+ raise DuplicatedMethodDefinitionError.new(
607
+ type: definition.self_type,
608
+ method_name: method.name,
609
+ members: [original, *duplicated_method.members]
610
+ )
611
+ end
732
612
 
733
- when nil
734
- unless definition.methods.key?(method_name)
735
- raise InvalidOverloadMethodError.new(
736
- type_name: definition.type_name,
737
- method_name: method_name,
738
- kind: :instance,
739
- members: method_def.overloads
740
- )
741
- end
613
+ defs = original.overloads.map do |overload|
614
+ Definition::Method::TypeDef.new(
615
+ type: subst.empty? ? overload.method_type : overload.method_type.sub(subst),
616
+ member: original,
617
+ defined_in: defined_in,
618
+ implemented_in: implemented_in
619
+ )
620
+ end
742
621
 
743
- if !super_interface_method && existing_method.defs.any? {|defn| defn.defined_in.interface? }
744
- super_method = existing_method.super_method
745
- else
746
- super_method = existing_method
747
- end
622
+ # @type var accessibility: RBS::Definition::accessibility
623
+ accessibility = if method.name == :initialize
624
+ :private
625
+ else
626
+ method.accessibility
627
+ end
628
+
629
+ # Skip setting up `super_method` if `implemented_in` is `nil`, that means the type doesn't have implementation.
630
+ # This typically happens if the type is an interface.
631
+ if implemented_in
632
+ super_method = existing_method
633
+ end
748
634
 
749
- method = Definition::Method.new(
750
- super_method: super_method,
751
- defs: existing_method.defs.map do |defn|
752
- defn.update(implemented_in: definition.type_name)
753
- end,
754
- accessibility: existing_method.accessibility,
755
- alias_of: existing_method.alias_of
635
+ method_definition = Definition::Method.new(
636
+ super_method: super_method,
637
+ defs: defs,
638
+ accessibility: accessibility,
639
+ alias_of: nil
640
+ )
641
+ when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
642
+ if duplicated_method = methods[method.name]
643
+ raise DuplicatedMethodDefinitionError.new(
644
+ type: definition.self_type,
645
+ method_name: method.name,
646
+ members: [*duplicated_method.members, original]
647
+ )
648
+ end
649
+
650
+ attr_type = original.type.sub(subst)
651
+ method_type =
652
+ if method.name.to_s.end_with?("=")
653
+ # setter
654
+ MethodType.new(
655
+ type_params: [],
656
+ type: Types::Function.empty(attr_type).update(
657
+ required_positionals: [
658
+ Types::Function::Param.new(type: attr_type, name: original.name)
659
+ ]
660
+ ),
661
+ block: nil,
662
+ location: nil
663
+ )
664
+ else
665
+ # getter
666
+ MethodType.new(
667
+ type_params: [],
668
+ type: Types::Function.empty(attr_type),
669
+ block: nil,
670
+ location: nil
756
671
  )
757
672
  end
673
+
674
+ if implemented_in
675
+ super_method = existing_method
758
676
  end
759
677
 
760
- method_def.overloads.each do |overload|
761
- type_defs = overload.types.map do |method_type|
678
+ method_definition = Definition::Method.new(
679
+ super_method: super_method,
680
+ defs: [
762
681
  Definition::Method::TypeDef.new(
763
682
  type: method_type,
764
- member: overload,
683
+ member: original,
765
684
  defined_in: definition.type_name,
766
685
  implemented_in: definition.type_name
767
686
  )
768
- end
769
-
770
- method.defs.unshift(*type_defs)
771
- end
772
-
773
- definition.methods[method_name] = method
774
- end
775
-
776
- interface_methods.each do |name, method|
777
- unless methods.methods.key?(name)
778
- merge_method(definition.type_name, definition.methods, name, method, Substitution.new)
687
+ ],
688
+ accessibility: method.accessibility,
689
+ alias_of: nil
690
+ )
691
+ when nil
692
+ # Overloading method definition only
693
+
694
+ case
695
+ when methods.key?(method.name)
696
+ # The method is defined in an interface
697
+ super_method = methods[method.name].super_method
698
+ when definition.methods.key?(method.name)
699
+ # The method is defined in the super class
700
+ super_method = existing_method
701
+ else
702
+ # Cannot find any non-overloading method
703
+ raise InvalidOverloadMethodError.new(
704
+ type_name: definition.type_name,
705
+ method_name: method.name,
706
+ kind: :instance,
707
+ members: method.overloads
708
+ )
779
709
  end
780
- end
781
- end
782
710
 
783
- def merge_definition(src:, dest:, subst:, implemented_in: :keep, keep_super: false)
784
- src.methods.each do |name, method|
785
- merge_method(dest.type_name, dest.methods, name, method, subst, implemented_in: implemented_in, keep_super: keep_super)
786
- end
787
-
788
- src.instance_variables.each do |name, variable|
789
- merge_variable(dest.instance_variables, name, variable, subst, keep_super: keep_super)
790
- end
791
-
792
- src.class_variables.each do |name, variable|
793
- merge_variable(dest.class_variables, name, variable, subst, keep_super: keep_super)
711
+ method_definition = Definition::Method.new(
712
+ super_method: super_method,
713
+ defs: existing_method.defs.map do |defn|
714
+ defn.update(implemented_in: definition.type_name)
715
+ end,
716
+ accessibility: existing_method.accessibility,
717
+ alias_of: existing_method.alias_of
718
+ )
794
719
  end
795
- end
796
720
 
797
- def merge_variable(variables, name, variable, sub, keep_super: false)
798
- super_variable = variables[name]
799
-
800
- variables[name] = Definition::Variable.new(
801
- parent_variable: keep_super ? variable.parent_variable : super_variable,
802
- type: sub.empty? ? variable.type : variable.type.sub(sub),
803
- declared_in: variable.declared_in
804
- )
805
- end
806
-
807
- def merge_method(type_name, methods, name, method, sub, implemented_in: :keep, keep_super: false)
808
- if sub.empty? && implemented_in == :keep && keep_super
809
- methods[name] = method
810
- else
811
- if sub.empty? && implemented_in == :keep
812
- defs = method.defs
813
- else
814
- defs = method.defs.map do |defn|
815
- defn.update(
816
- type: sub.empty? ? defn.type : defn.type.sub(sub),
817
- implemented_in: case implemented_in
818
- when :keep
819
- defn.implemented_in
820
- when nil
821
- nil
822
- else
823
- implemented_in
824
- end
825
- )
826
- end
721
+ method.overloads.each do |overloading_def|
722
+ overloading_def.overloads.reverse_each do |overload|
723
+ type_def = Definition::Method::TypeDef.new(
724
+ type: subst.empty? ? overload.method_type : overload.method_type.sub(subst),
725
+ member: overloading_def,
726
+ defined_in: definition.type_name,
727
+ implemented_in: definition.type_name
728
+ )
827
729
 
828
- defs = method.defs.map do |defn|
829
- defn.update(
830
- type: sub.empty? ? defn.type : defn.type.sub(sub),
831
- implemented_in: case implemented_in
832
- when :keep
833
- defn.implemented_in
834
- when nil
835
- nil
836
- else
837
- implemented_in
838
- end
839
- )
840
- end
730
+ method_definition.defs.unshift(type_def)
841
731
  end
842
-
843
- super_method = methods[name]
844
-
845
- methods[name] = Definition::Method.new(
846
- super_method: keep_super ? method.super_method : super_method,
847
- accessibility: method.accessibility,
848
- defs: defs,
849
- alias_of: method.alias_of
850
- )
851
732
  end
852
- end
853
733
 
854
- def try_cache(type_name, cache:, key: nil)
855
- # @type var cc: Hash[untyped, Definition | nil]
856
- # @type var key: untyped
857
- key ||= type_name
858
- cc = _ = cache
734
+ methods[method.name] = method_definition
735
+ end
859
736
 
860
- cc[key] ||= yield
737
+ def try_cache(type_name, cache:)
738
+ cache[type_name] ||= yield
861
739
  end
862
740
 
863
741
  def expand_alias(type_name)
@@ -903,8 +781,7 @@ module RBS
903
781
  builder.interface_cache.merge!(interface_cache)
904
782
 
905
783
  except.each do |name|
906
- builder.instance_cache.delete([name, true])
907
- builder.instance_cache.delete([name, false])
784
+ builder.instance_cache.delete(name)
908
785
  builder.singleton_cache.delete(name)
909
786
  builder.singleton0_cache.delete(name)
910
787
  builder.interface_cache.delete(name)