Enforcing the google C++ style guide

This commit is contained in:
Lakedaemon
2016-04-15 13:20:26 +02:00
parent 8a64afabfd
commit 38597160f2
4 changed files with 227 additions and 258 deletions

View File

@@ -17,48 +17,23 @@
#ifndef FLATBUFFERS_CODE_GENERATORS_H_ #ifndef FLATBUFFERS_CODE_GENERATORS_H_
#define FLATBUFFERS_CODE_GENERATORS_H_ #define FLATBUFFERS_CODE_GENERATORS_H_
/** This file defines some classes, that code generators should extend to gain
common functionalities :
BaseGenerator is the base class for all (binary, textual, strongly typed,
dynamically typed, whatever) generators.
It is really abstract, general and flexible and doesn't do much appart from
holding the parser, a path and a filename being processed.
Still, it brings a common structure (normalization) among generators
The many advantages of object based generators will come later from :
A) the CodeWriter class (semi-automatic indentation (python), semi-automatic
(C++) namespace scopes, export to different files (classic, top level
methods),
simpler code to generate string from things (comments (vector of strings),
indentation commands (TAB BAT), newlines (NL), numbers, const char* or
std::string)
B) the Generator subclass (heritance for supporting different versions of a
language, avoid field name clash, write text/binary to file, types
management,
common computations and sctructures : enum analysis (function, array, map,
ordered list + binarysearch),...)
*/
namespace flatbuffers { namespace flatbuffers {
class BaseGenerator { class BaseGenerator {
public: public:
BaseGenerator(const Parser &parser_, const std::string &path_, BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name_) const std::string &file_name)
: parser(parser_), path(path_), file_name(file_name_){}; : parser_(parser), path_(path), file_name_(file_name){};
virtual bool generate() = 0; virtual bool generate() = 0;
protected: protected:
virtual ~BaseGenerator(){}; virtual ~BaseGenerator(){};
const Parser &parser; const Parser &parser_;
const std::string &path; const std::string &path_;
const std::string &file_name; const std::string &file_name_;
}; };
} // namespace flatbuffers } // namespace flatbuffers
#endif // FLATBUFFERS_CODE_GENERATORS_H_ #endif // FLATBUFFERS_CODE_GENERATORS_H_

View File

