Skip to content

Commit

Permalink
Add option to make package namespace flat/nested
Browse files Browse the repository at this point in the history
  • Loading branch information
soutaro committed Jul 10, 2020
1 parent 17b0c5d commit 055e6c4
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 28 deletions.
4 changes: 3 additions & 1 deletion exe/protoc-gen-rbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ input = Google::Protobuf::Compiler::CodeGeneratorRequest.decode(STDIN.read)
translator = case backend
when "protobuf"
upcase_enum = ENV.key?("PB_UPCASE_ENUMS")
no_nested_namespace = ENV.key?("RBS_PROTOBUF_NO_NESTED_NAMESPACE")

RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: upcase_enum
upcase_enum: upcase_enum,
nested_namespace: !no_nested_namespace
)
when "google-protobuf"
raise NotImplementedError
Expand Down
35 changes: 31 additions & 4 deletions lib/rbs_protobuf/translator/protobuf_gem.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
module RBSProtobuf
module Translator
class ProtobufGem < Base
def initialize(input, upcase_enum:)
def initialize(input, upcase_enum:, nested_namespace:)
super(input)
@upcase_enum = upcase_enum
@nested_namespace = nested_namespace
end

def upcase_enum?
@upcase_enum
end

def nested_namespace?
@nested_namespace
end

def rbs_content(file)
decls = []

source_code_info = file.source_code_info

if file.package && !file.package.empty?
prefix = message_type(file.package).name.to_namespace
package_namespace = message_type(file.package).name.to_namespace
else
prefix = RBS::Namespace.empty
package_namespace = RBS::Namespace.empty
end

prefix = if nested_namespace?
RBS::Namespace.empty
else
package_namespace
end

file.enum_type.each_with_index do |enum, index|
decls << enum_type_to_decl(enum,
prefix: prefix,
Expand All @@ -35,6 +46,22 @@ def rbs_content(file)
path: [4, index])
end

if nested_namespace?
package_namespace.path.reverse_each do |name|
decls = [
RBS::AST::Declarations::Module.new(
name: factory.type_name(name.to_s),
self_type: nil,
type_params: factory.module_type_params,
location: nil,
comment: nil,
annotations: [],
members: decls
)
]
end
end

StringIO.new.tap do |io|
RBS::Writer.new(out: io).write(decls)
end.string
Expand Down Expand Up @@ -408,7 +435,7 @@ def enum_type_to_decl(enum_type, prefix:, source_code_info:, path:)

enum_decl.members << RBS::AST::Declarations::Constant.new(
name: factory.type_name(enum_name(v.name).to_s),
type: enum_name,
type: RBS::TypeName.new(name: enum_name.to_sym, namespace: prefix),
comment: comment,
location: nil
)
Expand Down
98 changes: 75 additions & 23 deletions test/protobuf_gem_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def test_message_with_base_type

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down Expand Up @@ -58,7 +59,8 @@ def test_message_with_bool_predicate

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down Expand Up @@ -95,7 +97,11 @@ def test_message_with_message
}
EOP

translator = RBSProtobuf::Translator::ProtobufGem.new(input, upcase_enum: false)
translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: false,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

assert_equal <<RBS, content
Expand Down Expand Up @@ -137,7 +143,11 @@ def test_enum
}
EOP

translator = RBSProtobuf::Translator::ProtobufGem.new(input, upcase_enum: false)
translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: false,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

assert_equal <<RBS, content
Expand Down Expand Up @@ -172,7 +182,11 @@ def test_enum_with_alias
}
EOP

translator = RBSProtobuf::Translator::ProtobufGem.new(input, upcase_enum: false)
translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: false,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

assert_equal <<RBS, content
Expand Down Expand Up @@ -211,7 +225,11 @@ def test_message_with_enum
}
EOP

translator = RBSProtobuf::Translator::ProtobufGem.new(input, upcase_enum: true)
translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

assert_equal <<RBS, content
Expand Down Expand Up @@ -271,27 +289,56 @@ def test_message_with_package

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

assert_equal <<RBS, content
class Foo::Ba_r::Message < ::Protobuf::Message
attr_reader name(): ::String
module Foo
module Ba_r
class Message < ::Protobuf::Message
attr_reader name(): ::String
attr_writer name(): ::String?
attr_writer name(): ::String?
attr_accessor replyTo(): ::Foo::Ba_r::Message?
attr_accessor replyTo(): ::Foo::Ba_r::Message?
def initialize: (?name: ::String?, ?replyTo: ::Foo::Ba_r::Message?) -> void
def initialize: (?name: ::String?, ?replyTo: ::Foo::Ba_r::Message?) -> void
def []: (:name) -> ::String
| (:replyTo) -> ::Foo::Ba_r::Message?
| (::Symbol) -> untyped
def []: (:name) -> ::String
| (:replyTo) -> ::Foo::Ba_r::Message?
| (::Symbol) -> untyped
def []=: (:name, ::String?) -> ::String?
| (:replyTo, ::Foo::Ba_r::Message?) -> ::Foo::Ba_r::Message?
| (::Symbol, untyped) -> untyped
def []=: (:name, ::String?) -> ::String?
| (:replyTo, ::Foo::Ba_r::Message?) -> ::Foo::Ba_r::Message?
| (::Symbol, untyped) -> untyped
end
end
end
RBS
end

def test_message_with_package_flat_namespace
input = read_proto(<<EOP)
syntax = "proto2";
package foo.ba_r;
message Message {
}
EOP

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true,
nested_namespace: false
)
content = translator.rbs_content(input.proto_file[0])

assert_equal <<RBS, content
class Foo::Ba_r::Message < ::Protobuf::Message
def initialize: () -> void
end
RBS
end
Expand All @@ -312,7 +359,8 @@ def test_message_with_one_of

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down Expand Up @@ -353,7 +401,8 @@ def test_message_with_map_to_base_and_message

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down Expand Up @@ -394,7 +443,8 @@ def test_message_with_map_to_enum

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down Expand Up @@ -444,7 +494,8 @@ def test_nested_message

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down Expand Up @@ -483,7 +534,8 @@ def test_nested_enum

translator = RBSProtobuf::Translator::ProtobufGem.new(
input,
upcase_enum: true
upcase_enum: true,
nested_namespace: true
)
content = translator.rbs_content(input.proto_file[0])

Expand Down

0 comments on commit 055e6c4

Please sign in to comment.