rbs 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +12 -0
  6. data/README.md +86 -47
  7. data/Rakefile +54 -21
  8. data/bin/rbs-prof +9 -0
  9. data/bin/run_in_md.rb +49 -0
  10. data/lib/rbs.rb +2 -0
  11. data/lib/rbs/ast/declarations.rb +62 -7
  12. data/lib/rbs/ast/members.rb +41 -17
  13. data/lib/rbs/cli.rb +299 -121
  14. data/lib/rbs/constant.rb +4 -4
  15. data/lib/rbs/constant_table.rb +50 -44
  16. data/lib/rbs/definition.rb +175 -59
  17. data/lib/rbs/definition_builder.rb +647 -603
  18. data/lib/rbs/environment.rb +338 -209
  19. data/lib/rbs/environment_walker.rb +14 -23
  20. data/lib/rbs/errors.rb +141 -3
  21. data/lib/rbs/parser.y +14 -9
  22. data/lib/rbs/prototype/rb.rb +100 -112
  23. data/lib/rbs/prototype/rbi.rb +4 -2
  24. data/lib/rbs/prototype/runtime.rb +10 -6
  25. data/lib/rbs/substitution.rb +8 -1
  26. data/lib/rbs/test/hook.rb +2 -2
  27. data/lib/rbs/test/setup.rb +3 -1
  28. data/lib/rbs/test/test_helper.rb +2 -5
  29. data/lib/rbs/test/type_check.rb +1 -2
  30. data/lib/rbs/type_name_resolver.rb +58 -0
  31. data/lib/rbs/types.rb +94 -2
  32. data/lib/rbs/validator.rb +51 -0
  33. data/lib/rbs/variance_calculator.rb +12 -2
  34. data/lib/rbs/version.rb +1 -1
  35. data/lib/rbs/writer.rb +125 -89
  36. data/rbs.gemspec +0 -10
  37. data/schema/decls.json +15 -0
  38. data/schema/members.json +3 -0
  39. data/stdlib/benchmark/benchmark.rbs +151 -151
  40. data/stdlib/builtin/enumerable.rbs +1 -1
  41. data/stdlib/builtin/file.rbs +0 -3
  42. data/stdlib/builtin/io.rbs +4 -4
  43. data/stdlib/builtin/thread.rbs +2 -2
  44. data/stdlib/csv/csv.rbs +4 -6
  45. data/stdlib/fiber/fiber.rbs +1 -1
  46. data/stdlib/json/json.rbs +1 -1
  47. data/stdlib/mutex_m/mutex_m.rbs +77 -0
  48. data/stdlib/pathname/pathname.rbs +6 -6
  49. data/stdlib/prime/integer-extension.rbs +1 -1
  50. data/stdlib/prime/prime.rbs +44 -44
  51. data/stdlib/tmpdir/tmpdir.rbs +1 -1
  52. metadata +8 -129
@@ -3,278 +3,407 @@ module RBS
3
3
  attr_reader :buffers
4
4
  attr_reader :declarations
5
5
 
6
- attr_reader :name_to_decl
7
- attr_reader :name_to_extensions
8
- attr_reader :name_to_constant
9
- attr_reader :name_to_global
10
- attr_reader :name_to_alias
6
+ attr_reader :class_decls
7
+ attr_reader :interface_decls
8
+ attr_reader :alias_decls
9
+ attr_reader :constant_decls
10
+ attr_reader :global_decls
11
+
12
+ module ContextUtil
13
+ def context
14
+ @context ||= begin
15
+ (outer + [decl]).each.with_object([Namespace.root]) do |decl, array|
16
+ array.unshift(array.first + decl.name.to_namespace)
17
+ end
18
+ end
19
+ end
20
+ end
11
21
 
12
- def initialize
13
- @buffers = []
14
- @declarations = []
22
+ class MultiEntry
23
+ D = Struct.new(:decl, :outer, keyword_init: true) do
24
+ include ContextUtil
25
+ end
15
26
 
16
- @name_to_decl = {}
17
- @name_to_extensions = {}
18
- @name_to_constant = {}
19
- @name_to_global = {}
20
- @name_to_alias = {}
21
- end
27
+ attr_reader :name
28
+ attr_reader :decls
22
29
 
