rbs_protobuf 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,43 @@
1
1
  module RBSProtobuf
2
2
  module Translator
3
3
  class ProtobufGem < Base
4
- def initialize(input, upcase_enum:, nested_namespace:)
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
+
18
+ attr_reader :stderr
19
+
20
+ attr_reader :accept_nil_writer
21
+
22
+ def initialize(input, upcase_enum:, nested_namespace:, extension:, accept_nil_writer:, stderr: STDERR)
5
23
  super(input)
6
24
  @upcase_enum = upcase_enum
7
25
  @nested_namespace = nested_namespace
26
+ @extension = extension
27
+ @accept_nil_writer = accept_nil_writer
28
+ @stderr = stderr
29
+ end
30
+
31
+ def ignore_extension?
32
+ !@extension
33
+ end
34
+
35
+ def print_extension_message?
36
+ @extension == nil
37
+ end
38
+
39
+ def print_extension?
40
+ @extension == :print
8
41
  end
9
42
 
10
43
  def upcase_enum?
@@ -74,12 +107,24 @@ module RBSProtobuf
74
107
  end
75
108
  end
76
109
 
77
- file.extension.group_by(&:extendee).each.with_index do |(name, extensions), index|
78
- decls.push(*extension_to_decl(name,
79
- extensions,
80
- prefix: RBS::Namespace.root,
81
- source_code_info: source_code_info,
82
- path: [7, index]))
110
+ file.extension.each.with_index do |extension, index|
111
+ if ignore_extension?
112
+ if print_extension_message?
113
+ stderr.puts "Extension for `#{extension.extendee}` ignored in `#{file.name}`; Set RBS_PROTOBUF_EXTENSION env var to generate RBS for extensions."
114
+ end
115
+ else
116
+ ext = extension_to_decl(extension, prefix: RBS::Namespace.root, source_code_info: source_code_info, path: [7, index])
117
+
118
+ if print_extension?
119
+ stderr.puts "#=========================================================="
120
+ stderr.puts "# Printing RBS for extensions from #{file.name}"
121
+ stderr.puts "#"
122
+ RBS::Writer.new(out: stderr).write([ext])
123
+ stderr.puts
124
+ else
125
+ decls.push(ext)
126
+ end
127
+ end
83
128
  end
84
129
 
85
130
  StringIO.new.tap do |io|
@@ -87,38 +132,20 @@ module RBSProtobuf
87
132
  end.string
88
133
  end
89
134
 
90
- def message_base_class
91
- RBS::AST::Declarations::Class::Super.new(
92
- name: RBS::TypeName.new(
93
- name: :Message,
94
- namespace: RBS::Namespace.parse("::Protobuf")
95
- ),
96
- args: [],
97
- location: nil
98
- )
99
- end
100
-
101
- def repeated_field_type(type, wtype = type)
102
- factory.instance_type(
103
- factory.type_name("::Protobuf::Field::FieldArray"),
104
- type,
105
- wtype
106
- )
107
- end
108
-
109
135
  def message_to_decl(message, prefix:, message_path:, source_code_info:, path:)
110
136
  class_name = ActiveSupport::Inflector.upcase_first(message.name)
111
- decl_namespace = prefix.append(class_name.to_sym)
112
137
 
113
138
  RBS::AST::Declarations::Class.new(
114
139
  name: RBS::TypeName.new(name: class_name.to_sym, namespace: prefix),
115
- super_class: message_base_class,
116
- type_params: RBS::AST::Declarations::ModuleTypeParams.empty,
140
+ super_class: MESSAGE.super_class,
141
+ type_params: [],
117
142
  location: nil,
118
- comment: comment_for_path(source_code_info, path),
143
+ comment: comment_for_path(source_code_info, path, options: message.options),
119
144
  members: [],
120
145
  annotations: []
121
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
+
122
149
  maps = {}
123
150
 
124
151
  message.nested_type.each_with_index do |nested_type, index|
@@ -146,49 +173,17 @@ module RBSProtobuf
146
173
  )
