diff options
author | Joshua Haberman <jhaberman@gmail.com> | 2016-07-26 10:55:34 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-26 10:55:34 -0700 |
commit | 234ec01795b0487392e87f5c67f4929d1b8f94fb (patch) | |
tree | b34ca93fbe44a63137f7049d894c5032dee3397c /src | |
parent | f11a4f1fe4b73044615b285a79ab09806fd54b7a (diff) | |
parent | 43b36dd98375b6d410996d52a9db4652dfd28997 (diff) | |
download | protobuf-234ec01795b0487392e87f5c67f4929d1b8f94fb.tar.gz protobuf-234ec01795b0487392e87f5c67f4929d1b8f94fb.tar.bz2 protobuf-234ec01795b0487392e87f5c67f4929d1b8f94fb.zip |
Merge pull request #1847 from haberman/GAfixes
GA fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb (renamed from src/google/protobuf/compiler/ruby/ruby_generated_code.rb) | 0 | ||||
-rw-r--r-- | src/google/protobuf/compiler/ruby/ruby_generator.cc | 60 | ||||
-rw-r--r-- | src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc | 4 |
4 files changed, 52 insertions, 14 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6e7dacfc..524886ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -547,7 +547,7 @@ EXTRA_DIST = \ google/protobuf/package_info.h \ google/protobuf/io/package_info.h \ google/protobuf/compiler/ruby/ruby_generated_code.proto \ - google/protobuf/compiler/ruby/ruby_generated_code.rb \ + google/protobuf/compiler/ruby/ruby_generated_code_pb.rb \ google/protobuf/compiler/package_info.h \ google/protobuf/compiler/zip_output_unittest.sh \ README.md diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb index 49b23fbe..49b23fbe 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index 92c76fb0..fbe3b4cb 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -48,7 +48,7 @@ namespace ruby { // Forward decls. std::string IntToString(int32 value); -std::string StripDotProto(const std::string& proto_file); +std::string GetRequireName(const std::string& proto_file); std::string LabelForField(google::protobuf::FieldDescriptor* field); std::string TypeName(google::protobuf::FieldDescriptor* field); void GenerateMessage(const google::protobuf::Descriptor* message, @@ -70,13 +70,13 @@ std::string IntToString(int32 value) { return os.str(); } -std::string StripDotProto(const std::string& proto_file) { +std::string GetRequireName(const std::string& proto_file) { int lastindex = proto_file.find_last_of("."); - return proto_file.substr(0, lastindex); + return proto_file.substr(0, lastindex) + "_pb"; } std::string GetOutputFilename(const std::string& proto_file) { - return StripDotProto(proto_file) + ".rb"; + return GetRequireName(proto_file) + ".rb"; } std::string LabelForField(const google::protobuf::FieldDescriptor* field) { @@ -237,15 +237,52 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en, "end\n"); } -// Module names, class names, and enum value names need to be Ruby constants, -// which must start with a capital letter. +// Locale-agnostic utility functions. +bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; } + +bool IsUpper(char ch) { return ch >= 'A' && ch <= 'Z'; } + +bool IsAlpha(char ch) { return IsLower(ch) || IsUpper(ch); } + +char ToUpper(char ch) { return IsLower(ch) ? (ch - 'a' + 'A') : ch; } + + +// Package names in protobuf are snake_case by convention, but Ruby module +// names must be PascalCased. +// +// foo_bar_baz -> FooBarBaz +std::string PackageToModule(const std::string& name) { + bool next_upper = true; + std::string result; + result.reserve(name.size()); + + for (int i = 0; i < name.size(); i++) { + if (name[i] == '_') { + next_upper = true; + } else { + if (next_upper) { + result.push_back(ToUpper(name[i])); + } else { + result.push_back(name[i]); + } + next_upper = false; + } + } + + return result; +} + +// Class and enum names in protobuf should be PascalCased by convention, but +// since there is nothing enforcing this we need to ensure that they are valid +// Ruby constants. That mainly means making sure that the first character is +// an upper-case letter. std::string RubifyConstant(const std::string& name) { std::string ret = name; if (!ret.empty()) { - if (ret[0] >= 'a' && ret[0] <= 'z') { + if (IsLower(ret[0])) { // If it starts with a lowercase letter, capitalize it. - ret[0] = ret[0] - 'a' + 'A'; - } else if (ret[0] < 'A' || ret[0] > 'Z') { + ret[0] = ToUpper(ret[0]); + } else if (!IsAlpha(ret[0])) { // Otherwise (e.g. if it begins with an underscore), we need to come up // with some prefix that starts with a capital letter. We could be smarter // here, e.g. try to strip leading underscores, but this may cause other @@ -254,6 +291,7 @@ std::string RubifyConstant(const std::string& name) { ret = "PB_" + ret; } } + return ret; } @@ -314,7 +352,7 @@ int GeneratePackageModules( component = package_name.substr(0, dot_index); package_name = package_name.substr(dot_index + 1); } - component = RubifyConstant(component); + component = PackageToModule(component); printer->Print( "module $name$\n", "name", component); @@ -391,7 +429,7 @@ bool MaybeEmitDependency(const FileDescriptor* import, return true; } else { printer->Print( - "require '$name$'\n", "name", StripDotProto(import->name())); + "require '$name$'\n", "name", GetRequireName(import->name())); return true; } } diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index c0acb407..1aabe8aa 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -91,12 +91,12 @@ TEST(RubyGeneratorTest, GeneratorTest) { // Load the generated output and compare to the expected result. string output; GOOGLE_CHECK_OK(File::GetContents( - TestTempDir() + "/ruby_generated_code.rb", + TestTempDir() + "/ruby_generated_code_pb.rb", &output, true)); string expected_output; GOOGLE_CHECK_OK(File::GetContents( - ruby_tests + "/ruby_generated_code.rb", + ruby_tests + "/ruby_generated_code_pb.rb", &expected_output, true)); EXPECT_EQ(expected_output, output); |