Browse Source

Fix few issues in globalenums.cpp generator

- Enable and fix compilation of globalenums.cpp
- Add metatype and qml type register for GlobalEnum class
- Add required copy and move constructors
TODO: make it uncreatable
Alexey Edelev 5 years ago
parent
commit
a702d21e78

+ 1 - 0
src/generator/classgeneratorbase.cpp

@@ -41,6 +41,7 @@ using namespace ::google::protobuf::compiler;
 ClassGeneratorBase::ClassGeneratorBase(std::string fullClassName, std::unique_ptr<::google::protobuf::io::ZeroCopyOutputStream> out) : mOutput(std::move(out))
   , mPrinter(mOutput.get(), '$')
 {
+    mPrinter.Print(Templates::DisclaimerTemplate);
     utils::split(fullClassName, mNamespaces, '.');
     assert(mNamespaces.size() > 0);
     mClassName = mNamespaces.back();

+ 12 - 0
src/generator/globalenumsgenerator.cpp

@@ -40,11 +40,23 @@ void GlobalEnumsGenerator::startEnum(const std::vector<std::string>& namespaces)
     printNamespaces(namespaces);
     printEnumClass();
     printPublic();
+    printConstructor();
     Indent();
     mPrinter.Print(Templates::ComplexTypeRegistrationMethodTemplate);
     Outdent();
 }
 
+void GlobalEnumsGenerator::printConstructor()
+{
+    Indent();
+    mPrinter.Print({{"classname", mClassName}}, Templates::ConstructorHeaderTemplate);
+    mPrinter.Print({{"classname", mClassName}}, Templates::CopyConstructorTemplate);
+    encloseNamespaces(1);
+    mPrinter.Print({{"classname", mClassName}}, Templates::MoveConstructorTemplate);
+    encloseNamespaces(1);
+    Outdent();
+}
+
 void GlobalEnumsGenerator::run() {
     printPreamble();
     std::vector<std::string> namespaces;

+ 1 - 0
src/generator/globalenumsgenerator.h

@@ -47,6 +47,7 @@ public:
     void printMetatype(const google::protobuf::FileDescriptor *file,
                        const std::vector<std::string>& namespaces);
     void printEnumClass();
+    void printConstructor();
 };
 
 } //namespace generator

+ 19 - 11
src/generator/globalenumssourcegenerator.cpp

