lib/tapioca/compilers/dsl/protobuf.rb in tapioca-0.4.27 vs lib/tapioca/compilers/dsl/protobuf.rb in tapioca-0.5.0

- old
+ new

@@ -1,8 +1,7 @@ # typed: strict # frozen_string_literal: true -require "parlour" begin require "google/protobuf" rescue LoadError return @@ -60,81 +59,36 @@ # sig { params(value: Float).returns(Float) } # def number_value=(value); end # end # ~~~ class Protobuf < Base - # Parlour doesn't support type members out of the box, so adding the - # ability to do that here. This should be upstreamed. - class TypeMember < Parlour::RbiGenerator::RbiObject - extend T::Sig - - sig { params(other: Object).returns(T::Boolean) } - def ==(other) - TypeMember === other && name == other.name - end - - sig do - override - .params(indent_level: Integer, options: Parlour::RbiGenerator::Options) - .returns(T::Array[String]) - end - def generate_rbi(indent_level, options) - [options.indented(indent_level, "#{name} = type_member")] - end - - sig do - override - .params(others: T::Array[Parlour::RbiGenerator::RbiObject]) - .returns(T::Boolean) - end - def mergeable?(others) - others.all? { |other| self == other } - end - - sig { override.params(others: T::Array[Parlour::RbiGenerator::RbiObject]).void } - def merge_into_self(others); end - - sig { override.returns(String) } - def describe - "Type Member (#{name})" - end - end - class Field < T::Struct prop :name, String prop :type, String prop :init_type, String prop :default, String - - extend T::Sig - - sig { returns(Parlour::RbiGenerator::Parameter) } - def to_init - Parlour::RbiGenerator::Parameter.new("#{name}:", type: init_type, default: default) - end end extend T::Sig - sig do - override.params( - root: Parlour::RbiGenerator::Namespace, - constant: Module - ).void - end + sig { override.params(root: RBI::Tree, constant: Module).void } def decorate(root, constant) - root.path(constant) do |klass| + root.create_path(constant) do |klass| if constant == Google::Protobuf::RepeatedField create_type_members(klass, "Elem") elsif constant == Google::Protobuf::Map create_type_members(klass, "Key", "Value") else descriptor = T.let(T.unsafe(constant).descriptor, Google::Protobuf::Descriptor) fields = descriptor.map { |desc| create_descriptor_method(klass, desc) } fields.sort_by!(&:name) - create_method(klass, "initialize", parameters: fields.map!(&:to_init)) + parameters = fields.map do |field| + create_kw_opt_param(field.name, type: field.init_type, default: field.default) + end + + klass.create_method("initialize", parameters: parameters, return_type: "void") end end end sig { override.returns(T::Enumerable[Module]) } @@ -144,16 +98,16 @@ results.any? ? results + [Google::Protobuf::RepeatedField, Google::Protobuf::Map] : [] end private - sig { params(klass: Parlour::RbiGenerator::Namespace, names: String).void } + sig { params(klass: RBI::Scope, names: String).void } def create_type_members(klass, *names) klass.create_extend("T::Generic") names.each do |name| - klass.children << TypeMember.new(klass.generator, name) + klass.create_type_member(name) end end sig do params( @@ -184,38 +138,38 @@ if descriptor.label == :repeated # Here we're going to check if the submsg_name is named according to # how Google names map entries. # https://github.com/protocolbuffers/protobuf/blob/f82e26/ruby/ext/google/protobuf_c/defs.c#L1963-L1966 if descriptor.submsg_name.to_s.end_with?("_MapEntry_#{descriptor.name}") - key = descriptor.subtype.lookup('key') - value = descriptor.subtype.lookup('value') + key = descriptor.subtype.lookup("key") + value = descriptor.subtype.lookup("value") key_type = type_of(key) value_type = type_of(value) type = "Google::Protobuf::Map[#{key_type}, #{value_type}]" default_args = [key.type.inspect, value.type.inspect] - default_args << value_type if %i[enum message].include?(value.type) + default_args << value_type if [:enum, :message].include?(value.type) Field.new( name: descriptor.name, type: type, init_type: "T.any(#{type}, T::Hash[#{key_type}, #{value_type}])", - default: "Google::Protobuf::Map.new(#{default_args.join(', ')})" + default: "Google::Protobuf::Map.new(#{default_args.join(", ")})" ) else elem_type = type_of(descriptor) type = "Google::Protobuf::RepeatedField[#{elem_type}]" default_args = [descriptor.type.inspect] - default_args << elem_type if %i[enum message].include?(descriptor.type) + default_args << elem_type if [:enum, :message].include?(descriptor.type) Field.new( name: descriptor.name, type: type, init_type: "T.any(#{type}, T::Array[#{elem_type}])", - default: "Google::Protobuf::RepeatedField.new(#{default_args.join(', ')})" + default: "Google::Protobuf::RepeatedField.new(#{default_args.join(", ")})" ) end else type = type_of(descriptor) @@ -228,28 +182,24 @@ end end sig do params( - klass: Parlour::RbiGenerator::Namespace, + klass: RBI::Scope, desc: Google::Protobuf::FieldDescriptor, ).returns(Field) end def create_descriptor_method(klass, desc) field = field_of(desc) - create_method( - klass, + klass.create_method( field.name, return_type: field.type ) - create_method( - klass, + klass.create_method( "#{field.name}=", - parameters: [ - Parlour::RbiGenerator::Parameter.new("value", type: field.type), - ], + parameters: [create_param("value", type: field.type)], return_type: field.type ) field end