23
- def initialize_copy(other)
24
- @buffers = other.buffers.dup
25
- @declarations = other.declarations.dup
30
+ def initialize(name:)
31
+ @name = name
32
+ @decls = []
33
+ end
26
34
 
27
- @name_to_decl = other.name_to_decl.dup
28
- @name_to_extensions = other.name_to_extensions.dup
29
- @name_to_constant = other.name_to_constant.dup
30
- @name_to_global = other.name_to_global.dup
31
- @name_to_alias = other.name_to_alias.dup
32
- end
35
+ def insert(decl:, outer:)
36
+ decls << D.new(decl: decl, outer: outer)
37
+ end
33
38
 
34
- def cache_name(cache, name:, decl:)
35
- if cache.key?(name)
36
- raise DuplicatedDeclarationError.new(name, decl, cache[name])
39
+ def type_params
40
+ primary.decl.type_params
37
41
  end
38
- cache[name] = decl
39
42
  end
40
43
 
41
- def <<(decl)
42
- declarations << decl
43
- case decl
44
- when AST::Declarations::Class, AST::Declarations::Module, AST::Declarations::Interface
45
- cache_name name_to_decl, name: decl.name.absolute!, decl: decl
46
- when AST::Declarations::Extension
47
- yield_self do
48
- name = decl.name.absolute!
49
- exts = name_to_extensions.fetch(name) do
50
- name_to_extensions[name] = []
44
+ class ModuleEntry < MultiEntry
45
+ def insert(decl:, outer:)
46
+ unless decl.is_a?(AST::Declarations::Module)
47
+ raise MixedClassModuleDeclarationError.new(name: name, decl: decl)
48
+ end
49
+
50
+ unless decls.empty?
51
+ names = decls[0].decl.type_params.each.map(&:name)
52
+ unless names.size == decl.type_params.each.size && decls[0].decl.type_params == decl.type_params.rename_to(names)
53
+ raise GenericParameterMismatchError.new(name: name, decl: decl)
51
54
  end
52
- exts << decl
53
55
  end
54
- when AST::Declarations::Alias
55
- cache_name name_to_alias, name: decl.name.absolute!, decl: decl
56
- when AST::Declarations::Constant
57
- cache_name name_to_constant, name: decl.name.absolute!, decl: decl
58
- when AST::Declarations::Global
59
- cache_name name_to_global, name: decl.name, decl: decl
56
+
57
+ super(decl: decl, outer: outer)
60
58
  end
61
- end
62
59
 
63
- def find_class(type_name)
64
- name_to_decl[type_name]
65
- end
60
+ def primary
61
+ @primary ||= decls.find {|d| d.decl.self_type } || decls.first
62
+ end
66
63
 
67
- def each_decl
68
- if block_given?
69
- name_to_decl.each do |name, decl|
70
- yield name, decl
71
- end
72
- else
73
- enum_for :each_decl
64
+ def self_type
65
+ primary.decl.self_type
74
66
  end
75
67
  end
76
68
 
77
- def each_constant
78
- if block_given?
79
- name_to_constant.each do |name, decl|
80
- yield name, decl
69
+ class ClassEntry < MultiEntry
70
+ def insert(decl:, outer:)
71
+ unless decl.is_a?(AST::Declarations::Class)
72
+ raise MixedClassModuleDeclarationError.new(name: name, decl: decl)
81
73
  end
82
- else
83
- enum_for :each_constant
84
- end
85
- end
86
74
 
87
- def each_global
88
- if block_given?
89
- name_to_global.each do |name, global|
90
- yield name, global
75
+ unless decls.empty?
76
+ names = decls[0].decl.type_params.each.map(&:name)
77
+ unless names.size == decl.type_params.each.size && decls[0].decl.type_params == decl.type_params.rename_to(names)
78
+ raise GenericParameterMismatchError.new(name: name, decl: decl)
79
+ end
91
80
  end
92
- else
93
- enum_for :each_global
81
+
82
+ super(decl: decl, outer: outer)
94
83
  end
95
- end
96
84
 
97
- def each_alias(&block)
98
- if block_given?
99
- name_to_alias.each(&block)
100
- else
101
- enum_for :each_alias
85
+ def primary
86
+ @primary ||= begin
87
+ decls.find {|d| d.decl.super_class } || decls.first
88
+ end
102
89
  end
