summaryrefslogtreecommitdiff
path: root/cpp/src/slice2swift/SwiftUtil.cpp
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2019-03-15 11:31:34 -0400
committerJoe George <joe@zeroc.com>2019-03-15 11:32:09 -0400
commit0c79bb767709ffec0a481d5159fe65f91837db59 (patch)
tree92cdda8e73d0ba1392846d424061df31a8ab5199 /cpp/src/slice2swift/SwiftUtil.cpp
parentFixes for OutputStream and InputStream initialization (diff)
downloadice-0c79bb767709ffec0a481d5159fe65f91837db59.tar.bz2
ice-0c79bb767709ffec0a481d5159fe65f91837db59.tar.xz
ice-0c79bb767709ffec0a481d5159fe65f91837db59.zip
Add async proxy operations
Diffstat (limited to 'cpp/src/slice2swift/SwiftUtil.cpp')
-rw-r--r--cpp/src/slice2swift/SwiftUtil.cpp235
1 files changed, 235 insertions, 0 deletions
diff --git a/cpp/src/slice2swift/SwiftUtil.cpp b/cpp/src/slice2swift/SwiftUtil.cpp
index 13033a19db3..2d75436f9d2 100644
--- a/cpp/src/slice2swift/SwiftUtil.cpp
+++ b/cpp/src/slice2swift/SwiftUtil.cpp
@@ -1112,12 +1112,247 @@ SwiftGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
return true;
}
+void
+SwiftGenerator::writeProxyOperation(::IceUtilInternal::Output& out, const OperationPtr& op, bool async)
+{
+ const string opName = fixIdent(op->name()) + (async ? "Async" : "");
+ TypePtr returnType = op->returnType();
+
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList inParams = op->inParameters();
+ ParamDeclList outParams = op->outParameters();
+
+ ParamDeclList requiredInParams, optionalInParams;
+ ParamDeclList requiredOutParams, optionalOutParams;
+ op->inParameters(requiredInParams, optionalInParams);
+ op->outParameters(requiredOutParams, optionalOutParams);
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ const bool twowayOnly = op->returnsData();
+ const bool useInputStream = !op->outParameters().empty() || returnType;
+
+ out << sp;
+ out << nl << "func " << opName;
+ out << spar;
+ const string omitLabel = inParams.size() == 1 ? "_ " : "";
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ out << (omitLabel + param->name() + ": " + typeToString(param->type(), param));
+ }
+ // context
+ out << "context: Context? = nil";
+ if(async)
+ {
+ out << "sent: ((Bool) -> Void)? = nil";
+ }
+ out << epar;
+
+ out << " throws";
+ if(useInputStream || async)
+ {
+ out << " -> ";
+ // Async operations always return a Promise
+ if(async)
+ {
+ out << "PromiseKit.Promise<";
+ }
+ }
+
+ if(useInputStream)
+ {
+ StringList returnTypes;
+ if(returnType) // return parameter first
+ {
+ returnTypes.push_back(typeToString(returnType, op));
+ }
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ returnTypes.push_back(typeToString(param->type(), param, param->getMetaData(), param->optional()));
+ }
+
+ if(returnTypes.size() == 1)
+ {
+ out << returnTypes.front();
+ }
+ else
+ {
+ out << spar;
+ if(returnType)
+ {
+ out << typeToString(returnType, op);
+ }
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ out << typeToString(param->type(), param, param->getMetaData(), param->optional());
+ }
+ out << epar;
+ }
+
+ if(async)
+ {
+ out << ">";
+ }
+ }
+ else if(async)
+ {
+ out << "Void>";
+ }
+
+ out << sb;
+
+ //
+ // Marshal parameters
+ // 1. required
+ // 2. optional
+ //
+ out << nl << "let ostr = impl._createOutputStream()";
+ out << nl << "ostr.startEncapsulation()";
+ for(ParamDeclList::const_iterator q = requiredInParams.begin(); q != requiredInParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ ContainedPtr topLevel = getTopLevelModule(ContainedPtr::dynamicCast(param));
+ writeMarshalUnmarshalCode(out, param, topLevel, false, false, true);
+ }
+ for(ParamDeclList::const_iterator q = optionalInParams.begin(); q != optionalInParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ assert(param->optional());
+ ContainedPtr topLevel = getTopLevelModule(ContainedPtr::dynamicCast(param));
+ writeMarshalUnmarshalCode(out, param, topLevel, false, false, true, param->tag());
+ }
+ out << nl << "ostr.endEncapsulation()";
+
+ //
+ // Invoke
+ //
+ out << sp;
+ out << nl;
+
+ if(async)
+ {
+ out << "return impl._invokeAsync(";
+ }
+ else
+ {
+ out << "let " << (useInputStream ? "istr " : "_ ");
+ out << "= try impl._invoke(";
+ }
+
+ out.useCurrentPosAsIndent();
+ out << "operation: \"" << fixIdent(op->name()) << "\",";
+ out << nl << "mode: " << modeToString(op->mode()) << ",";
+ out << nl << "twowayOnly: " << (twowayOnly ? "true" : "false") << ",";
+ out << nl << "inParams: ostr,";
+ out << nl << "hasOutParams: " << (useInputStream ? "true" : "false") << ",";
+ out << nl << "exceptions: ";
+ out << "[";
+ for(ExceptionList::const_iterator q = throws.begin(); q != throws.end(); ++q)
+ {
+ ExceptionPtr ex = *q;
+ const string swiftModule = getSwiftModule(getTopLevelModule(ContainedPtr::dynamicCast(ex)));
+ out << getUnqualified(getAbsolute(ex), swiftModule) << ".self";
+ if(q != throws.end())
+ {
+ out << ',';
+ }
+ }
+ out << "],";
+ out << nl << "context: context";
+ out << ")";
+ out.restoreIndent();
+
+ //
+ // Unmarshal parameters
+ // 1. required
+ // 2. return
+ // 3. optional (including optional return)
+ //
+ if(async && !useInputStream)
+ {
+ out << sb;
+ out << " _ in";
+ out << eb;
+ }
+ if(useInputStream)
+ {
+ if(async)
+ {
+ out << sb;
+ out << " istr in";
+ }
+ out << sp;
+ StringList returnVals;
+ for(ParamDeclList::const_iterator q = requiredOutParams.begin(); q != requiredOutParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ ContainedPtr topLevel = getTopLevelModule(ContainedPtr::dynamicCast(param));
+ writeMarshalUnmarshalCode(out, param, topLevel, false, true, false);
+ returnVals.push_back((*q)->name());
+ }
+
+ // If the return type is optional we unmarshal it with the rest of the optional params (in order)
+ if(returnType && !op->returnIsOptional())
+ {
+ writeMarshalUnmarshalCode(out, returnType, typeToString(returnType, op), "ret", false, true, false);
+ returnVals.push_front("ret");
+ }
+
+ bool optReturnUnmarshaled = false;
+ for(ParamDeclList::const_iterator q = optionalOutParams.begin(); q != optionalOutParams.end(); ++q)
+ {
+ ParamDeclPtr param = *q;
+ assert(param->optional());
+
+ if(returnType && op->returnIsOptional() && !optReturnUnmarshaled && (op->returnTag() < param->tag()))
+ {
+ writeMarshalUnmarshalCode(out, returnType, typeToString(returnType, op), "ret", false, true, false, op->returnTag());
+ returnVals.push_front("ret");
+ optReturnUnmarshaled = true;
+ }
+
+ ContainedPtr topLevel = getTopLevelModule(ContainedPtr::dynamicCast(param));
+ writeMarshalUnmarshalCode(out, param, topLevel, false, true, false, param->tag());
+ returnVals.push_back((*q)->name());
+ }
+
+ out << sp;
+ out << nl << "return ";
+ if(returnVals.size() == 1)
+ {
+ out << returnVals.front();
+ }
+ else
+ {
+ out << spar;
+ for(StringList::const_iterator q = returnVals.begin(); q != returnVals.end(); ++q)
+ {
+ out << *q;
+ }
+ out << epar;
+ }
+
+ if(async)
+ {
+ out << eb;
+ }
+ }
+
+ out << eb;
+}
+
bool
SwiftGenerator::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
{
validate(p);
return true;
}
+
bool
SwiftGenerator::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
{