From 6765c19d45509fdcffd5ee62cac5cacea32bd397 Mon Sep 17 00:00:00 2001 From: Lakedaemon Date: Tue, 26 Apr 2016 17:08:13 +0200 Subject: [PATCH] memory leak fix + php/js/python transition to class based generator --- src/idl_gen_cpp.cpp | 4 +- src/idl_gen_general.cpp | 5 +- src/idl_gen_go.cpp | 4 +- src/idl_gen_js.cpp | 113 +++++++++++++++++++++++----------------- src/idl_gen_php.cpp | 65 +++++++++++++++-------- src/idl_gen_python.cpp | 60 ++++++++++++++------- 6 files changed, 153 insertions(+), 98 deletions(-) diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index c1b6ba566..0e5d823f3 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -906,8 +906,8 @@ class CppGenerator : public BaseGenerator { bool GenerateCPP(const Parser &parser, const std::string &path, const std::string &file_name) { - cpp::CppGenerator *generator = new cpp::CppGenerator(parser, path, file_name); - return generator->generate(); + cpp::CppGenerator generator(parser, path, file_name); + return generator.generate(); } std::string CPPMakeRule(const Parser &parser, diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index a763d969b..e28661e82 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -1195,9 +1195,8 @@ class GeneralGenerator : public BaseGenerator { bool GenerateGeneral(const Parser &parser, const std::string &path, const std::string &file_name) { - general::GeneralGenerator *generator = - new general::GeneralGenerator(parser, path, file_name); - return generator->generate(); + general::GeneralGenerator generator(parser, path, file_name); + return generator.generate(); } static std::string ClassFileName(const LanguageParameters &lang, diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index f674d1f47..bce8f95bc 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -688,8 +688,8 @@ class GoGenerator : public BaseGenerator { bool GenerateGo(const Parser &parser, const std::string &path, const std::string &file_name) { - go::GoGenerator *generator = new go::GoGenerator(parser, path, file_name); - return generator->generate(); + go::GoGenerator generator(parser, path, file_name); + return generator.generate(); } } // namespace flatbuffers diff --git a/src/idl_gen_js.cpp b/src/idl_gen_js.cpp index f824bc688..de81f2764 100644 --- a/src/idl_gen_js.cpp +++ b/src/idl_gen_js.cpp @@ -19,6 +19,7 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" #include "flatbuffers/util.h" +#include "flatbuffers/code_generators.h" namespace flatbuffers { namespace js { @@ -661,60 +662,76 @@ static void GenStruct(const Parser &parser, StructDef &struct_def, } // namespace js -// Iterate through all definitions we haven't generate code for (enums, structs, -// and tables) and output them to a single file. -std::string GenerateJS(const Parser &parser) { - using namespace js; - - // Generate code for all the enum declarations. - std::string enum_code, exports_code; - for (auto it = parser.enums_.vec.begin(); - it != parser.enums_.vec.end(); ++it) { - GenEnum(**it, &enum_code, &exports_code); - } - - // Generate code for all structs, then all tables. - std::string decl_code; - for (auto it = parser.structs_.vec.begin(); - it != parser.structs_.vec.end(); ++it) { - GenStruct(parser, **it, &decl_code, &exports_code); - } - - // Only output file-level code if there were any declarations. - if (enum_code.length() || decl_code.length()) { - std::string code; - code = "// automatically generated by the FlatBuffers compiler," - " do not modify\n\n"; - - // Generate code for all the namespace declarations. - GenNamespaces(parser, &code, &exports_code); - - // Output the main declaration code from above. - code += enum_code; - code += decl_code; - - if (!exports_code.empty() && !parser.opts.skip_js_exports) { - code += "// Exports for Node.js and RequireJS\n"; - code += exports_code; - } - - return code; - } - - return std::string(); -} - static std::string GeneratedFileName(const std::string &path, const std::string &file_name) { return path + file_name + "_generated.js"; } -bool GenerateJS(const Parser &parser, - const std::string &path, - const std::string &file_name) { - auto code = GenerateJS(parser); +namespace js { +// Iterate through all definitions we haven't generate code for (enums, structs, +// and tables) and output them to a single file. +class JsGenerator : public BaseGenerator { + public: + JsGenerator(const Parser &parser, const std::string &path, + const std::string &file_name) + : BaseGenerator(parser, path, file_name){}; + // Iterate through all definitions we haven't generate code for (enums, + // structs, and tables) and output them to a single file. + bool generate() { + std::string enum_code, struct_code, exports_code, code; + generateEnums(&enum_code, &exports_code); + generateStructs(&struct_code, &exports_code); + + // Only output file-level code if there were any declarations. + if (enum_code.length() || struct_code.length()) { + code += + "// automatically generated by the FlatBuffers compiler, do not " + "modify\n\n"; + + // Generate code for all the namespace declarations. + GenNamespaces(parser_, &code, &exports_code); + + // Output the main declaration code from above. + code += enum_code; + code += struct_code; + + if (!exports_code.empty() && !parser_.opts.skip_js_exports) { + code += "// Exports for Node.js and RequireJS\n"; + code += exports_code; + } + } + return !code.length() || - SaveFile(GeneratedFileName(path, file_name).c_str(), code, false); + SaveFile(GeneratedFileName(path_, file_name_).c_str(), code, false); + } + + private: + // Generate code for all enums. + void generateEnums(std::string *enum_code_ptr, + std::string *exports_code_ptr) { + for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); + ++it) { + auto &enum_def = **it; + GenEnum(enum_def, enum_code_ptr, exports_code_ptr); + } + } + + // Generate code for all structs. + void generateStructs(std::string *decl_code_ptr, + std::string *exports_code_ptr) { + for (auto it = parser_.structs_.vec.begin(); + it != parser_.structs_.vec.end(); ++it) { + auto &struct_def = **it; + GenStruct(parser_, struct_def, decl_code_ptr, exports_code_ptr); + } + } +}; +} // namespace js + +bool GenerateJS(const Parser &parser, const std::string &path, + const std::string &file_name) { + js::JsGenerator generator(parser, path, file_name); + return generator.generate(); } std::string JSMakeRule(const Parser &parser, diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp index 5b904a077..b43ea6702 100644 --- a/src/idl_gen_php.cpp +++ b/src/idl_gen_php.cpp @@ -21,6 +21,7 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" #include "flatbuffers/util.h" +#include "flatbuffers/code_generators.h" namespace flatbuffers { namespace php { @@ -974,29 +975,47 @@ namespace php { code += Indent + "}\n"; } -} // namespace php + class PhpGenerator : public BaseGenerator { + public: + PhpGenerator(const Parser &parser, const std::string &path, + const std::string &file_name) + : BaseGenerator(parser, path, file_name){}; + bool generate() { + if (!generateEnums()) return false; + if (!generateStructs()) return false; + return true; + } - bool GeneratePhp(const Parser &parser, - const std::string &path, - const std::string & /*file_name*/) { - for (auto it = parser.enums_.vec.begin(); - it != parser.enums_.vec.end(); ++it) { - std::string enumcode; - php::GenEnum(**it, &enumcode); + private: + bool generateEnums() { + for (auto it = parser_.enums_.vec.begin(); + it != parser_.enums_.vec.end(); ++it) { + auto &enum_def = **it; + std::string enumcode; + GenEnum(enum_def, &enumcode); + if (!SaveType(parser_, enum_def, enumcode, path_, false)) + return false; + } + return true; + } - if (!php::SaveType(parser, **it, enumcode, path, false)) - return false; + bool generateStructs() { + for (auto it = parser_.structs_.vec.begin(); + it != parser_.structs_.vec.end(); ++it) { + auto &struct_def = **it; + std::string declcode; + GenStruct(parser_, struct_def, &declcode); + if (!SaveType(parser_, struct_def, declcode, path_, true)) + return false; + } + return true; + } + }; + } // namespace php + + bool GeneratePhp(const Parser &parser, const std::string &path, + const std::string &file_name) { + php::PhpGenerator generator(parser, path, file_name); + return generator.generate(); } - - for (auto it = parser.structs_.vec.begin(); - it != parser.structs_.vec.end(); ++it) { - std::string declcode; - php::GenStruct(parser, **it, &declcode); - - if (!php::SaveType(parser, **it, declcode, path, true)) - return false; - } - - return true; -} -} // namespace flatbuffers + } // namespace flatbuffers diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 7cd09cfcd..ee6d16874 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -21,6 +21,7 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" #include "flatbuffers/util.h" +#include "flatbuffers/code_generators.h" namespace flatbuffers { namespace python { @@ -634,28 +635,47 @@ static void GenStructBuilder(const StructDef &struct_def, EndBuilderBody(code_ptr); } +class PythonGenerator : public BaseGenerator { + public: + PythonGenerator(const Parser &parser, const std::string &path, + const std::string &file_name) + : BaseGenerator(parser, path, file_name){}; + bool generate() { + if (!generateEnums()) return false; + if (!generateStructs()) return false; + return true; + } + + private: + bool generateEnums() { + for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); + ++it) { + auto &enum_def = **it; + std::string enumcode; + GenEnum(enum_def, &enumcode); + if (!SaveType(parser_, enum_def, enumcode, path_, false)) return false; + } + return true; + } + + bool generateStructs() { + for (auto it = parser_.structs_.vec.begin(); + it != parser_.structs_.vec.end(); ++it) { + auto &struct_def = **it; + std::string declcode; + GenStruct(struct_def, &declcode, parser_.root_struct_def_); + if (!SaveType(parser_, struct_def, declcode, path_, true)) return false; + } + return true; + } +}; + } // namespace python -bool GeneratePython(const Parser &parser, - const std::string &path, - const std::string & /*file_name*/) { - for (auto it = parser.enums_.vec.begin(); - it != parser.enums_.vec.end(); ++it) { - std::string enumcode; - python::GenEnum(**it, &enumcode); - if (!python::SaveType(parser, **it, enumcode, path, false)) - return false; - } - - for (auto it = parser.structs_.vec.begin(); - it != parser.structs_.vec.end(); ++it) { - std::string declcode; - python::GenStruct(**it, &declcode, parser.root_struct_def_); - if (!python::SaveType(parser, **it, declcode, path, true)) - return false; - } - - return true; +bool GeneratePython(const Parser &parser, const std::string &path, + const std::string &file_name) { + python::PythonGenerator generator(parser, path, file_name); + return generator.generate(); } } // namespace flatbuffers