103
90
  end
104
91
 
105
- def each_class_name(&block)
106
- each_decl.select {|name,| class?(name) }.each(&block)
107
- end
92
+ class SingleEntry
93
+ include ContextUtil
94
+
95
+ attr_reader :name
96
+ attr_reader :outer
97
+ attr_reader :decl
108
98
 
109
- def class?(type_name)
110
- find_class(type_name)&.yield_self do |decl|
111
- decl.is_a?(AST::Declarations::Class) || decl.is_a?(AST::Declarations::Module)
99
+ def initialize(name:, decl:, outer:)
100
+ @name = name
101
+ @decl = decl
102
+ @outer = outer
112
103
  end
113
104
  end
114
105
 
115
- def find_type_decl(type_name)
116
- name_to_decl[type_name]
106
+ def initialize
107
+ @buffers = []
108
+ @declarations = []
109
+
110
+ @class_decls = {}
111
+ @interface_decls = {}
112
+ @alias_decls = {}
113
+ @constant_decls = {}
114
+ @global_decls = {}
117
115
  end
118
116
 
119
- def find_extensions(type_name)
120
- name_to_extensions[type_name] || []
117
+ def initialize_copy(other)
118
+ @buffers = other.buffers.dup
119
+ @declarations = other.declarations.dup
120
+
121
+ @class_decls = other.class_decls.dup
122
+ @interface_decls = other.interface_decls.dup
123
+ @alias_decls = other.alias_decls.dup
124
+ @constant_decls = other.constant_decls.dup
125
+ @global_decls = other.global_decls.dup
121
126
  end
122
127
 
123
- def find_alias(type_name)
124
- name_to_alias[type_name]
128
+ def self.from_loader(loader)
129
+ self.new.tap do |env|
130
+ loader.load(env: env)
131
+ end
125
132
  end
126
133
 
127
- def each_extension(type_name, &block)
128
- if block_given?
129
- (name_to_extensions[type_name] || []).each(&block)
130
- else
131
- enum_for :each_extension, type_name
134
+ def cache_name(cache, name:, decl:, outer:)
135
+ if cache.key?(name)
136
+ raise DuplicatedDeclarationError.new(name, decl, cache[name])
132
137
  end
138
+
139
+ cache[name] = SingleEntry.new(name: name, decl: decl, outer: outer)
133
140
  end
134
141
 
135
- def absolute_type_name_in(environment, name:, namespace:)
136
- raise "Namespace should be absolute: #{namespace}" unless namespace.absolute?
142
+ def insert_decl(decl, outer:, namespace:)
143
+ case decl
144
+ when AST::Declarations::Class, AST::Declarations::Module
145
+ name = decl.name.with_prefix(namespace)
137
146
 
138
- if name.absolute?
139
- name if environment.key?(name)
140
- else
141
- absolute_name = name.with_prefix(namespace)
142
-
143
- if environment.key?(absolute_name)
144
- absolute_name
145
- else
146
- if namespace.empty?
147
- nil
148
- else
149
- parent = namespace.parent
150
- absolute_type_name_in environment, name: name, namespace: parent
147
+ if constant_decls.key?(name)
148
+ raise DuplicatedDeclarationError.new(name, decl, constant_decls[name].decl)
149
+ end
150
+
151
+ unless class_decls.key?(name)
152
+ case decl
153
+ when AST::Declarations::Class
154
+ class_decls[name] ||= ClassEntry.new(name: name)
155
+ when AST::Declarations::Module
156
+ class_decls[name] ||= ModuleEntry.new(name: name)
151
157
  end
152
158
  end
