rbs_protobuf 0.3.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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