rbs_protobuf 0.3.0 → 1.1.0

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.
@@ -1,13 +1,30 @@
1
1
  module RBSProtobuf
2
2
  module Translator
3
3
  class ProtobufGem < Base
4
+ FIELD_ARRAY = Name::Class.new(TypeName("::Protobuf::Field::FieldArray"))
5
+
6
+ FIELD_HASH = Name::Class.new(TypeName("::Protobuf::Field::FieldHash"))
7
+
8
+ ENUM = Name::Class.new(TypeName("::Protobuf::Enum"))
9
+
10
+ MESSAGE = Name::Class.new(TypeName("::Protobuf::Message"))
11
+
12
+ TO_PROTO = Name::Interface.new(TypeName("_ToProto"))
13
+
14
+ FIELD_ARRAY_a = Name::Alias.new(TypeName("::Protobuf::field_array"))
15
+
16
+ FIELD_HASH_a = Name::Alias.new(TypeName("::Protobuf::field_hash"))
17
+
4
18
  attr_reader :stderr
5
19
 
6
- def initialize(input, upcase_enum:, nested_namespace:, extension:, stderr: STDERR)
20
+ attr_reader :accept_nil_writer
21
+
22
+ def initialize(input, upcase_enum:, nested_namespace:, extension:, accept_nil_writer:, stderr: STDERR)
7
23
  super(input)
8
24
  @upcase_enum = upcase_enum
9
25
  @nested_namespace = nested_namespace
10
26
  @extension = extension
27
+ @accept_nil_writer = accept_nil_writer
11
28
  @stderr = stderr
12
29
  end
13
30
 
@@ -90,26 +107,22 @@ module RBSProtobuf
90
107
  end
91
108
  end
92
109
 
93
- file.extension.group_by(&:extendee).each.with_index do |(name, extensions), index|
110
+ file.extension.each.with_index do |extension, index|
94
111
  if ignore_extension?
95
112
  if print_extension_message?
96
- stderr.puts "Extension for `#{name}` ignored in `#{file.name}`; Set RBS_PROTOBUF_EXTENSION env var to generate RBS for extensions."
113
+ stderr.puts "Extension for `#{extension.extendee}` ignored in `#{file.name}`; Set RBS_PROTOBUF_EXTENSION env var to generate RBS for extensions."
97
114
  end
98
115
  else
99
- exts = extension_to_decl(name,
100
- extensions,
101
- prefix: RBS::Namespace.root,
102
- source_code_info: source_code_info,
103
- path: [7, index])
116
+ ext = extension_to_decl(extension, prefix: RBS::Namespace.root, source_code_info: source_code_info, path: [7, index])
104
117
 
105
118
  if print_extension?
106
119
  stderr.puts "#=========================================================="
107
120
  stderr.puts "# Printing RBS for extensions from #{file.name}"
108
121
  stderr.puts "#"
109
- RBS::Writer.new(out: stderr).write(exts)
122
+ RBS::Writer.new(out: stderr).write([ext])
110
123
  stderr.puts
111
124
  else
112
- decls.push(*exts)
125
+ decls.push(ext)
113
126
  end
114
127
  end
115
128
  end
@@ -119,37 +132,20 @@ module RBSProtobuf
119
132
  end.string
120
133
  end
121
134
 
122
- def message_base_class
123
- RBS::AST::Declarations::Class::Super.new(
124
- name: RBS::TypeName.new(
125
- name: :Message,
126
- namespace: RBS::Namespace.parse("::Protobuf")
127
- ),
128
- args: [],
129
- location: nil
130
- )
131
- end
132
-
133
- def repeated_field_type(type, wtype = type)
134
- factory.instance_type(
135
- factory.type_name("::Protobuf::Field::FieldArray"),
136
- type,
137
- wtype
138
- )
139
- end
140
-
141
135
  def message_to_decl(message, prefix:, message_path:, source_code_info:, path:)
142
136
  class_name = ActiveSupport::Inflector.upcase_first(message.name)
143
137
 
144
138
  RBS::AST::Declarations::Class.new(
145
139
  name: RBS::TypeName.new(name: class_name.to_sym, namespace: prefix),
146
- super_class: message_base_class,
140
+ super_class: MESSAGE.super_class,
147
141
  type_params: [],
148
142
  location: nil,
149
143
  comment: comment_for_path(source_code_info, path, options: message.options),
150
144
  members: [],
151
145
  annotations: []
152
146
  ).tap do |class_decl|
