Browse Source

Implemet equal operator generation

- Add template and code for equal operator
- Fix coding style
- Fix assignment issue in setters
Alexey Edelev 6 years ago
parent
commit
8a55c59037

+ 27 - 7
src/generator/classgeneratorbase.cpp

@@ -46,7 +46,7 @@ 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);
 
@@ -77,7 +77,7 @@ void ClassGeneratorBase::printPreamble()
     mPrinter.Print(PreambleTemplate);
 }
 
-void ClassGeneratorBase::printIncludes(const Descriptor* message)
+void ClassGeneratorBase::printIncludes(const Descriptor *message)
 {
     PropertyMap properties;
     std::set<std::string> existingIncludes;
@@ -105,7 +105,7 @@ void ClassGeneratorBase::printIncludes(const Descriptor* message)
     }
 }
 
-void ClassGeneratorBase::printNamespaces(const std::string& package)
+void ClassGeneratorBase::printNamespaces(const std::string &package)
 {
     std::vector<std::string> namespaces;
     utils::split(package, namespaces, '.');
@@ -120,7 +120,7 @@ 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++) {
@@ -134,6 +134,7 @@ void ClassGeneratorBase::printProperties(const Descriptor* message)
     //public section
     printPublic();
     printConstructor();
+    printEqualOperator(message);
     for (int i = 0; i < message->field_count(); i++) {
         printField(message->field(i), GetterTemplate);
     }
@@ -152,7 +153,7 @@ void ClassGeneratorBase::printProperties(const Descriptor* message)
     }
 }
 
-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)) {
@@ -164,12 +165,12 @@ void ClassGeneratorBase::enclose()
 {
     mPrinter.Print("};\n");
     while (mNamespaceCount > 0) {
-        mPrinter.Print("}\n");
+        mPrinter.Print(SimpleBlockEnclosureTemplate);
         --mNamespaceCount;
     }
 }
 
-std::string ClassGeneratorBase::getTypeName(const FieldDescriptor* field)
+std::string ClassGeneratorBase::getTypeName(const FieldDescriptor *field)
 {
     std::string typeName;
     if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
@@ -251,3 +252,22 @@ void ClassGeneratorBase::printPublic()
 {
     mPrinter.Print("\npublic:\n");
 }
+
+void ClassGeneratorBase::printEqualOperator(const Descriptor *message)
+{
+    bool isFirst = true;
+    PropertyMap properties;
+    mPrinter.Print({{"type", message->name()}}, EqualOperatorTemplate);
+    for (int i = 1; i < message->field_count(); i++) {
+        const FieldDescriptor* field = message->field(i);
+        if (producePropertyMap(field, properties)) {
+            if (!isFirst) {
+                mPrinter.Print("\n            && ");
+            }
+            isFirst = false;
+            mPrinter.Print(properties, EqualOperatorPropertyTemplate);
+        }
+    }
+    mPrinter.Print(";\n    ");
+    mPrinter.Print(SimpleBlockEnclosureTemplate);
+}

+ 8 - 7
src/generator/classgeneratorbase.h

@@ -48,17 +48,17 @@ protected:
     std::string mClassName;
     int mNamespaceCount;
 
-    bool producePropertyMap(const ::google::protobuf::FieldDescriptor* field, PropertyMap& propertyMap);
+    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 printIncludes(const ::google::protobuf::Descriptor *message);
+    void printNamespaces(const std::string &package);
     void printClass();
-    void printField(const ::google::protobuf::FieldDescriptor* field, const char* fieldTemplate);
+    void printField(const ::google::protobuf::FieldDescriptor *field, const char *fieldTemplate);
     void enclose();
-    std::string getTypeName(const ::google::protobuf::FieldDescriptor* field);
+    std::string getTypeName(const ::google::protobuf::FieldDescriptor *field);
 
     template<typename T>
-    void printQEnums(const T* message) {
+    void printQEnums(const T *message) {
         if (message->enum_type_count() <= 0) {
             return;
         }
@@ -82,7 +82,8 @@ protected:
         }
     }
 
-    void printProperties(const ::google::protobuf::Descriptor* message);
+    void printEqualOperator(const ::google::protobuf::Descriptor *message);
+    void printProperties(const ::google::protobuf::Descriptor *message);
     void printConstructor();
     void printPublic();
 };

+ 12 - 12
src/generator/generator.cpp

@@ -51,7 +51,7 @@ class QtClassGenerator : public ClassGeneratorBase
     std::set<std::string> mExtractedModels;
 
 public:
-    QtClassGenerator(const std::string& package, const Descriptor* message, std::unique_ptr<io::ZeroCopyOutputStream> out) :
+    QtClassGenerator(const std::string &package, const Descriptor *message, std::unique_ptr<io::ZeroCopyOutputStream> out) :
         ClassGeneratorBase(message->name(), std::move(out))
       , mPackage(std::move(package))
       , mMessage(message){}
@@ -80,7 +80,7 @@ public:
         enclose();
     }
 
