memory leak fix + php/js/python transition to class based generator
authorLakedaemon <olivier.binda@wanadoo.fr>
Tue, 26 Apr 2016 15:08:13 +0000 (17:08 +0200)
committerLakedaemon <olivier.binda@wanadoo.fr>
Tue, 26 Apr 2016 18:36:43 +0000 (20:36 +0200)
src/idl_gen_cpp.cpp
src/idl_gen_general.cpp
src/idl_gen_go.cpp
src/idl_gen_js.cpp
src/idl_gen_php.cpp
src/idl_gen_python.cpp

index c1b6ba5..0e5d823 100644 (file)
@@ -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,
index a763d96..e28661e 100644 (file)
@@ -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,
index f674d1f..bce8f95 100644 (file)
@@ -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
index f824bc6..de81f27 100644 (file)
@@ -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
 
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name) {
+  return path + file_name + "_generated.js";
+}
+
+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);
-  }
+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;
+      }
+    }
 
-  // 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);
+    return !code.length() ||
+           SaveFile(GeneratedFileName(path_, file_name_).c_str(), code, false);
   }
 
-  // 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;
+ 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);
     }
-
-    return code;
   }
 
-  return std::string();
-}
-
-static std::string GeneratedFileName(const std::string &path,
-                                     const std::string &file_name) {
-  return path + file_name + "_generated.js";
-}
+  // 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,
+bool GenerateJS(const Parser &parser, const std::string &path,
                 const std::string &file_name) {
-    auto code = GenerateJS(parser);
-    return !code.length() ||
-           SaveFile(GeneratedFileName(path, file_name).c_str(), code, false);
+  js::JsGenerator generator(parser, path, file_name);
+  return generator.generate();
 }
 
 std::string JSMakeRule(const Parser &parser,
index 5b904a0..b43ea67 100644 (file)
@@ -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
-
-  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);
+    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;
+      }
 
-      if (!php::SaveType(parser, **it, enumcode, path, false))
-        return false;
-    }
+     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;
+      }
 
-    for (auto it = parser.structs_.vec.begin();
-    it != parser.structs_.vec.end(); ++it) {
-      std::string declcode;
-      php::GenStruct(parser, **it, &declcode);
+      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
 
-      if (!php::SaveType(parser, **it, declcode, path, true))
-        return false;
+    bool GeneratePhp(const Parser &parser, const std::string &path,
+                     const std::string &file_name) {
+      php::PhpGenerator generator(parser, path, file_name);
+      return generator.generate();
     }
-
-    return true;
-}
-}  // namespace flatbuffers
+    }  // namespace flatbuffers
index 7cd09cf..ee6d168 100644 (file)
@@ -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);
 }
 
-}  // namespace python
+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;
+  }
 
-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;
+ 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;
   }
 
-  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;
+  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
 
-  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