From d65def0159ce785488d9e8316d56a1d595bc1408 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Tue, 4 Jun 2013 01:18:45 +0200 Subject: [PATCH] THRIFT-1977: Fix to ensure proper C# class names Patch: Jens Geyer --- .../cpp/src/generate/t_csharp_generator.cc | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc index 26f1bdf9..016e3f8b 100644 --- a/compiler/cpp/src/generate/t_csharp_generator.cc +++ b/compiler/cpp/src/generate/t_csharp_generator.cc @@ -21,6 +21,8 @@ * details. */ +#include + #include #include #include @@ -160,6 +162,8 @@ class t_csharp_generator : public t_oop_generator std::string type_to_enum(t_type* ttype); std::string prop_name(t_field* tfield); std::string get_enum_class_name(t_type* type); + + std::string make_valid_csharp_identifier( std::string const & fromName); bool field_has_default(t_field* tfield) { return tfield->get_value() != NULL; @@ -302,7 +306,7 @@ void t_csharp_generator::generate_consts(std::vector consts) { start_csharp_namespace(f_consts); indent(f_consts) << - "public static class " << program_name_ << "Constants" << endl; + "public static class " << make_valid_csharp_identifier(program_name_) << "Constants" << endl; scope_up(f_consts); vector::iterator c_iter; @@ -372,7 +376,7 @@ void t_csharp_generator::print_const_def_value(std::ofstream& out, string name, } void t_csharp_generator::print_const_constructor(std::ofstream& out, std::vector consts) { - indent(out) << "static " << program_name_ << "Constants()" << endl; + indent(out) << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << endl; scope_up(out); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -2246,6 +2250,35 @@ void t_csharp_generator::generate_csharp_property(ofstream& out, t_field* tfield out << endl; } +std::string t_csharp_generator::make_valid_csharp_identifier( std::string const & fromName) { + std::string str = fromName; + if( str.empty()) { + return str; + } + + // tests rely on this + assert( ('A' < 'Z') && ('a' < 'z') && ('0' < '9')); + + // if the first letter is a number, we add an additional underscore in front of it + char c = str.at(0); + if( ('0' <= c) && (c <= '9')) { + str = "_" + str; + } + + // following chars: letter, number or underscore + for( size_t i = 0; i < str.size(); ++i) { + c = str.at(i); + if( (('A' > c) || (c > 'Z')) && + (('a' > c) || (c > 'z')) && + (('0' > c) || (c > '9')) && + ('_' != c) ) { + str.replace( i, 1, "_"); + } + } + + return str; +} + std::string t_csharp_generator::prop_name(t_field* tfield) { string name (tfield->get_name()); name[0] = toupper(name[0]); -- 2.17.1