159
+
160
+ class_decls[name].insert(decl: decl, outer: outer)
161
+
162
+ prefix = outer + [decl]
163
+ ns = name.to_namespace
164
+ decl.each_decl do |d|
165
+ insert_decl(d, outer: prefix, namespace: ns)
166
+ end
167
+
168
+ when AST::Declarations::Interface
169
+ cache_name interface_decls, name: decl.name.with_prefix(namespace), decl: decl, outer: outer
170
+
171
+ when AST::Declarations::Alias
172
+ cache_name alias_decls, name: decl.name.with_prefix(namespace), decl: decl, outer: outer
173
+
174
+ when AST::Declarations::Constant
175
+ name = decl.name.with_prefix(namespace)
176
+
177
+ if class_decls.key?(name)
178
+ raise DuplicatedDeclarationError.new(name, decl, class_decls[name].decls[0].decl)
179
+ end
180
+
181
+ cache_name constant_decls, name: name, decl: decl, outer: outer
182
+
183
+ when AST::Declarations::Global
184
+ cache_name global_decls, name: decl.name, decl: decl, outer: outer
185
+
186
+ when AST::Declarations::Extension
187
+ RBS.logger.warn "#{Location.to_string decl.location} Extension construct is deprecated: use class/module syntax instead"
153
188
  end
154
189
  end
155
190
 
156
- def absolute_class_name(name, namespace:)
157
- raise "Class name expected: #{name}" unless name.class?
158
- absolute_type_name_in name_to_decl, name: name, namespace: namespace
191
+ def <<(decl)
192
+ declarations << decl
193
+ insert_decl(decl, outer: [], namespace: Namespace.root)
194
+ self
159
195
  end
160
196
 
161
- def absolute_interface_name(name, namespace:)
162
- raise "Interface name expected: #{name}" unless name.interface?
163
- absolute_type_name_in name_to_decl, name: name, namespace: namespace
164
- end
197
+ def resolve_type_names
198
+ resolver = TypeNameResolver.from_env(self)
199
+ env = Environment.new()
165
200
 
166
- def absolute_alias_name(name, namespace:)
167
- raise "Alias name expected: #{name}" unless name.alias?
168
- absolute_type_name_in name_to_alias, name: name, namespace: namespace
169
- end
201
+ declarations.each do |decl|
202
+ env << resolve_declaration(resolver, decl, outer: [], prefix: Namespace.root)
203
+ end
170
204
 
171
- def absolute_type_name(type_name, namespace:)
172
- absolute_name = case
173
- when type_name.class?
174
- absolute_class_name(type_name, namespace: namespace)
175
- when type_name.alias?
176
- absolute_alias_name(type_name, namespace: namespace)
177
- when type_name.interface?
178
- absolute_interface_name(type_name, namespace: namespace)
179
- end
180
-
181
- absolute_name || yield(type_name)
205
+ env
182
206
  end
183
207
 
184
- def absolute_name_or(name, type)
185
- if name.absolute?
186
- type
187
- else
188
- yield
208
+ def resolve_declaration(resolver, decl, outer:, prefix:)
209
+ if decl.is_a?(AST::Declarations::Global)
210
+ return AST::Declarations::Global.new(
211
+ name: decl.name,
212
+ type: absolute_type(resolver, decl.type, context: [Namespace.root]),
213
+ location: decl.location,
214
+ comment: decl.comment
215
+ )
216
+ end
217
+
218
+ context = (outer + [decl]).each.with_object([Namespace.root]) do |decl, array|
219
+ array.unshift(array.first + decl.name.to_namespace)
220
+ end
221
+
222
+ case decl
223
+ when AST::Declarations::Class
224
+ outer_ = outer + [decl]
225
+ prefix_ = prefix + decl.name.to_namespace
226
+ AST::Declarations::Class.new(
227
+ name: decl.name.with_prefix(prefix),
228
+ type_params: decl.type_params,
229
+ super_class: decl.super_class&.yield_self do |super_class|
230
+ AST::Declarations::Class::Super.new(
231
+ name: absolute_type_name(resolver, super_class.name, context: context),
232
+ args: super_class.args.map {|type| absolute_type(resolver, type, context: context) }
233
+ )
234
+ end,
235
+ members: decl.members.map do |member|
236
+ case member
237
+ when AST::Members::Base
238
+ resolve_member(resolver, member, context: context)
239
+ when AST::Declarations::Base
240
+ resolve_declaration(
241
+ resolver,
242
+ member,
243
+ outer: outer_,
244
+ prefix: prefix_
245
+ )
246
+ end
247
+ end,
248
+ location: decl.location,
249
+ annotations: decl.annotations,
250
+ comment: decl.comment
251
+ )
252
+ when AST::Declarations::Module
253
+ outer_ = outer + [decl]
254
+ prefix_ = prefix + decl.name.to_namespace
255
+ AST::Declarations::Module.new(
256
+ name: decl.name.with_prefix(prefix),
257
+ type_params: decl.type_params,
258
+ self_type: decl.self_type&.yield_self do |self_type|
259
+ absolute_type(resolver, self_type, context: context)
260
+ end,
261
+ members: decl.members.map do |member|
262
+ case member
263
+ when AST::Members::Base
264
+ resolve_member(resolver, member, context: context)
265
+ when AST::Declarations::Base
266
+ resolve_declaration(
267
+ resolver,
268
+ member,
269
+ outer: outer_,
270
+ prefix: prefix_
271
+ )
272
+ end
273
+ end,
274
+ location: decl.location,
275
+ annotations: decl.annotations,
276
+ comment: decl.comment
277
+ )
278
+ when AST::Declarations::Interface
279
+ AST::Declarations::Interface.new(
280
+ name: decl.name.with_prefix(prefix),
281
+ type_params: decl.type_params,
282
+ members: decl.members.map do |member|
283
+ resolve_member(resolver, member, context: context)
284
+ end,
285
+ comment: decl.comment,
286
+ location: decl.location,
287
+ annotations: decl.annotations
288
+ )
289
+ when AST::Declarations::Alias
290
+ AST::Declarations::Alias.new(
291
+ name: decl.name.with_prefix(prefix),
292
+ type: absolute_type(resolver, decl.type, context: context),
293
+ location: decl.location,
294
+ annotations: decl.annotations,
295
+ comment: decl.comment
296
+ )
297
+
298
+ when AST::Declarations::Constant
299
+ AST::Declarations::Constant.new(
300
+ name: decl.name.with_prefix(prefix),
301
+ type: absolute_type(resolver, decl.type, context: context),
302
+ location: decl.location,
303
+ comment: decl.comment
304
+ )
189
305
  end