147
174
  end
148
175
 
149
- field_read_types = {}
150
- field_write_types = {}
176
+ # @type var field_types: Hash[Symbol, [RBS::Types::t, Array[RBS::Types::t], RBS::Types::t]]
177
+ field_types = {}
151
178
 
152
179
  message.field.each_with_index do |field, index|
153
180
  field_name = field.name.to_sym
154
- comment = comment_for_path(source_code_info, path + [2, index])
181
+ comment = comment_for_path(source_code_info, path + [2, index], options: field.options)
155
182
 
156
- read_type, write_type = field_type(field, maps)
183
+ read_type, write_types, init_type = field_type(field, maps)
184
+ field_types[field_name] = [read_type, write_types, init_type]
157
185
 
158
- field_read_types[field_name] = read_type
159
- field_write_types[field_name] = write_type
160
-
161
- if read_type == write_type
162
- class_decl.members << RBS::AST::Members::AttrAccessor.new(
163
- name: field_name,
164
- type: read_type,
165
- comment: comment,
166
- location: nil,
167
- annotations: [],
168
- ivar_name: false,
169
- kind: :instance
170
- )
171
- else
172
- class_decl.members << RBS::AST::Members::AttrReader.new(
173
- name: field_name,
174
- type: read_type,
175
- comment: comment,
176
- location: nil,
177
- annotations: [],
178
- ivar_name: false,
179
- kind: :instance
180
- )
181
-
182
- class_decl.members << RBS::AST::Members::AttrWriter.new(
183
- name: field_name,
184
- type: write_type,
185
- comment: comment,
186
- location: nil,
187
- annotations: [],
188
- ivar_name: false,
189
- kind: :instance
190
- )
191
- end
186
+ add_field(class_decl.members, name: field_name, read_type: read_type, write_types: write_types, comment: comment)
192
187
  end
193
188
 