147
+ class_instance_type = factory.instance_type(RBS::TypeName.new(name: class_decl.name.name, namespace: RBS::Namespace.empty))
148
+
153
149
  maps = {}
154
150
 
155
151
  message.nested_type.each_with_index do |nested_type, index|
@@ -177,141 +173,129 @@ module RBSProtobuf
177
173
  )
178
174
  end
179
175
 
180
- field_read_types = {}
181
- field_write_types = {}
176
+ # @type var field_types: Hash[Symbol, [RBS::Types::t, Array[RBS::Types::t], RBS::Types::t]]
177
+ field_types = {}
182
178
 
183
179
  message.field.each_with_index do |field, index|
184
180
  field_name = field.name.to_sym
185
181
  comment = comment_for_path(source_code_info, path + [2, index], options: field.options)
186
182
 
187
- read_type, write_type = field_type(field, maps)
188
-
189
- field_read_types[field_name] = read_type
190
- field_write_types[field_name] = write_type
183
+ read_type, write_types, init_type = field_type(field, maps)
184
+ field_types[field_name] = [read_type, write_types, init_type]
191
185
 
192
- if read_type == write_type
193
- class_decl.members << RBS::AST::Members::AttrAccessor.new(
194
- name: field_name,
195
- type: read_type,
196
- comment: comment,
197
- location: nil,
198
- annotations: [],
199
- ivar_name: false,
200
- kind: :instance
201
- )
202
- else
203
- class_decl.members << RBS::AST::Members::AttrReader.new(
204
- name: field_name,
205
- type: read_type,
206
- comment: comment,
207
- location: nil,
208
- annotations: [],
209
- ivar_name: false,
210
- kind: :instance
211
- )
212
-
213
- class_decl.members << RBS::AST::Members::AttrWriter.new(
214
- name: field_name,
215
- type: write_type,
216
- comment: comment,
217
- location: nil,
218
- annotations: [],
219
- ivar_name: false,
220
- kind: :instance
221
- )
222
- end
223
-
224
- class_decl.members << RBS::AST::Members::MethodDefinition.new(
225
- name: :"#{field_name}!",
226
- types: [
227
- factory.method_type(
228
- type: factory.function(factory.optional_type(read_type))
229
- )
230
- ],
231
- annotations: [],
232
- comment: nil,
233
- location: nil,
234
- overload: false,
235
- kind: :instance
236
- )
186
+ add_field(class_decl.members, name: field_name, read_type: read_type, write_types: write_types, comment: comment)
237
187
  end
238
188
 
239
189
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
240
190
  name: :initialize,
241
- types: [
242
- factory.method_type(
243
- type: factory.function().update(
244
- optional_keywords: field_write_types.transform_values {|ty|
245
- factory.param(ty)
246
- }
247
- )
248
- )
191
+ overloads: [
192
+ RBS::AST::Members::MethodDefinition::Overload.new(
193
+ method_type: factory.method_type(
194
+ type: factory.function().update(
195
+ optional_keywords: field_types.transform_values {|pair|
196
+ _, _, init_type = pair
197
+ factory.param(init_type)
198
+ }
199
+ )
200
+ ),
201
+ annotations: []
202
+ ),
249
203
  ],
250
204
  annotations: [],
251
205
  comment: nil,
252
206
  location: nil,
253
- overload: false,
207
+ overloading: false,
208
+ visibility: nil,
254
209
  kind: :instance
255
210
  )
256
211
 
257
- unless field_read_types.empty?
212
+ unless field_types.empty?
258
213
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
259
214
  name: :[],
