summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/slice2swift/Gen.cpp200
-rw-r--r--cpp/src/slice2swift/SwiftUtil.cpp242
-rw-r--r--cpp/src/slice2swift/SwiftUtil.h19
3 files changed, 429 insertions, 32 deletions
diff --git a/cpp/src/slice2swift/Gen.cpp b/cpp/src/slice2swift/Gen.cpp
index e9869d450c2..2d3c804e3dd 100644
--- a/cpp/src/slice2swift/Gen.cpp
+++ b/cpp/src/slice2swift/Gen.cpp
@@ -340,7 +340,7 @@ Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
{
DataMemberPtr member = *q;
TypePtr type = member->type();
- writeMarshalUnmarshalCode(out, type, member->name(), swiftModule, false, false, false);
+ writeMarshalUnmarshalCode(out, member, p, false, false, false);
}
if(base)
{
@@ -395,9 +395,7 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p)
out << sb;
for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
{
- DataMemberPtr member = *q;
- TypePtr type = member->type();
- writeMarshalUnmarshalCode(out, type, member->name(), swiftModule, true, true, false);
+ writeMarshalUnmarshalCode(out, *q, p, true, true, false);
}
out << nl << "return " << name;
@@ -418,7 +416,7 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p)
out << nl << "func write(_ v: " << name << ")" << sb;
for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
{
- writeMarshalUnmarshalCode(out, (*q)->type(), fixIdent((*q)->name()) , swiftModule, true, false, true);
+ writeMarshalUnmarshalCode(out, *q, p, true, false, true);
}
out << eb;
@@ -434,8 +432,97 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p)
const string swiftModule = getSwiftModule(getTopLevelModule(ContainedPtr::dynamicCast(p)));
const string name = getUnqualified(getAbsolute(p), swiftModule);
+ const TypePtr type = p->type();
+
out << sp;
out << nl << "public typealias " << name << " = [" << typeToString(p->type(), p) << "]";
+
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(builtin && builtin->kind() <= Builtin::KindString)
+ {
+ return; // No helpers for sequence of primitive types
+ }
+
+ const string ostr = getUnqualified("Ice.OutputStream", swiftModule);
+ const string istr = getUnqualified("Ice.InputStream", swiftModule);
+
+ const string optionalFormat = getUnqualified(getOptionalFormat(p->type()), swiftModule);
+
+ out << sp;
+ out << nl << "public struct _" << name << "Helper";
+ out << sb;
+
+ out << nl << "public static func read(from istr: " << istr << ") throws -> " << name;
+ out << sb;
+ out << nl << "let sz = try istr.readAndCheckSeqSize(minSize: " << p->type()->minWireSize() << ")";
+ out << nl << "var v = " << name << "()";
+ out << nl << "v.reserveCapacity(sz)";
+ out << nl << "for i in 0 ..< sz";
+ out << sb;
+ writeMarshalUnmarshalCode(out, type, typeToString(p->type(), p), "v[i]", false, false, false);
+ out << eb;
+ out << nl << "return v";
+ out << eb;
+
+ out << nl << "public static func read(from istr: " << istr << ", tag: Int32) throws -> " << name << "?";
+ out << sb;
+ out << nl << "guard try istr.readOptional(tag: tag, expectedFormat: " << optionalFormat << ") else";
+ out << sb;
+ out << nl << "return nil";
+ out << eb;
+ if(p->type()->isVariableLength())
+ {
+ out << nl << "try istr.skip(4)";
+ }
+ else if(p->type()->minWireSize() > 1)
+ {
+ out << nl << "try istr.skipSize()";
+ }
+ out << nl << "return try read(from: istr)";
+ out << eb;
+
+ out << sp;
+ out << nl << "public static func write(to ostr: " << ostr << ", value v: " << name << ")";
+ out << sb;
+ out << nl << "ostr.write(size: v.count)";
+ out << nl << "v.forEach";
+ out << sb;
+ writeMarshalUnmarshalCode(out, type, typeToString(p->type(), p), "$0", false, false, true);
+ out << eb;
+ out << eb;
+
+ out << sp;
+ out << nl << "public static func write(to ostr: " << ostr << ", tag: Int32, value v: "<< name << "?)";
+ out << sb;
+ out << nl << "guard let val = v else";
+ out << sb;
+ out << nl << "return";
+ out << eb;
+ if(p->type()->isVariableLength())
+ {
+ out << nl << "if ostr.writeOptional(tag: tag, format: " << optionalFormat << ")";
+ out << sb;
+ out << nl << "let pos = ostr.startSize()";
+ out << nl << "write(to: ostr, value: val)";
+ out << nl << "ostr.endSize(position: pos)";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if ostr.writeOptionalVSize(tag: tag, len: val.count, elemSize: " << p->type()->minWireSize() << ")";
+ out << sb;
+ out << nl << "ostr.write(size: val.count)";
+ out << nl << "write(to: ostr, value: val)";
+ out << eb;
+ }
+ out << eb;
+
+ out << eb;
}
void
@@ -446,9 +533,95 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
out << sp;
out << nl << "public typealias " << name << " = ["
- << typeToString(p->keyType(), p) << ":"
+ << typeToString(p->keyType(), p) << ": "
<< typeToString(p->valueType(), p)
<< "]";
+
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ const string ostr = getUnqualified("Ice.OutputStream", swiftModule);
+ const string istr = getUnqualified("Ice.InputStream", swiftModule);
+
+ const string optionalFormat = getUnqualified(getOptionalFormat(p), swiftModule);
+ const bool isVariableLength = p->keyType()->isVariableLength() || p->valueType()->isVariableLength();
+ const int minWireSize = p->keyType()->minWireSize() + p->valueType()->minWireSize();
+
+ out << sp;
+ out << nl << "public struct _" << name << "Helper";
+ out << sb;
+
+ out << nl << "public static func read(from istr: " << istr << ") throws -> " << name;
+ out << sb;
+ out << nl << "let sz = try Int(istr.readSize())";
+ out << nl << "var v = " << name << "()";
+ out << nl << "for _ in 0 ..< sz";
+ out << sb;
+ writeMarshalUnmarshalCode(out, p->keyType(), typeToString(p->keyType(), p), "key", false, true, false);
+ writeMarshalUnmarshalCode(out, p->valueType(), typeToString(p->valueType(), p), "value", false, true, false);
+ out << nl << "v[key] = value";
+ out << eb;
+ out << nl << "return v";
+ out << eb;
+
+ out << nl << "public static func read(from istr: " << istr << ", tag: Int32) throws -> " << name << "?";
+ out << sb;
+ out << nl << "guard try istr.readOptional(tag: tag, expectedFormat: " << optionalFormat << ") else";
+ out << sb;
+ out << nl << "return nil";
+ out << eb;
+ if(p->keyType()->isVariableLength() || p->valueType()->isVariableLength())
+ {
+ out << nl << "try istr.skip(4)";
+ }
+ else
+ {
+ out << nl << "try istr.skipSize()";
+ }
+ out << nl << "return try read(from: istr)";
+ out << eb;
+
+ out << sp;
+ out << nl << "public static func write(to ostr: " << ostr << ", value v: " << name << ")";
+ out << sb;
+ out << nl << "ostr.write(size: v.count)";
+ out << nl << "v.forEach";
+ out << sb;
+ out << "key, value in";
+ writeMarshalUnmarshalCode(out, p->keyType(), typeToString(p->keyType(), p), "key", false, false, true);
+ writeMarshalUnmarshalCode(out, p->valueType(), typeToString(p->valueType(), p), "value", false, false, true);
+ out << eb;
+ out << eb;
+
+ out << sp;
+ out << nl << "public static func write(to ostr: " << ostr << ", tag: Int32, value v: "<< name << "?)";
+ out << sb;
+ out << nl << "guard let val = v else";
+ out << sb;
+ out << nl << "return";
+ out << eb;
+ if(isVariableLength)
+ {
+ out << nl << "if ostr.writeOptional(tag: tag, format: " << optionalFormat << ")";
+ out << sb;
+ out << nl << "let pos = ostr.startSize()";
+ out << nl << "write(to: ostr, value: val)";
+ out << nl << "ostr.endSize(position: pos)";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if ostr.writeOptionalVSize(tag: tag, len: val.count, elemSize: " << minWireSize << ")";
+ out << sb;
+ out << nl << "ostr.write(size: val.count)";
+ out << nl << "write(to: ostr, value: val)";
+ out << eb;
+ }
+ out << eb;
+
+ out << eb;
}
void
@@ -684,6 +857,7 @@ Gen::ValueVisitor::visitClassDefStart(const ClassDefPtr& p)
const DataMemberList allMembers = p->allDataMembers();
const DataMemberList optionalMembers = p->orderedOptionalDataMembers();
+ // TODO:
//const bool basePreserved = p->inheritsMetaData("preserve-slice");
//const bool preserved = p->hasMetaData("preserve-slice");
@@ -728,12 +902,12 @@ Gen::ValueVisitor::visitClassDefStart(const ClassDefPtr& p)
TypePtr type = member->type();
if(!member->optional())
{
- writeMarshalUnmarshalCode(out, type, fixIdent(member->name()), swiftModule, false, false, true);
+ writeMarshalUnmarshalCode(out, member, p, false, false, true);
}
}
for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d)
{
- // TODO :
+ writeMarshalUnmarshalCode(out, *d, p, false, false, true, (*d)->tag());
}
out << nl << "// to.endSlice();";
if(base)
@@ -936,6 +1110,8 @@ Gen::LocalObjectVisitor::visitOperation(const OperationPtr& p)
const string name = fixIdent(p->name());
ParamDeclList params = p->parameters();
+ int typeCtx = TypeContextInParam | TypeContextLocal;
+
out << sp;
out << nl << "func " << name;
out << spar;
@@ -947,7 +1123,7 @@ Gen::LocalObjectVisitor::visitOperation(const OperationPtr& p)
TypePtr type = param->type();
ostringstream s;
s << fixIdent(param->name()) << ": "
- << typeToString(type, p, param->getMetaData(), param->optional(), TypeContextInParam);
+ << typeToString(type, p, param->getMetaData(), param->optional(), typeCtx);
out << s.str();
}
}
@@ -966,12 +1142,12 @@ Gen::LocalObjectVisitor::visitOperation(const OperationPtr& p)
out << " -> ";
if(outParams.empty())
{
- out << typeToString(ret, p, p->getMetaData(), p->returnIsOptional());
+ out << typeToString(ret, p, p->getMetaData(), p->returnIsOptional(), typeCtx);
}
else if(!ret && outParams.size() == 1)
{
ParamDeclPtr param = outParams.front();
- out << typeToString(param->type(), p, param->getMetaData(), param->optional());
+ out << typeToString(param->type(), p, param->getMetaData(), param->optional(), typeCtx);
}
else
{
@@ -992,7 +1168,7 @@ Gen::LocalObjectVisitor::visitOperation(const OperationPtr& p)
{
ParamDeclPtr param = *i;
out << (fixIdent(param->name()) + ": " +
- typeToString(param->type(), p, p->getMetaData(), param->optional()));
+ typeToString(param->type(), p, p->getMetaData(), param->optional(), typeCtx));
}
out << epar;
}
diff --git a/cpp/src/slice2swift/SwiftUtil.cpp b/cpp/src/slice2swift/SwiftUtil.cpp
index afc3e4c4514..8ce47228c71 100644
--- a/cpp/src/slice2swift/SwiftUtil.cpp
+++ b/cpp/src/slice2swift/SwiftUtil.cpp
@@ -301,7 +301,14 @@ SwiftGenerator::typeToString(const TypePtr& type, const ContainedPtr& toplevel,
if(builtin)
{
- t = getUnqualified(builtinTable[builtin->kind()], currentModule);
+ if(builtin->kind() == Builtin::KindObject && !(typeCtx & TypeContextLocal))
+ {
+ t = getUnqualified(builtinTable[Builtin::KindValue], currentModule);
+ }
+ else
+ {
+ t = getUnqualified(builtinTable[builtin->kind()], currentModule);
+ }
}
ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
@@ -468,6 +475,91 @@ SwiftGenerator::modeToString(Operation::Mode opMode)
return mode;
}
+string
+SwiftGenerator::getOptionalFormat(const TypePtr& type)
+{
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
+ if(bp)
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ {
+ return "Ice.OptionalFormat.F1";
+ }
+ case Builtin::KindShort:
+ {
+ return "Ice.OptionalFormat.F2";
+ }
+ case Builtin::KindInt:
+ case Builtin::KindFloat:
+ {
+ return "Ice.OptionalFormat.F4";
+ }
+ case Builtin::KindLong:
+ case Builtin::KindDouble:
+ {
+ return "Ice.OptionalFormat.F8";
+ }
+ case Builtin::KindString:
+ {
+ return "Ice.OptionalFormat.VSize";
+ }
+ case Builtin::KindObject:
+ {
+ return "Ice.OptionalFormat.Class";
+ }
+ case Builtin::KindObjectProxy:
+ {
+ return "Ice.OptionalFormat.FSize";
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ case Builtin::KindValue:
+ {
+ return "Ice.OptionalFormat.Class";
+ }
+ }
+ }
+
+ if(EnumPtr::dynamicCast(type))
+ {
+ return "Ice.OptionalFormat.Size";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return seq->type()->isVariableLength() ? "Ice.OptionalFormat.FSize" : "Ice.OptionalFormat.VSize";
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ?
+ "Ice.OptionalFormat.FSize" : "Ice.OptionalFormat.VSize";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ return st->isVariableLength() ? "Ice.OptionalFormat.FSize" : "Ice.OptionalFormat.VSize";
+ }
+
+ if(ProxyPtr::dynamicCast(type))
+ {
+ return "Ice.OptionalFormat.FSize";
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ assert(cl);
+ return "Ice.OptionalFormat.Class";
+}
+
bool
SwiftGenerator::isNullableType(const TypePtr& type)
{
@@ -647,20 +739,42 @@ SwiftGenerator::writeMembers(IceUtilInternal::Output& out,
void
SwiftGenerator::writeMarshalUnmarshalCode(Output &out,
+ const DataMemberPtr& member,
+ const ContainedPtr& topLevel,
+ bool insideStream,
+ bool declareParam,
+ bool marshal,
+ int tag)
+{
+ TypePtr type = member->type();
+ string typeStr = typeToString(type, topLevel, member->getMetaData(), member->optional());
+ string param = member->name();
+
+ writeMarshalUnmarshalCode(out, type, typeStr, param, insideStream, declareParam, marshal, tag);
+}
+
+void
+SwiftGenerator::writeMarshalUnmarshalCode(Output &out,
const TypePtr& type,
+ const string& typeStr,
const string& param,
- const string& swiftModule,
bool insideStream,
bool declareParam,
- bool marshal)
+ bool marshal,
+ int tag)
{
- string unqualifiedType = getUnqualified(getAbsolute(type), swiftModule);
-
string streamName = marshal ? "ostr" : "istr";
- string assign = declareParam ? ("let " + param + ": " + unqualifiedType) : param;
+ string assign = declareParam ? ("let " + param + ": " + typeStr) : param;
string marshalParam = insideStream ? ("v." + param) : param;
+ string unmarshalParam;
string stream = insideStream ? "" : (streamName + ".");
+ if(tag >= 0)
+ {
+ marshalParam = "tag: " + int64ToString(tag) + ", value: " + marshalParam;
+ unmarshalParam = "tag: " + int64ToString(tag);
+ }
+
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
if(builtin)
{
@@ -674,6 +788,17 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out,
case Builtin::KindFloat:
case Builtin::KindDouble:
case Builtin::KindString:
+ {
+ if(marshal)
+ {
+ out << nl << stream << "write(" << marshalParam << ")";
+ }
+ else
+ {
+ out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")";
+ }
+ break;
+ }
case Builtin::KindObjectProxy:
{
if(marshal)
@@ -682,7 +807,7 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out,
}
else
{
- out << nl << assign << " = try " << stream << "read()";
+ out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ") as _ObjectPrxI?";
}
break;
}
@@ -695,8 +820,7 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out,
}
else
{
- out << nl << assign << "= try " << stream << "read(value: " << unqualifiedType << ") { ";
- out << param << " = $0 }";
+ out << nl << "try " << stream << "read(" << unmarshalParam << ") { " << param << " = $0 }";
}
break;
@@ -722,20 +846,102 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out,
}
else
{
- out << nl << assign << " = try " << stream << "read()";
+ out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")";
+ }
+ return;
+ }
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ if(marshal)
+ {
+ out << nl << stream << "write(" << marshalParam << ")";
+ }
+ else
+ {
+ out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")";
}
return;
}
-}
-void
-SwiftGenerator::writeOptionalMarshalUnmarshalCode(Output&,
- const TypePtr&,
- const string&,
- int,
- bool)
-{
+ if(StructPtr::dynamicCast(type))
+ {
+ if(marshal)
+ {
+ out << nl << stream << "write(" << marshalParam << ")";
+ }
+ else
+ {
+ out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")";
+ }
+ return;
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ BuiltinPtr seqBuiltin = BuiltinPtr::dynamicCast(seq->type());
+ if(seqBuiltin && seqBuiltin->kind() <= Builtin::KindString)
+ {
+ if(marshal)
+ {
+ out << nl << stream << "write(" << marshalParam << ")";
+ }
+ else
+ {
+ out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")";
+ }
+ }
+ else
+ {
+ string helper = "_" + typeStr + "Helper";
+ if(marshal)
+ {
+ out << nl << helper <<".write";
+ out << spar;
+ out << ("to: " + streamName);
+ out << ("value: " + marshalParam);
+ out << epar;
+ }
+ else
+ {
+ out << nl << assign << " = try " << helper << ".read";
+ out << spar;
+ out << ("from: " + streamName);
+ if(!unmarshalParam.empty())
+ {
+ out << unmarshalParam;
+ }
+ out << epar;
+ }
+ }
+ return;
+ }
+ if(DictionaryPtr::dynamicCast(type))
+ {
+ string helper = "_" + typeStr + "Helper";
+ if(marshal)
+ {
+ out << nl << helper << ".write";
+ out << spar;
+ out << ("to: " + streamName);
+ out << ("value: " + marshalParam);
+ out << epar;
+ }
+ else
+ {
+ out << nl << assign << " = try " << helper << ".read";
+ out << spar;
+ out << ("from: " + streamName);
+ if(!unmarshalParam.empty())
+ {
+ out << unmarshalParam;
+ }
+ out << epar;
+ }
+ return;
+ }
}
bool
diff --git a/cpp/src/slice2swift/SwiftUtil.h b/cpp/src/slice2swift/SwiftUtil.h
index ec271a65e17..3a8f952675e 100644
--- a/cpp/src/slice2swift/SwiftUtil.h
+++ b/cpp/src/slice2swift/SwiftUtil.h
@@ -18,6 +18,7 @@ namespace Slice
const int TypeContextInParam = 1;
const int TypeContextProtocol = 2;
+const int TypeContextLocal = 32;
std::string getSwiftModule(const ModulePtr&, std::string&);
std::string getSwiftModule(const ModulePtr&);
@@ -52,6 +53,7 @@ protected:
std::string getUnqualified(const std::string&, const std::string&);
std::string modeToString(Operation::Mode);
+ std::string getOptionalFormat(const TypePtr&);
bool isNullableType(const TypePtr&);
bool isObjcRepresentable(const TypePtr&);
@@ -67,8 +69,21 @@ protected:
const DataMemberList&, const ContainedPtr&, bool rootClass = false);
void writeMembers(IceUtilInternal::Output&, const DataMemberList&, const ContainedPtr&, int = 0);
- void writeMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, const std::string&, bool, bool, bool);
- void writeOptionalMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, int, bool);
+ void writeMarshalUnmarshalCode(::IceUtilInternal::Output&,
+ const TypePtr&,
+ const std::string&,
+ const std::string&,
+ bool,
+ bool,
+ bool,
+ int = -1);
+ void writeMarshalUnmarshalCode(::IceUtilInternal::Output&,
+ const DataMemberPtr&,
+ const ContainedPtr&,
+ bool,
+ bool,
+ bool,
+ int = -1);
private: