From fe36de435a2ab2f46da25642fcfe9b5e8d436d4d Mon Sep 17 00:00:00 2001 From: jusung son Date: Thu, 24 Aug 2023 20:06:17 +0900 Subject: [PATCH] Support 'struct' inheritance feature for C# Generator Change-Id: Ib87019148b06e7f3d1f8de36d6c5f2a8b96f4903 Signed-off-by: jusung son --- idlc/ast/structure.cc | 51 ++++++++-------- idlc/gen/version2/cs_generator_base.cc | 107 +++++++++++++++++++++++++++------ idlc/gen/version2/cs_generator_base.h | 4 ++ 3 files changed, 118 insertions(+), 44 deletions(-) diff --git a/idlc/ast/structure.cc b/idlc/ast/structure.cc index 4562896..94aedba 100644 --- a/idlc/ast/structure.cc +++ b/idlc/ast/structure.cc @@ -25,30 +25,19 @@ namespace tidl { namespace { -bool ValidateEnum(const Structure* st, const BaseType& type) { - if (st->GetBase() != nullptr) { - if (ValidateEnum(st->GetBase().get(), type)) - return true; - } - - auto name = type.GetFullName(); - auto pos = name.find("."); - if (pos == std::string::npos) - return true; - - std::string base_name = name.substr(0, pos); - name = name.erase(0, pos + 1); - if (st->GetID() == base_name) { - if (st->GetEnums().Exist(name)) - return true; +bool ValidateElement(const Structure* st, const std::string& id) { + if (st->GetEnums().Exist(id)) { + std::cerr << "[TIDL:Parsr] error syntax error. already exists. " + << id << " of " << st->GetID() << std::endl; + return false; } - return false; + return true; } -bool ValidateElement(const Structure* st, const std::string& id) { +bool ValidateParent(const Structure* st, const std::string& id) { if (st->GetBase() != nullptr) { - if (!ValidateElement(st->GetBase().get(), id)) + if (!ValidateParent(st->GetBase().get(), id)) return false; } @@ -60,6 +49,12 @@ bool ValidateElement(const Structure* st, const std::string& id) { } } + if (st->GetEnums().Exist(id)) { + std::cerr << "[TIDL:Parsr] error syntax error. already exists. " + << id << " of " << st->GetID() << std::endl; + return false; + } + return true; } @@ -87,13 +82,21 @@ const std::shared_ptr& Structure::GetBase() const { bool Structure::FindAndValidateElements() const { for (auto& elm : GetElements()) { - if (!ValidateEnum(this, elm->GetType())) + if (!ValidateElement(this, elm->GetID())) return false; + } - if (GetBase() != nullptr) { - if (!ValidateElement(GetBase().get(), elm->GetID())) - return false; - } + if (GetBase() == nullptr) + return true; + + for (auto& elm : GetElements()) { + if (!ValidateParent(GetBase().get(), elm->GetID())) + return false; + } + + for (auto& enm : GetEnums()) { + if (!ValidateParent(GetBase().get(), enm->GetID())) + return false; } return true; diff --git a/idlc/gen/version2/cs_generator_base.cc b/idlc/gen/version2/cs_generator_base.cc index c20d3bc..17dadfe 100644 --- a/idlc/gen/version2/cs_generator_base.cc +++ b/idlc/gen/version2/cs_generator_base.cc @@ -86,7 +86,14 @@ void CsGeneratorBase::GenEnum(std::ofstream& stream, const Block& block, void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) { std::vector v; - stream << Tab(1) << "public sealed class " << st.GetID() << NLine(1); + stream << Tab(1) << "public class " << st.GetID(); + + if (st.GetBase() == nullptr) { + stream << NLine(1); + } else { + stream << " : " << st.GetBase()->GetID() << NLine(1); + } + GenBrace(stream, TAB_SIZE, [&]() { GenEnum(stream, st, 2); for (const auto& i : st.GetElements()) { @@ -119,30 +126,50 @@ void CsGeneratorBase::GenSerializer(std::ofstream& stream, stream << GetSerializer(st); } +std::string CsGeneratorBase::GetStructureSerialize(const Structure& st) { + std::string code; + std::string type_str; + + for (const auto& i : st.GetElements()) { + code += Tab(4) + "map.Write(\"" + i->GetID() + "\", param." + + i->GetID() + ");" + NLine(1); + } + + if (st.GetBase() != nullptr) + code += GetStructureSerialize(*st.GetBase()); + + return code; +} + +std::string CsGeneratorBase::GetStructureDeserialize(const Structure& st) { + std::string code; + std::string type_str; + + for (const auto& i : st.GetElements()) { + auto& t = i->GetType(); + if (t.IsEnumType()) + type_str = "int"; + else + type_str = GetTypeString(t); + + code += Tab(4) + "map.Read(\"" + i->GetID() + "\", out param." + + i->GetID() + ");" + NLine(1); + } + + if (st.GetBase() != nullptr) + code += GetStructureDeserialize(*st.GetBase()); + + return code; +} + std::string CsGeneratorBase::GetSerializer(const Structure& st) { std::string str(ReplaceAll(CB_SERIALIZER) .Change("", st.GetID()) - .Change("", [&]() { - std::string ret; - for (const auto& i : st.GetElements()) { - ret += Tab(4) + "map.Write(\"" + i->GetID() + - "\", param." + i->GetID() + ");" + NLine(1); - } - return ret; - })); + .Change("", GetStructureSerialize(st))); str += ReplaceAll(CB_DESERIALIZER) .Change("", st.GetID()) - .Change("", [&]() { - std::string ret; - std::string type_str; - for (const auto& i : st.GetElements()) { - ret += Tab(4) + "map.Read(\"" + i->GetID() + - "\", out param." + i->GetID() + ");" + - NLine(1); - } - return ret; - }); + .Change("", GetStructureDeserialize(st)); return str; } @@ -540,6 +567,33 @@ std::string CsGeneratorBase::GetEnumTypeString(const BaseType& base_type) { return block_id + "_" + type_id; } +std::string CsGeneratorBase::GetStructTypeString(const Structure& st) { + std::string str; + + if (st.GetBase() != nullptr) { + str += GetStructTypeString(*st.GetBase()) + "::"; + } + str += st.GetID(); + + return str; +} + +std::string CsGeneratorBase::GetStructTypeString(const BaseType& base_type) { + std::string str; + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() == Block::TYPE_STRUCTURE) { + const Structure& st = static_cast(*i); + if (st.GetID() == base_type.GetFullName()) { + str = GetStructTypeString(st); + break; + } + } + } + + return str; +} + std::string CsGeneratorBase::GetTypeString(const BaseType& base_type) { std::string ret; @@ -551,6 +605,8 @@ std::string CsGeneratorBase::GetTypeString(const BaseType& base_type) { ret = ConvertTypeToString(base_type); } else if (base_type.GetUserDefinedType() == BaseType::UserType::DELEGATE) { ret = "delegate"; + } else if (base_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE) { + ret = GetStructTypeString(base_type); } else if (base_type.IsUserDefinedType()) { ret = ConvertTypeToString(base_type); } else { @@ -651,7 +707,18 @@ std::string CsGeneratorBase::GenUnitMapReadWrite(const Interface& iface) { const Structure& st = static_cast(*i); for (const auto& i : st.GetElements()) { auto& type = i->GetType(); - AddTypeMap(types, type, st.GetID()); + + std::string name = type.GetFullName(); + std::size_t pos = name.find('.'); + + if (pos == std::string::npos) { + AddTypeMap(types, type, st.GetID()); + } else { + std::string st_id = name.substr(0, pos); + std::string enum_id = name.substr(pos + 1, name.size() - (pos + 1)); + BaseType enum_type(enum_id, "", BaseType::UserType::ENUM); + AddTypeMap(types, enum_type, st_id); + } } } } diff --git a/idlc/gen/version2/cs_generator_base.h b/idlc/gen/version2/cs_generator_base.h index 59d5552..f177206 100644 --- a/idlc/gen/version2/cs_generator_base.h +++ b/idlc/gen/version2/cs_generator_base.h @@ -106,6 +106,10 @@ class CsGeneratorBase : public Generator { std::string GenUnitMapParamInit(const Interface& iface, const BaseType& base_type, const std::string& type_str); + std::string GetStructureSerialize(const Structure& st); + std::string GetStructureDeserialize(const Structure& st); + std::string GetStructTypeString(const BaseType& base_type); + std::string GetStructTypeString(const Structure& st); private: std::map type_map_; -- 2.7.4