diff options
Diffstat (limited to 'cpp/src/slice2swift/SwiftUtil.cpp')
-rw-r--r-- | cpp/src/slice2swift/SwiftUtil.cpp | 833 |
1 files changed, 517 insertions, 316 deletions
diff --git a/cpp/src/slice2swift/SwiftUtil.cpp b/cpp/src/slice2swift/SwiftUtil.cpp index ed46a909a9b..f41d29fe73f 100644 --- a/cpp/src/slice2swift/SwiftUtil.cpp +++ b/cpp/src/slice2swift/SwiftUtil.cpp @@ -618,6 +618,40 @@ SwiftGenerator::isProxyType(const TypePtr& p) return (builtin && builtin->kind() == Builtin::KindObjectProxy) || ProxyPtr::dynamicCast(p); } +bool +SwiftGenerator::isClassType(const TypePtr& p) +{ + const BuiltinPtr builtin = BuiltinPtr::dynamicCast(p); + return (builtin && (builtin->kind() == Builtin::KindObject || + builtin->kind() == Builtin::KindValue)) || + ClassDeclPtr::dynamicCast(p); +} + +bool +SwiftGenerator::containsClassMembers(const StructPtr& s) +{ + DataMemberList dm = s->dataMembers(); + for(DataMemberList::const_iterator i = dm.begin(); i != dm.end(); ++i) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast((*i)->type()); + + if(builtin && (builtin->kind() == Builtin::KindObject || + builtin->kind() == Builtin::KindValue)) + { + return true; + } + else if(ClassDefPtr::dynamicCast((*i)->type())) + { + return true; + } + else if(StructPtr::dynamicCast((*i)->type()) && containsClassMembers(StructPtr::dynamicCast((*i)->type()))) + { + return true; + } + } + return false; +} + void SwiftGenerator::writeDefaultInitializer(IceUtilInternal::Output& out, const DataMemberList& members, @@ -754,61 +788,50 @@ 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, topLevel, insideStream, declareParam, marshal, tag); -} - -void -SwiftGenerator::writeMarshalUnmarshalCode(Output &out, - const ParamDeclPtr& param, - bool insideStream, - bool declareParam, - bool marshal, - int tag) +bool +SwiftGenerator::usesMarshalHelper(const TypePtr& type) { - ContainedPtr topLevel = ContainedPtr::dynamicCast(param->container()); - TypePtr type = param->type(); - string typeStr = typeToString(type, topLevel, param->getMetaData(), param->optional()); - string name = param->name(); - - writeMarshalUnmarshalCode(out, type, typeStr, name, topLevel, insideStream, declareParam, marshal, tag); + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); + if(builtin) + { + return builtin->kind() > Builtin::KindString; + } + return true; + } + return DictionaryPtr::dynamicCast(type); } void SwiftGenerator::writeMarshalUnmarshalCode(Output &out, const TypePtr& type, - const string& typeStr, + const ContainedPtr& p, const string& param, - const ContainedPtr& topLevel, - bool insideStream, - bool declareParam, bool marshal, int tag) { - string streamName = marshal ? "ostr" : "istr"; - string assign = declareParam ? ("let " + param + ": " + typeStr) : param; - string marshalParam = insideStream ? ("v." + param) : param; - string unmarshalParam; - string stream = insideStream ? "" : (streamName + "."); - - string swiftModule = getSwiftModule(getTopLevelModule(topLevel)); + string swiftModule = getSwiftModule(getTopLevelModule(p)); + string stream = StructPtr::dynamicCast(p) ? "self" : marshal ? "ostr" : "istr"; + string args; if(tag >= 0) { - marshalParam = "tag: " + int64ToString(tag) + ", value: " + marshalParam; - unmarshalParam = "tag: " + int64ToString(tag); + args += "tag: " + int64ToString(tag); + if(marshal) + { + args += ", "; + } + } + + if(marshal) + { + if(tag >= 0 || usesMarshalHelper(type)) + { + args += "value: "; + } + args += param; } BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); @@ -827,11 +850,11 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")"; + out << nl << param << " = try " << stream << ".read(" << args << ")"; } break; } @@ -839,21 +862,17 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - // proxy reads requires an additional parameter - const string prxType = getUnqualified(getAbsolute(type), swiftModule) + ".self"; - if(unmarshalParam.empty()) + if(tag >= 0) { - unmarshalParam = prxType; + args += ", type: "; } - else - { - unmarshalParam += ", type: " + prxType; - } - out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")"; + args += getUnqualified(getAbsolute(type), swiftModule) + ".self"; + + out << nl << param << " = try " << stream << ".read(" << args << ")"; } break; } @@ -862,20 +881,11 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - if(declareParam) - { - out << nl << "var " << param << ": " << typeStr; - } - out << nl << "try " << stream << "read(" << unmarshalParam << ") { "; - if(!declareParam) - { - out << "self."; - } - out << param << " = $0 }"; + out << nl << "try " << stream << ".read(" << args << ") { " << param << " = $0 }"; } break; } @@ -886,7 +896,7 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, } default: { - + break; } } } @@ -896,43 +906,22 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - if(declareParam) - { - out << nl << "var " << param << ": " << typeStr; - } if(cl->isInterface()) { - out << nl << "try " << stream << "read(" << unmarshalParam << ") { "; - if(!declareParam) - { - out << "self."; - } - out << param << " = $0 }"; + out << nl << "try " << stream << ".read(" << args << ") { " << param << " = $0 }"; } else { - const string className = getUnqualified(getAbsolute(type), swiftModule); - if(unmarshalParam.empty()) + if(tag >= 0) { - unmarshalParam = className + ".self"; + args += ", value: "; } - else - { - unmarshalParam += ", value: " + className + ".self"; - } - out << nl << "try " << stream << "read(" << unmarshalParam << ")"; - out << sb; - out << nl; - if(!declareParam) - { - out << "self."; - } - out << param << " = $0"; - out << eb; + args += getUnqualified(getAbsolute(type), swiftModule) + ".self"; + out << nl << "try " << stream << ".read(" << args << ") { " << param << " = $0 " << "}"; } } return; @@ -943,34 +932,30 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")"; + out << nl << param << " = try " << stream << ".read(" << args << ")"; } return; } + ProxyPtr prx = ProxyPtr::dynamicCast(type); if(prx) { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - // proxy reads requires an additional parameter - const string prxType = getUnqualified(getAbsolute(type), swiftModule) + ".self"; - if(unmarshalParam.empty()) - { - unmarshalParam = prxType; - } - else + if(tag >= 0) { - unmarshalParam += ", type: " + prxType; + args += ", type: "; } - out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")"; + args += getUnqualified(getAbsolute(type), swiftModule) + ".self"; + out << nl << param << " = try " << stream << ".read(" << args << ")"; } return; } @@ -979,11 +964,11 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")"; + out << nl << param << " = try " << stream << ".read(" << args << ")"; } return; } @@ -996,34 +981,28 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, { if(marshal) { - out << nl << stream << "write(" << marshalParam << ")"; + out << nl << stream << ".write(" << args << ")"; } else { - out << nl << assign << " = try " << stream << "read(" << unmarshalParam << ")"; + out << nl << param << " = try " << stream << ".read(" << args << ")"; } } else { - string helper = typeStr + "Helper"; + string helper = getUnqualified(getAbsoluteImpl(ContainedPtr::dynamicCast(type)), swiftModule) + "Helper"; if(marshal) { - out << nl << helper <<".write"; - out << spar; - out << ("to: " + streamName); - out << ("value: " + marshalParam); - out << epar; + out << nl << helper <<".write(to: ostr, " << args << ")"; } else { - out << nl << assign << " = try " << helper << ".read"; - out << spar; - out << ("from: " + streamName); - if(!unmarshalParam.empty()) + out << nl << param << " = try " << helper << ".read(from: istr"; + if(!args.empty()) { - out << unmarshalParam; + out << ", " << args; } - out << epar; + out << ")"; } } return; @@ -1031,25 +1010,19 @@ SwiftGenerator::writeMarshalUnmarshalCode(Output &out, if(DictionaryPtr::dynamicCast(type)) { - string helper = typeStr + "Helper"; + string helper = getUnqualified(getAbsoluteImpl(ContainedPtr::dynamicCast(type)), swiftModule) + "Helper"; if(marshal) { - out << nl << helper << ".write"; - out << spar; - out << ("to: " + streamName); - out << ("value: " + marshalParam); - out << epar; + out << nl << helper <<".write(to: ostr, " << args << ")"; } else { - out << nl << assign << " = try " << helper << ".read"; - out << spar; - out << ("from: " + streamName); - if(!unmarshalParam.empty()) + out << nl << param << " = try " << helper << ".read(from: istr"; + if(!args.empty()) { - out << unmarshalParam; + out << ", " << args; } - out << epar; + out << ")"; } return; } @@ -1135,141 +1108,364 @@ SwiftGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p) return true; } -void -SwiftGenerator::writeProxyOperation(::IceUtilInternal::Output& out, const OperationPtr& op, bool async) +string +SwiftGenerator::operationReturnTypeLabel(const OperationPtr& op) { - const string opName = fixIdent(op->name()) + (async ? "Async" : ""); - TypePtr returnType = op->returnType(); + string returnValueS = "returnValue"; + ParamDeclList outParams = op->outParameters(); + for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q) + { + if((*q)->name() == "returnValue") + { + returnValueS = "_returnValue"; + break; + } + } + return returnValueS; +} - ParamDeclList paramList = op->parameters(); - ParamDeclList inParams = op->inParameters(); +bool +SwiftGenerator::operationReturnIsTuple(const OperationPtr& op) +{ ParamDeclList outParams = op->outParameters(); + return (op->returnType() && outParams.size() > 0) || outParams.size() > 1; +} - ParamDeclList requiredInParams, optionalInParams; - ParamDeclList requiredOutParams, optionalOutParams; - op->inParameters(requiredInParams, optionalInParams); - op->outParameters(requiredOutParams, optionalOutParams); +string +SwiftGenerator::operationReturnType(const OperationPtr& op) +{ + ostringstream os; + bool returnIsTuple = operationReturnIsTuple(op); + if(returnIsTuple) + { + os << "("; + } - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); + TypePtr returnType = op->returnType(); + if(returnType) + { + if(returnIsTuple) + { + os << operationReturnTypeLabel(op) << ": "; + } + os << typeToString(returnType, op, op->getMetaData(), op->returnIsOptional()); + } - const string swiftModule = getSwiftModule(getTopLevelModule(ContainedPtr::dynamicCast(op))); + ParamDeclList outParams = op->outParameters(); + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + if(returnType || q != outParams.begin()) + { + os << ", "; + } - const bool twowayOnly = op->returnsData(); - const bool useInputStream = !op->outParameters().empty() || returnType; + if(returnIsTuple) + { + os << (*q)->name() << ": "; + } - 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)); + os << typeToString((*q)->type(), *q, (*q)->getMetaData(), (*q)->optional()); } - // context - out << "context: Context? = nil"; - // extra async params - if(async) + if(returnIsTuple) { - out << "sent: ((Bool) -> Void)? = nil"; - out << "sentOn: Dispatch.DispatchQueue? = PromiseKit.conf.Q.map"; + os << ")"; } - out << epar; - if(!async) + return os.str(); +} + +ParamInfoList +SwiftGenerator::getAllInParams(const OperationPtr& op) +{ + const ParamDeclList l = op->inParameters(); + ParamInfoList r; + for(ParamDeclList::const_iterator p = l.begin(); p != l.end(); ++p) + { + ParamInfo info; + info.name = (*p)->name(); + info.fixedName = fixIdent((*p)->name()); + info.type = (*p)->type(); + info.typeStr = typeToString(info.type, op, (*p)->getMetaData(), (*p)->optional()); + info.optional = (*p)->optional(); + info.tag = (*p)->tag(); + info.param = *p; + r.push_back(info); + } + return r; +} + +void +SwiftGenerator::getInParams(const OperationPtr& op, ParamInfoList& required, ParamInfoList& optional) +{ + const ParamInfoList params = getAllInParams(op); + for(ParamInfoList::const_iterator p = params.begin(); p != params.end(); ++p) { - out << " throws"; + if(p->optional) + { + optional.push_back(*p); + } + else + { + required.push_back(*p); + } } - if(useInputStream || async) + // + // Sort optional parameters by tag. + // + class SortFn { - out << " -> "; - // Async operations always return a Promise - if(async) + public: + static bool compare(const ParamInfo& lhs, const ParamInfo& rhs) { - out << "PromiseKit.Promise<"; + return lhs.tag < rhs.tag; } + }; + optional.sort(SortFn::compare); +} + +ParamInfoList +SwiftGenerator::getAllOutParams(const OperationPtr& op) +{ + ParamDeclList params = op->outParameters(); + ParamInfoList l; + + if(op->returnType()) + { + ParamInfo info; + info.name = operationReturnTypeLabel(op); + info.fixedName = info.name; + info.type = op->returnType(); + info.typeStr = typeToString(info.type, op, op->getMetaData(), op->returnIsOptional()); + info.optional = op->returnIsOptional(); + info.tag = op->returnTag(); + l.push_back(info); } - if(useInputStream) + for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) + { + ParamInfo info; + info.name = (*p)->name(); + info.fixedName = fixIdent((*p)->name()); + info.type = (*p)->type(); + info.typeStr = typeToString(info.type, op, (*p)->getMetaData(), (*p)->optional()); + info.optional = (*p)->optional(); + info.tag = (*p)->tag(); + info.param = *p; + l.push_back(info); + } + + return l; +} + +void +SwiftGenerator::getOutParams(const OperationPtr& op, ParamInfoList& required, ParamInfoList& optional) +{ + const ParamInfoList params = getAllOutParams(op); + for(ParamInfoList::const_iterator p = params.begin(); p != params.end(); ++p) { - StringList returnTypes; - if(returnType) // return parameter first + if(p->optional) { - returnTypes.push_back(typeToString(returnType, op)); + optional.push_back(*p); } - for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + else { - ParamDeclPtr param = *q; - returnTypes.push_back(typeToString(param->type(), param, param->getMetaData(), param->optional())); + required.push_back(*p); } + } - if(returnTypes.size() == 1) + // + // Sort optional parameters by tag. + // + class SortFn + { + public: + static bool compare(const ParamInfo& lhs, const ParamInfo& rhs) { - out << returnTypes.front(); + return lhs.tag < rhs.tag; } - else + }; + optional.sort(SortFn::compare); +} + +void +SwiftGenerator::writeMarshalInParams(::IceUtilInternal::Output& out, const OperationPtr& op) +{ + ParamInfoList requiredInParams, optionalInParams; + getInParams(op, requiredInParams, optionalInParams); + const ParamInfoList allInParams = getAllInParams(op); + + out << "{ ostr in"; + out.inc(); + // + // Marshal parameters + // 1. required + // 2. optional + // + + for(ParamInfoList::const_iterator q = requiredInParams.begin(); q != requiredInParams.end(); ++q) + { + writeMarshalUnmarshalCode(out, q->type, op, q->fixedName, true); + } + + for(ParamInfoList::const_iterator q = optionalInParams.begin(); q != optionalInParams.end(); ++q) + { + writeMarshalUnmarshalCode(out, q->type, op, q->fixedName, true, q->tag); + } + + if(op->sendsClasses(false)) + { + out << nl << "ostr.writePendingValues()"; + } + out.dec(); + out << nl << "}"; +} + +void +SwiftGenerator::writeUnmarshalOutParams(::IceUtilInternal::Output& out, const OperationPtr& op) +{ + TypePtr returnType = op->returnType(); + + ParamInfoList requiredOutParams, optionalOutParams; + getOutParams(op, requiredOutParams, optionalOutParams); + const ParamInfoList allOutParams = getAllOutParams(op); + // + // Unmarshal parameters + // 1. required + // 2. return + // 3. optional (including optional return) + // + out << "{ istr in"; + out.inc(); + for(ParamInfoList::const_iterator q = requiredOutParams.begin(); q != requiredOutParams.end(); ++q) + { + if(q->param) { - out << spar; - if(returnType) + string param; + if(isClassType(q->type)) { - string returnValueS = "returnValue"; - - for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q) - { - if((*q)->name() == "returnValue") - { - returnValueS = "_returnValue"; - } - } - out << (returnValueS + ": " + typeToString(returnType, op)); + out << nl << "var " << q->fixedName << ": " << q->typeStr; + param = q->fixedName; } - for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + else { - ParamDeclPtr param = *q; - out << (param->name() + ": " + typeToString(param->type(), param, param->getMetaData(), param->optional())); + param = "let " + q->fixedName + ": " + q->typeStr; } - out << epar; + writeMarshalUnmarshalCode(out, q->type, op, param, false); } + } - if(async) + if(returnType && !op->returnIsOptional()) + { + ParamInfo r = requiredOutParams.front(); + string param; + if(isClassType(r.type)) + { + out << nl << "var " << r.fixedName << ": " << r.typeStr; + param = r.fixedName; + } + else { - out << ">"; + param = "let " + r.fixedName + ": " + r.typeStr; } + writeMarshalUnmarshalCode(out, r.type, op, param, false); } - else if(async) + + for(ParamInfoList::const_iterator q = optionalOutParams.begin(); q != optionalOutParams.end(); ++q) { - out << "Void>"; + string param; + if(isClassType(q->type)) + { + out << nl << "var " << q->fixedName << ": " << q->typeStr; + param = q->fixedName; + } + else + { + param = "let " + q->fixedName + ": " + q->typeStr; + } + writeMarshalUnmarshalCode(out, q->type, op, param, false, q->tag); } - out << sb; + if(op->returnsClasses(false)) + { + out << nl << "try istr.readPendingValues()"; + } - // - // 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) + out << nl << "return "; + if(allOutParams.size() > 1) { - ParamDeclPtr param = *q; - writeMarshalUnmarshalCode(out, param, false, false, true); + out << spar; } - for(ParamDeclList::const_iterator q = optionalInParams.begin(); q != optionalInParams.end(); ++q) + + for(ParamInfoList::const_iterator q = allOutParams.begin(); q != allOutParams.end(); ++q) { - ParamDeclPtr param = *q; - assert(param->optional()); - writeMarshalUnmarshalCode(out, param, false, false, true, param->tag()); + out << q->fixedName; } - if(op->sendsClasses(false)) + + if(allOutParams.size() > 1) { - out << nl << "ostr.writePendingValues()"; + out << epar; + } + + out.dec(); + out << nl << "}"; +} + +void +SwiftGenerator::writeUnmarshalUserException(::IceUtilInternal::Output& out, const OperationPtr& op) +{ + const string swiftModule = getSwiftModule(getTopLevelModule(ContainedPtr::dynamicCast(op))); + ExceptionList throws = op->throws(); + throws.sort(); + throws.unique(); + + out << "{ ex in"; + out.inc(); + out << nl << "do "; + out << sb; + out << nl << "throw ex"; + out << eb; + for(ExceptionList::const_iterator q = throws.begin(); q != throws.end(); ++q) + { + out << " catch let error as " << getUnqualified(getAbsolute(*q), swiftModule) << sb; + out << nl << "throw error"; + out << eb; } - out << nl << "ostr.endEncapsulation()"; + out << " catch is " << getUnqualified("Ice.UserException", swiftModule) << " {}"; + out.dec(); + out << nl << "}"; +} + +void +SwiftGenerator::writeProxyOperation(::IceUtilInternal::Output& out, const OperationPtr& op) +{ + const string opName = fixIdent(op->name()); + + const ParamInfoList allInParams = getAllInParams(op); + const ParamInfoList allOutParams = getAllOutParams(op); + const ExceptionList allExceptions = op->throws(); + + const string swiftModule = getSwiftModule(getTopLevelModule(ContainedPtr::dynamicCast(op))); + + out << sp; + out << nl << "func " << opName; + out << spar; + for(ParamInfoList::const_iterator q = allInParams.begin(); q != allInParams.end(); ++q) + { + out << ((allInParams.size() == 1 ? "_ " : "") + q->name + ": " + typeToString(q->type, op)); + } + out << "context: Context? = nil"; + + out << epar; + out << " throws"; + + if(allOutParams.size() > 0) + { + out << " -> " << operationReturnType(op); + } + + out << sb; // // Invoke @@ -1277,129 +1473,134 @@ SwiftGenerator::writeProxyOperation(::IceUtilInternal::Output& out, const Operat out << sp; out << nl; - if(async) + if(op->returnsData()) { - out << "return impl._invokeAsync("; + out << "guard _impl.isTwoway else " << sb; + out << nl << "throw TwowayOnlyException(operation: \"" << op->name() << "\")"; + out << eb; } - else + + out << nl; + if(allOutParams.size() > 0) { - out << "let " << (useInputStream ? "istr " : "_ "); - out << "= try impl._invoke("; + out << "return "; } + out << "try _impl._invoke("; out.useCurrentPosAsIndent(); - out << "operation: \"" << fixIdent(op->name()) << "\","; + out << "operation: \"" << op->name() << "\","; out << nl << "mode: " << modeToString(op->sendMode()) << ","; - 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) + + if(allInParams.size() > 0) { - ExceptionPtr ex = *q; - out << getUnqualified(getAbsolute(ex), swiftModule) << ".self"; - if(q != throws.end()) - { - out << ','; - } + out << nl << "write: "; + writeMarshalInParams(out, op); + out << ","; } - out << "],"; - out << nl << "context: context"; - // extra async params - if(async) + if(allOutParams.size() > 0) { - out << ", "; - out << nl << "sent: sent,"; - out << nl << "sentOn: sentOn"; + out << nl << "read: "; + writeUnmarshalOutParams(out, op); + out << ","; } - out << ")"; + + if(allExceptions.size() > 0) + { + out << nl << "userException:"; + writeUnmarshalUserException(out, op); + out << ","; + } + + out << nl << "context: context)"; out.restoreIndent(); + out << eb; +} + +void +SwiftGenerator::writeProxyAsyncOperation(::IceUtilInternal::Output& out, const OperationPtr& op) +{ + const string opName = fixIdent(op->name() + "Async"); + + const ParamInfoList allInParams = getAllInParams(op); + const ParamInfoList allOutParams = getAllOutParams(op); + const ExceptionList allExceptions = op->throws(); + + const string swiftModule = getSwiftModule(getTopLevelModule(ContainedPtr::dynamicCast(op))); + + out << sp; + out << nl << "func " << opName; + out << spar; + for(ParamInfoList::const_iterator q = allInParams.begin(); q != allInParams.end(); ++q) + { + out << ((allInParams.size() == 1 ? "_ " : "") + q->name + ": " + typeToString(q->type, op)); + } + out << "context: Context? = nil"; + out << "sent: ((Bool) -> Void)? = nil"; + out << "sentOn: DispatchQueue? = PromiseKit.conf.Q.return"; + out << "sentFlags: DispatchWorkItemFlags? = nil"; + + out << epar; + out << " -> PromiseKit.Promise<"; + if(allOutParams.empty()) + { + out << "Void"; + } + else + { + out << operationReturnType(op); + } + out << ">"; + + out << sb; + // - // Unmarshal parameters - // 1. required - // 2. return - // 3. optional (including optional return) + // Invoke // - if(async && !useInputStream) + out << sp; + out << nl; + + if(op->returnsData()) { - out << sb; - out << " _ in"; + out << "guard _impl.isTwoway else " << sb; + out << nl << "return Promise(error: TwowayOnlyException(operation: \"" << op->name() << "\"))"; out << eb; } - if(useInputStream) - { - if(async) - { - out << sb; - out << " istr in"; - } - out << sp; - out << nl << "try istr.startEncapsulation()"; - StringList returnVals; - for(ParamDeclList::const_iterator q = requiredOutParams.begin(); q != requiredOutParams.end(); ++q) - { - ParamDeclPtr param = *q; - writeMarshalUnmarshalCode(out, param, 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", - ContainedPtr::dynamicCast(op->container()), false, - true, false); - returnVals.push_front("ret"); - } + out << nl << "return _impl._invokeAsync("; - bool optReturnUnmarshaled = false; - for(ParamDeclList::const_iterator q = optionalOutParams.begin(); q != optionalOutParams.end(); ++q) - { - ParamDeclPtr param = *q; - assert(param->optional()); + out.useCurrentPosAsIndent(); + out << "operation: \"" << op->name() << "\","; + out << nl << "mode: " << modeToString(op->sendMode()) << ","; - if(returnType && op->returnIsOptional() && !optReturnUnmarshaled && (op->returnTag() < param->tag())) - { - writeMarshalUnmarshalCode(out, returnType, typeToString(returnType, op), "ret", - ContainedPtr::dynamicCast(op->container()), false, - true, false, op->returnTag()); - returnVals.push_front("ret"); - optReturnUnmarshaled = true; - } - writeMarshalUnmarshalCode(out, param, false, true, false, param->tag()); - returnVals.push_back((*q)->name()); - } - if(op->returnsClasses(false)) - { - out << nl << "try istr.readPendingValues()"; - } - out << nl << "try istr.endEncapsulation()"; + if(allInParams.size() > 0) + { + out << nl << "write: "; + writeMarshalInParams(out, op); + out << ","; + } - 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(allOutParams.size() > 0) + { + out << nl << "read: "; + writeUnmarshalOutParams(out, op); + out << ","; + } - if(async) - { - out << eb; - } + if(allExceptions.size() > 0) + { + out << nl << "userException:"; + writeUnmarshalUserException(out, op); + out << ","; } + out << nl << "context: context,"; + out << nl << "sent: sent,"; + out << nl << "sentOn: sentOn,"; + out << nl << "sentFlags: sentFlags)"; + out.restoreIndent(); + out << eb; } |