diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/JavaUtil.cpp | 167 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.cpp | 89 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.h | 5 |
3 files changed, 212 insertions, 49 deletions
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp index 9af4e993894..a1dabf6d6dc 100644 --- a/cpp/src/Slice/JavaUtil.cpp +++ b/cpp/src/Slice/JavaUtil.cpp @@ -550,6 +550,36 @@ Slice::JavaGenerator::getStaticId(const TypePtr& type, const string& package) co } } +bool +Slice::JavaGenerator::useOptionalMapping(const ParamDeclPtr& p) +{ + if(p->optional()) + { + // + // Optional in parameters can be marked with the "java:optional" metadata to force + // the mapping to use the Ice.Optional types. The tag can also be applied to an + // operation or its interface. + // + // Without the tag, in parameters use the normal (non-optional) mapping. + // + if(!p->isOutParam()) + { + static const string tag = "java:optional"; + + OperationPtr op = OperationPtr::dynamicCast(p->container()); + assert(op); + ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); + assert(cl); + + return p->hasMetaData(tag) || op->hasMetaData(tag) || cl->hasMetaData(tag); + } + + return true; + } + + return false; +} + string Slice::JavaGenerator::getOptionalType(const TypePtr& type) { @@ -667,6 +697,20 @@ Slice::JavaGenerator::typeToString(const TypePtr& type, "Ice.ObjectPrxHolder", "Ice.LocalObjectHolder" }; + static const char* builtinOptionalTable[] = + { + "Ice.ByteOptional", + "Ice.BooleanOptional", + "Ice.ShortOptional", + "Ice.IntOptional", + "Ice.LongOptional", + "Ice.FloatOptional", + "Ice.DoubleOptional", + "???", + "???", + "???", + "???" + }; if(!type) { @@ -679,7 +723,26 @@ Slice::JavaGenerator::typeToString(const TypePtr& type, { if(optional) { - return "Ice.Optional<" + typeToObjectString(builtin, TypeModeIn, package, metaData, formal) + ">"; + switch(builtin->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindLong: + case Builtin::KindFloat: + case Builtin::KindDouble: + { + return builtinOptionalTable[builtin->kind()]; + } + case Builtin::KindString: + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + break; + } + } } else { @@ -1184,13 +1247,25 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, { if(isOptionalParam(optional)) { - out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag - << ", " << getOptionalType(type) << "))"; - out << sb; - out << nl << stream << ".startSize();"; - out << nl << typeS << "Helper.__write(" << stream << ", " << v << ".get());"; - out << nl << stream << ".endSize();"; - out << eb; + if(optional == OptionalInParamReq) + { + out << nl << "if(" << stream << ".writeOpt(" << tag << ", " << getOptionalType(type) << "))"; + out << sb; + out << nl << stream << ".startSize();"; + out << nl << typeS << "Helper.__write(" << stream << ", " << v << ");"; + out << nl << stream << ".endSize();"; + out << eb; + } + else + { + out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag + << ", " << getOptionalType(type) << "))"; + out << sb; + out << nl << stream << ".startSize();"; + out << nl << typeS << "Helper.__write(" << stream << ", " << v << ".get());"; + out << nl << stream << ".endSize();"; + out << eb; + } } else if(optional == OptionalMember) { @@ -1298,10 +1373,19 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, if(isOptionalParam(optional)) { - out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag - << ", " << getOptionalType(type) << "))"; + if(optional == OptionalInParamReq) + { + out << nl << "if(" << stream << ".writeOpt(" << tag << ", " << getOptionalType(type) << "))"; + val = v; + } + else + { + out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" + << tag << ", " << getOptionalType(type) << "))"; + val = v + ".get()"; + } + out << sb; - val = v + ".get()"; } else { @@ -1391,11 +1475,21 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, { if(isOptionalParam(optional)) { - out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag - << ", " << getOptionalType(type) << "))"; - out << sb; - out << nl << v << ".get().__write(" << stream << ");"; - out << eb; + if(optional == OptionalInParamReq) + { + out << nl << "if(" << stream << ".writeOpt(" << tag << ", " << getOptionalType(type) << "))"; + out << sb; + out << nl << v << ".__write(" << stream << ");"; + out << eb; + } + else + { + out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag + << ", " << getOptionalType(type) << "))"; + out << sb; + out << nl << v << ".get().__write(" << stream << ");"; + out << eb; + } } else { @@ -1441,14 +1535,22 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, { if(isOptionalParam(optional)) { - out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag - << ", " << getOptionalType(type) << "))"; - out << sb; + if(optional == OptionalInParamReq) + { + out << nl << "if(" << stream << ".writeOpt(" << tag << ", " << getOptionalType(type) << "))"; + out << sb; + } + else + { + out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" + << tag << ", " << getOptionalType(type) << "))"; + out << sb; + } } if(keyType->isVariableLength() || valueType->isVariableLength()) { - string d = isOptionalParam(optional) ? v + ".get()" : v; + string d = isOptionalParam(optional) && optional != OptionalInParamReq ? v + ".get()" : v; out << nl << stream << ".startSize();"; writeDictionaryMarshalUnmarshalCode(out, package, dict, d, marshal, iter, true, metaData); out << nl << stream << ".endSize();"; @@ -1457,7 +1559,7 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, { const int wireSize = keyType->minWireSize() + valueType->minWireSize(); string tmpName; - if(isOptionalParam(optional)) + if(isOptionalParam(optional) && optional != OptionalInParamReq) { tmpName = "__optDict"; out << nl << "final " << typeS << ' ' << tmpName << " = " << v << ".get();"; @@ -1548,6 +1650,9 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, "Float", "Double", "String", + "???", + "???", + "???" }; switch(elemBuiltin->kind()) @@ -1589,14 +1694,22 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, { if(isOptionalParam(optional)) { - out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" << tag - << ", " << getOptionalType(type) << "))"; + if(optional == OptionalInParamReq) + { + out << nl << "if(" << stream << ".writeOpt(" << tag << ", " << getOptionalType(type) << "))"; + } + else + { + out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOpt(" + << tag << ", " << getOptionalType(type) << "))"; + } + out << sb; } if(elemType->isVariableLength()) { - string s = isOptionalParam(optional) ? v + ".get()" : v; + string s = isOptionalParam(optional) && optional != OptionalInParamReq ? v + ".get()" : v; out << nl << stream << ".startSize();"; writeSequenceMarshalUnmarshalCode(out, package, seq, s, marshal, iter, true, metaData); out << nl << stream << ".endSize();"; @@ -1610,7 +1723,7 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, // string tmpName; - if(isOptionalParam(optional)) + if(isOptionalParam(optional) && optional != OptionalInParamReq) { tmpName = "__optSeq"; out << nl << "final " << typeS << ' ' << tmpName << " = " << v << ".get();"; @@ -1647,7 +1760,7 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, // // This just writes a byte sequence. // - string s = isOptionalParam(optional) ? v + ".get()" : v; + string s = isOptionalParam(optional) && optional != OptionalInParamReq ? v + ".get()" : v; writeSequenceMarshalUnmarshalCode(out, package, seq, s, marshal, iter, true, metaData); } else @@ -1657,7 +1770,7 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out, // string tmpName; - if(isOptionalParam(optional)) + if(isOptionalParam(optional) && optional != OptionalInParamReq) { tmpName = "__optSeq"; out << nl << "final " << typeS << ' ' << tmpName << " = " << v << ".get();"; diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp index ee4f01688d3..37879c13ca7 100644 --- a/cpp/src/slice2java/Gen.cpp +++ b/cpp/src/slice2java/Gen.cpp @@ -109,7 +109,7 @@ Slice::JavaVisitor::~JavaVisitor() } vector<string> -Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package, bool final) +Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package) { vector<string> params; @@ -119,6 +119,23 @@ Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package, boo StringList metaData = (*q)->getMetaData(); string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package, metaData, true, (*q)->optional()); + params.push_back(typeString + ' ' + fixKwd((*q)->name())); + } + + return params; +} + +vector<string> +Slice::JavaVisitor::getParamsProxy(const OperationPtr& op, const string& package, bool final) +{ + vector<string> params; + + ParamDeclList paramList = op->parameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + StringList metaData = (*q)->getMetaData(); + string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package, + metaData, true, useOptionalMapping(*q)); if(final) { typeString = "final " + typeString; @@ -130,7 +147,7 @@ Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package, boo } vector<string> -Slice::JavaVisitor::getInOutParams(const OperationPtr& op, const string& package, ParamDir paramType) +Slice::JavaVisitor::getInOutParams(const OperationPtr& op, const string& package, ParamDir paramType, bool proxy) { vector<string> params; @@ -139,9 +156,14 @@ Slice::JavaVisitor::getInOutParams(const OperationPtr& op, const string& package { if((*q)->isOutParam() == (paramType == OutParam)) { + bool optional = (*q)->optional(); + if(optional && proxy) + { + optional = useOptionalMapping(*q); + } StringList metaData = (*q)->getMetaData(); string typeString = typeToString((*q)->type(), paramType == InParam ? TypeModeIn : TypeModeOut, package, - metaData, true, (*q)->optional()); + metaData, true, optional); params.push_back(typeString + ' ' + fixKwd((*q)->name())); } } @@ -152,7 +174,7 @@ Slice::JavaVisitor::getInOutParams(const OperationPtr& op, const string& package vector<string> Slice::JavaVisitor::getParamsAsync(const OperationPtr& op, const string& package, bool amd) { - vector<string> params = getInOutParams(op, package, InParam); + vector<string> params = getInOutParams(op, package, InParam, !amd); string name = op->name(); ContainerPtr container = op->container(); @@ -358,9 +380,18 @@ Slice::JavaVisitor::writeMarshalUnmarshalParams(Output& out, const string& packa checkReturnType = false; } - writeMarshalUnmarshalCode(out, package, (*pli)->type(), - (*pli)->isOutParam() ? OptionalOutParam : OptionalInParam, (*pli)->tag(), - fixKwd((*pli)->name()), marshal, iter, false, (*pli)->getMetaData()); + OptionalMode mode; + if((*pli)->isOutParam()) + { + mode = OptionalOutParam; + } + else + { + mode = useOptionalMapping(*pli) ? OptionalInParamOpt : OptionalInParamReq; + } + + writeMarshalUnmarshalCode(out, package, (*pli)->type(), mode, (*pli)->tag(), fixKwd((*pli)->name()), marshal, + iter, false, (*pli)->getMetaData()); } if(checkReturnType) @@ -2793,11 +2824,11 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) out << ';'; // - // Generate asynchronous API for local operations marked with XXX metadata. + // Generate asynchronous API for local operations marked with "async" metadata. // if(p->hasMetaData("async") || op->hasMetaData("async")) { - vector<string> inParams = getInOutParams(op, package, InParam); + vector<string> inParams = getInOutParams(op, package, InParam, true); out << sp; writeDocCommentAMI(out, op, InParam); @@ -2827,7 +2858,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) string cb = "Callback_" + name + "_" + opname + " __cb"; out << "Ice.AsyncResult begin_" << opname << spar << inParams << cb << epar << ';'; - vector<string> outParams = getInOutParams(op, package, OutParam); + vector<string> outParams = getInOutParams(op, package, OutParam, true); out << sp; writeDocCommentAMI(out, op, OutParam); out << nl; @@ -4384,7 +4415,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) TypePtr ret = op->returnType(); string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, op->returnIsOptional()); - vector<string> params = getParams(op, package); + vector<string> params = getParamsProxy(op, package); vector<string> args = getArgs(op); ExceptionList throws = op->throws(); @@ -4478,7 +4509,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) // // Write the asynchronous begin/end methods. // - vector<string> inParams = getInOutParams(op, package, InParam); + vector<string> inParams = getInOutParams(op, package, InParam, true); vector<string> inArgs = getInOutArgs(op, InParam); string callbackParam = "Ice.Callback __cb"; int iter; @@ -4600,7 +4631,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) out << nl << "return __result;"; out << eb; - vector<string> outParams = getInOutParams(op, package, OutParam); + vector<string> outParams = getInOutParams(op, package, OutParam, true); // // End method @@ -5316,7 +5347,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) TypePtr ret = p->returnType(); string retS = typeToString(ret, TypeModeReturn, package, p->getMetaData(), true, p->returnIsOptional()); - vector<string> params = getParams(p, package); + vector<string> params = getParamsProxy(p, package); ExceptionList throws = p->throws(); throws.sort(); throws.unique(); @@ -5349,7 +5380,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) // // Start with the type-unsafe begin methods. // - vector<string> inParams = getInOutParams(p, package, InParam); + vector<string> inParams = getInOutParams(p, package, InParam, true); string callbackParam = "Ice.Callback __cb"; string callbackDoc = "@param __cb The asynchronous callback object."; @@ -5394,7 +5425,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam << typeSafeCallbackParam << epar << ';'; - vector<string> outParams = getInOutParams(p, package, OutParam); + vector<string> outParams = getInOutParams(p, package, OutParam, true); out << sp; writeDocCommentAMI(out, p, OutParam); @@ -5477,7 +5508,7 @@ Slice::Gen::DelegateVisitor::visitClassDefStart(const ClassDefPtr& p) TypePtr ret = op->returnType(); string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, op->returnIsOptional()); - vector<string> params = getParams(op, package); + vector<string> params = getParamsProxy(op, package); ExceptionList throws = op->throws(); throws.sort(); @@ -5565,7 +5596,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) throws.sort(Slice::DerivedToBaseCompare()); #endif - vector<string> params = getParams(op, package); + vector<string> params = getParamsProxy(op, package); out << sp; out << nl << "public " << retS << nl << opName << spar << params << contextParam << epar; @@ -5730,8 +5761,26 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) throws.sort(Slice::DerivedToBaseCompare()); #endif - vector<string> params = getParams(op, package, true); - vector<string> args = getArgs(op); + vector<string> params = getParamsProxy(op, package, true); + + // + // Collect the arguments that will be passed to the servant. + // + // Note that for optional in parameters, we may have to wrap a value + // in an Optional object to be compatible with the servant's signature. + // + vector<string> args; + ParamDeclList paramList = op->parameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + string param = fixKwd((*q)->name()); + if(!(*q)->isOutParam() && (*q)->optional() && !useOptionalMapping(*q)) + { + string typeString = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData(), true, true); + param = "new " + typeString + "(" + param + ")"; + } + args.push_back(param); + } out << sp; if(!deprecateReason.empty()) diff --git a/cpp/src/slice2java/Gen.h b/cpp/src/slice2java/Gen.h index 001bca3c89e..5cfeae3714a 100644 --- a/cpp/src/slice2java/Gen.h +++ b/cpp/src/slice2java/Gen.h @@ -32,8 +32,9 @@ protected: // // Compose the parameter lists for an operation. // - std::vector<std::string> getParams(const OperationPtr&, const std::string&, bool = false); - std::vector<std::string> getInOutParams(const OperationPtr&, const std::string&, ParamDir); + std::vector<std::string> getParams(const OperationPtr&, const std::string&); + std::vector<std::string> getParamsProxy(const OperationPtr&, const std::string&, bool = false); + std::vector<std::string> getInOutParams(const OperationPtr&, const std::string&, ParamDir, bool); std::vector<std::string> getParamsAsync(const OperationPtr&, const std::string&, bool); std::vector<std::string> getParamsAsyncCB(const OperationPtr&, const std::string&); |