190
306
  end
191
307
 
192
- def absolute_type(type, namespace:, &block)
193
- case type
194
- when Types::ClassSingleton
195
- absolute_name_or(type.name, type) do
196
- absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
197
- Types::ClassSingleton.new(name: absolute_name, location: type.location)
198
- end
199
- when Types::ClassInstance
200
- absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
201
- Types::ClassInstance.new(name: absolute_name,
202
- args: type.args.map {|ty|
203
- absolute_type(ty, namespace: namespace, &block)
204
- },
205
- location: type.location)
206
- when Types::Interface
207
- absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
208
- Types::Interface.new(name: absolute_name,
209
- args: type.args.map {|ty|
210
- absolute_type(ty, namespace: namespace, &block)
211
- },
212
- location: type.location)
213
- when Types::Alias
214
- absolute_name_or(type.name, type) do
215
- absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
216
- Types::Alias.new(name: absolute_name, location: type.location)
217
- end
218
- when Types::Tuple
219
- Types::Tuple.new(
220
- types: type.types.map {|ty| absolute_type(ty, namespace: namespace, &block) },
221
- location: type.location
308
+ def resolve_member(resolver, member, context:)
309
+ case member
310
+ when AST::Members::MethodDefinition
311
+ AST::Members::MethodDefinition.new(
312
+ name: member.name,
313
+ kind: member.kind,
314
+ types: member.types.map do |type|
315
+ type.map_type {|ty| absolute_type(resolver, ty, context: context) }
316
+ end,
317
+ comment: member.comment,
318
+ overload: member.overload?,
319
+ annotations: member.annotations,
320
+ attributes: member.attributes,
321
+ location: member.location
322
+ )
323
+ when AST::Members::AttrAccessor
324
+ AST::Members::AttrAccessor.new(
325
+ name: member.name,
326
+ type: absolute_type(resolver, member.type, context: context),
327
+ annotations: member.annotations,
328
+ comment: member.comment,
329
+ location: member.location,
330
+ ivar_name: member.ivar_name
331
+ )
332
+ when AST::Members::AttrReader
333
+ AST::Members::AttrReader.new(
334
+ name: member.name,
335
+ type: absolute_type(resolver, member.type, context: context),
336
+ annotations: member.annotations,
337
+ comment: member.comment,
338
+ location: member.location,
339
+ ivar_name: member.ivar_name
340
+ )
341
+ when AST::Members::AttrWriter
342
+ AST::Members::AttrWriter.new(
343
+ name: member.name,
344
+ type: absolute_type(resolver, member.type, context: context),
345
+ annotations: member.annotations,
346
+ comment: member.comment,
347
+ location: member.location,
348
+ ivar_name: member.ivar_name
222
349
  )
223
- when Types::Record
224
- Types::Record.new(
225
- fields: type.fields.transform_values {|ty| absolute_type(ty, namespace: namespace, &block) },
226
- location: type.location
350
+ when AST::Members::InstanceVariable
351
+ AST::Members::InstanceVariable.new(
352
+ name: member.name,
353
+ type: absolute_type(resolver, member.type, context: context),
354
+ comment: member.comment,
355
+ location: member.location
227
356
  )
228
- when Types::Union
229
- Types::Union.new(
230
- types: type.types.map {|ty| absolute_type(ty, namespace: namespace, &block) },
231
- location: type.location
357
+ when AST::Members::ClassInstanceVariable
358
+ AST::Members::ClassInstanceVariable.new(
359
+ name: member.name,
360
+ type: absolute_type(resolver, member.type, context: context),
361
+ comment: member.comment,
362
+ location: member.location
232
363
  )
233
- when Types::Intersection
234
- Types::Intersection.new(
235
- types: type.types.map {|ty| absolute_type(ty, namespace: namespace, &block) },
236
- location: type.location
364
+ when AST::Members::ClassVariable
365
+ AST::Members::ClassVariable.new(
366
+ name: member.name,
367
+ type: absolute_type(resolver, member.type, context: context),
368
+ comment: member.comment,
369
+ location: member.location
237
370
  )
238
- when Types::Optional
239
- Types::Optional.new(
240
- type: absolute_type(type.type, namespace: namespace, &block),
241
- location: type.location
371
+ when AST::Members::Include
372
+ AST::Members::Include.new(
373
+ name: absolute_type_name(resolver, member.name, context: context),
374
+ args: member.args.map {|type| absolute_type(resolver, type, context: context) },
375
+ comment: member.comment,
376
+ location: member.location,
377
+ annotations: member.annotations
242
378
  )
243
- when Types::Proc
244
- Types::Proc.new(
245
- type: type.type.map_type {|ty| absolute_type(ty, namespace: namespace, &block) },
246
- location: type.location
379
+ when AST::Members::Extend
380
+ AST::Members::Extend.new(
381
+ name: absolute_type_name(resolver, member.name, context: context),
382
+ args: member.args.map {|type| absolute_type(resolver, type, context: context) },
383
+ comment: member.comment,
384
+ location: member.location,
385
+ annotations: member.annotations
386
+ )
387
+ when AST::Members::Prepend
388
+ AST::Members::Prepend.new(
389
+ name: absolute_type_name(resolver, member.name, context: context),
390
+ args: member.args.map {|type| absolute_type(resolver, type, context: context) },
391
+ comment: member.comment,
392
+ location: member.location,
393
+ annotations: member.annotations
247
394
  )
248
395
  else
249
- type
396
+ member
250
397
  end
251
398
  end
252
399
 
253
- # Validates presence of the relative type, and application arity match.
254
- def validate(type, namespace:)
255
- case type
256
- when Types::ClassInstance, Types::Interface
257
- if type.name.namespace.relative?
258
- type = absolute_type(type, namespace: namespace) do |type|
259
- NoTypeFoundError.check!(type.name.absolute!, env: self, location: type.location)
260
- end
261
- end
262
-
263
- decl = find_class(type.name)
264
- unless decl
265
- raise NoTypeFoundError.new(type_name: type.name, location: type.location)
266
- end
267
-
268
- InvalidTypeApplicationError.check!(
269
- type_name: type.name,
270
- args: type.args,
271
- params: decl.type_params,
272
- location: type.location
273
- )
274
- end
400
+ def absolute_type_name(resolver, type_name, context:)
401
+ resolver.resolve(type_name, context: context) || type_name
402
+ end
275
403
 
276
- type.each_type do |type_|
277
- validate(type_, namespace: namespace)
404
+ def absolute_type(resolver, type, context:)
405
+ type.map_type_name do |name|
406
+ absolute_type_name(resolver, name, context: context)
278
407
  end
279
408
  end
280
409
  end