Преглед изворни кода

Add includes

- Add includes to internal and external class
- Make repeated simpletypes QVariantList
Alexey Edelev пре 6 година
родитељ
комит
30d6da5c84

+ 70 - 20
src/generator/classgeneratorbase.cpp

@@ -31,6 +31,8 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 
+#include <set>
+
 using namespace qtprotobuf;
 using namespace ::google::protobuf;
 using namespace ::google::protobuf::io;
@@ -44,7 +46,8 @@ ClassGeneratorBase::ClassGeneratorBase(std::string mClassName, std::unique_ptr<:
 
 }
 
-bool ClassGeneratorBase::producePropertyMap(const FieldDescriptor* field, PropertyMap& propertyMap) {
+bool ClassGeneratorBase::producePropertyMap(const FieldDescriptor* field, PropertyMap& propertyMap)
+{
     std::string typeName = getTypeName(field);
 
     if (typeName.size() <= 0) {
@@ -56,21 +59,52 @@ bool ClassGeneratorBase::producePropertyMap(const FieldDescriptor* field, Proper
         return false;
     }
 
+    std::string typeNameLower(typeName);
+    std::transform(std::begin(typeName), std::end(typeName), std::begin(typeNameLower), ::tolower);
+
     std::string capProperty = field->camelcase_name();
     capProperty[0] = ::toupper(capProperty[0]);
 
     propertyMap = {{"type", typeName},
-        {"property_name", field->camelcase_name()},
-        {"property_name_cap", capProperty}};
+                   {"type_lower", typeNameLower},
+                   {"property_name", field->camelcase_name()},
+                   {"property_name_cap", capProperty}};
     return true;
 }
 
-void ClassGeneratorBase::printPreamble() {
+void ClassGeneratorBase::printPreamble()
+{
     mPrinter.Print("#pragma once\n"
                    "#include <QObject>\n");
 }
 
-void ClassGeneratorBase::printNamespaces(const std::string& package) {
+void ClassGeneratorBase::printIncludes(const Descriptor* message)
+{
+    PropertyMap properties;
+    std::set<std::string> existingIncludes;
+    std::string newinclude;
+    const char* includeTemplate;
+    for (int i = 0; i < message->field_count(); i++) {
+        const FieldDescriptor* field = message->field(i);
+        if (producePropertyMap(field, properties)) {
+            if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
+                newinclude = properties["type_lower"];
+                includeTemplate = InternalIncludeTemplate;
+            } else if (field->type() == FieldDescriptor::TYPE_STRING) {
+                includeTemplate = ExternalIncludeTemplate;
+            } else {
+                continue;
+            }
+            if (existingIncludes.find(newinclude) == std::end(existingIncludes)) {
+                mPrinter.Print(properties, includeTemplate);
+                existingIncludes.insert(newinclude);
+            }
+        }
+    }
+}
+
+void ClassGeneratorBase::printNamespaces(const std::string& package)
+{
     std::vector<std::string> namespaces;
     utils::split(package, namespaces, '.');
     mNamespaceCount = namespaces.size();
@@ -79,11 +113,13 @@ void ClassGeneratorBase::printNamespaces(const std::string& package) {
     }
 }
 
-void ClassGeneratorBase::printClass() {
+void ClassGeneratorBase::printClass()
+{
     mPrinter.Print({{"classname", mClassName}}, StartTemplate);
 }
 
-void ClassGeneratorBase::printProperties(const Descriptor* message) {
+void ClassGeneratorBase::printProperties(const Descriptor* message)
+{
     //private section
     for (int i = 0; i < message->field_count(); i++) {
         printField(message->field(i), PropertyTemplate);
@@ -113,14 +149,17 @@ void ClassGeneratorBase::printProperties(const Descriptor* message) {
         printField(message->field(i), SignalTemplate);
     }
 }
-void ClassGeneratorBase::printField(const FieldDescriptor* field, const char* fieldTemplate) {
+
+void ClassGeneratorBase::printField(const FieldDescriptor* field, const char* fieldTemplate)
+{
     std::map<std::string, std::string> propertyMap;
     if (producePropertyMap(field, propertyMap)) {
         mPrinter.Print(propertyMap, fieldTemplate);
     }
 }
 
-void ClassGeneratorBase::enclose() {
+void ClassGeneratorBase::enclose()
+{
     mPrinter.Print("};\n");
     while (mNamespaceCount > 0) {
         mPrinter.Print("}\n");
@@ -128,27 +167,37 @@ void ClassGeneratorBase::enclose() {
     }
 }
 
-std::string ClassGeneratorBase::getTypeName(const FieldDescriptor* field) {
+std::string ClassGeneratorBase::getTypeName(const FieldDescriptor* field)
+{
     std::string typeName;
     if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
         typeName = field->message_type()->name();
+        if (field->is_repeated()) {
+            typeName = typeName.append("Model");
+        }
     } else if (field->type() == FieldDescriptor::TYPE_ENUM) {
-        typeName = field->enum_type()->name();
-    } else {
-        auto it = TypeReflection.find(field->type());
-        if (it != std::end(TypeReflection)) {
-            typeName = it->second;
+        if (field->is_repeated()) {
+            typeName = std::string("QVariantList");
+        } else {
+            typeName = field->enum_type()->name();
         }
+    } else {
+            auto it = TypeReflection.find(field->type());
+            if (it != std::end(TypeReflection)) {
+                if (field->is_repeated()) {
+                    typeName = std::string("QVariantList");
+                } else {
+                    typeName = it->second;
+                }
+            }
     }
 
-    if (field->is_repeated()) {
-        typeName = typeName.append("Model");
-    }
 
     return typeName;
 }
 
-void ClassGeneratorBase::printConstructor() {
+void ClassGeneratorBase::printConstructor()
+{
     mPrinter.Print({{"classname", mClassName}},
                    "    $classname$(QObject parent = nullptr) : QObject(parent)\n");
 
@@ -196,6 +245,7 @@ void ClassGeneratorBase::printConstructor() {
     mPrinter.Print("    {}\n\n");
 }
 
-void ClassGeneratorBase::printPublic() {
+void ClassGeneratorBase::printPublic()
+{
     mPrinter.Print("\npublic:\n");
 }

+ 1 - 0
src/generator/classgeneratorbase.h

@@ -49,6 +49,7 @@ public:
 protected:
     bool producePropertyMap(const ::google::protobuf::FieldDescriptor* field, PropertyMap& propertyMap);
     void printPreamble();
+    void printIncludes(const ::google::protobuf::Descriptor* message);
     void printNamespaces(const std::string& package);
     void printClass();
     void printField(const ::google::protobuf::FieldDescriptor* field, const char* fieldTemplate);

+ 1 - 0
src/generator/generator.cpp

@@ -57,6 +57,7 @@ public:
 
     void run() {
         printPreamble();
+        printIncludes(mMessage);
         printNamespaces(mPackage);
         printClass();
         printProperties(mMessage);

+ 12 - 9
src/generator/templates.h

@@ -31,35 +31,38 @@
 
 namespace qtprotobuf {
 
-static const char* StartTemplate = "\nclass $classname$ : public QObject\n"
+static const char *StartTemplate = "\nclass $classname$ : public QObject\n"
                       "{\n"
                       "    Q_OBJECT\n";
 
-static const char* NamespaceTemplate = "\nnamespace $namespace$\n"
+static const char *NamespaceTemplate = "\nnamespace $namespace$\n"
                                   "{\n\n";
-static const char* PropertyTemplate = "    Q_PROPERTY($type$ $property_name$ READ $property_name$ WRITE set$property_name_cap$ NOTIFY $property_name$Changed)\n";
-static const char* GetterTemplate = "    $type$ $property_name$() const {\n"
+static const char *PropertyTemplate = "    Q_PROPERTY($type$ $property_name$ READ $property_name$ WRITE set$property_name_cap$ NOTIFY $property_name$Changed)\n";
+static const char *GetterTemplate = "    $type$ $property_name$() const {\n"
                                     "        return m_$property_name$;\n"
                                     "    }\n";
 
-static const char* SetterTemplateSimpleType = "    void set$property_name_cap$($type$ $property_name$) {\n"
+static const char *SetterTemplateSimpleType = "    void set$property_name_cap$($type$ $property_name$) {\n"
                                               "        if (m_$property_name$ != $property_name$) {\n"
                                               "             m_$property_name$ == $property_name$;\n"
                                               "             $property_name$Changed();\n"
                                               "        }\n"
                                               "    }\n";
 
-static const char* SetterTemplateComplexType = "    void set$property_name_cap$(const $type$ &$property_name$) {\n"
+static const char *SetterTemplateComplexType = "    void set$property_name_cap$(const $type$ &$property_name$) {\n"
                                               "        if (m_$property_name$ != $property_name$) {\n"
                                               "             m_$property_name$ == $property_name$;\n"
                                               "             $property_name$Changed();\n"
                                               "        }\n"
                                               "    }\n";
 
-static const char* SignalTemplate = "    void $property_name$Changed();\n";
-static const char* MemberTemplate = "    $type$ m_$property_name$;\n";
+static const char *SignalTemplate = "    void $property_name$Changed();\n";
+static const char *MemberTemplate = "    $type$ m_$property_name$;\n";
 
-static const char* EnumTemplate = "$type$";
+static const char *InternalIncludeTemplate =  "#include \"$type_lower$.h\"\n";
+static const char *ExternalIncludeTemplate = "#include <$type$>\n";
+
+static const char *EnumTemplate = "$type$";
 
 static const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string> TypeReflection = {
     {::google::protobuf::FieldDescriptor::TYPE_DOUBLE, "qreal"},