Support 'struct' inheritance feature for C++ Generator 61/297361/8
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 17 Aug 2023 09:30:18 +0000 (18:30 +0900)
committerHwanKyu Jhun <h.jhun@samsung.com>
Fri, 25 Aug 2023 07:06:22 +0000 (07:06 +0000)
This patch supports the struct inheritance feature.

Change-Id: Ic3c4749316c8fc870da6e621976e6f094cef9d38
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
idlc/gen/version2/cpp_generator_base.cc
idlc/gen/version2/cpp_generator_base.hh
idlc/gen/version2/cpp_generator_base_cb.hh

index dc2851fd2a1f0a0b6dfa6c758897dbab3f95fda8..71a2ea4e75a8802bd5964bad61c85b6227e273ce 100644 (file)
@@ -41,6 +41,13 @@ bool IsObject(const BaseType& type) {
   return false;
 }
 
+std::string GetBaseTypeName(const std::shared_ptr<Structure>& base) {
+  if (base->GetBase() != nullptr)
+    return GetBaseTypeName(base->GetBase()) + "::" + base->GetID();
+
+  return base->GetID();
+}
+
 }  // namespace
 
 CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc,
@@ -87,6 +94,25 @@ CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc,
     {"float", "0.0f"},
     {"double", "0.0"},
   };
