rbs_protobuf 0.1.0 → 1.0.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,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
  )