260
- types:
261
- field_read_types.keys.map do |key|
262
- factory.method_type(
263
- type: factory.function(field_read_types[key]).update(
264
- required_positionals: [
265
- factory.param(factory.literal_type(key))
266
- ]
267
- )
268
- )
269
- end +
270
- [
271
- factory.method_type(
272
- type: factory.function(factory.untyped).update(
215
+ overloads:
216
+ field_types.map do |field_name, pair|
217
+ read_type, _ = pair
218
+
219
+ RBS::AST::Members::MethodDefinition::Overload.new(
220
+ method_type: factory.method_type(
221
+ type: factory.function(read_type).update(
273
222
  required_positionals: [
274
- factory.param(RBS::BuiltinNames::Symbol.instance_type)
223
+ factory.param(factory.literal_type(field_name))
275
224
  ]
276
225
  )
226
+ ),
227
+ annotations: []
228
+ )
229
+ end +
230
+ [
231
+ RBS::AST::Members::MethodDefinition::Overload.new(
232
+ method_type: factory.method_type(
233
+ type: factory.function(factory.untyped).update(
234
+ required_positionals: [
235
+ factory.param(RBS::BuiltinNames::Symbol.instance_type)
236
+ ]
237
+ )
238
+ ),
239
+ annotations: []
277
240
  )
278
241
  ],
279
242
  annotations: [],
280
243
  comment: nil,
281
244
  location: nil,
282
- overload: false,
245
+ overloading: false,
246
+ visibility: nil,
283
247
  kind: :instance
284
248
  )
285
- end
286
249
 
287
- unless field_write_types.empty?
288
250
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
289
251
  name: :[]=,
290
- types:
291
- field_write_types.keys.map do |key|
292
- factory.method_type(
293
- type: factory.function(field_write_types[key]).update(
294
- required_positionals: [
295
- factory.literal_type(key),
296
- field_write_types[key]
297
- ].map {|t| factory.param(t) }
298
- )
299
- )
252
+ overloads:
253
+ field_types.flat_map do |field_name, pair|
254
+ read_type, write_types = pair
255
+
256
+ [read_type, *write_types].map do |type|
257
+ method_type =
258
+ if (type_param, type_var = interface_type?(type))
259
+ factory.method_type(
260
+ type: factory.function(type_var).update(
261
+ required_positionals: [
262
+ factory.literal_type(field_name),
263
+ type_var
264
+ ].map {|t| factory.param(t) }
265
+ )
266
+ ).update(type_params: [type_param])
267
+ else
268
+ factory.method_type(
269
+ type: factory.function(type).update(
270
+ required_positionals: [
271
+ factory.literal_type(field_name),
272
+ type
273
+ ].map {|t| factory.param(t) }
274
+ )
275
+ )
276
+ end
277
+
278
+ RBS::AST::Members::MethodDefinition::Overload.new(method_type: method_type, annotations: [])
279
+ end
300
280
  end +
301
281
  [
302
- factory.method_type(
303
- type: factory.function(factory.untyped).update(
304
- required_positionals: [
305
- RBS::BuiltinNames::Symbol.instance_type,
306
- factory.untyped
307
- ].map {|t| factory.param(t) }
308
- )
282
+ RBS::AST::Members::MethodDefinition::Overload.new(
283
+ method_type: factory.method_type(
284
+ type: factory.function(factory.untyped).update(
285
+ required_positionals: [
286
+ RBS::BuiltinNames::Symbol.instance_type,
287
+ factory.untyped
288
+ ].map {|t| factory.param(t) }
289
+ )
290
+ ),
291
+ annotations: []
309
292
  )
310
293
  ],
311
294
  annotations: [],
312
295
  comment: nil,
313
296
  location: nil,
314
- overload: false,
297
+ overloading: false,
298
+ visibility: nil,
315
299
  kind: :instance
316
300
  )
317
301
  end
@@ -320,95 +304,342 @@ module RBSProtobuf
320
304
  if field.type == FieldDescriptorProto::Type::TYPE_BOOL
321
305
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
322
306
  name: :"#{field.name}?",
323
- types: [
324
- factory.method_type(
325
- type: factory.function(factory.bool_type)
307
+ overloads: [
308
+ RBS::AST::Members::MethodDefinition::Overload.new(
309
+ method_type: factory.method_type(
310
+ type: factory.function(factory.bool_type)
311
+ ),
312
+ annotations: []
326
313
  )
327
314
  ],
328
315
  annotations: [],
329
316
  comment: nil,
330
317
  location: nil,
331
- overload: false,
318
+ overloading: false,
319
+ visibility: nil,
332
320
  kind: :instance
333
321
  )
334
322
  end
335
323
  end
324
+
325
+ class_decl.members << RBS::AST::Declarations::Interface.new(
326
+ name: TO_PROTO.name,
327
+ type_params: [],
328
+ members: [],
329
+ annotations: [],
330
+ comment: nil,
331
+ location: nil
332
+ ).tap do |interface_decl|
333
+ interface_decl.members << RBS::AST::Members::MethodDefinition.new(
334
+ name: :to_proto,
335
+ overloads: [
336
+ RBS::AST::Members::MethodDefinition::Overload.new(
337
+ method_type: factory.method_type(
338
+ type: factory.function(class_instance_type)
339
+ ),
340
+ annotations: []
341
+ )
342
+ ],
343
+ annotations: [],
344
+ comment: nil,
345
+ location: nil,
346
+ overloading: false,
347
+ visibility: nil,
348
+ kind: :instance
349
+ )
350
+ end
351
+
352
+ class_decl.members << RBS::AST::Declarations::TypeAlias.new(
353
+ name: TypeName("init"),
354
+ type_params: [],
355
+ type: factory.union_type(class_instance_type, TO_PROTO[]),
356
+ annotations: [],
357
+ comment: RBS::AST::Comment.new(string: "The type of `#initialize` parameter.", location: nil),
358
+ location: nil
359
+ )
360
+
361
+ class_decl.members << RBS::AST::Declarations::TypeAlias.new(
362
+ name: TypeName("field_array"),
363
+ type_params: [],
364
+ type: FIELD_ARRAY[
365
+ class_instance_type,
366
+ factory.union_type(class_instance_type, TO_PROTO[])
367
+ ],
368
+ annotations: [],
369
+ comment: RBS::AST::Comment.new(string: "The type of `repeated` field.", location: nil),
370
+ location: nil
371
+ )
372
+
373
+ class_decl.members << RBS::AST::Declarations::TypeAlias.new(
374
+ name: TypeName("field_hash"),
375
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
376
+ type: FIELD_HASH[
377
+ factory.type_var(:KEY),
378
+ class_instance_type,
379
+ factory.union_type(class_instance_type, TO_PROTO[])
380
+ ],
381
+ annotations: [],
382
+ comment: RBS::AST::Comment.new(string: "The type of `map` field.", location: nil),
383
+ location: nil
384
+ )
385
+
386
+ class_decl.members << RBS::AST::Declarations::TypeAlias.new(
387
+ name: TypeName("array"),
388
+ type_params: [],
389
+ type: RBS::BuiltinNames::Array.instance_type(factory.union_type(class_instance_type, TO_PROTO[])),
390
+ annotations: [],
391
+ comment: nil,
392
+ location: nil
393
+ )
394
+
395
+ class_decl.members << RBS::AST::Declarations::TypeAlias.new(
396
+ name: TypeName("hash"),
397
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
398
+ type: RBS::BuiltinNames::Hash.instance_type(
399
+ factory.type_var(:KEY),
400
+ factory.union_type(class_instance_type, TO_PROTO[])
401
+ ),
402
+ annotations: [],
403
+ comment: nil,
404
+ location: nil
405
+ )
336
406
  end
337
407
  end
338
408
 
409
+ def message_to_proto_type(type)
410
+ namespace = type.name.to_namespace
411
+ RBS::Types::Interface.new(
412
+ name: RBS::TypeName.new(name: :_ToProto, namespace: namespace),
413
+ args: [],
414
+ location: nil
415
+ )
416
+ end
417
+
418
+ def message_init_type(type)
419
+ RBS::Types::Alias.new(
420
+ name: RBS::TypeName.new(name: :init, namespace: type.name.to_namespace),
421
+ args: [],
422
+ location: nil
423
+ )
424
+ end
425
+
426
+ def message_field_array_type(type)
427
+ RBS::Types::Alias.new(
428
+ name: RBS::TypeName.new(name: :field_array, namespace: type.name.to_namespace),
429
+ args: [],
430
+ location: nil
431
+ )
432
+ end
433
+
434
+ def message_array_type(type)
435
+ RBS::Types::Alias.new(
436
+ name: RBS::TypeName.new(name: :array, namespace: type.name.to_namespace),
437
+ args: [],
438
+ location: nil
439
+ )
440
+ end
441
+
442
+ def message_hash_type(type, key)
443
+ RBS::Types::Alias.new(
444
+ name: RBS::TypeName.new(name: :hash, namespace: type.name.to_namespace),
445
+ args: [key],
446
+ location: nil
447
+ )
448
+ end
449
+
450
+ def message_field_hash_type(type, key)
451
+ RBS::Types::Alias.new(
452
+ name: RBS::TypeName.new(name: :field_hash, namespace: type.name.to_namespace),
453
+ args: [key],
454
+ location: nil
455
+ )
456
+ end
457
+
339
458
  def field_type(field, maps)
340
- case
341
- when field.type == FieldDescriptorProto::Type::TYPE_MESSAGE
342
- if maps.key?(field.type_name)
343
- key_field, value_field = maps[field.type_name]
344
-
345
- key_type_r, _ = field_type(key_field, maps)
346
- value_type_r, value_type_w = field_type(value_field, maps)
347
-
348
- hash_type = factory.instance_type(
349
- factory.type_name("::Protobuf::Field::FieldHash"),
350
- key_type_r,
351
- factory.unwrap_optional(value_type_r),
352
- factory.unwrap_optional(value_type_w)
353
- )
459
+ # @type var triple: [RBS::Types::t, Array[RBS::Types::t], RBS::Types::t]
460
+ triple =
461
+ case
462
+ when field.type == FieldDescriptorProto::Type::TYPE_MESSAGE
463
+ if maps.key?(field.type_name)
464
+ key_field, value_field = maps[field.type_name]
465
+
466
+ key_type_r, _ = field_type(key_field, maps)
467
+ value_type_r, value_write_types = field_type(value_field, maps)
468
+
469
+ value_type_r = factory.unwrap_optional(value_type_r)
470
+ value_write_types = value_write_types.map {|type| factory.unwrap_optional(type) }
471
+
472
+ case value_field.type
473
+ when FieldDescriptorProto::Type::TYPE_MESSAGE, FieldDescriptorProto::Type::TYPE_ENUM
474
+ value_type_r.is_a?(RBS::Types::ClassInstance) or raise
475
+ [
476
+ message_field_hash_type(value_type_r, key_type_r),
477
+ [message_hash_type(value_type_r, key_type_r)],
478
+ message_hash_type(value_type_r, key_type_r)
479
+ ]
480
+ else
481
+ hash_type = FIELD_HASH[
482
+ key_type_r,
483
+ value_type_r,
484
+ factory.union_type(value_type_r, *value_write_types)
485
+ ]
486
+
487
+ [
488
+ FIELD_HASH_a[key_type_r, value_type_r],
489
+ [RBS::BuiltinNames::Hash.instance_type(key_type_r, value_type_r)],
490
+ RBS::BuiltinNames::Hash.instance_type(key_type_r, value_type_r)
491
+ ]
492
+ end
493
+ else
494
+ type = message_type(field.type_name)
354
495
 
355
- [
356
- hash_type,
357
- hash_type
358
- ]
359
- else
496
+ case field.label
497
+ when FieldDescriptorProto::Label::LABEL_OPTIONAL
498
+ [
499
+ factory.optional_type(type),
500
+ [
501
+ factory.optional_type(message_to_proto_type(type))
502
+ ],
503
+ factory.optional_type(message_init_type(type))
504
+ ]
505
+ when FieldDescriptorProto::Label::LABEL_REPEATED
506
+ [
507
+ message_field_array_type(type),
508
+ [
509
+ message_array_type(type)
510
+ ],
511
+ message_array_type(type)
512
+ ]
513
+ else
514
+ [
515
+ type,
516
+ [message_to_proto_type(type)],
517
+ message_init_type(type)
518
+ ]
519
+ end
520
+ end
521
+ when field.type == FieldDescriptorProto::Type::TYPE_ENUM
360
522
  type = message_type(field.type_name)
361
-
362
- case field.label
363
- when FieldDescriptorProto::Label::LABEL_OPTIONAL
364
- type = factory.optional_type(type)
365
- [type, type]
366
- when FieldDescriptorProto::Label::LABEL_REPEATED
367
- type = repeated_field_type(type)
368
- [type, type]
523
+ enum_namespace = type.name.to_namespace
524
+ values = factory.alias_type(RBS::TypeName.new(name: :values, namespace: enum_namespace))
525
+
526
+ if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
527
+ [
528
+ message_field_array_type(type),
529
+ [message_array_type(type)],
530
+ message_array_type(type)
531
+ ]
532
+ else
533
+ [
534
+ type,
535
+ [values],
536
+ message_init_type(type)
537
+ ]
538
+ end
539
+ else
540
+ type = base_type(field.type)
541
+
542
+ if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
543
+ [
544
+ FIELD_ARRAY_a[type],
545
+ [RBS::BuiltinNames::Array.instance_type(type)],
546
+ RBS::BuiltinNames::Array.instance_type(type)
547
+ ]
369
548
  else
370
- [type, factory.optional_type(type)]
549
+ [type, [], type]
371
550
  end
372
551
  end
373
- when field.type == FieldDescriptorProto::Type::TYPE_ENUM
374
- type = message_type(field.type_name)
375
- enum_namespace = type.name.to_namespace
376
552
 
377
- wtype = factory.union_type(
378
- type,
379
- factory.alias_type(RBS::TypeName.new(name: :values, namespace: enum_namespace))
380
- )
381
-
382
- if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
383
- type = repeated_field_type(type, wtype)
553
+ if accept_nil_writer
554
+ read_type, write_types, init_type = triple
555
+ [
556
+ read_type,
557
+ ([factory.optional_type(read_type)] + write_types.map {|t| factory.optional_type(t) }).uniq,
558
+ factory.optional_type(init_type)
559
+ ]
560
+ else
561
+ triple
562
+ end
563
+ end
384
564
 
565
+ def interface_type?(type)
566
+ case
567
+ when type.is_a?(RBS::Types::Interface)
568
+ [
569
+ RBS::AST::TypeParam.new(name: :M, upper_bound: type, variance: :invariant, location: nil),
570
+ factory.type_var(:M)
571
+ ]
572
+ when type.is_a?(RBS::Types::Optional)
573
+ if (type = type.type).is_a?(RBS::Types::Interface)
385
574
  [
386
- type,
387
- type
388
- ]
389
- else
390
- [
391
- type,
392
- factory.optional_type(wtype)
575
+ RBS::AST::TypeParam.new(name: :M, upper_bound: type, variance: :invariant, location: nil),
576
+ factory.optional_type(factory.type_var(:M))
393
577
  ]
394
578
  end
395
- else
396
- type = base_type(field.type)
397
-
398
- if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
399
- type = repeated_field_type(type)
400
- [type, type]
401
- else
402
- [type, factory.optional_type(type)]
403
- end
404
579
  end
405
580
  end
406
581
 
407
- def enum_base_class
408
- RBS::AST::Declarations::Class::Super.new(
409
- name: factory.type_name("::Protobuf::Enum"),
410
- args: [],
411
- location: nil
582
+ def add_field(members, name:, read_type:, write_types:, comment:)
583
+ members << RBS::AST::Members::AttrAccessor.new(
584
+ name: name,
585
+ type: read_type,
586
+ comment: comment,
587
+ location: nil,
588
+ annotations: [],
589
+ ivar_name: false,
590
+ kind: :instance
591
+ )
592
+
593
+ unless write_types.empty?
594
+ members << RBS::AST::Members::MethodDefinition.new(
595
+ name: :"#{name}=",
596
+ overloads:
597
+ write_types.map do |write_type|
598
+ method_type =
599
+ if (type_param, type = interface_type?(write_type))
600
+ factory.method_type(
601
+ type: factory.function(type).update(
602
+ required_positionals:[factory.param(type)]
603
+ )
604
+ ).update(type_params: [type_param])
605
+ else
606
+ factory.method_type(
607
+ type: factory.function(write_type).update(
608
+ required_positionals:[factory.param(write_type)]
609
+ )
610
+ )
611
+ end
612
+
613
+ RBS::AST::Members::MethodDefinition::Overload.new(
614
+ method_type: method_type,
615
+ annotations: []
616
+ )
617
+ end,
618
+ annotations: [],
619
+ comment: comment,
620
+ location: nil,
621
+ overloading: true,
622
+ visibility: nil,
623
+ kind: :instance
624
+ )
625
+ end
626
+
627
+ members << RBS::AST::Members::MethodDefinition.new(
628
+ name: :"#{name}!",
629
+ overloads: [
630
+ RBS::AST::Members::MethodDefinition::Overload.new(
631
+ method_type: factory.method_type(
632
+ type: factory.function(factory.optional_type(read_type))
633
+ ),
634
+ annotations: []
635
+ )
636
+ ],
637
+ annotations: [],
638
+ comment: nil,
639
+ location: nil,
640
+ overloading: false,
641
+ visibility: nil,
642
+ kind: :instance
412
643
  )
413
644
  end
414
645
 
@@ -425,7 +656,7 @@ module RBSProtobuf
425
656
 
426
657
  RBS::AST::Declarations::Class.new(
427
658
  name: RBS::TypeName.new(name: enum_name.to_sym, namespace: prefix),
428
- super_class: enum_base_class(),
659
+ super_class: ENUM.super_class,
429
660
  type_params: factory.module_type_params(),
430
661
  members: [],
431
662
  comment: comment_for_path(source_code_info, path, options: enum_type.options),
@@ -444,7 +675,7 @@ module RBSProtobuf
444
675
  factory.literal_type(v.number)
445
676
  end.uniq
446
677
 
447
- enum_decl.members << RBS::AST::Declarations::Alias.new(
678
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
448
679
  name: factory.type_name("names"),
449
680
  type_params: [],
450
681
  type: factory.union_type(*names),
@@ -453,7 +684,7 @@ module RBSProtobuf
453
684
  annotations: []
454
685
  )
455
686
 
456
- enum_decl.members << RBS::AST::Declarations::Alias.new(
687
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
457
688
  name: factory.type_name("strings"),
458
689
  type_params: [],
459
690
  type: factory.union_type(*strings),
@@ -462,7 +693,7 @@ module RBSProtobuf
462
693
  annotations: []
463
694
  )
464
695
 
465
- enum_decl.members << RBS::AST::Declarations::Alias.new(
696
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
466
697
  name: factory.type_name("tags"),
467
698
  type_params: [],
468
699
  type: factory.union_type(*tags),
@@ -471,7 +702,7 @@ module RBSProtobuf
471
702
  annotations: []
472
703
  )
473
704
 
474
- enum_decl.members << RBS::AST::Declarations::Alias.new(
705
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
475
706
  name: factory.type_name("values"),
476
707
  type_params: [],
477
708
  type: factory.union_type(
@@ -514,95 +745,143 @@ module RBSProtobuf
514
745
  location: nil
515
746
  )
516
747
  end
517
- end
518
- end
519
748
 
520
- def extension_to_decl(extendee_name, extensions, prefix:, source_code_info:, path:)
521
- class_name = message_type(extendee_name).name
749
+ enum_instance_type = factory.instance_type(RBS::TypeName.new(name: enum_name.to_sym, namespace: RBS::Namespace.empty))
750
+ values_type = factory.alias_type(RBS::TypeName.new(name: :values, namespace: RBS::Namespace.empty))
522
751
 
523
- extensions.map do |field|
524
- field_name = field.name.to_sym
752
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
753
+ name: TypeName("init"),
754
+ type_params: [],
755
+ type: factory.union_type(enum_instance_type, values_type),
756
+ annotations: [],
757
+ comment: RBS::AST::Comment.new(string: "The type of `#initialize` parameter.", location: nil),
758
+ location: nil
759
+ )
525
760
 
526
- RBS::AST::Declarations::Class.new(
527
- name: class_name,
528
- super_class: nil,
761
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
762
+ name: TypeName("field_array"),
529
763
  type_params: [],
530
- location: nil,
764
+ type: FIELD_ARRAY[
765
+ enum_instance_type,
766
+ factory.union_type(enum_instance_type, values_type)
767
+ ],
768
+ annotations: [],
769
+ comment: RBS::AST::Comment.new(string: "The type of `repeated` field.", location: nil),
770
+ location: nil
771
+ )
772
+
773
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
774
+ name: TypeName("field_hash"),
775
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
776
+ type: FIELD_HASH[
777
+ factory.type_var(:KEY),
778
+ enum_instance_type,
779
+ factory.union_type(enum_instance_type, values_type)
780
+ ],
781
+ annotations: [],
782
+ comment: RBS::AST::Comment.new(string: "The type of `map` field.", location: nil),
783
+ location: nil
784
+ )
785
+
786
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
787
+ name: TypeName("array"),
788
+ type_params: [],
789
+ type: RBS::BuiltinNames::Array.instance_type(factory.union_type(enum_instance_type, values_type)),
790
+ annotations: [],
531
791
  comment: nil,
532
- members: [],
533
- annotations: []
534
- ).tap do |class_decl|
535
- read_type, write_type = field_type(field, {})
792
+ location: nil
793
+ )
536
794
 
537
- if read_type == write_type
538
- class_decl.members << RBS::AST::Members::AttrAccessor.new(
539
- name: field_name,
540
- type: read_type,
541
- comment: nil,
542
- location: nil,
543
- annotations: [],
544
- ivar_name: false,
545
- kind: :instance
546
- )
547
- else
548
- class_decl.members << RBS::AST::Members::AttrReader.new(
549
- name: field_name,
550
- type: read_type,
551
- comment: nil,
552
- location: nil,
553
- annotations: [],
554
- ivar_name: false,
555
- kind: :instance
556
- )
795
+ enum_decl.members << RBS::AST::Declarations::TypeAlias.new(
796
+ name: TypeName("hash"),
797
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
798
+ type: RBS::BuiltinNames::Hash.instance_type(
799
+ factory.type_var(:KEY),
800
+ factory.union_type(enum_instance_type, values_type)
801
+ ),
802
+ annotations: [],
803
+ comment: nil,
804
+ location: nil
805
+ )
806
+ end
807
+ end
557
808
 
558
- class_decl.members << RBS::AST::Members::AttrWriter.new(
559
- name: field_name,
560
- type: write_type,
561
- comment: nil,
562
- location: nil,
563
- annotations: [],
564
- ivar_name: false,
565
- kind: :instance
566
- )
567
- end
809
+ def extension_to_decl(extension, prefix:, source_code_info:, path:)
810
+ class_name = message_type(extension.extendee).name
568
811
 
569
- class_decl.members << RBS::AST::Members::MethodDefinition.new(
570
- name: :[],
571
- types: [
572
- factory.method_type(
812
+ comment = comment_for_path(source_code_info, path, options: extension.options)
813
+ field_name = extension.name.to_sym
814
+
815
+ RBS::AST::Declarations::Class.new(
816
+ name: class_name,
817
+ super_class: nil,
818
+ type_params: [],
819
+ location: nil,
820
+ comment: nil,
821
+ members: [],
822
+ annotations: []
823
+ ).tap do |class_decl|
824
+ read_type, write_types, _ = field_type(extension, {})
825
+
826
+ add_field(class_decl.members, name: field_name, read_type: read_type, write_types: write_types, comment: comment)
827
+
828
+ class_decl.members << RBS::AST::Members::MethodDefinition.new(
829
+ name: :[],
830
+ overloads: [
831
+ RBS::AST::Members::MethodDefinition::Overload.new(
832
+ method_type: factory.method_type(
573
833
  type: factory.function(read_type).update(
574
834
  required_positionals: [
575
835
  factory.param(factory.literal_type(field_name))
576
836
  ]
577
837
  )
578
- )
579
- ],
580
- annotations: [],
581
- comment: nil,
582
- location: nil,
583
- overload: true,
584
- kind: :instance
585
- )
838
+ ),
839
+ annotations: []
840
+ )
841
+ ],
842
+ annotations: [],
843
+ comment: nil,
844
+ location: nil,
845
+ overloading: true,
846
+ visibility: nil,
847
+ kind: :instance
848
+ )
586
849
 
587
- class_decl.members << RBS::AST::Members::MethodDefinition.new(
588
- name: :[]=,
589
- types: [
590
- factory.method_type(
591
- type: factory.function(write_type).update(
592
- required_positionals: [
593
- factory.param(factory.literal_type(field_name)),
594
- factory.param(write_type)
595
- ]
850
+ class_decl.members << RBS::AST::Members::MethodDefinition.new(
851
+ name: :[]=,
852
+ overloads: [read_type, *write_types].map do |write_type|
853
+ method_type =
854
+ if (type_param, type_var = interface_type?(write_type))
855
+ factory.method_type(
856
+ type: factory.function(type_var).update(
857
+ required_positionals: [
858
+ factory.param(factory.literal_type(field_name)),
859
+ factory.param(type_var)
860
+ ]
861
+ )
862
+ ).update(type_params: [type_param])
863
+ else
864
+ factory.method_type(
865
+ type: factory.function(write_type).update(
866
+ required_positionals: [
867
+ factory.param(factory.literal_type(field_name)),
868
+ factory.param(write_type)
869
+ ]
870
+ )
596
871
  )
597
- )
598
- ],
599
- annotations: [],
600
- comment: nil,
601
- location: nil,
602
- overload: true,
603
- kind: :instance
604
- )
605
- end
872
+ end
873
+ RBS::AST::Members::MethodDefinition::Overload.new(
874
+ method_type: method_type,
875
+ annotations: []
876
+ )
877
+ end,
878
+ annotations: [],
879
+ comment: nil,
880
+ location: nil,
881
+ overloading: true,
882
+ visibility: nil,
883
+ kind: :instance
884
+ )
606
885
  end
607
886
  end
608
887