-    const std::set<std::string>& extractedModels() const {
+    const std::set<std::string> &extractedModels() const {
         return mExtractedModels;
     }
 
@@ -88,10 +88,10 @@ public:
 
 class GlobalEnumsGenerator : public ClassGeneratorBase
 {
-    const FileDescriptor* mFile;
+    const FileDescriptor *mFile;
 
 public:
-    GlobalEnumsGenerator(const FileDescriptor* file, std::unique_ptr<io::ZeroCopyOutputStream> out) :
+    GlobalEnumsGenerator(const FileDescriptor *file, std::unique_ptr<io::ZeroCopyOutputStream> out) :
         ClassGeneratorBase("GlobalEnums", std::move(out))
     , mFile(file)
     {}
@@ -105,10 +105,10 @@ public:
     }
 };
 
-bool QtGenerator::Generate(const FileDescriptor* file,
-                           const std::string& /*parameter*/,
-                           GeneratorContext* generator_context,
-                           std::string* error) const
+bool QtGenerator::Generate(const FileDescriptor *file,
+                           const std::string &/*parameter*/,
+                           GeneratorContext *generatorContext,
+                           std::string *error) const
 {
     if (file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
         *error = "Invalid proto used. This plugin only supports 'proto3' syntax";
@@ -118,22 +118,22 @@ bool QtGenerator::Generate(const FileDescriptor* file,
     std::set<std::string> extractedModels;
 
     for(int i = 0; i < file->message_type_count(); i++) {
-        const Descriptor* message = file->message_type(i);
+        const Descriptor *message = file->message_type(i);
         std::string filename = message->name() + ".h";
         std::transform(std::begin(filename), std::end(filename), std::begin(filename), ::tolower);
         QtClassGenerator classGen(file->package(), message,
-                                  std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generator_context->Open(filename))));
+                                  std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generatorContext->Open(filename))));
         classGen.run();
         extractedModels.insert(std::begin(classGen.extractedModels()), std::end(classGen.extractedModels()));
     }
 
     std::string globalEnumsFilename = "globalenums.h";
-    GlobalEnumsGenerator enumGen(file, std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generator_context->Open(globalEnumsFilename))));
+    GlobalEnumsGenerator enumGen(file, std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generatorContext->Open(globalEnumsFilename))));
     enumGen.run();
 
     //TODO: move to separate class also slipt definitions
     //Print list models
-    std::unique_ptr<io::ZeroCopyOutputStream> out(generator_context->Open("listmodels.h"));
+    std::unique_ptr<io::ZeroCopyOutputStream> out(generatorContext->Open("listmodels.h"));
     io::Printer printer(out.get(), '$');
     printer.Print(PreambleTemplate);
 

+ 4 - 4
src/generator/generator.h

@@ -38,10 +38,10 @@ namespace qtprotobuf {
 
 class QtGenerator : public ::google::protobuf::compiler::CodeGenerator
 {
-    virtual bool Generate(const ::google::protobuf::FileDescriptor* file,
-                          const std::string& parameter,
-                          ::google::protobuf::compiler::GeneratorContext* generator_context,
-                          std::string* error) const override;
+    virtual bool Generate(const ::google::protobuf::FileDescriptor *file,
+                          const std::string &parameter,
+                          ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                          std::string *error) const override;
 };
 
 }  // namespace qtprotobuf

+ 1 - 1
src/generator/main.cpp

@@ -27,7 +27,7 @@
 
 #include "generator.h"
 
-int main(int argc, char* argv[])
+int main(int argc, char *argv[])
 {
     qtprotobuf::QtGenerator generator;
     return ::google::protobuf::compiler::PluginMain(argc, argv, &generator);

+ 7 - 2
src/generator/templates.h

@@ -48,14 +48,14 @@ static const char *GetterTemplate = "    $type$ $property_name$() const {\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"
+                                              "             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"
                                               "        if (m_$property_name$ != $property_name$) {\n"
-                                              "             m_$property_name$ == $property_name$;\n"
+                                              "             m_$property_name$ = $property_name$;\n"
                                               "             $property_name$Changed();\n"
                                               "        }\n"
                                               "    }\n";
@@ -69,6 +69,11 @@ static const char *ExternalIncludeTemplate = "#include <$type$>\n";
 static const char *EnumTemplate = "$type$";
 static const char *ModelClassTemplate = "using $type$Model = UniversalListModel<$type$>;\n";
 
+static const char *EqualOperatorTemplate = "    operator ==(const $type$& other) {\n"
+                                          "        return ";
+static const char *EqualOperatorPropertyTemplate = "m_$property_name$ == other.m_$property_name$";
+static const char *SimpleBlockEnclosureTemplate = "}\n";
+
 static const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string> TypeReflection = {
     {::google::protobuf::FieldDescriptor::TYPE_DOUBLE, "qreal"},
     {::google::protobuf::FieldDescriptor::TYPE_FLOAT, "qreal"},

+ 1 - 1
src/generator/utils.h

@@ -30,7 +30,7 @@
 namespace qtprotobuf {
 namespace utils {
 
-void split(const std::string& str, std::vector<std::string>& container, char delim)
+void split(const std::string &str, std::vector<std::string> &container, char delim)
 {
     std::stringstream stream(str);
     std::string token;