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