From: Junghoon Park Date: Tue, 2 Jan 2018 08:32:08 +0000 (+0900) Subject: Implement c# stub generator (interface part) X-Git-Tag: accepted/tizen/unified/20180302.061550~33 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f171058997949c277175aa463646ac2458af7233;p=platform%2Fcore%2Fappfw%2Ftidl.git Implement c# stub generator (interface part) Change-Id: I0a472a05ebd8675dd355a06263937775b96db537 Signed-off-by: Junghoon Park --- diff --git a/idlc/cs_gen/cs_gen_base.cc b/idlc/cs_gen/cs_gen_base.cc index ca703f2..ee59520 100644 --- a/idlc/cs_gen/cs_gen_base.cc +++ b/idlc/cs_gen/cs_gen_base.cc @@ -28,6 +28,18 @@ CsGeneratorBase::CsGeneratorBase(std::shared_ptr doc) {"list", "List"}, {"float","float"}, {"double", "double"}, {"bundle", "Bundle"} }; + + parcel_type_map_ = { + {"char", "Byte"}, + {"int", "Int32"}, + {"short", "Int16"}, + {"long", "Int64"}, + {"string", "String"}, + {"bool", "Bool"}, + {"float", "Float"}, + {"double", "Double"}, + {"bundle", "Bundle"}, + }; } void CsGeneratorBase::GenStructures(std::ofstream& stream) { @@ -48,8 +60,8 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) { "$$" \ " }\n"; - stream << TAB <<"sealed class " << st.GetID() << std::endl; - GenBrace(stream, 4, [&]() { + stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1); + GenBrace(stream, TAB_SIZE, [&]() { for (auto& i : st.GetElements().GetElms()) { GenTemplate(property, stream, [&]()->std::string { @@ -90,4 +102,71 @@ std::string CsGeneratorBase::ConvertTypeToString(const BaseType& type) { return type_map_[type.ToString()]; } +std::string CsGeneratorBase::ConvertTypeToParcelType(const std::string& key) { + return parcel_type_map_[key]; +} + +std::string CsGeneratorBase::ConvertTypeToDeserializer( + const ParameterType& type, std::string id) { + if (type.GetDirection() == ParameterType::Direction::OUT) + return ""; + + if (type.GetBaseType().IsUserDefinedType() || + type.GetBaseType().GetMetaType() != nullptr) { + std::string n; + + if (type.GetBaseType().GetMetaType() != nullptr) + n = ConvertTypeToString(type.GetBaseType()); + else + n = type.GetBaseType().ToString(); + + std::string ret = n + " " + id + " = new " + n +"();\n"; + ret += "Deserialize(p, " + id +");\n"; + return ret; + } + + std::string ret = "Interop.LibRPCPort.Parcel.Read" + + parcel_type_map_[type.GetBaseType().ToString()] + + "(p, out " + + ConvertTypeToString(type.GetBaseType()) + " " + + id + ");\n"; + + return ret; +} + +std::string CsGeneratorBase::ConvertTypeToSerializer( + const BaseType& type, std::string id) { + + if (type.IsUserDefinedType() || + type.GetMetaType() != nullptr) { + return "Serialize(result, " + id + ");\n"; + } + + std::string ret = "Interop.LibRPCPort.Parcel.Write" + + parcel_type_map_[type.ToString()] + + "(result, " + id + ");\n"; + + return ret; +} + +std::string CsGeneratorBase::Tab(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += " "; + } + + return t; +} + +std::string CsGeneratorBase::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + } // namespace tidl diff --git a/idlc/cs_gen/cs_gen_base.h b/idlc/cs_gen/cs_gen_base.h index 0e9ffd6..e6fa30a 100644 --- a/idlc/cs_gen/cs_gen_base.h +++ b/idlc/cs_gen/cs_gen_base.h @@ -35,11 +35,19 @@ class CsGeneratorBase : public Generator { void GenStructures(std::ofstream& stream); void GenStructure(std::ofstream& stream, const Structure& st); std::string ConvertTypeToString(const BaseType& type); + std::string ConvertTypeToDeserializer(const ParameterType& type, + std::string id); + std::string ConvertTypeToSerializer(const BaseType& type, + std::string id); + std::string ConvertTypeToParcelType(const std::string& key); + std::string Tab(int cnt); + std::string NLine(int cnt); protected: - const std::string TAB = " "; + const int TAB_SIZE = 4; private: std::map type_map_; + std::map parcel_type_map_; }; } // namespace tidl diff --git a/idlc/cs_gen/cs_proxy_gen.cc b/idlc/cs_gen/cs_proxy_gen.cc index 4a72377..0e38727 100644 --- a/idlc/cs_gen/cs_proxy_gen.cc +++ b/idlc/cs_gen/cs_proxy_gen.cc @@ -23,11 +23,11 @@ CsProxyGen::CsProxyGen(std::shared_ptr doc) void CsProxyGen::OnInitGen(std::ofstream& stream) { GenCodeBlock("copyright.cb"); - stream << std::endl; - stream << "using System;" << std::endl - << "using System.Collections.Generic;" << std::endl - << "using System.Runtime.InteropServices;" << std::endl - << "using Tizen.Applications;" << std::endl << std::endl; + stream << NLine(1); + stream << "using System;" << NLine(1) + << "using System.Collections.Generic;" << NLine(1) + << "using System.Runtime.InteropServices;" << NLine(1) + << "using Tizen.Applications;" << NLine(2); GenInterop(stream); GenNamespace(stream); } @@ -36,7 +36,7 @@ void CsProxyGen::OnFiniGen(std::ofstream& stream) { } void CsProxyGen::GenNamespace(std::ofstream& stream) { - stream << "namespace RPCPort" << std::endl; + stream << "namespace RPCPort" << NLine(1); GenBrace(stream, 0, [&]() { GenStructures(stream); }); diff --git a/idlc/cs_gen/cs_stub_gen.cc b/idlc/cs_gen/cs_stub_gen.cc index b2569a1..47619bc 100644 --- a/idlc/cs_gen/cs_stub_gen.cc +++ b/idlc/cs_gen/cs_stub_gen.cc @@ -23,12 +23,13 @@ CsStubGen::CsStubGen(std::shared_ptr doc) void CsStubGen::OnInitGen(std::ofstream& stream) { GenCodeBlock("copyright.cb"); - stream << std::endl; - stream << "using System;" << std::endl - << "using System.Collections.Generic;" << std::endl - << "using System.Runtime.InteropServices;" << std::endl - << "using Tizen.Applications;" << std::endl << std::endl; + stream << NLine(1); + stream << "using System;" << NLine(1) + << "using System.Collections.Generic;" << NLine(1) + << "using System.Runtime.InteropServices;" << NLine(1) + << "using Tizen.Applications;" << NLine(2); GenInterop(stream); + stream << NLine(1); GenNamespace(stream); } @@ -41,10 +42,463 @@ void CsStubGen::GenInterop(std::ofstream& stream) { } void CsStubGen::GenNamespace(std::ofstream& stream) { - stream << "namespace RPCPort" << std::endl; + stream << "namespace RPCPort" << NLine(1); GenBrace(stream, 0, [&]() { GenStructures(stream); + stream << Tab(1) << "namespace Stub" << NLine(1); + GenBrace(stream, TAB_SIZE, [&]() { + GenInterfaces(stream); + }); }); } +void CsStubGen::GenInterfaces(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + Interface& iface = static_cast(*i); + GenInterface(stream, iface); + stream << std::endl; + } +} + +void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) { + stream << Tab(2) << "public sealed class " << iface.GetID() << NLine(1); + GenBrace(stream, TAB_SIZE * 2, [&]() { + GenServiceBase(stream, iface); + stream << Tab(3) + << "private IntPtr _stub;" << NLine(2); + stream << Tab(3) + << "private List _services = new List();" + << NLine(2); + stream << Tab(3) + << "private Type _serviceType;" << NLine(2); + GenMethodId(stream, iface); + GenSerializer(stream); + GenListSerializer(stream); + GenReceivedEvent(stream, iface); + GenConnectedEvent(stream); + GenDisconnectedEvent(stream); + GenCtor(stream, iface); + GenCommonMethods(stream); + }); +} + +void CsStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) { + const char cls[] = + "public abstract class ServiceBase\n" \ + "{\n" \ + " public string Sender\n" \ + " {\n" \ + " get; internal set;\n" \ + " }\n" \ + "\n" \ + " protected ServiceBase()\n" \ + " {\n" \ + " }\n" \ + "\n"; + + stream << AddIndent(TAB_SIZE * 3, cls); + GenDeclarations(stream, iface.GetDeclarations()); + stream << NLine(1); + stream << AddIndent(TAB_SIZE * 3, "}\n"); + stream << NLine(1); +} + +void CsStubGen::GenDeclarations(std::ofstream& stream, + const Declarations& decls) { + for (auto& i : decls.GetDecls()) { + stream << Tab(4) << "public abstract "; + GenDeclaration(stream, *i); + stream << NLine(1); + } +} + +void CsStubGen::GenDeclaration(std::ofstream& stream, const Declaration& decl) { + stream << ConvertTypeToString(decl.GetType()) << " " + << decl.GetID() << "("; + GenParameters(stream, decl.GetParameters()); + stream << ");"; +} + +void CsStubGen::GenParameters(std::ofstream& stream, const Parameters& ps) { + bool first = true; + for (auto& i : ps.GetParams()) { + if (!first) { + stream << ", "; + } + + auto dir = i->GetParameterType().GetDirection(); + if (dir == ParameterType::Direction::OUT) { + stream << "out "; + } else if (dir == ParameterType::Direction::REF) { + stream << "ref "; + } + + stream << ConvertTypeToString(i->GetParameterType().GetBaseType()) << " " + << i->GetID(); + first = false; + } +} + +void CsStubGen::GenMethodId(std::ofstream& stream, const Interface& iface) { + stream << Tab(3) << "private enum MethodId : int" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + int cnt = 1; + for (auto& i : iface.GetDeclarations().GetDecls()) { + stream << Tab(4) + << i->GetID() << " = " << cnt++ << "," << NLine(1); + } + }); + stream << NLine(1); +} + +void CsStubGen::GenWriteBundle(std::ofstream& stream, const std::string& id) { + const char block[] = + "if (param.$$ != null)\n" \ + "{\n" \ + " Interop.LibRPCPort.Parcel.WriteBundle(h, param.$$.SafeBundleHandle.DangerousGetHandle());\n" \ + "}\n" \ + "else\n" \ + "{\n" \ + " Interop.LibRPCPort.Parcel.WriteBundle(h, new Bundle().SafeBundleHandle.DangerousGetHandle());\n" \ + "}\n"; + + GenTemplate(AddIndent(TAB_SIZE * 4, block), stream, + [&]()->std::string { + return id; + }, + [&]()->std::string { + return id; + } + ); +} + +void CsStubGen::GenSerializer(std::ofstream& stream, const Structure& st) { + stream << Tab(3) << "private static void Serialize(IntPtr h, " + << st.GetID() << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + for (auto& i : st.GetElements().GetElms()) { + auto& t = i->GetType(); + if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) { + if (t.ToString() == "bundle") { + GenWriteBundle(stream, i->GetID()); + } else { + stream << Tab(4) << "Interop.LibRPCPort.Parcel.Write" + << ConvertTypeToParcelType(t.ToString()) + << "(h, param." + << i->GetID() + << ");" << NLine(1); + } + } else { + stream << Tab(4) << "Serialize(h, param." << i->GetID() + << ");" << NLine(1); + } + } + }); + stream << NLine(1); + + stream << Tab(3) << "private static void Deserialize(IntPtr h, " + << st.GetID() << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + for (auto& i : st.GetElements().GetElms()) { + auto& t = i->GetType(); + if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) { + stream << Tab(4) << "Interop.LibRPCPort.Parcel.Read" + << ConvertTypeToParcelType(t.ToString()) + << "(h, out var " + << i->GetID() + << ");" << NLine(1); + if (t.ToString() == "bundle") { + stream << Tab(4) << "param." << i->GetID() + << " = new Bundle(new SafeBundleHandle(" << i->GetID() + << ", true));" << NLine(1); + } else { + stream << Tab(4) << "param." << i->GetID() << " = " << i->GetID() + << ";" << NLine(1); + } + } else { + stream << Tab(4) << "param." << i->GetID() << " = new " + << ConvertTypeToString(t) + << "();" << NLine(1); + stream << Tab(4) << "Deserialize(h, param." << i->GetID() + << ");" << NLine(1); + } + + } + }); + stream << NLine(1); +} + +void CsStubGen::GenSerializer(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() == Block::TYPE_STRUCTURE) { + const Structure& st = static_cast(*i); + GenSerializer(stream, st); + } + } +} + +void CsStubGen::AddSerializerList(const BaseType& type) { + if (type.GetMetaType() != nullptr) { + serializer_list_[ConvertTypeToString(type)] = &type; + AddSerializerList(*type.GetMetaType()); + } +} + +void CsStubGen::GenListSerializer(std::ofstream& stream, const BaseType& type) { + stream << Tab(3) << "private static void Serialize(IntPtr h, " + << ConvertTypeToString(type) << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + stream << Tab(4) + << "Interop.LibRPCPort.Parcel.WriteArrayCount(h, param.Count);" + << NLine(1); + stream << Tab(4) << "foreach (var i in param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 4, [&]() { + auto& mt = *type.GetMetaType(); + if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) { + stream << Tab(5) << "Interop.LibRPCPort.Parcel.Write" + << ConvertTypeToParcelType(mt.ToString()) + << "(h, i);" << NLine(1); + } else { + stream << Tab(5) << "Serialize(h, i);" << NLine(1); + } + }); + }); + stream << NLine(1); + + stream << Tab(3) << "private static void Deserialize(IntPtr h, " + << ConvertTypeToString(type) << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + stream << Tab(4) + << "Interop.LibRPCPort.Parcel.ReadArrayCount(h, out int l);" + << NLine(1); + stream << Tab(4) << "for (int i = 0; i < l; i++)" << NLine(1); + GenBrace(stream, TAB_SIZE * 4, [&]() { + auto& mt = *type.GetMetaType(); + if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) { + stream << Tab(5) << "Interop.LibRPCPort.Parcel.Read" + << ConvertTypeToParcelType(mt.ToString()) + << "(h, out var v);" << NLine(1); + } else { + stream << Tab(5) << "var v = new " << ConvertTypeToString(mt) + << "();" << NLine(1); + stream << Tab(5) << "Deserialize(h, v);" << NLine(1); + } + stream << Tab(5) << "param.Add(v);" << NLine(1); + }); + }); + stream << NLine(1); +} + +void CsStubGen::GenListSerializer(std::ofstream& stream) { + serializer_list_.clear(); + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() == Block::TYPE_STRUCTURE) { + const Structure& st = static_cast(*i); + for (auto& j : st.GetElements().GetElms()) { + auto& t = j->GetType(); + AddSerializerList(t); + } + } else if (i->GetType() == Block::TYPE_INTERFACE) { + const Interface& iface = static_cast(*i); + for (auto& j : iface.GetDeclarations().GetDecls()) { + auto& t = j->GetType(); + AddSerializerList(t); + for (auto& k : j->GetParameters().GetParams()) { + auto& t1 = k->GetParameterType().GetBaseType(); + AddSerializerList(t1); + } + } + } + } + + for (auto& p : serializer_list_) { + const BaseType* t = p.second; + GenListSerializer(stream, *t); + } +} + +void CsStubGen::GenReceivedEvent(std::ofstream& stream, const Interface& iface) { + const char method_front[] = + "private int OnReceivedEvent(string sender, IntPtr port, IntPtr data)\n" \ + "{\n" \ + " int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);\n" \ + "\n" \ + " if (ret != 0)\n" \ + " return ret;\n" \ + "\n" \ + " Interop.LibRPCPort.Parcel.Create(out IntPtr result);\n" \ + " Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);\n" \ + " ServiceBase b = null;\n" \ + "\n" \ + " foreach (var i in _services)\n" \ + " {\n" \ + " if (i.Sender.Equals(sender))\n" \ + " {\n" \ + " b = i;\n" \ + " break;\n" \ + " }\n" \ + " }\n" \ + "\n" \ + " if (b == null)\n" \ + " return -1;\n" \ + "\n" + " switch ((MethodId)cmd)\n" \ + " {\n"; + + const char method_back[] = + " default:\n" \ + " return -1;\n" \ + " }\n" \ + "\n" \ + " Interop.LibRPCPort.Parcel.Destroy(p);\n" \ + " Interop.LibRPCPort.Parcel.Destroy(result);\n" \ + "\n" \ + " return 0;\n" \ + "}\n"; + + stream << AddIndent(TAB_SIZE * 3, method_front); + for (auto& i : iface.GetDeclarations().GetDecls()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + stream << Tab(5) << "case MethodId." << i->GetID() << ":" << NLine(1); + GenBrace(stream, TAB_SIZE * 6, [&]() { + GenInvocation(stream, *i); + stream << Tab(7) << "break;" << NLine(1); + }); + } + stream << AddIndent(TAB_SIZE * 3, method_back) << NLine(1); +} + +void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { + int cnt = 1; + + // Deserialize + for (auto& i : decl.GetParameters().GetParams()) { + std::string v = "param" + std::to_string(cnt); + std::string c = ConvertTypeToDeserializer(i->GetParameterType(), v); + if (c != "") + stream << AddIndent(TAB_SIZE * 7, c); + cnt++; + } + + // Invoke + cnt = 1; + std::string m; + bool hasRet = false; + + if (decl.GetType().ToString() != "void") { + m += "var retVal = "; + hasRet = true; + } + + m += "b." + decl.GetID() + "("; + for (auto& i : decl.GetParameters().GetParams()) { + if (cnt != 1) { + m += ", "; + } + + std::string v = "param" + std::to_string(cnt); + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT) { + m += "out " + ConvertTypeToString(pt.GetBaseType()) + " "; + } else if (pt.GetDirection() == ParameterType::Direction::REF) { + m += "ref "; + } + m += v; + cnt++; + } + + m += ");\n"; + stream << AddIndent(TAB_SIZE * 7, m); + + // Serialize + if (decl.GetMethodType() == Declaration::MethodType::ASYNC) + return; + + cnt = 0; + m = ""; + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + cnt++; + if (pt.GetDirection() == ParameterType::Direction::IN) + continue; + m += ConvertTypeToSerializer(pt.GetBaseType(), "param" + std::to_string(cnt)); + } + + if (hasRet) { + m += ConvertTypeToSerializer(decl.GetType(), "retVal"); + } + + m += "Interop.LibRPCPort.Parcel.Send(result, port);\n"; + stream << AddIndent(TAB_SIZE * 7, m); +} + +void CsStubGen::GenConnectedEvent(std::ofstream& stream) { + const char method[] = + "private void OnConnectedEvent(string sender, IntPtr data)\n" \ + "{\n" \ + " ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;\n" \ + " s.Sender = sender;\n" \ + " _services.Add(s);\n" \ + "}\n"; + stream << AddIndent(TAB_SIZE * 3, method) << NLine(1); +} + +void CsStubGen::GenDisconnectedEvent(std::ofstream& stream) { + const char method[] = + "private void OnDisconnectedEvent(string sender, IntPtr data)\n" \ + "{\n" \ + " foreach (var i in _services)\n" \ + " {\n" \ + " if (i.Sender.Equals(sender))\n" \ + " {\n" \ + " _services.Remove(i);\n" \ + " break;\n" \ + " }\n" \ + " }\n" \ + "}\n"; + stream << AddIndent(TAB_SIZE * 3, method) << NLine(1); +} + +void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { + const char ctor[] = + "public $$()\n" \ + "{\n" \ + " Interop.LibRPCPort.Stub.Create(out _stub, \"$$\");\n" \ + " Interop.LibRPCPort.Stub.AddReceivedEventCb(_stub, OnReceivedEvent, IntPtr.Zero);\n" \ + " Interop.LibRPCPort.Stub.AddConnectedEventCb(_stub, OnConnectedEvent, IntPtr.Zero);\n" \ + " Interop.LibRPCPort.Stub.AddDisconnectedEventCb(_stub, OnDisconnectedEvent, IntPtr.Zero);\n" \ + "}\n"; + + GenTemplate(AddIndent(TAB_SIZE * 3, ctor), stream, + [&]()->std::string { + return iface.GetID(); + }, + [&]()->std::string { + return iface.GetID(); + } + ); + stream << NLine(1); +} + +void CsStubGen::GenCommonMethods(std::ofstream& stream) { + const char method_listen[] = + "public void Listen(Type serviceType)\n" \ + "{\n" \ + " _serviceType = serviceType;\n" \ + " Interop.LibRPCPort.Stub.Listen(_stub);\n" \ + "}\n"; + + const char method_get_services[] = + "public IEnumerable GetServices()\n" \ + "{\n" \ + " return _services;\n" \ + "}\n"; + + stream << AddIndent(TAB_SIZE * 3, method_listen) << NLine(1); + stream << AddIndent(TAB_SIZE * 3, method_get_services); +} + } // namespace tidl diff --git a/idlc/cs_gen/cs_stub_gen.h b/idlc/cs_gen/cs_stub_gen.h index 3dcc5c8..74c6993 100644 --- a/idlc/cs_gen/cs_stub_gen.h +++ b/idlc/cs_gen/cs_stub_gen.h @@ -19,6 +19,7 @@ #include #include +#include #include "idlc/cs_gen/cs_gen_base.h" @@ -35,6 +36,28 @@ class CsStubGen : public CsGeneratorBase { private: void GenNamespace(std::ofstream& stream); void GenInterop(std::ofstream& stream); + void GenInterfaces(std::ofstream& stream); + void GenInterface(std::ofstream& stream, const Interface& iface); + void GenMethodId(std::ofstream& stream, const Interface& iface); + void GenServiceBase(std::ofstream& stream, const Interface& iface); + void GenSerializer(std::ofstream& stream); + void GenSerializer(std::ofstream& stream, const Structure& st); + void GenListSerializer(std::ofstream& stream); + void GenListSerializer(std::ofstream& stream, const BaseType& type); + void GenReceivedEvent(std::ofstream& stream, const Interface& iface); + void GenConnectedEvent(std::ofstream& stream); + void GenDisconnectedEvent(std::ofstream& stream); + void GenCtor(std::ofstream& stream, const Interface& iface); + void GenCommonMethods(std::ofstream& stream); + void GenDeclarations(std::ofstream& stream, const Declarations& decls); + void GenDeclaration(std::ofstream& stream, const Declaration& decl); + void GenParameters(std::ofstream& stream, const Parameters& ps); + void GenInvocation(std::ofstream& stream, const Declaration& decl); + void GenWriteBundle(std::ofstream& stream, const std::string& id); + void AddSerializerList(const BaseType& type); + + private: + std::map serializer_list_; }; } // namespace tidl diff --git a/idlc/generator.cc b/idlc/generator.cc index cdcf937..717d2ed 100644 --- a/idlc/generator.cc +++ b/idlc/generator.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #include "idlc/generator.h" #include "idlc/block.h" #include "idlc/interface.h" @@ -34,4 +36,26 @@ void Generator::Run(const std::string& file_name) { out_file_.close(); } +std::string Generator::AddIndent(int indent, std::string lines, bool space) { + std::stringstream ss(lines); + std::string result; + std::string to; + + while (std::getline(ss, to, '\n')) { + if (to.length() > 0) { + for (int i = 0; i < indent; i++) { + if (space) + result += " "; + else + result += "\t"; + } + } + + result += to; + result += "\n"; + } + + return result; +} + } // namespace tidl diff --git a/idlc/generator.h b/idlc/generator.h index 0788d3a..f364513 100644 --- a/idlc/generator.h +++ b/idlc/generator.h @@ -36,6 +36,7 @@ class Generator { virtual ~Generator() = default; void Run(const std::string& file_name); + std::string AddIndent(int indent, std::string lines, bool space = true); template void GenCodeBlock(std::string filename, T cb = CallEmptyCallback) { diff --git a/unit_tests/cs_gen/cs_proxy_gen_unittest.cc b/unit_tests/cs_gen/cs_proxy_gen_unittest.cc index bef1f70..f83561c 100644 --- a/unit_tests/cs_gen/cs_proxy_gen_unittest.cc +++ b/unit_tests/cs_gen/cs_proxy_gen_unittest.cc @@ -61,8 +61,8 @@ TEST_F(CsProxyGenTest, CsProxyGen_Run) { ASSERT_TRUE(FindStringFromFile("test.cs", "namespace RPCPort")); ASSERT_TRUE(FindStringFromFile("test.cs", " internal static partial class Proxy")); - ASSERT_TRUE(FindStringFromFile("test.cs", " sealed class Student")); + ASSERT_TRUE(FindStringFromFile("test.cs", " public sealed class Student")); ASSERT_TRUE(FindStringFromFile("test.cs", " public string name { get; set; }")); - ASSERT_TRUE(FindStringFromFile("test.cs", " sealed class Class")); + ASSERT_TRUE(FindStringFromFile("test.cs", " public sealed class Class")); ASSERT_TRUE(FindStringFromFile("test.cs", " public List students { get; set; }")); } diff --git a/unit_tests/cs_gen/cs_stub_gen_unittest.cc b/unit_tests/cs_gen/cs_stub_gen_unittest.cc index 8d4def5..3a7bebf 100644 --- a/unit_tests/cs_gen/cs_stub_gen_unittest.cc +++ b/unit_tests/cs_gen/cs_stub_gen_unittest.cc @@ -61,8 +61,8 @@ TEST_F(CsStubGenTest, CsStubGen_Run) { ASSERT_TRUE(FindStringFromFile("test_stub.cs", "namespace RPCPort")); ASSERT_TRUE(FindStringFromFile("test_stub.cs", " internal static partial class Stub")); - ASSERT_TRUE(FindStringFromFile("test_stub.cs", " sealed class Student")); + ASSERT_TRUE(FindStringFromFile("test_stub.cs", " public sealed class Student")); ASSERT_TRUE(FindStringFromFile("test_stub.cs", " public string name { get; set; }")); - ASSERT_TRUE(FindStringFromFile("test_stub.cs", " sealed class Class")); + ASSERT_TRUE(FindStringFromFile("test_stub.cs", " public sealed class Class")); ASSERT_TRUE(FindStringFromFile("test_stub.cs", " public List students { get; set; }")); }