@@ -37,7 +37,8 @@ GlobalEnumsSourceGenerator::GlobalEnumsSourceGenerator(const PackagesList &packa
   , mPackageList(packageList) {}
 
 void GlobalEnumsSourceGenerator::run() {
-    printPreamble();
+    mPrinter.Print("#include \"globalenums.h\"\n"
+                   "#include <QQmlEngine>");
 
     std::vector<std::string> namespaces;
     for (auto package : mPackageList) {
@@ -52,6 +53,8 @@ void GlobalEnumsSourceGenerator::run() {
 void GlobalEnumsSourceGenerator::printRegisterBody(const std::list<const FileDescriptor *> &list,
                                                    const std::vector<std::string> &namespaces)
 {
+    assert(list.size() > 0);
+
     std::string fullNamespace;
     for (auto name : namespaces) {
         if (fullNamespace.empty()) {
@@ -60,23 +63,28 @@ void GlobalEnumsSourceGenerator::printRegisterBody(const std::list<const FileDes
         }
         fullNamespace.append("::").append(name);
     }
+
     const std::map<std::string, std::string> registrationProperties = {{"classname", mClassName},
-                                                                       {"namespaces", fullNamespace}};
+                                                                       {"type", mClassName},
+                                                                       {"namespaces", fullNamespace},
+                                                                       {"package", list.front()->package()}};
+
     mPrinter.Print(registrationProperties, Templates::ComplexGlobalEnumRegistrationTemplate);
+    Indent();
+    Indent();
+    mPrinter.Print(registrationProperties, Templates::RegisterMetaTypeTemplate);
+    mPrinter.Print(registrationProperties, Templates::QmlRegisterTypeTemplate);
+
     for (auto file : list) {
-        std::string fullClassname;
         for (int i = 0; i < file->enum_type_count(); i++) {
             const auto enumDescr = file->enum_type(i);
-            if (!enumDescr->name().empty()) {
-                const std::map<std::string, std::string> properties = {{"classname", mClassName},
-                                                                       {"enum", enumDescr->name() + "List"},
-                                                                       {"namespaces", fullNamespace}};
-                mPrinter.Print(properties, Templates::ComplexGlobalEnumFieldRegistrationTemplate);
-            }
+            const std::map<std::string, std::string> properties = {{"classname", mClassName},
+                                                                   {"enum", enumDescr->name() + "List"},
+                                                                   {"namespaces", fullNamespace}};
+            mPrinter.Print(properties, Templates::ComplexGlobalEnumFieldRegistrationTemplate);
         }
     }
-
-    Indent();
+    Outdent();
     mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
     Outdent();
     mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);

+ 4 - 3
src/generator/templates.cpp

@@ -36,8 +36,8 @@ const char *Templates::DefaultProtobufIncludesTemplate = "#include <QMetaType>\n
 
 const char *Templates::GlobalEnumClassNameTemplate = "GlobalEnums";
 
-const char *Templates::PreambleTemplate = "/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */\n\n"
-                                      "#pragma once\n\n"
+const char *Templates::DisclaimerTemplate = "/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */\n\n";
+const char *Templates::PreambleTemplate = "#pragma once\n\n"
                                       "#include <QObject>\n";
 
 const char *Templates::InternalIncludeTemplate =  "#include \"$include$.h\"\n";
@@ -59,7 +59,7 @@ const char *Templates::ComplexGlobalEnumRegistrationTemplate = "void $classname$
                                                                "    static bool registationDone = false;\n"
                                                                "    if (!registationDone) {\n\n"
                                                                "        registationDone = true;\n";
-const char *Templates::ComplexGlobalEnumFieldRegistrationTemplate = "        qRegisterMetaType<$classname$::$enum$>(\"$namespaces$::$classname$::$enum$\");\n";
+const char *Templates::ComplexGlobalEnumFieldRegistrationTemplate = "qRegisterMetaType<$classname$::$enum$>(\"$namespaces$::$classname$::$enum$\");\n";
 const char *Templates::ComplexListTypeUsingTemplate = "using $classname$List = QList<QSharedPointer<$classname$>>;\n";
 const char *Templates::MapTypeUsingTemplate = "using $classname$ = QMap<$key$, $value$>;\n";
 const char *Templates::MessageMapTypeUsingTemplate = "using $classname$ = QMap<$key$, QSharedPointer<$value$>>;\n";
@@ -87,6 +87,7 @@ const char *Templates::EnumDefinitionTemplate = "enum $enum$ {\n";
 const char *Templates::EnumFieldTemplate = "$enumvalue$ = $value$,\n";
 const char *Templates::ProtoConstructorTemplate = "$classname$($parameter_list$QObject *parent = nullptr) : QObject(parent)";
 const char *Templates::ConstructorTemplate = "$classname$();\n";
+const char *Templates::ConstructorHeaderTemplate = "$classname$(){}\n";
 const char *Templates::CopyConstructorTemplate = "$classname$(const $classname$ &other) : QObject() {\n";
 const char *Templates::MoveConstructorTemplate = "$classname$($classname$ &&other) : QObject() {\n";
 const char *Templates::CopyFieldTemplate = "m_$property_name$ = other.m_$property_name$;\n";

+ 2 - 0
src/generator/templates.h

@@ -37,6 +37,7 @@ public:
     static const char *DefaultProtobufIncludesTemplate;
     static const char *GlobalEnumClassNameTemplate;
     static const char *PreambleTemplate;
+    static const char *DisclaimerTemplate;
     static const char *InternalIncludeTemplate;
     static const char *ExternalIncludeTemplate;
     static const char *GlobalEnumIncludeTemplate;
@@ -53,6 +54,7 @@ public:
     static const char *UsingNamespaceTemplate;
     static const char *NonProtoClassDefinitionTemplate;
     static const char *ProtoClassDefinitionTemplate;
+    static const char *ConstructorHeaderTemplate;
     static const char *ClassDefinitionTemplate;
     static const char *PropertyTemplate;
     static const char *MessagePropertyTemplate;

+ 0 - 1
tests/test_grpc/CMakeLists.txt

@@ -40,7 +40,6 @@ list(APPEND GENERATED_SOURCES ${MOC_SOURCES})
 
 # TODO: so far the following cpp files are not generated 
 list(REMOVE_ITEM GENERATED_SOURCES
-    ${GENERATED_SOURCES_DIR}/globalenums.cpp
     ${GENERATED_SOURCES_DIR}/testserviceserver.cpp
 )
 set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)

+ 0 - 4
tests/test_protobuf/CMakeLists.txt

@@ -177,10 +177,6 @@ endforeach(EXPECTED_GENERATED_HEADER)
 qt5_wrap_cpp(MOC_SOURCES ${GENERATED_HEADERS})
 list(APPEND GENERATED_SOURCES ${MOC_SOURCES})
 
-# TODO: so far the following cpp files are not generated 
-list(REMOVE_ITEM GENERATED_SOURCES
-    ${GENERATED_SOURCES_DIR}/globalenums.cpp
-)
 set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
 
 # TODO: but their headers should be included in sources for executable to be processed by moc

+ 4 - 0
tests/test_protobuf/simpletest.cpp

@@ -307,6 +307,8 @@ TEST_F(SimpleTest, SimpleExternalEnumMessageTest)
 {
     const char* propertyName = "externalEnum";
     using ExternalGlobalEnums = qtprotobufnamespace1::externaltests::GlobalEnums;
+    ExternalGlobalEnums::registerTypes();
+
     SimpleExternalEnumMessage test;
     int propertyNumber = SimpleExternalEnumMessage::propertyOrdering.at(1); //See externalpackagetest.proto
     ASSERT_STREQ(SimpleExternalEnumMessage::staticMetaObject.property(propertyNumber).typeName(), "qtprotobufnamespace1::externaltests::GlobalEnums::ExternalTestEnum");
@@ -683,6 +685,7 @@ TEST_F(SimpleTest, RepeatedSFixedInt64MessageTest)
 
 TEST_F(SimpleTest, StepChildEnumMessageTest)
 {
+    qtprotobufnamespace::tests::SimpleEnumMessage::registerTypes();
     const char* propertyName = "localStepChildEnum";
     StepChildEnumMessage test;
     int propertyNumber = StepChildEnumMessage::propertyOrdering.at(1); //See simpletest.proto
@@ -696,6 +699,7 @@ TEST_F(SimpleTest, StepChildEnumMessageTest)
 
 TEST_F(SimpleTest, StepChildEnumListMessageTest)
 {
+    qtprotobufnamespace::tests::SimpleEnumMessage::registerTypes();
     const char* propertyName = "localStepChildList";
     StepChildEnumMessage test;
     int propertyNumber = StepChildEnumMessage::propertyOrdering.at(2); //See simpletest.proto