194
189
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
@@ -196,8 +191,9 @@ module RBSProtobuf
196
191
  types: [
197
192
  factory.method_type(
198
193
  type: factory.function().update(
199
- optional_keywords: field_write_types.transform_values {|ty|
200
- factory.param(ty)
194
+ optional_keywords: field_types.transform_values {|pair|
195
+ _, _, init_type = pair
196
+ factory.param(init_type)
201
197
  }
202
198
  )
203
199
  )
@@ -209,15 +205,17 @@ module RBSProtobuf
209
205
  kind: :instance
210
206
  )
211
207
 
212
- unless field_read_types.empty?
208
+ unless field_types.empty?
213
209
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
214
210
  name: :[],
215
211
  types:
216
- field_read_types.keys.map do |key|
212
+ field_types.map do |field_name, pair|
213
+ read_type, _ = pair
214
+
217
215
  factory.method_type(
218
- type: factory.function(field_read_types[key]).update(
216
+ type: factory.function(read_type).update(
219
217
  required_positionals: [
220
- factory.param(factory.literal_type(key))
218
+ factory.param(factory.literal_type(field_name))
221
219
  ]
222
220
  )
223
221
  )
@@ -237,21 +235,34 @@ module RBSProtobuf
237
235
  overload: false,
238
236
  kind: :instance
239
237
  )
240
- end
241
238
 
242
- unless field_write_types.empty?
243
239
  class_decl.members << RBS::AST::Members::MethodDefinition.new(
244
240
  name: :[]=,
245
241
  types:
246
- field_write_types.keys.map do |key|
247
- factory.method_type(
248
- type: factory.function(field_write_types[key]).update(
249
- required_positionals: [
250
- factory.literal_type(key),
251
- field_write_types[key]
252
- ].map {|t| factory.param(t) }
253
- )
254
- )
242
+ field_types.flat_map do |field_name, pair|
243
+ read_type, write_types = pair
244
+
245
+ [read_type, *write_types].map do |type|
246
+ if (type_param, type_var = interface_type?(type))
247
+ factory.method_type(
248
+ type: factory.function(type_var).update(
249
+ required_positionals: [
250
+ factory.literal_type(field_name),
251
+ type_var
252
+ ].map {|t| factory.param(t) }
253
+ )
254
+ ).update(type_params: [type_param])
255
+ else
256
+ factory.method_type(
257
+ type: factory.function(type).update(
258
+ required_positionals: [
259
+ factory.literal_type(field_name),
260
+ type
261
+ ].map {|t| factory.param(t) }
262
+ )
263
+ )
264
+ end
265
+ end
255
266
  end +
256
267
  [
257
268
  factory.method_type(
@@ -288,82 +299,310 @@ module RBSProtobuf
288
299
  )
289
300
  end
290
301
  end
302
+
303
+ class_decl.members << RBS::AST::Declarations::Interface.new(
304
+ name: TO_PROTO.name,
305
+ type_params: [],
306
+ members: [],
307
+ annotations: [],
308
+ comment: nil,
309
+ location: nil
310
+ ).tap do |interface_decl|
311
+ interface_decl.members << RBS::AST::Members::MethodDefinition.new(
312
+ name: :to_proto,
313
+ types: [
314
+ factory.method_type(
315
+ type: factory.function(class_instance_type)
316
+ )
317
+ ],
318
+ annotations: [],
319
+ comment: nil,
320
+ location: nil,
321
+ overload: false,
322
+ kind: :instance
323
+ )
324
+ end
325
+
326
+ class_decl.members << RBS::AST::Declarations::Alias.new(
327
+ name: TypeName("init"),
328
+ type_params: [],
329
+ type: factory.union_type(class_instance_type, TO_PROTO[]),
330
+ annotations: [],
331
+ comment: RBS::AST::Comment.new(string: "The type of `#initialize` parameter.", location: nil),
332
+ location: nil
333
+ )
334
+
335
+ class_decl.members << RBS::AST::Declarations::Alias.new(
336
+ name: TypeName("field_array"),
337
+ type_params: [],
338
+ type: FIELD_ARRAY[
339
+ class_instance_type,
340
+ factory.union_type(class_instance_type, TO_PROTO[])
341
+ ],
342
+ annotations: [],
343
+ comment: RBS::AST::Comment.new(string: "The type of `repeated` field.", location: nil),
344
+ location: nil
345
+ )
346
+
347
+ class_decl.members << RBS::AST::Declarations::Alias.new(
348
+ name: TypeName("field_hash"),
349
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
350
+ type: FIELD_HASH[
351
+ factory.type_var(:KEY),
352
+ class_instance_type,
353
+ factory.union_type(class_instance_type, TO_PROTO[])
354
+ ],
355
+ annotations: [],
356
+ comment: RBS::AST::Comment.new(string: "The type of `map` field.", location: nil),
357
+ location: nil
358
+ )
359
+
360
+ class_decl.members << RBS::AST::Declarations::Alias.new(
361
+ name: TypeName("array"),
362
+ type_params: [],
363
+ type: RBS::BuiltinNames::Array.instance_type(factory.union_type(class_instance_type, TO_PROTO[])),
364
+ annotations: [],
365
+ comment: nil,
366
+ location: nil
367
+ )
368
+
369
+ class_decl.members << RBS::AST::Declarations::Alias.new(
370
+ name: TypeName("hash"),
371
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
372
+ type: RBS::BuiltinNames::Hash.instance_type(
373
+ factory.type_var(:KEY),
374
+ factory.union_type(class_instance_type, TO_PROTO[])
375
+ ),
376
+ annotations: [],
377
+ comment: nil,
378
+ location: nil
379
+ )
291
380
  end
292
381
  end
293
382
 
383
+ def message_to_proto_type(type)
384
+ namespace = type.name.to_namespace
385
+ RBS::Types::Interface.new(
386
+ name: RBS::TypeName.new(name: :_ToProto, namespace: namespace),
387
+ args: [],
388
+ location: nil
389
+ )
390
+ end
391
+
392
+ def message_init_type(type)
393
+ RBS::Types::Alias.new(
394
+ name: RBS::TypeName.new(name: :init, namespace: type.name.to_namespace),
395
+ args: [],
396
+ location: nil
397
+ )
398
+ end
399
+
400
+ def message_field_array_type(type)
401
+ RBS::Types::Alias.new(
402
+ name: RBS::TypeName.new(name: :field_array, namespace: type.name.to_namespace),
403
+ args: [],
404
+ location: nil
405
+ )
406
+ end
407
+
408
+ def message_array_type(type)
409
+ RBS::Types::Alias.new(
410
+ name: RBS::TypeName.new(name: :array, namespace: type.name.to_namespace),
411
+ args: [],
412
+ location: nil
413
+ )
414
+ end
415
+
416
+ def message_hash_type(type, key)
417
+ RBS::Types::Alias.new(
418
+ name: RBS::TypeName.new(name: :hash, namespace: type.name.to_namespace),
419
+ args: [key],
420
+ location: nil
421
+ )
422
+ end
423
+
424
+ def message_field_hash_type(type, key)
425
+ RBS::Types::Alias.new(
426
+ name: RBS::TypeName.new(name: :field_hash, namespace: type.name.to_namespace),
427
+ args: [key],
428
+ location: nil
429
+ )
430
+ end
431
+
294
432
  def field_type(field, maps)
295
- case
296
- when field.type == FieldDescriptorProto::Type::TYPE_MESSAGE
297
- if maps.key?(field.type_name)
298
- key_field, value_field = maps[field.type_name]
299
-
300
- key_type_r, _ = field_type(key_field, maps)
301
- value_type_r, value_type_w = field_type(value_field, maps)
302
-
303
- hash_type = factory.instance_type(
304
- factory.type_name("::Protobuf::Field::FieldHash"),
305
- key_type_r,
306
- factory.unwrap_optional(value_type_r),
307
- factory.unwrap_optional(value_type_w)
308
- )
433
+ # @type var triple: [RBS::Types::t, Array[RBS::Types::t], RBS::Types::t]
434
+ triple =
435
+ case
436
+ when field.type == FieldDescriptorProto::Type::TYPE_MESSAGE
437
+ if maps.key?(field.type_name)
438
+ key_field, value_field = maps[field.type_name]
439
+
440
+ key_type_r, _ = field_type(key_field, maps)
441
+ value_type_r, value_write_types = field_type(value_field, maps)
442
+
443
+ value_type_r = factory.unwrap_optional(value_type_r)
444
+ value_write_types = value_write_types.map {|type| factory.unwrap_optional(type) }
445
+
446
+ case value_field.type
447
+ when FieldDescriptorProto::Type::TYPE_MESSAGE, FieldDescriptorProto::Type::TYPE_ENUM
448
+ value_type_r.is_a?(RBS::Types::ClassInstance) or raise
449
+ [
450
+ message_field_hash_type(value_type_r, key_type_r),
451
+ [message_hash_type(value_type_r, key_type_r)],
452
+ message_hash_type(value_type_r, key_type_r)
453
+ ]
454
+ else
455
+ hash_type = FIELD_HASH[
456
+ key_type_r,
457
+ value_type_r,
458
+ factory.union_type(value_type_r, *value_write_types)
459
+ ]
460
+
461
+ [
462
+ FIELD_HASH_a[key_type_r, value_type_r],
463
+ [RBS::BuiltinNames::Hash.instance_type(key_type_r, value_type_r)],
464
+ RBS::BuiltinNames::Hash.instance_type(key_type_r, value_type_r)
465
+ ]
466
+ end
467
+ else
468
+ type = message_type(field.type_name)
309
469
 
310
- [
311
- hash_type,
312
- hash_type
313
- ]
314
- else
470
+ case field.label
471
+ when FieldDescriptorProto::Label::LABEL_OPTIONAL
472
+ [
473
+ factory.optional_type(type),
474
+ [
475
+ factory.optional_type(message_to_proto_type(type))
476
+ ],
477
+ factory.optional_type(message_init_type(type))
478
+ ]
479
+ when FieldDescriptorProto::Label::LABEL_REPEATED
480
+ [
481
+ message_field_array_type(type),
482
+ [
483
+ message_array_type(type)
484
+ ],
485
+ message_array_type(type)
486
+ ]
487
+ else
488
+ [
489
+ type,
490
+ [message_to_proto_type(type)],
491
+ message_init_type(type)
492
+ ]
493
+ end
494
+ end
495
+ when field.type == FieldDescriptorProto::Type::TYPE_ENUM
315
496
  type = message_type(field.type_name)
316
-
317
- case field.label
318
- when FieldDescriptorProto::Label::LABEL_OPTIONAL
319
- type = factory.optional_type(type)
320
- [type, type]
321
- when FieldDescriptorProto::Label::LABEL_REPEATED
322
- type = repeated_field_type(type)
323
- [type, type]
497
+ enum_namespace = type.name.to_namespace
498
+ values = factory.alias_type(RBS::TypeName.new(name: :values, namespace: enum_namespace))
499
+
500
+ if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
501
+ [
502
+ message_field_array_type(type),
503
+ [message_array_type(type)],
504
+ message_array_type(type)
505
+ ]
506
+ else
507
+ [
508
+ type,
509
+ [values],
510
+ message_init_type(type)
511
+ ]
512
+ end
513
+ else
514
+ type = base_type(field.type)
515
+
516
+ if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
517
+ [
518
+ FIELD_ARRAY_a[type],
519
+ [RBS::BuiltinNames::Array.instance_type(type)],
520
+ RBS::BuiltinNames::Array.instance_type(type)
521
+ ]
324
522
  else
325
- [type, factory.optional_type(type)]
523
+ [type, [], type]
326
524
  end
327
525
  end
328
- when field.type == FieldDescriptorProto::Type::TYPE_ENUM
329
- type = message_type(field.type_name)
330
- enum_namespace = type.name.to_namespace
331
-
332
- wtype = factory.union_type(
333
- type,
334
- factory.alias_type(RBS::TypeName.new(name: :values, namespace: enum_namespace))
335
- )
336
526
 
337
- if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
338
- type = repeated_field_type(type, wtype)
527
+ if accept_nil_writer
528
+ read_type, write_types, init_type = triple
529
+ [
530
+ read_type,
531
+ ([factory.optional_type(read_type)] + write_types.map {|t| factory.optional_type(t) }).uniq,
532
+ factory.optional_type(init_type)
533
+ ]
534
+ else
535
+ triple
536
+ end
537
+ end
339
538
 
539
+ def interface_type?(type)
540
+ case
541
+ when type.is_a?(RBS::Types::Interface)
542
+ [
543
+ RBS::AST::TypeParam.new(name: :M, upper_bound: type, variance: :invariant, location: nil),
544
+ factory.type_var(:M)
545
+ ]
546
+ when type.is_a?(RBS::Types::Optional)
547
+ if (type = type.type).is_a?(RBS::Types::Interface)
340
548
  [
341
- type,
342
- type
343
- ]
344
- else
345
- [
346
- type,
347
- factory.optional_type(wtype)
549
+ RBS::AST::TypeParam.new(name: :M, upper_bound: type, variance: :invariant, location: nil),
550
+ factory.optional_type(factory.type_var(:M))
348
551
  ]
349
552
  end
350
- else
351
- type = base_type(field.type)
352
-
353
- if field.label == FieldDescriptorProto::Label::LABEL_REPEATED
354
- type = repeated_field_type(type)
355
- [type, type]
356
- else
357
- [type, factory.optional_type(type)]
358
- end
359
553
  end
360
554
  end
361
555
 
362
- def enum_base_class
363
- RBS::AST::Declarations::Class::Super.new(
364
- name: factory.type_name("::Protobuf::Enum"),
365
- args: [],
366
- location: nil
556
+ def add_field(members, name:, read_type:, write_types:, comment:)
557
+ members << RBS::AST::Members::AttrAccessor.new(
558
+ name: name,
559
+ type: read_type,
560
+ comment: comment,
561
+ location: nil,
562
+ annotations: [],
563
+ ivar_name: false,
564
+ kind: :instance
565
+ )
566
+
567
+ unless write_types.empty?
568
+ members << RBS::AST::Members::MethodDefinition.new(
569
+ name: :"#{name}=",
570
+ types:
571
+ write_types.map do |write_type|
572
+ if (type_param, type = interface_type?(write_type))
573
+ factory.method_type(
574
+ type: factory.function(type).update(
575
+ required_positionals:[factory.param(type)]
576
+ )
577
+ ).update(type_params: [type_param])
578
+ else
579
+ factory.method_type(
580
+ type: factory.function(write_type).update(
581
+ required_positionals:[factory.param(write_type)]
582
+ )
583
+ )
584
+ end
585
+ end,
586
+ annotations: [],
587
+ comment: comment,
588
+ location: nil,
589
+ overload: true,
590
+ kind: :instance
591
+ )
592
+ end
593
+
594
+ members << RBS::AST::Members::MethodDefinition.new(
595
+ name: :"#{name}!",
596
+ types: [
597
+ factory.method_type(
598
+ type: factory.function(factory.optional_type(read_type))
599
+ )
600
+ ],
601
+ annotations: [],
602
+ comment: nil,
603
+ location: nil,
604
+ overload: false,
605
+ kind: :instance
367
606
  )
368
607
  end
369
608
 
@@ -380,10 +619,10 @@ module RBSProtobuf
380
619
 
381
620
  RBS::AST::Declarations::Class.new(
382
621
  name: RBS::TypeName.new(name: enum_name.to_sym, namespace: prefix),
383
- super_class: enum_base_class(),
622
+ super_class: ENUM.super_class,
384
623
  type_params: factory.module_type_params(),
385
624
  members: [],
386
- comment: comment_for_path(source_code_info, path),
625
+ comment: comment_for_path(source_code_info, path, options: enum_type.options),
387
626
  location: nil,
388
627
  annotations: []
389
628
  ).tap do |enum_decl|
@@ -401,6 +640,7 @@ module RBSProtobuf
401
640
 
402
641
  enum_decl.members << RBS::AST::Declarations::Alias.new(
403
642
  name: factory.type_name("names"),
643
+ type_params: [],
404
644
  type: factory.union_type(*names),
405
645
  location: nil,
406
646
  comment: nil,
@@ -409,6 +649,7 @@ module RBSProtobuf
409
649
 
410
650
  enum_decl.members << RBS::AST::Declarations::Alias.new(
411
651
  name: factory.type_name("strings"),
652
+ type_params: [],
412
653
  type: factory.union_type(*strings),
413
654
  location: nil,
414
655
  comment: nil,
@@ -417,6 +658,7 @@ module RBSProtobuf
417
658
 
418
659
  enum_decl.members << RBS::AST::Declarations::Alias.new(
419
660
  name: factory.type_name("tags"),
661
+ type_params: [],
420
662
  type: factory.union_type(*tags),
421
663
  location: nil,
422
664
  comment: nil,
@@ -425,6 +667,7 @@ module RBSProtobuf
425
667
 
426
668
  enum_decl.members << RBS::AST::Declarations::Alias.new(
427
669
  name: factory.type_name("values"),
670
+ type_params: [],
428
671
  type: factory.union_type(
429
672
  factory.alias_type("names"),
430
673
  factory.alias_type("strings"),
@@ -456,88 +699,126 @@ module RBSProtobuf
456
699
  )
457
700
 
458
701
  enum_type.value.each.with_index do |v, index|
459
- comment = comment_for_path(source_code_info, path + [2, index])
702
+ comment = comment_for_path(source_code_info, path + [2, index], options: v.options)
460
703
 
461
704
  enum_decl.members << RBS::AST::Declarations::Constant.new(
462
705
  name: factory.type_name(enum_name(v.name).to_s),
463
- type: RBS::TypeName.new(name: enum_name.to_sym, namespace: prefix),
706
+ type: factory.instance_type(RBS::TypeName.new(name: enum_name.to_sym, namespace: prefix)),
464
707
  comment: comment,
465
708
  location: nil
466
709
  )
467
710
  end
711
+
712
+ enum_instance_type = factory.instance_type(RBS::TypeName.new(name: enum_name.to_sym, namespace: RBS::Namespace.empty))
713
+ values_type = factory.alias_type(RBS::TypeName.new(name: :values, namespace: RBS::Namespace.empty))
714
+
715
+ enum_decl.members << RBS::AST::Declarations::Alias.new(
716
+ name: TypeName("init"),
717
+ type_params: [],
718
+ type: factory.union_type(enum_instance_type, values_type),
719
+ annotations: [],
720
+ comment: RBS::AST::Comment.new(string: "The type of `#initialize` parameter.", location: nil),
721
+ location: nil
722
+ )
723
+
724
+ enum_decl.members << RBS::AST::Declarations::Alias.new(
725
+ name: TypeName("field_array"),
726
+ type_params: [],
727
+ type: FIELD_ARRAY[
728
+ enum_instance_type,
729
+ factory.union_type(enum_instance_type, values_type)
730
+ ],
731
+ annotations: [],
732
+ comment: RBS::AST::Comment.new(string: "The type of `repeated` field.", location: nil),
733
+ location: nil
734
+ )
735
+
736
+ enum_decl.members << RBS::AST::Declarations::Alias.new(
737
+ name: TypeName("field_hash"),
738
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
739
+ type: FIELD_HASH[
740
+ factory.type_var(:KEY),
741
+ enum_instance_type,
742
+ factory.union_type(enum_instance_type, values_type)
743
+ ],
744
+ annotations: [],
745
+ comment: RBS::AST::Comment.new(string: "The type of `map` field.", location: nil),
746
+ location: nil
747
+ )
748
+
749
+ enum_decl.members << RBS::AST::Declarations::Alias.new(
750
+ name: TypeName("array"),
751
+ type_params: [],
752
+ type: RBS::BuiltinNames::Array.instance_type(factory.union_type(enum_instance_type, values_type)),
753
+ annotations: [],
754
+ comment: nil,
755
+ location: nil
756
+ )
757
+
758
+ enum_decl.members << RBS::AST::Declarations::Alias.new(
759
+ name: TypeName("hash"),
760
+ type_params: [RBS::AST::TypeParam.new(name: :KEY, variance: :invariant, upper_bound: nil, location: nil)],
761
+ type: RBS::BuiltinNames::Hash.instance_type(
762
+ factory.type_var(:KEY),
763
+ factory.union_type(enum_instance_type, values_type)
764
+ ),
765
+ annotations: [],
766
+ comment: nil,
767
+ location: nil
768
+ )
468
769
  end
469
770
  end
470
771
 
471
- def extension_to_decl(extendee_name, extensions, prefix:, source_code_info:, path:)
472
- class_name = message_type(extendee_name).name
772
+ def extension_to_decl(extension, prefix:, source_code_info:, path:)
773
+ class_name = message_type(extension.extendee).name
473
774
 
474
- extensions.map do |field|
475
- field_name = field.name.to_sym
775
+ comment = comment_for_path(source_code_info, path, options: extension.options)
776
+ field_name = extension.name.to_sym
476
777
 
477
- RBS::AST::Declarations::Class.new(
478
- name: class_name,
479
- super_class: nil,
480
- type_params: RBS::AST::Declarations::ModuleTypeParams.empty,
481
- location: nil,
482
- comment: nil,
483
- members: [],
484
- annotations: []
485
- ).tap do |class_decl|
486
- read_type, write_type = field_type(field, {})
778
+ RBS::AST::Declarations::Class.new(
779
+ name: class_name,
780
+ super_class: nil,
781
+ type_params: [],
782
+ location: nil,
783
+ comment: nil,
784
+ members: [],
785
+ annotations: []
786
+ ).tap do |class_decl|
787
+ read_type, write_types, _ = field_type(extension, {})
487
788
 
488
- if read_type == write_type
489
- class_decl.members << RBS::AST::Members::AttrAccessor.new(
490
- name: field_name,
491
- type: read_type,
492
- comment: nil,
493
- location: nil,
494
- annotations: [],
495
- ivar_name: false,
496
- kind: :instance
497
- )
498
- else
499
- class_decl.members << RBS::AST::Members::AttrReader.new(
500
- name: field_name,
501
- type: read_type,
502
- comment: nil,
503
- location: nil,
504
- annotations: [],
505
- ivar_name: false,
506
- kind: :instance
507
- )
789
+ add_field(class_decl.members, name: field_name, read_type: read_type, write_types: write_types, comment: comment)
508
790
 
509
- class_decl.members << RBS::AST::Members::AttrWriter.new(
510
- name: field_name,
511
- type: write_type,
512
- comment: nil,
513
- location: nil,
514
- annotations: [],
515
- ivar_name: false,
516
- kind: :instance
791
+ class_decl.members << RBS::AST::Members::MethodDefinition.new(
792
+ name: :[],
793
+ types: [
794
+ factory.method_type(
795
+ type: factory.function(read_type).update(
796
+ required_positionals: [
797
+ factory.param(factory.literal_type(field_name))
798
+ ]
799
+ )
517
800
  )
518
- end
801
+ ],
802
+ annotations: [],
803
+ comment: nil,
804
+ location: nil,
805
+ overload: true,
806
+ kind: :instance
807
+ )
519
808
 
520
- class_decl.members << RBS::AST::Members::MethodDefinition.new(
521
- name: :[],
522
- types: [
809
+ class_decl.members << RBS::AST::Members::MethodDefinition.new(
810
+ name: :[]=,
811
+ types: [read_type, *write_types].map do |write_type|
812
+ if (type_param, type_var = interface_type?(write_type))
523
813
  factory.method_type(
524
- type: factory.function(read_type).update(
814
+ type: factory.function(type_var).update(
525
815
  required_positionals: [
526
- factory.param(factory.literal_type(field_name))
816
+ factory.param(factory.literal_type(field_name)),
817
+ factory.param(type_var)
527
818
  ]
528
819
  )
529
- )
530
- ],
531
- annotations: [],
532
- comment: nil,
533
- location: nil,
534
- overload: true,
535
- kind: :instance
536
- )
537
-
538
- class_decl.members << RBS::AST::Members::MethodDefinition.new(
539
- name: :[]=,
540
- types: [
820
+ ).update(type_params: [type_param])
821
+ else
541
822
  factory.method_type(
542
823
  type: factory.function(write_type).update(
543
824
  required_positionals: [
@@ -546,14 +827,14 @@ module RBSProtobuf
546
827
  ]
547
828
  )
548
829
  )
549
- ],
550
- annotations: [],
551
- comment: nil,
552
- location: nil,
553
- overload: true,
554
- kind: :instance
555
- )
556
- end
830
+ end
831
+ end,
832
+ annotations: [],
833
+ comment: nil,
834
+ location: nil,
835
+ overload: true,
836
+ kind: :instance
837
+ )
557
838
  end
558
839
  end
559
840
 
@@ -573,7 +854,7 @@ module RBSProtobuf
573
854
  super_class: service_base_class,
574
855
  type_params: factory.module_type_params(),
575
856
  members: [],
576
- comment: comment_for_path(source_code_info, path),
857
+ comment: comment_for_path(source_code_info, path, options: nil),
577
858
  location: nil,
578
859
  annotations: []
579
860
  )