+
+  for (auto& block : GetDocument().GetBlocks()) {
+    if (block->GetType() != Block::TYPE_STRUCTURE)
+      continue;
+
+    auto& st = static_cast<const Structure&>(*block);
+    AddTypeName(st);
+  }
+}
+
+void CppGeneratorBase::AddTypeName(const Structure& st) {
+  std::string name = st.GetID();
+  std::string type_name;
+  if (st.GetBase() != nullptr)
+    type_name = GetBaseTypeName(st.GetBase()) + "::" + name;
+  else
+    type_name = name;
+
+  struct_types_[std::move(name)] = std::move(type_name);
 }
 
 void CppGeneratorBase::GenVersion(std::ofstream& stream) {
@@ -313,18 +339,42 @@ std::string CppGeneratorBase::GenStructuresForHeader(bool use_file) {
 std::string CppGeneratorBase::GenStructureForHeader(const Structure& st) {
   std::string code;
   if (st.GetElements().Empty()) {
-    code = ReplaceAll(CB_HEADER_STRUCTURE_BASE_EMPTY)
-        .Change("<CLS_NAME>", st.GetID())
-        .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+    if (st.GetBase() == nullptr) {
+      code = ReplaceAll(CB_HEADER_STRUCTURE_BASE_EMPTY)
+                 .Change("<CLS_NAME>", st.GetID())
+                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+    } else {
+      code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE_EMPTY)
+                 .Change("<CLS_NAME>", st.GetID())
+                 .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
+                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+    }
   } else {
-    code = ReplaceAll(CB_HEADER_STRUCTURE_BASE)
-          .Change("<CLS_NAME>", st.GetID())
-          .Change("<PARAMS>", GenParameters(st.GetElements()))
-          .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
-          .Change("<GETTER_SETTER>",
-                  GenStructureGetterSetterForHeader(st.GetElements()))
-          .Change("<MEMBERS>\n",
-                  GenStructureMembersForHeader(st.GetElements()));
+    if (st.GetBase() == nullptr) {
+      code = ReplaceAll(CB_HEADER_STRUCTURE_BASE)
+                 .Change("<CLS_NAME>", st.GetID())
+                 .Change("<PARAMS>", GenParameters(st.GetElements()))
+                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
+                 .Change("<GETTER_SETTER>",
+                         GenStructureGetterSetterForHeader(st.GetElements()))
+                 .Change("<MEMBERS>\n",
+                         GenStructureMembersForHeader(st.GetElements()));
+    } else {
+      std::string params = GenParameters(st.GetBase()->GetElements());
+      if (!params.empty())
+        params += ", ";
+
+      params += GenParameters(st.GetElements());
+      code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE)
+                 .Change("<CLS_NAME>", st.GetID())
+                 .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
+                 .Change("<PARAMS>", params)
+                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
+                 .Change("<GETTER_SETTER>",
+                         GenStructureGetterSetterForHeader(st.GetElements()))
+                 .Change("<MEMBERS>\n",
+                         GenStructureMembersForHeader(st.GetElements()));
+    }
   }
 
   return code;
@@ -469,11 +519,41 @@ std::string CppGeneratorBase::GenStructure(const Structure& st) {
     code = ReplaceAll(CB_BODY_STRUCTURE_BASE_EMPTY)
                .Change("<CLS_NAME>", st.GetID());
   } else {
-    code = ReplaceAll(CB_BODY_STRUCTURE_BASE)
-            .Change("<CLS_NAME>", st.GetID())
-            .Change("<PARAMS>", GenParameters(st.GetElements()))
-            .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
-            .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+    if (st.GetBase() == nullptr) {
+      code =
+          ReplaceAll(CB_BODY_STRUCTURE_BASE)
+              .Change("<CLS_NAME>", st.GetID())
+              .Change("<PARAMS>", GenParameters(st.GetElements()))
+              .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
+              .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+    } else {
+      std::string params = GenParameters(st.GetBase()->GetElements());
+      if (!params.empty())
+        params += ", ";
+
+      params += GenParameters(st.GetElements());
+      code =
+          ReplaceAll(CB_BODY_INHERITED_STRUCTURE_BASE)
+              .Change("<CLS_NAME>", st.GetID())
+              .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
+              .Change("<BASE_ARGS>",
+                      GenStructureBaseArgs(st.GetBase()->GetElements()))
+              .Change("<PARAMS>", params)
+              .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
+              .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+    }
+  }
+
+  return code;
+}
+
+std::string CppGeneratorBase::GenStructureBaseArgs(const Elements& elms) {
+  std::string code;
+  for (auto& elm : elms) {
+    if (!code.empty())
+      code += ", ";
+
+    code += GetSetterValue(elm->GetType(), elm->GetID());
   }
 
   return code;
@@ -645,6 +725,10 @@ std::string CppGeneratorBase::GenUnitMap(bool use_file) {
 }
 
 std::string CppGeneratorBase::GetFullNameFromType(const BaseType& type) {
+  auto found = struct_types_.find(type.GetFullName(true));
+  if (found != struct_types_.end())
+    return found->second;
+
   if (type.IsEnumType())
     return "int";
 
@@ -724,6 +808,17 @@ std::string CppGeneratorBase::GenUnitImplSerializer(const BaseType& type) {
   return RemoveLine(code);
 }
 
+std::string CppGeneratorBase::GenUnitMapBaseWrite(const Structure& st) {
+  std::string code;
+  if (st.GetBase() != nullptr)
+    code += GenUnitMapBaseWrite(*st.GetBase());
+
+  for (auto& elm : st.GetElements())
+    code += ReplaceAll(CB_UNIT_MAP_BASE_WRITE).Change("<NAME>", elm->GetID());
+
+  return code;
+}
+
 std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
   std::string code;
   if (type.ToString().find("::CallbackBase") != std::string::npos) {
@@ -743,10 +838,8 @@ std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
       if (block->GetType() == Block::TYPE_STRUCTURE) {
          auto& st = static_cast<const Structure&>(*block);
          if (st.GetID() == type.ToString()) {
-          for (auto& elm : st.GetElements()) {
-            code += ReplaceAll(CB_UNIT_MAP_BASE_WRITE)
-              .Change("<NAME>", elm->GetID());
-          }
+          code = GenUnitMapBaseWrite(st);
+          break;
          }
       }
     }
@@ -784,6 +877,20 @@ std::string CppGeneratorBase::GenUnitImplDeserializer(const BaseType& type) {
   return RemoveLine(code);
 }
 
+std::string CppGeneratorBase::GenUnitMapBaseRead(const Structure& st) {
+  std::string code;
+  if (st.GetBase() != nullptr)
+    code += GenUnitMapBaseRead(*st.GetBase());
+
+  for (auto& elm : st.GetElements()) {
+    code += ReplaceAll(CB_UNIT_MAP_BASE_READ)
+        .Change("<TYPE>", ConvertTypeToString(elm->GetType()))
+        .Change("<NAME>", elm->GetID());
+  }
+
+  return code;
+}
+
 std::string CppGeneratorBase::GenUnitMapRead(const BaseType& type) {
   std::string code;
   if (type.ToString().find("::CallbackBase") != std::string::npos) {
@@ -808,11 +915,8 @@ std::string CppGeneratorBase::GenUnitMapRead(const BaseType& type) {
       if (block->GetType() == Block::TYPE_STRUCTURE) {
         auto& st = static_cast<const Structure&>(*block);
         if (st.GetID() == type.ToString()) {
-          for (auto& elm : st.GetElements()) {
-            code += ReplaceAll(CB_UNIT_MAP_BASE_READ)
-                        .Change("<TYPE>", ConvertTypeToString(elm->GetType()))
-                        .Change("<NAME>", elm->GetID());
-          }
+          code = GenUnitMapBaseRead(st);
+          break;
         }
       }
     }
index 176fb6c73d8b1279cfbd342a0dc49b09cbc9bd6a..d752739b25c5493d0cdc8eb833604fbc2e2511b8 100644 (file)
@@ -65,10 +65,12 @@ class CppGeneratorBase : public tidl::Generator {
   std::string GenRemoteExceptionForHeader();
 
  private:
+  void AddTypeName(const Structure& st);
   std::string GenStructureForHeader(const Structure& st);
   std::string GenStructureGetterSetterForHeader(const Elements& elms);
   std::string GenStructureMembersForHeader(const Elements& elms);
   std::string GenStructure(const Structure& st);
+  std::string GenStructureBaseArgs(const Elements& elms);
   std::string GenStructureMemberInit(const Elements& elms);
   std::string GenStructureGetterSetter(const Structure& st);
   void InitUnitTypes(bool use_file);
@@ -81,8 +83,10 @@ class CppGeneratorBase : public tidl::Generator {
   std::string GenUnitSerializerHeaders();
   std::string GenUnitSerializerBodies();
   std::string GenUnitImplSerializer(const BaseType& type);
+  std::string GenUnitMapBaseWrite(const Structure& st);
   std::string GenUnitMapWrite(const BaseType& type);
   std::string GenUnitImplDeserializer(const BaseType& type);
+  std::string GenUnitMapBaseRead(const Structure& st);
   std::string GenUnitMapRead(const BaseType& type);
   std::string GetParcelType(const BaseType& type);
   std::string GetFullNameFromType(const BaseType& type);
@@ -96,6 +100,7 @@ class CppGeneratorBase : public tidl::Generator {
   std::unordered_map<std::string, std::string> parcel_type_map_;
   std::unordered_map<std::string, std::string> type_init_map_;
   std::unordered_map<std::string, BaseType> unit_types_;
+  std::unordered_map<std::string, std::string> struct_types_;
 };
 
 }  // namespace version2
index 88875de7a2cb165dc25524266f5b8c51008441bc..9cef83c42ec651a5e304d781859e4de674869ba1 100644 (file)
@@ -227,7 +227,7 @@ class UnitMap;
  */
 constexpr const char CB_HEADER_STRUCTURE_BASE[] =
 R"__cpp_cb(
-class <CLS_NAME> final {
+class <CLS_NAME> {
  public:
   <ENUMS>
   <CLS_NAME>();
@@ -238,9 +238,48 @@ class <CLS_NAME> final {
 };
 )__cpp_cb";
 
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <BASE_CLS_NAME> The base class name of the structure.
+ * <PARAMS> The parameters of the structure.
+ * <ENUMS> The enumerations of the structure.
+ * <GETTER_SETTER> The getters and setters.
+ * <MEMBERS> The member variables of the structure.
+ */
+constexpr const char CB_HEADER_INHERITED_STRUCTURE_BASE[] =
+R"__cpp_cb(
+class <CLS_NAME> : public <BASE_CLS_NAME> {
+ public:
+  <ENUMS>
+  <CLS_NAME>();
+  <CLS_NAME>(<PARAMS>);
+  <GETTER_SETTER>
+ private:
+  <MEMBERS>
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <ENUMS> The enumerations of the structure.
+ */
 constexpr const char CB_HEADER_STRUCTURE_BASE_EMPTY[] =
 R"__cpp_cb(
-class <CLS_NAME> final {
+class <CLS_NAME> {
+ public:
+  <ENUMS>
+  <CLS_NAME>();
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <BASE_CLS_NAME> The base class name of the structure.
+ * <ENUMS> The enumerations of the structure.
+ */
+constexpr const char CB_HEADER_INHERITED_STRUCTURE_BASE_EMPTY[] =
+R"__cpp_cb(
+class <CLS_NAME> : public <BASE_CLS_NAME> {
  public:
   <ENUMS>
   <CLS_NAME>();
@@ -435,6 +474,23 @@ R"__cpp_cb(
 <GETTER_SETTER>
 )__cpp_cb";
 
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <BASE_CLS_NAME> The base class name of the structure.
+ * <BASE_ARGS> The arguments of the base class.
+ * <PARAMS> The parameters of the structure.
+ * <GETTER_SETTER> The getters and setters.
+ * <MEMBERS> The member variables of the structure.
+ */
+constexpr const char CB_BODY_INHERITED_STRUCTURE_BASE[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>() {}
+
+<CLS_NAME>::<CLS_NAME>(<PARAMS>) : <BASE_CLS_NAME>(<BASE_ARGS>), <MEMBER_INIT> {}
+
+<GETTER_SETTER>
+)__cpp_cb";
+
 /**
  * <CLS_NAME> The class name of the structure.
  */
@@ -931,6 +987,11 @@ void Read(const std::string& name, <PARAM_TYPE>& value) const {
     return;
   }
 
+  if (unit->GetType().compare(0, strlen("<TYPE>"), "<TYPE>") != 0) {
+    _E("type(%s) is not <TYPE>", unit->GetType().c_str());
+    return;
+  }
+
   unit->Read(value);
 }