diff --git a/lib/tapioca/dsl/compilers/protobuf.rb b/lib/tapioca/dsl/compilers/protobuf.rb index a97dd5512..457f676d5 100644 --- a/lib/tapioca/dsl/compilers/protobuf.rb +++ b/lib/tapioca/dsl/compilers/protobuf.rb @@ -145,7 +145,9 @@ def decorate klass.create_method("initialize", parameters: [kwargs_parameter], return_type: "void") end else - raise TypeError, "Unexpected descriptor class: #{descriptor.class.name}" + add_error(<<~MSG.strip) + Unexpected descriptor class `#{descriptor.class.name}` for `#{constant}` + MSG end end end @@ -162,7 +164,17 @@ def gather_constants T.cast(desc, Google::Protobuf::EnumDescriptor).enummodule end - results = T.cast(ObjectSpace.each_object(marker).to_a, T::Array[Module]).concat(enum_modules) + results = if Google::Protobuf.const_defined?(:AbstractMessage) + abstract_message_const = ::Google::Protobuf.const_get(:AbstractMessage) + descendants_of(abstract_message_const) - [abstract_message_const] + else + T.cast( + ObjectSpace.each_object(marker).to_a, + T::Array[Module], + ) + end + + results = results.concat(enum_modules) results.any? ? results + [Google::Protobuf::RepeatedField, Google::Protobuf::Map] : [] end end diff --git a/spec/tapioca/dsl/compilers/protobuf_spec.rb b/spec/tapioca/dsl/compilers/protobuf_spec.rb index 91ca06bb2..0b5c56967 100644 --- a/spec/tapioca/dsl/compilers/protobuf_spec.rb +++ b/spec/tapioca/dsl/compilers/protobuf_spec.rb @@ -35,6 +35,7 @@ class ProtobufSpec < ::DslSpec assert_equal(["Cart"], gathered_constants.reject { |constant| constant.start_with?("Google::Protobuf") }) assert_includes(gathered_constants, "Google::Protobuf::Map") assert_includes(gathered_constants, "Google::Protobuf::RepeatedField") + refute_includes(gathered_constants, "Google::Protobuf::AbstractMessage") end end @@ -500,6 +501,23 @@ def clear_phone_number; end def contact_info; end RBI end + + it "shows an error for an unexpected descriptor class" do + expect_dsl_compiler_errors! + + add_ruby_file("protobuf.rb", <<~RUBY) + Cart = Class.new(::Google::Protobuf.const_get(:AbstractMessage)) + RUBY + + rbi_output = rbi_for(:Cart) + + assert_equal(<<~RBI, rbi_output) + # typed: strong + + class Cart; end + RBI + assert_equal(["Unexpected descriptor class `NilClass` for `Cart`"], generated_errors) + end end end end