rbs 2.8.4 → 3.0.0.dev.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -28
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +16 -16
  5. data/Rakefile +1 -9
  6. data/ext/rbs_extension/constants.c +2 -0
  7. data/ext/rbs_extension/constants.h +1 -0
  8. data/ext/rbs_extension/extconf.rb +1 -1
  9. data/ext/rbs_extension/parser.c +23 -13
  10. data/ext/rbs_extension/ruby_objs.c +15 -3
  11. data/ext/rbs_extension/ruby_objs.h +2 -1
  12. data/lib/rbs/ast/members.rb +49 -15
  13. data/lib/rbs/cli.rb +6 -1
  14. data/lib/rbs/collection/config/lockfile.rb +115 -0
  15. data/lib/rbs/collection/config/lockfile_generator.rb +89 -48
  16. data/lib/rbs/collection/config.rb +11 -39
  17. data/lib/rbs/collection/installer.rb +9 -13
  18. data/lib/rbs/collection/sources/base.rb +2 -2
  19. data/lib/rbs/collection/sources/git.rb +135 -62
  20. data/lib/rbs/collection/sources/rubygems.rb +10 -12
  21. data/lib/rbs/collection/sources/stdlib.rb +10 -13
  22. data/lib/rbs/collection/sources.rb +7 -1
  23. data/lib/rbs/collection.rb +1 -0
  24. data/lib/rbs/definition.rb +1 -1
  25. data/lib/rbs/definition_builder/method_builder.rb +3 -3
  26. data/lib/rbs/definition_builder.rb +449 -572
  27. data/lib/rbs/environment.rb +5 -3
  28. data/lib/rbs/environment_loader.rb +11 -10
  29. data/lib/rbs/locator.rb +2 -2
  30. data/lib/rbs/prototype/helpers.rb +29 -13
  31. data/lib/rbs/prototype/node_usage.rb +99 -0
  32. data/lib/rbs/prototype/rb.rb +3 -2
  33. data/lib/rbs/prototype/rbi.rb +6 -4
  34. data/lib/rbs/prototype/runtime.rb +25 -12
  35. data/lib/rbs/substitution.rb +19 -0
  36. data/lib/rbs/types.rb +1 -5
  37. data/lib/rbs/validator.rb +2 -1
  38. data/lib/rbs/version.rb +1 -1
  39. data/lib/rbs/writer.rb +26 -17
  40. data/lib/rbs.rb +1 -0
  41. data/lib/rdoc_plugin/parser.rb +1 -1
  42. data/rbs.gemspec +1 -1
  43. data/schema/members.json +15 -10
  44. data/sig/collection/config/lockfile.rbs +80 -0
  45. data/sig/collection/config/lockfile_generator.rbs +55 -0
  46. data/sig/collection/config.rbs +5 -48
  47. data/sig/collection/installer.rbs +1 -1
  48. data/sig/collection/sources.rbs +66 -29
  49. data/sig/definition_builder.rbs +94 -81
  50. data/sig/environment_loader.rbs +1 -1
  51. data/sig/errors.rbs +21 -0
  52. data/sig/members.rbs +31 -7
  53. data/sig/prototype/node_usage.rbs +20 -0
  54. data/sig/shims/bundler.rbs +13 -0
  55. data/sig/shims/rubygems.rbs +9 -0
  56. data/sig/shims.rbs +0 -22
  57. data/sig/substitution.rbs +6 -0
  58. data/sig/writer.rbs +2 -0
  59. data/steep/Gemfile +3 -0
  60. data/steep/Gemfile.lock +61 -0
  61. metadata +13 -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, no_self_types: true)
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)