@@ -716,194 +716,195 @@ static std::string GeneratedFileName(const std::string &path,
namespace cpp { namespace cpp {
class CppGenerator : public BaseGenerator { class CppGenerator : public BaseGenerator {
public: public:
CppGenerator(const Parser &parser_, const std::string &path_, CppGenerator(const Parser &parser, const std::string &path,
const std::string &file_name_) const std::string &file_name)
: BaseGenerator(parser_, path_, file_name_){}; : BaseGenerator(parser, path, file_name){};
// Iterate through all definitions we haven't generate code for (enums, structs, // Iterate through all definitions we haven't generate code for (enums,
// structs,
// and tables) and output them to a single file. // and tables) and output them to a single file.
bool generate() { bool generate() {
// Check if we have any code to generate at all, to avoid an empty header. // Check if we have any code to generate at all, to avoid an empty header.
for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) { ++it) {
if (!(*it)->generated) goto generate_code; if (!(*it)->generated) goto generate_code;
} }
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
++it) { ++it) {
if (!(*it)->generated) goto generate_code; if (!(*it)->generated) goto generate_code;
} }
// No code to generate, exit: // No code to generate, exit:
return true; return true;
generate_code: generate_code:
using namespace cpp; using namespace cpp;
std::string code; std::string code;
code = "// automatically generated by the FlatBuffers compiler," code =
" do not modify\n\n"; "// automatically generated by the FlatBuffers compiler,"
" do not modify\n\n";
// Generate include guard. // Generate include guard.
std::string include_guard_ident = file_name; std::string include_guard_ident = file_name_;
// Remove any non-alpha-numeric characters that may appear in a filename. // Remove any non-alpha-numeric characters that may appear in a filename.
include_guard_ident.erase( include_guard_ident.erase(
std::remove_if(include_guard_ident.begin(), std::remove_if(include_guard_ident.begin(), include_guard_ident.end(),
include_guard_ident.end(), IsAlnum()),
IsAlnum()), include_guard_ident.end());
include_guard_ident.end()); std::string include_guard = "FLATBUFFERS_GENERATED_" + include_guard_ident;
std::string include_guard = "FLATBUFFERS_GENERATED_" + include_guard_ident; include_guard += "_";
include_guard += "_"; // For further uniqueness, also add the namespace.
// For further uniqueness, also add the namespace. auto name_space = parser_.namespaces_.back();
auto name_space = parser.namespaces_.back(); for (auto it = name_space->components.begin();
for (auto it = name_space->components.begin(); it != name_space->components.end(); ++it) {
it != name_space->components.end(); ++it) { include_guard += *it + "_";
include_guard += *it + "_"; }
} include_guard += "H_";
include_guard += "H_"; std::transform(include_guard.begin(), include_guard.end(),
std::transform(include_guard.begin(), include_guard.end(), include_guard.begin(), ::toupper);
include_guard.begin(), ::toupper); code += "#ifndef " + include_guard + "\n";
code += "#ifndef " + include_guard + "\n"; code += "#define " + include_guard + "\n\n";
code += "#define " + include_guard + "\n\n";
code += "#include \"flatbuffers/flatbuffers.h\"\n\n"; code += "#include \"flatbuffers/flatbuffers.h\"\n\n";
if (parser.opts.include_dependence_headers) { if (parser_.opts.include_dependence_headers) {
int num_includes = 0; int num_includes = 0;
for (auto it = parser.included_files_.begin(); for (auto it = parser_.included_files_.begin();
it != parser.included_files_.end(); ++it) { it != parser_.included_files_.end(); ++it) {
auto basename = flatbuffers::StripPath( auto basename =
flatbuffers::StripExtension(it->first)); flatbuffers::StripPath(flatbuffers::StripExtension(it->first));
if (basename != file_name) { if (basename != file_name_) {
code += "#include \"" + basename + "_generated.h\"\n"; code += "#include \"" + basename + "_generated.h\"\n";
num_includes++; num_includes++;
}
}
if (num_includes) code += "\n";
}
assert(!code_generator_cur_name_space);
// Generate forward declarations for all structs/tables, since they may
// have circular references.
for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
++it) {
auto &struct_def = **it;
if (!struct_def.generated) {
CheckNameSpace(struct_def, &code);
code += "struct " + struct_def.name + ";\n\n";
} }
} }
if (num_includes) code += "\n";
}
assert(!code_generator_cur_name_space); // Generate code for all the enum declarations.
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
// Generate forward declarations for all structs/tables, since they may ++it) {
// have circular references. auto &enum_def = **it;
for (auto it = parser.structs_.vec.begin(); if (!enum_def.generated) {
it != parser.structs_.vec.end(); ++it) { CheckNameSpace(**it, &code);
auto &struct_def = **it; GenEnum(parser_, **it, &code);
if (!struct_def.generated) { }
CheckNameSpace(struct_def, &code);
code += "struct " + struct_def.name + ";\n\n";
} }
}
// Generate code for all the enum declarations. // Generate code for all structs, then all tables.
for (auto it = parser.enums_.vec.begin(); for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
it != parser.enums_.vec.end(); ++it) { ++it) {
auto &enum_def = **it; auto &struct_def = **it;
if (!enum_def.generated) { if (struct_def.fixed && !struct_def.generated) {
CheckNameSpace(**it, &code); CheckNameSpace(struct_def, &code);
GenEnum(parser, **it, &code); GenStruct(parser_, struct_def, &code);
}
} }
} for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
++it) {
// Generate code for all structs, then all tables. auto &struct_def = **it;
for (auto it = parser.structs_.vec.begin(); if (!struct_def.fixed && !struct_def.generated) {
it != parser.structs_.vec.end(); ++it) { CheckNameSpace(struct_def, &code);
auto &struct_def = **it; GenTable(parser_, struct_def, &code);
if (struct_def.fixed && !struct_def.generated) { }
CheckNameSpace(struct_def, &code);
GenStruct(parser, struct_def, &code);
} }
}
for (auto it = parser.structs_.vec.begin(); // Generate code for union verifiers.
it != parser.structs_.vec.end(); ++it) { for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
auto &struct_def = **it; ++it) {
if (!struct_def.fixed && !struct_def.generated) { auto &enum_def = **it;
CheckNameSpace(struct_def, &code); if (enum_def.is_union && !enum_def.generated) {
GenTable(parser, struct_def, &code); CheckNameSpace(enum_def, &code);
GenEnumPost(parser_, enum_def, &code);
}
} }
}
// Generate code for union verifiers. // Generate convenient global helper functions:
for (auto it = parser.enums_.vec.begin(); if (parser_.root_struct_def_) {
it != parser.enums_.vec.end(); ++it) { CheckNameSpace(*parser_.root_struct_def_, &code);
auto &enum_def = **it; auto &name = parser_.root_struct_def_->name;
if (enum_def.is_union && !enum_def.generated) { std::string qualified_name =
CheckNameSpace(enum_def, &code); parser_.namespaces_.back()->GetFullyQualifiedName(name);
GenEnumPost(parser, enum_def, &code); std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
}
}
// Generate convenient global helper functions: // The root datatype accessor:
if (parser.root_struct_def_) { code += "inline const " + cpp_qualified_name + " *Get";
CheckNameSpace(*parser.root_struct_def_, &code);
auto &name = parser.root_struct_def_->name;
std::string qualified_name =
parser.namespaces_.back()->GetFullyQualifiedName(name);
std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
// The root datatype accessor:
code += "inline const " + cpp_qualified_name + " *Get";
code += name;
code += "(const void *buf) { return flatbuffers::GetRoot<";
code += cpp_qualified_name + ">(buf); }\n\n";
if (parser.opts.mutable_buffer) {
code += "inline " + name + " *GetMutable";
code += name; code += name;
code += "(void *buf) { return flatbuffers::GetMutableRoot<"; code += "(const void *buf) { return flatbuffers::GetRoot<";
code += name + ">(buf); }\n\n"; code += cpp_qualified_name + ">(buf); }\n\n";
if (parser_.opts.mutable_buffer) {
code += "inline " + name + " *GetMutable";
code += name;
code += "(void *buf) { return flatbuffers::GetMutableRoot<";
code += name + ">(buf); }\n\n";
}
// The root verifier:
code += "inline bool Verify";
code += name;
code +=
"Buffer(flatbuffers::Verifier &verifier) { "
"return verifier.VerifyBuffer<";
code += cpp_qualified_name + ">(); }\n\n";
if (parser_.file_identifier_.length()) {
// Return the identifier
code += "inline const char *" + name;
code += "Identifier() { return \"" + parser_.file_identifier_;
code += "\"; }\n\n";
// Check if a buffer has the identifier.
code += "inline bool " + name;
code += "BufferHasIdentifier(const void *buf) { return flatbuffers::";
code += "BufferHasIdentifier(buf, ";
code += name + "Identifier()); }\n\n";
}
if (parser_.file_extension_.length()) {
// Return the extension
code += "inline const char *" + name;
code += "Extension() { return \"" + parser_.file_extension_;
code += "\"; }\n\n";
}
// Finish a buffer with a given root object:
code += "inline void Finish" + name;
code +=
"Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
code += cpp_qualified_name + "> root) { fbb.Finish(root";
if (parser_.file_identifier_.length())
code += ", " + name + "Identifier()";
code += "); }\n\n";
} }
// The root verifier: assert(code_generator_cur_name_space);
code += "inline bool Verify"; CloseNestedNameSpaces(code_generator_cur_name_space, &code);
code += name;
code += "Buffer(flatbuffers::Verifier &verifier) { "
"return verifier.VerifyBuffer<";
code += cpp_qualified_name + ">(); }\n\n";
if (parser.file_identifier_.length()) { code_generator_cur_name_space = nullptr;
// Return the identifier
code += "inline const char *" + name;
code += "Identifier() { return \"" + parser.file_identifier_;
code += "\"; }\n\n";
// Check if a buffer has the identifier. // Close the include guard.
code += "inline bool " + name; code += "\n#endif // " + include_guard + "\n";
code += "BufferHasIdentifier(const void *buf) { return flatbuffers::";
code += "BufferHasIdentifier(buf, ";
code += name + "Identifier()); }\n\n";
}
if (parser.file_extension_.length()) { return SaveFile(GeneratedFileName(path_, file_name_).c_str(), code, false);
// Return the extension
code += "inline const char *" + name;
code += "Extension() { return \"" + parser.file_extension_;
code += "\"; }\n\n";
}
// Finish a buffer with a given root object:
code += "inline void Finish" + name;
code += "Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
code += cpp_qualified_name + "> root) { fbb.Finish(root";
if (parser.file_identifier_.length())
code += ", " + name + "Identifier()";
code += "); }\n\n";
}
assert(code_generator_cur_name_space);
CloseNestedNameSpaces(code_generator_cur_name_space, &code);
code_generator_cur_name_space = nullptr;
// Close the include guard.
code += "\n#endif // " + include_guard + "\n";
return SaveFile(GeneratedFileName(path, file_name).c_str(), code, false);
} }
}; };
} // namespace cpp } // namespace cpp
bool GenerateCPP(const Parser &parser, const std::string &path,
bool GenerateCPP(const Parser &parser,
const std::string &path,
const std::string &file_name) { const std::string &file_name) {
cpp::CppGenerator *generator = new cpp::CppGenerator(parser, path, file_name); cpp::CppGenerator *generator = new cpp::CppGenerator(parser, path, file_name);
return generator->generate(); return generator->generate();

View File

@@ -1147,58 +1147,54 @@ static bool SaveClass(const LanguageParameters &lang, const Parser &parser,
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
} }
/** it'll be split later in java/csharp... and moved to separate files */
namespace general { namespace general {
/** members methods signature will be simpler as they won't have to pass parser,
* filename & path */
/** more features coming through the JavaGenerator, CSharpGenerator ...*/
class GeneralGenerator : public BaseGenerator { class GeneralGenerator : public BaseGenerator {
public: public:
GeneralGenerator(const Parser &parser_, const std::string &path_, GeneralGenerator(const Parser &parser, const std::string &path,
const std::string &file_name_) const std::string &file_name)
: BaseGenerator(parser_, path_, file_name_){}; : BaseGenerator(parser, path, file_name){};
bool generate() { bool generate() {
assert(parser.opts.lang <= IDLOptions::kMAX); assert(parser_.opts.lang <= IDLOptions::kMAX);
auto lang = language_parameters[parser.opts.lang]; auto lang = language_parameters[parser_.opts.lang];
std::string one_file_code; std::string one_file_code;
for (auto it = parser.enums_.vec.begin(); for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
it != parser.enums_.vec.end(); ++it) { ++it) {
std::string enumcode; std::string enumcode;
GenEnum(lang, parser, **it, &enumcode); GenEnum(lang, parser_, **it, &enumcode);
if (parser.opts.one_file) { if (parser_.opts.one_file) {
one_file_code += enumcode; one_file_code += enumcode;
} else {
if (!SaveClass(lang, parser_, (**it).name, enumcode, path_, false,
false))
return false;
}
} }
else {
if (!SaveClass(lang, parser, (**it).name, enumcode, path, false, false))
return false;
}
}
for (auto it = parser.structs_.vec.begin(); for (auto it = parser_.structs_.vec.begin();
it != parser.structs_.vec.end(); ++it) { it != parser_.structs_.vec.end(); ++it) {
std::string declcode; std::string declcode;
GenStruct(lang, parser, **it, &declcode); GenStruct(lang, parser_, **it, &declcode);
if (parser.opts.one_file) { if (parser_.opts.one_file) {
one_file_code += declcode; one_file_code += declcode;
} else {
if (!SaveClass(lang, parser_, (**it).name, declcode, path_, true,
false))
return false;
}
} }
else {
if (!SaveClass(lang, parser, (**it).name, declcode, path, true, false))
return false;
}
}
if (parser.opts.one_file) { if (parser_.opts.one_file) {
return SaveClass(lang, parser, file_name, one_file_code,path, true, true); return SaveClass(lang, parser_, file_name_, one_file_code, path_, true,
} true);
return true; }
return true;
} }
}; };
} // namespace general } // namespace general
bool GenerateGeneral(const Parser &parser, bool GenerateGeneral(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name) {
const std::string & file_name) {
general::GeneralGenerator *generator = general::GeneralGenerator *generator =
new general::GeneralGenerator(parser, path, file_name); new general::GeneralGenerator(parser, path, file_name);
return generator->generate(); return generator->generate();

View File

@@ -662,35 +662,32 @@ static void GenStructBuilder(const StructDef &struct_def,
} }
class GoGenerator : public BaseGenerator { class GoGenerator : public BaseGenerator {
public: public:
GoGenerator(const Parser &parser_, const std::string &path_, GoGenerator(const Parser &parser, const std::string &path,
const std::string &file_name_) const std::string &file_name)
: BaseGenerator(parser_, path_, file_name_){}; : BaseGenerator(parser, path, file_name){};
bool generate() { bool generate() {
for (auto it = parser.enums_.vec.begin(); for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
it != parser.enums_.vec.end(); ++it) { ++it) {
std::string enumcode; std::string enumcode;
go::GenEnum(**it, &enumcode); go::GenEnum(**it, &enumcode);
if (!go::SaveType(parser, **it, enumcode, path, false)) if (!go::SaveType(parser_, **it, enumcode, path_, false)) return false;
return false; }
}
for (auto it = parser.structs_.vec.begin(); for (auto it = parser_.structs_.vec.begin();
it != parser.structs_.vec.end(); ++it) { it != parser_.structs_.vec.end(); ++it) {
std::string declcode; std::string declcode;
go::GenStruct(**it, &declcode, parser.root_struct_def_); go::GenStruct(**it, &declcode, parser_.root_struct_def_);
if (!go::SaveType(parser, **it, declcode, path, true)) if (!go::SaveType(parser_, **it, declcode, path_, true)) return false;
return false; }
}
return true; return true;
} }
}; };
} // namespace go } // namespace go
bool GenerateGo(const Parser &parser, bool GenerateGo(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name) {
const std::string & file_name) {
go::GoGenerator *generator = new go::GoGenerator(parser, path, file_name); go::GoGenerator *generator = new go::GoGenerator(parser, path, file_name);
return generator->generate(); return generator->generate();
} }