diff options
Diffstat (limited to 'cpp/src/slice2java/Gen.cpp')
-rw-r--r-- | cpp/src/slice2java/Gen.cpp | 2307 |
1 files changed, 1473 insertions, 834 deletions
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp index b9125e22729..1327e24fb14 100644 --- a/cpp/src/slice2java/Gen.cpp +++ b/cpp/src/slice2java/Gen.cpp @@ -24,7 +24,7 @@ using namespace Slice; // // Don't use "using namespace IceUtil", or VC++ 6.0 complains -// about ambigious symbols for constructs like +// about ambiguous symbols for constructs like // "IceUtil::constMemFun(&Slice::Exception::isLocal)". // using IceUtilInternal::Output; @@ -66,6 +66,24 @@ sliceModeToIceMode(Operation::Mode opMode) } static string +formatTypeToString(FormatType type) +{ + switch(type) + { + case DefaultFormat: + return "Ice.FormatType.DefaultFormat"; + case CompactFormat: + return "Ice.FormatType.CompactFormat"; + case SlicedFormat: + return "Ice.FormatType.SlicedFormat"; + default: + assert(false); + } + + return "???"; +} + +static string getDeprecateReason(const ContainedPtr& p1, const ContainedPtr& p2, const string& type) { string deprecateMetadata, deprecateReason; @@ -91,16 +109,52 @@ 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, bool local) { vector<string> params; + const bool optionalMapping = useOptionalMapping(op); + ParamDeclList paramList = op->parameters(); for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) { StringList metaData = (*q)->getMetaData(); + bool optional = (*q)->optional(); + if(optional && (local || (*q)->isOutParam())) + { + optional = optionalMapping; + } string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package, - metaData); + metaData, true, 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; + + const bool optionalMapping = useOptionalMapping(op); + + ParamDeclList paramList = op->parameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + bool optional; + if((*q)->optional()) + { + optional = (*q)->isOutParam() ? true : optionalMapping; + } + else + { + optional = false; + } + + StringList metaData = (*q)->getMetaData(); + string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package, + metaData, true, optional); if(final) { typeString = "final " + typeString; @@ -112,18 +166,36 @@ 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; + const bool optionalMapping = useOptionalMapping(op); + ParamDeclList paramList = op->parameters(); for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) { if((*q)->isOutParam() == (paramType == OutParam)) { + bool optional; + if((*q)->optional()) + { + if(proxy) + { + optional = paramType == InParam ? optionalMapping : true; + } + else + { + optional = true; + } + } + else + { + optional = false; + } StringList metaData = (*q)->getMetaData(); string typeString = typeToString((*q)->type(), paramType == InParam ? TypeModeIn : TypeModeOut, package, - metaData); + metaData, true, optional); params.push_back(typeString + ' ' + fixKwd((*q)->name())); } } @@ -134,7 +206,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(); @@ -146,14 +218,17 @@ Slice::JavaVisitor::getParamsAsync(const OperationPtr& op, const string& package } vector<string> -Slice::JavaVisitor::getParamsAsyncCB(const OperationPtr& op, const string& package) +Slice::JavaVisitor::getParamsAsyncCB(const OperationPtr& op, const string& package, bool amd) { vector<string> params; + const bool optionalMapping = amd ? useOptionalMapping(op) : true; + TypePtr ret = op->returnType(); if(ret) { - string retS = typeToString(ret, TypeModeIn, package, op->getMetaData()); + string retS = typeToString(ret, TypeModeIn, package, op->getMetaData(), true, + optionalMapping && op->returnIsOptional()); params.push_back(retS + " __ret"); } @@ -162,7 +237,8 @@ Slice::JavaVisitor::getParamsAsyncCB(const OperationPtr& op, const string& packa { if((*q)->isOutParam()) { - string typeString = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData()); + string typeString = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData(), true, + optionalMapping && (*q)->optional()); params.push_back(typeString + ' ' + fixKwd((*q)->name())); } } @@ -249,6 +325,113 @@ Slice::JavaVisitor::getArgsAsyncCB(const OperationPtr& op) } void +Slice::JavaVisitor::writeMarshalUnmarshalParams(Output& out, const string& package, const ParamDeclList& params, + const OperationPtr& op, int& iter, bool marshal, bool optionalMapping, + bool dispatch) +{ + ParamDeclList optionals; + ParamDeclList::const_iterator pli; + + for(pli = params.begin(); pli != params.end(); ++pli) + { + if((*pli)->optional()) + { + optionals.push_back(*pli); + } + else + { + string paramName = fixKwd((*pli)->name()); + bool holder = marshal == dispatch; + string patchParams; + if(!marshal) + { + patchParams = paramName; + } + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalNone, false, 0, paramName, marshal, + iter, holder, (*pli)->getMetaData(), patchParams); + } + } + + TypePtr ret; + bool returnsObject = false; + + if(op && op->returnType()) + { + ret = op->returnType(); + BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(ret); + returnsObject = (builtin && builtin->kind() == Builtin::KindObject) || cl; + const bool optional = optionalMapping && op->returnIsOptional(); + + string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, optional); + bool holder = false; + + if(!marshal) + { + if(optional) + { + out << nl << retS << " __ret = new " << retS << "();"; + } + else if(returnsObject) + { + out << nl << retS << "Holder __ret = new " << retS << "Holder();"; + holder = true; + } + else + { + out << nl << retS << " __ret;"; + } + } + + if(!op->returnIsOptional()) + { + writeMarshalUnmarshalCode(out, package, ret, OptionalNone, false, 0, "__ret", marshal, iter, holder, + op->getMetaData()); + } + } + + // + // Sort optional parameters by tag. + // + class SortFn + { + public: + static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + optionals.sort(SortFn::compare); + + // + // Handle optional parameters. + // + bool checkReturnType = op && op->returnIsOptional(); + + for(pli = optionals.begin(); pli != optionals.end(); ++pli) + { + if(checkReturnType && op->returnTag() < (*pli)->tag()) + { + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, optionalMapping, op->returnTag(), + "__ret", marshal, iter, false, op->getMetaData()); + checkReturnType = false; + } + + const bool holder = dispatch && (*pli)->isOutParam() && !optionalMapping; + + writeMarshalUnmarshalCode(out, package, (*pli)->type(), + (*pli)->isOutParam() ? OptionalOutParam : OptionalInParam, optionalMapping, + (*pli)->tag(), fixKwd((*pli)->name()), marshal, iter, holder, (*pli)->getMetaData()); + } + + if(checkReturnType) + { + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, optionalMapping, op->returnTag(), "__ret", + marshal, iter, false, op->getMetaData()); + } +} + +void Slice::JavaVisitor::writeThrowsClause(const string& package, const ExceptionList& throws) { Output& out = output(); @@ -397,12 +580,253 @@ Slice::JavaVisitor::writeHashCode(Output& out, const TypePtr& type, const string } void +Slice::JavaVisitor::writeMarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, int& iter) +{ + if(!member->optional()) + { + writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, fixKwd(member->name()), + true, iter, false, member->getMetaData()); + } + else + { + out << nl << "if(__has_" << member->name() << " && __os.writeOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + out << sb; + writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), true, + iter, false, member->getMetaData()); + out << eb; + } +} + +void +Slice::JavaVisitor::writeUnmarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, + int& iter, bool needPatcher, int& patchIter) +{ + string patchParams; + if(needPatcher) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + { + ostringstream ostr; + ostr << "new Patcher(" << patchIter++ << ')'; + patchParams = ostr.str(); + } + } + + if(!member->optional()) + { + writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, fixKwd(member->name()), false, + iter, false, member->getMetaData(), patchParams); + } + else + { + out << nl << "if(__has_" << member->name() << " = __is.readOpt(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + out << sb; + writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), false, + iter, false, member->getMetaData(), patchParams); + out << eb; + } +} + +void +Slice::JavaVisitor::writeStreamMarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, + int& iter) +{ + if(!member->optional()) + { + writeStreamMarshalUnmarshalCode(out, package, member->type(), OptionalNone, 0, fixKwd(member->name()), true, + iter, false, member->getMetaData()); + } + else + { + out << nl << "if(__has_" << member->name() << " && __outS.writeOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + out << sb; + writeStreamMarshalUnmarshalCode(out, package, member->type(), OptionalMember, member->tag(), + fixKwd(member->name()), true, iter, false, member->getMetaData()); + out << eb; + } +} + +void +Slice::JavaVisitor::writeStreamUnmarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, + int& iter, bool needPatcher, int& patchIter) +{ + string patchParams; + if(needPatcher) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + { + ostringstream ostr; + ostr << "new Patcher(" << patchIter++ << ')'; + patchParams = ostr.str(); + } + } + + if(!member->optional()) + { + writeStreamMarshalUnmarshalCode(out, package, member->type(), OptionalNone, 0, fixKwd(member->name()), false, + iter, false, member->getMetaData(), patchParams); + } + else + { + out << nl << "if(__has_" << member->name() << " = __inS.readOptional(" << member->tag() << ", " + << getOptionalType(member->type()) << "))"; + out << sb; + writeStreamMarshalUnmarshalCode(out, package, member->type(), OptionalMember, member->tag(), + fixKwd(member->name()), false, iter, false, member->getMetaData(), patchParams); + out << eb; + } +} + +void +Slice::JavaVisitor::writePatcher(Output& out, const string& package, const DataMemberList& classMembers, bool stream) +{ + out << sp << nl << "private class Patcher implements IceInternal.Patcher"; + if(stream) + { + out << ", Ice.ReadObjectCallback"; + } + out << sb; + if(classMembers.size() > 1) + { + out << sp << nl << "Patcher(int member)"; + out << sb; + out << nl << "__member = member;"; + out << eb; + } + + out << sp << nl << "public void" << nl << "patch(Ice.Object v)"; + out << sb; + if(classMembers.size() > 1) + { + out << nl << "switch(__member)"; + out << sb; + } + int memberCount = 0; + for(DataMemberList::const_iterator d = classMembers.begin(); d != classMembers.end(); ++d) + { + BuiltinPtr b = BuiltinPtr::dynamicCast((*d)->type()); + if(b) + { + assert(b->kind() == Builtin::KindObject); + } + + if(classMembers.size() > 1) + { + out.dec(); + out << nl << "case " << memberCount << ":"; + out.inc(); + if(b) + { + out << nl << "__typeId = Ice.ObjectImpl.ice_staticId();"; + } + else + { + out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";"; + } + } + + if((*d)->optional()) + { + string capName = (*d)->name(); + capName[0] = toupper(static_cast<unsigned char>(capName[0])); + + if(b) + { + out << nl << "set" << capName << "(v);"; + } + else + { + string memberType = typeToString((*d)->type(), TypeModeMember, package); + out << nl << "if(v == null || v instanceof " << memberType << ")"; + out << sb; + out << nl << "set" << capName << "((" << memberType << ")v);"; + out << eb; + out << nl << "else"; + out << sb; + out << nl << "IceInternal.Ex.throwUOE(type(), v);"; + out << eb; + } + } + else + { + string memberName = fixKwd((*d)->name()); + if(b) + { + out << nl << memberName << " = v;"; + } + else + { + string memberType = typeToString((*d)->type(), TypeModeMember, package); + out << nl << "if(v == null || v instanceof " << memberType << ")"; + out << sb; + out << nl << memberName << " = (" << memberType << ")v;"; + out << eb; + out << nl << "else"; + out << sb; + out << nl << "IceInternal.Ex.throwUOE(type(), v);"; + out << eb; + } + } + + if(classMembers.size() > 1) + { + out << nl << "break;"; + } + + memberCount++; + } + if(classMembers.size() > 1) + { + out << eb; + } + out << eb; + + out << sp << nl << "public String" << nl << "type()"; + out << sb; + if(classMembers.size() > 1) + { + out << nl << "return __typeId;"; + } + else + { + out << nl << "return \"" << (*classMembers.begin())->type()->typeId() << "\";"; + } + out << eb; + + if(stream) + { + out << sp << nl << "public void" << nl << "invoke(Ice.Object v)"; + out << sb; + out << nl << "patch(v);"; + out << eb; + } + + if(classMembers.size() > 1) + { + out << sp << nl << "private int __member;"; + out << nl << "private String __typeId;"; + } + + out << eb; +} + +void Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& p, bool stream) { string name = fixKwd(p->name()); string package = getPackage(p); string scoped = p->scoped(); ClassList bases = p->bases(); + ClassDefPtr base; + if(!bases.empty() && !bases.front()->isInterface()) + { + base = bases.front(); + } ClassList allBases = p->allBases(); StringList ids; @@ -486,7 +910,8 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& string deprecateReason = getDeprecateReason(op, cl, "operation"); - bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); + const bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); + const bool optionalMapping = useOptionalMapping(op); vector<string> params; vector<string> args; @@ -567,7 +992,9 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& { writeDocComment(out, op, deprecateReason); } - out << nl << "public final " << typeToString(ret, TypeModeReturn, package, op->getMetaData()) + out << nl << "public final " + << typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, + optionalMapping && op->returnIsOptional()) << nl << opName << spar << params << epar; if(op->hasMetaData("UserException")) { @@ -614,7 +1041,9 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& << " __obj, IceInternal.Incoming __inS, Ice.Current __current)"; out << sb; - bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); + const bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); + const bool optionalMapping = useOptionalMapping(op); + if(!amd) { TypePtr ret = op->returnType(); @@ -660,53 +1089,49 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& // // Unmarshal 'in' parameters. // - out << nl << "IceInternal.BasicStream __is = __inS.is();"; - out << nl << "__is.startReadEncaps();"; - iter = 0; + out << nl << "IceInternal.BasicStream __is = __inS.startReadParams();"; for(pli = inParams.begin(); pli != inParams.end(); ++pli) { - StringList metaData = (*pli)->getMetaData(); TypePtr paramType = (*pli)->type(); string paramName = fixKwd((*pli)->name()); - string typeS = typeToString(paramType, TypeModeIn, package, metaData); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + string typeS = typeToString(paramType, TypeModeIn, package, (*pli)->getMetaData(), + true, (*pli)->optional()); + if((*pli)->optional()) { - out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();"; - writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, true, - metaData, string()); + out << nl << typeS << ' ' << paramName << " = new " << typeS << "();"; } else { - out << nl << typeS << ' ' << paramName << ';'; - writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, false, metaData); + BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + { + out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();"; + } + else + { + out << nl << typeS << ' ' << paramName << ';'; + } } } - if(op->sendsClasses()) - { - out << nl << "__is.readPendingObjects();"; - } - out << nl << "__is.endReadEncaps();"; + iter = 0; + writeMarshalUnmarshalParams(out, package, inParams, 0, iter, false, true, true); + out << nl << "__inS.endReadParams();"; } else { - out << nl << "__inS.is().skipEmptyEncaps();"; + out << nl << "__inS.readEmptyParams();"; } // - // Create holders for 'out' parameters. + // Declare 'out' parameters. // for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string typeS = typeToString((*pli)->type(), TypeModeOut, package, (*pli)->getMetaData()); + string typeS = typeToString((*pli)->type(), TypeModeOut, package, (*pli)->getMetaData(), true, + optionalMapping && (*pli)->optional()); out << nl << typeS << ' ' << fixKwd((*pli)->name()) << " = new " << typeS << "();"; } - if(!outParams.empty() || ret || !throws.empty()) - { - out << nl << "IceInternal.BasicStream __os = __inS.os();"; - } - // // Call on the servant. // @@ -718,7 +1143,8 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& out << nl; if(ret) { - string retS = typeToString(ret, TypeModeReturn, package, opMetaData); + string retS = typeToString(ret, TypeModeReturn, package, opMetaData, true, + optionalMapping && op->returnIsOptional()); out << retS << " __ret = "; } out << "__obj." << fixKwd(opName) << '('; @@ -726,10 +1152,13 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& { TypePtr paramType = (*pli)->type(); out << fixKwd((*pli)->name()); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + if(!(*pli)->optional()) { - out << ".value"; + BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + { + out << ".value"; + } } out << ", "; } @@ -742,18 +1171,20 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& // // Marshal 'out' parameters and return value. // - for(pli = outParams.begin(); pli != outParams.end(); ++pli) + FormatType format = op->format(); + if(!outParams.empty() || ret) { - writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), true, iter, true, - (*pli)->getMetaData()); - } - if(ret) - { - writeMarshalUnmarshalCode(out, package, ret, "__ret", true, iter, false, opMetaData); + out << nl << "IceInternal.BasicStream __os = __inS.__startWriteParams();"; + if(op->returnsClasses() && format != DefaultFormat) + { + out << nl << "__os.format(" << formatTypeToString(format) << ");"; + } + writeMarshalUnmarshalParams(out, package, outParams, op, iter, true, optionalMapping, true); + out << nl << "__inS.__endWriteParams(true);"; } - if(op->returnsClasses()) + else { - out << nl << "__os.writePendingObjects();"; + out << nl << "__inS.__writeEmptyParams();"; } out << nl << "return Ice.DispatchStatus.DispatchOK;"; @@ -769,7 +1200,13 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& string exS = getAbsolute(*t, package); out << nl << "catch(" << exS << " ex)"; out << sb; + out << nl << "IceInternal.BasicStream __os = __inS.__startWriteParams();"; + if(format != DefaultFormat) + { + out << nl << "__os.format(" << formatTypeToString(format) << ");"; + } out << nl << "__os.writeUserException(ex);"; + out << nl << "__inS.__endWriteParams(false);"; out << nl << "return Ice.DispatchStatus.DispatchUserException;"; out << eb; } @@ -799,37 +1236,37 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& // // Unmarshal 'in' parameters. // - out << nl << "IceInternal.BasicStream __is = __inS.is();"; - out << nl << "__is.startReadEncaps();"; + out << nl << "IceInternal.BasicStream __is = __inS.startReadParams();"; iter = 0; for(pli = inParams.begin(); pli != inParams.end(); ++pli) { - StringList metaData = (*pli)->getMetaData(); TypePtr paramType = (*pli)->type(); string paramName = fixKwd((*pli)->name()); - string typeS = typeToString(paramType, TypeModeIn, package, metaData); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + string typeS = typeToString(paramType, TypeModeIn, package, (*pli)->getMetaData(), + true, (*pli)->optional()); + if((*pli)->optional()) { - out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();"; - writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, true, metaData, - string()); + out << nl << typeS << ' ' << paramName << " = new " << typeS << "();"; } else { - out << nl << typeS << ' ' << paramName << ';'; - writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, false, metaData); + BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + { + out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();"; + } + else + { + out << nl << typeS << ' ' << paramName << ';'; + } } } - if(op->sendsClasses()) - { - out << nl << "__is.readPendingObjects();"; - } - out << nl << "__is.endReadEncaps();"; + writeMarshalUnmarshalParams(out, package, inParams, 0, iter, false, true, true); + out << nl << "__inS.endReadParams();"; } else { - out << nl << "__inS.is().skipEmptyEncaps();"; + out << nl << "__inS.readEmptyParams();"; } // @@ -845,10 +1282,13 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& { TypePtr paramType = (*pli)->type(); out << fixKwd((*pli)->name()); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + if(!(*pli)->optional()) { - out << ".value"; + BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + { + out << ".value"; + } } out << ", "; } @@ -982,7 +1422,6 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& out << nl << "throw new Ice.OperationNotExistException(__current.id, __current.facet, __current.operation);"; out << eb; - // // Check if we need to generate ice_operationAttributes() // @@ -1036,180 +1475,165 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& int iter; DataMemberList members = p->dataMembers(); + DataMemberList optionalMembers = p->orderedOptionalDataMembers(); + bool basePreserved = p->inheritsMetaData("preserve-slice"); + bool preserved = basePreserved || p->hasMetaData("preserve-slice"); DataMemberList::const_iterator d; out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)"; out << sb; - out << nl << "__os.writeTypeId(ice_staticId());"; - out << nl << "__os.startWriteSlice();"; + if(preserved) + { + out << nl << "__os.startWriteObject(__slicedData);"; + } + else + { + out << nl << "__os.startWriteObject(null);"; + } + out << nl << "__writeImpl(__os);"; + out << nl << "__os.endWriteObject();"; + out << eb; + + out << sp << nl << "public void" << nl << "__writeImpl(IceInternal.BasicStream __os)"; + out << sb; + out << nl << "__os.startWriteSlice(ice_staticId(), " << (!base ? "true" : "false") << ");"; iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData); + if(!(*d)->optional()) + { + writeMarshalDataMember(out, package, *d, iter); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeMarshalDataMember(out, package, *d, iter); } out << nl << "__os.endWriteSlice();"; - out << nl << "super.__write(__os);"; + if(base) + { + out << nl << "super.__writeImpl(__os);"; + } + out << eb; + + out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is)"; + out << sb; + out << nl << "__is.startReadObject();"; + out << nl << "__readImpl(__is);"; + if(preserved) + { + out << nl << "__slicedData = __is.endReadObject(true);"; + } + else + { + out << nl << "__is.endReadObject(false);"; + } out << eb; DataMemberList allClassMembers = p->allClassDataMembers(); if(allClassMembers.size() != 0) { - out << sp << nl << "private class Patcher implements IceInternal.Patcher"; - if(stream) - { - out << ", Ice.ReadObjectCallback"; - } - out << sb; - if(allClassMembers.size() > 1) - { - out << sp << nl << "Patcher(int member)"; - out << sb; - out << nl << "__member = member;"; - out << eb; - } - - out << sp << nl << "public void" << nl << "patch(Ice.Object v)"; - out << sb; - if(allClassMembers.size() > 1) - { - out << nl << "switch(__member)"; - out << sb; - } - int memberCount = 0; - for(d = allClassMembers.begin(); d != allClassMembers.end(); ++d) - { - if(allClassMembers.size() > 1) - { - out.dec(); - out << nl << "case " << memberCount << ":"; - out.inc(); - } - if(allClassMembers.size() > 1) - { - out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";"; - } - string memberName = fixKwd((*d)->name()); - string memberType = typeToString((*d)->type(), TypeModeMember, package); - out << nl << "if(v == null || v instanceof " << memberType << ")"; - out << sb; - out << nl << memberName << " = (" << memberType << ")v;"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; - out << eb; - if(allClassMembers.size() > 1) - { - out << nl << "break;"; - } - memberCount++; - } - if(allClassMembers.size() > 1) - { - out << eb; - } - out << eb; - - out << sp << nl << "public String" << nl << "type()"; - out << sb; - if(allClassMembers.size() > 1) - { - out << nl << "return __typeId;"; - } - else - { - out << nl << "return \"" << (*allClassMembers.begin())->type()->typeId() << "\";"; - } - out << eb; - - if(stream) - { - out << sp << nl << "public void" << nl << "invoke(Ice.Object v)"; - out << sb; - out << nl << "patch(v);"; - out << eb; - } - - if(allClassMembers.size() > 1) - { - out << sp << nl << "private int __member;"; - out << nl << "private String __typeId;"; - } - out << eb; + writePatcher(out, package, allClassMembers, stream); } - out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is, boolean __rid)"; + out << sp << nl << "public void" << nl << "__readImpl(IceInternal.BasicStream __is)"; out << sb; - out << nl << "if(__rid)"; - out << sb; - out << nl << "__is.readTypeId();"; - out << eb; out << nl << "__is.startReadSlice();"; - iter = 0; DataMemberList classMembers = p->classDataMembers(); - size_t classMemberCount = allClassMembers.size() - classMembers.size(); + int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); + const bool needCustomPatcher = classMembers.size() > 1 || allClassMembers.size() > 1; + iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - ostringstream patchParams; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) + if(!(*d)->optional()) { - if(classMembers.size() > 1 || allClassMembers.size() > 1) - { - patchParams << "new Patcher(" << classMemberCount++ << ')'; - } + writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } - writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData, - patchParams.str()); + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } out << nl << "__is.endReadSlice();"; - out << nl << "super.__read(__is, true);"; + if(base) + { + out << nl << "super.__readImpl(__is);"; + } out << eb; if(stream) { out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __outS)"; out << sb; - out << nl << "__outS.writeTypeId(ice_staticId());"; - out << nl << "__outS.startSlice();"; + if(preserved) + { + out << nl << "__outS.startObject(__slicedData);"; + } + else + { + out << nl << "__outS.startObject(null);"; + } + out << nl << "__writeImpl(__outS);"; + out << nl << "__outS.endObject();"; + out << eb; + + out << sp << nl << "public void" << nl << "__writeImpl(Ice.OutputStream __outS)"; + out << sb; + out << nl << "__outS.startSlice(ice_staticId(), " << (!base ? "true" : "false") << ");"; iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, - metaData); + if(!(*d)->optional()) + { + writeStreamMarshalDataMember(out, package, *d, iter); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeStreamMarshalDataMember(out, package, *d, iter); } out << nl << "__outS.endSlice();"; - out << nl << "super.__write(__outS);"; + if(base) + { + out << nl << "super.__writeImpl(__outS);"; + } out << eb; - out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS, boolean __rid)"; - out << sb; - out << nl << "if(__rid)"; + out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS)"; out << sb; - out << nl << "__inS.readTypeId();"; + out << nl << "__inS.startObject();"; + out << nl << "__readImpl(__inS);"; + if(preserved) + { + out << nl << "__slicedData = __inS.endObject(true);"; + } + else + { + out << nl << "__inS.endObject(false);"; + } out << eb; + + out << sp << nl << "public void" << nl << "__readImpl(Ice.InputStream __inS)"; + out << sb; out << nl << "__inS.startSlice();"; iter = 0; + classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - ostringstream patchParams; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) + if(!(*d)->optional()) { - if(classMembers.size() > 1 || allClassMembers.size() > 1) - { - patchParams << "new Patcher(" << classMemberCount++ << ')'; - } + writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } - writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, - metaData, patchParams.str()); + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } out << nl << "__inS.endSlice();"; - out << nl << "super.__read(__inS, true);"; + if(base) + { + out << nl << "super.__readImpl(__inS);"; + } out << eb; } else @@ -1225,13 +1649,18 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& out << nl << "throw ex;"; out << eb; - out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS, boolean __rid)"; + out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS)"; out << sb; out << nl << "Ice.MarshalException ex = new Ice.MarshalException();"; out << nl << "ex.reason = \"type " << scoped.substr(2) << " was not generated with stream support\";"; out << nl << "throw ex;"; out << eb; } + + if(preserved && !basePreserved) + { + out << sp << nl << "protected Ice.SlicedData __slicedData;"; + } } void @@ -1374,10 +1803,20 @@ Slice::JavaVisitor::writeDataMemberInitializers(Output& out, const DataMemberLis { if((*p)->defaultValueType()) { - string memberName = fixKwd((*p)->name()); - out << nl << memberName << " = "; - writeConstantValue(out, (*p)->type(), (*p)->defaultValueType(), (*p)->defaultValue(), package); - out << ';'; + if((*p)->optional()) + { + string capName = (*p)->name(); + capName[0] = toupper(static_cast<unsigned char>(capName[0])); + out << nl << "set" << capName << '('; + writeConstantValue(out, (*p)->type(), (*p)->defaultValueType(), (*p)->defaultValue(), package); + out << ");"; + } + else + { + out << nl << fixKwd((*p)->name()) << " = "; + writeConstantValue(out, (*p)->type(), (*p)->defaultValueType(), (*p)->defaultValue(), package); + out << ';'; + } } } } @@ -1960,7 +2399,8 @@ Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent) TypePtr ret; vector<string> params; - bool amd = !p->isLocal() && (cl->hasMetaData("amd") || op->hasMetaData("amd")); + const bool amd = !p->isLocal() && (cl->hasMetaData("amd") || op->hasMetaData("amd")); + const bool optionalMapping = useOptionalMapping(op); if(amd) { @@ -1972,7 +2412,8 @@ Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent) ret = op->returnType(); } - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData()); + string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, + optionalMapping && op->returnIsOptional()); ExceptionList throws = op->throws(); throws.sort(); throws.unique(); @@ -2131,7 +2572,9 @@ Slice::Gen::TieVisitor::visitClassDefStart(const ClassDefPtr& p) { ContainerPtr container = (*r)->container(); ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - bool hasAMD = cl->hasMetaData("amd") || (*r)->hasMetaData("amd"); + const bool hasAMD = cl->hasMetaData("amd") || (*r)->hasMetaData("amd"); + const bool optionalMapping = useOptionalMapping(*r); + #if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550) // // Work around for Sun CC 5.5 bug #4853566 @@ -2148,8 +2591,10 @@ Slice::Gen::TieVisitor::visitClassDefStart(const ClassDefPtr& p) #else string opName = hasAMD ? (*r)->name() + "_async" : fixKwd((*r)->name()); #endif + TypePtr ret = (*r)->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, (*r)->getMetaData()); + string retS = typeToString(ret, TypeModeReturn, package, (*r)->getMetaData(), true, + optionalMapping && (*r)->returnIsOptional()); vector<string> params; vector<string> args; @@ -2383,7 +2828,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) // // For local classes and interfaces, we don't use the OperationsNC interface. - // Instead, we generated the operation signatures directly into the class + // Instead, we generate the operation signatures directly into the class // or interface. // if(p->isLocal()) @@ -2396,12 +2841,13 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) ContainerPtr container = op->container(); ClassDefPtr cl = ClassDefPtr::dynamicCast(container); string opname = op->name(); + const bool optionalMapping = useOptionalMapping(op); - TypePtr ret; - vector<string> params = getParams(op, package); - ret = op->returnType(); + TypePtr ret = op->returnType(); + vector<string> params = getParams(op, package, true); - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData()); + string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, + optionalMapping && op->returnIsOptional()); ExceptionList throws = op->throws(); throws.sort(); throws.unique(); @@ -2427,11 +2873,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); @@ -2461,7 +2907,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; @@ -2476,8 +2922,23 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) if(!p->isInterface() && !allDataMembers.empty()) { + bool hasOptionalMembers = false; + bool hasRequiredMembers = false; + + for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d) + { + if((*d)->optional()) + { + hasOptionalMembers = true; + } + else + { + hasRequiredMembers = true; + } + } + // - // Constructors. + // Default constructor. // out << sp; out << nl << "public " << fixKwd(name) << "()"; @@ -2494,6 +2955,71 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) // if(allDataMembers.size() < 255) { + DataMemberList baseDataMembers; + if(baseClass) + { + baseDataMembers = baseClass->allDataMembers(); + } + + if(hasRequiredMembers && hasOptionalMembers) + { + // + // Generate a constructor accepting parameters for just the required members. + // + out << sp << nl << "public " << fixKwd(name) << spar; + vector<string> paramDecl; + for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + string memberName = fixKwd((*d)->name()); + string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData()); + paramDecl.push_back(memberType + " " + memberName); + } + } + out << paramDecl << epar; + out << sb; + if(!baseDataMembers.empty()) + { + bool hasBaseRequired = false; + for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + hasBaseRequired = true; + break; + } + } + if(hasBaseRequired) + { + out << nl << "super" << spar; + vector<string> baseParamNames; + for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + baseParamNames.push_back(fixKwd((*d)->name())); + } + } + out << baseParamNames << epar << ';'; + } + } + + for(d = members.begin(); d != members.end(); ++d) + { + if(!(*d)->optional()) + { + string paramName = fixKwd((*d)->name()); + out << nl << "this." << paramName << " = " << paramName << ';'; + } + } + writeDataMemberInitializers(out, p->orderedOptionalDataMembers(), package); + out << eb; + } + + // + // Generate a constructor accepting parameters for all members. + // out << sp << nl << "public " << fixKwd(name) << spar; vector<string> paramDecl; for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d) @@ -2508,21 +3034,25 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) { out << nl << "super" << spar; vector<string> baseParamNames; - DataMemberList baseDataMembers = baseClass->allDataMembers(); for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d) { baseParamNames.push_back(fixKwd((*d)->name())); } out << baseParamNames << epar << ';'; } - vector<string> paramNames; for(d = members.begin(); d != members.end(); ++d) { - paramNames.push_back(fixKwd((*d)->name())); - } - for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) - { - out << nl << "this." << *i << " = " << *i << ';'; + string paramName = fixKwd((*d)->name()); + if((*d)->optional()) + { + string capName = paramName; + capName[0] = toupper(static_cast<unsigned char>(capName[0])); + out << nl << "set" << capName << '(' << paramName << ");"; + } + else + { + out << nl << "this." << paramName << " = " << paramName << ';'; + } } out << eb; } @@ -2568,7 +3098,7 @@ void Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p) { Output& out = output(); - out << nl << "public static final long serialVersionUID = "; + out << sp << nl << "public static final long serialVersionUID = "; string serialVersionUID; if(p->findMetaData("java:serialVersionUID", serialVersionUID)) { @@ -2589,7 +3119,8 @@ Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p) if(!IceUtilInternal::stringToInt64(serialVersionUID, v)) // conversion error { ostringstream os; - os << "ignoring invalid serialVersionUID for class `" << p->scoped() << "'; generating default value"; + os << "ignoring invalid serialVersionUID for class `" << p->scoped() + << "'; generating default value"; emitWarning("", "", os.str()); out << computeSerialVersionUUID(p); } @@ -2614,8 +3145,8 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) ExceptionPtr base = p->base(); string package = getPackage(p); string absolute = getAbsolute(p); - DataMemberList allDataMembers = p->allDataMembers(); DataMemberList members = p->dataMembers(); + DataMemberList allDataMembers = p->allDataMembers(); DataMemberList::const_iterator d; open(absolute, p->file()); @@ -2646,7 +3177,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out << sb; // - // Constructors. + // Default constructor. // out << sp; out << nl << "public " << name << "()"; @@ -2659,19 +3190,137 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out << eb; out << sp; - out << nl << "public " << name << "(Throwable cause)"; + out << nl << "public " << name << "(Throwable __cause)"; out << sb; - out << nl << "super(cause);"; + out << nl << "super(__cause);"; writeDataMemberInitializers(out, members, package); out << eb; + bool hasOptionalMembers = false; + bool hasRequiredMembers = false; + for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d) + { + if((*d)->optional()) + { + hasOptionalMembers = true; + } + else + { + hasRequiredMembers = true; + } + } + if(!allDataMembers.empty()) { + DataMemberList baseDataMembers; + if(base) + { + baseDataMembers = base->allDataMembers(); + } + // // A method cannot have more than 255 parameters (including the implicit "this" argument). // if(allDataMembers.size() < 255) { + if(hasRequiredMembers && hasOptionalMembers) + { + bool hasBaseRequired = false; + for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + hasBaseRequired = true; + break; + } + } + + DataMemberList optionalMembers = p->orderedOptionalDataMembers(); + + // + // Generate a constructor accepting parameters for just the required members. + // + out << sp << nl << "public " << name << spar; + vector<string> paramDecl; + for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + string memberName = fixKwd((*d)->name()); + string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData()); + paramDecl.push_back(memberType + " " + memberName); + } + } + out << paramDecl << epar; + out << sb; + if(!baseDataMembers.empty()) + { + if(hasBaseRequired) + { + out << nl << "super" << spar; + vector<string> baseParamNames; + for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + baseParamNames.push_back(fixKwd((*d)->name())); + } + } + out << baseParamNames << epar << ';'; + } + } + + for(d = members.begin(); d != members.end(); ++d) + { + if(!(*d)->optional()) + { + string paramName = fixKwd((*d)->name()); + out << nl << "this." << paramName << " = " << paramName << ';'; + } + } + writeDataMemberInitializers(out, optionalMembers, package); + out << eb; + + // + // Create constructor that takes all data members plus a Throwable. + // + if(allDataMembers.size() < 254) + { + paramDecl.push_back("Throwable __cause"); + out << sp << nl << "public " << name << spar; + out << paramDecl << epar; + out << sb; + if(hasBaseRequired) + { + out << nl << "super" << spar; + vector<string> baseParamNames; + for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d) + { + if(!(*d)->optional()) + { + baseParamNames.push_back(fixKwd((*d)->name())); + } + } + baseParamNames.push_back("__cause"); + out << baseParamNames << epar << ';'; + } + else + { + out << nl << "super(__cause);"; + } + for(d = members.begin(); d != members.end(); ++d) + { + if(!(*d)->optional()) + { + string paramName = fixKwd((*d)->name()); + out << nl << "this." << paramName << " = " << paramName << ';'; + } + } + writeDataMemberInitializers(out, optionalMembers, package); + out << eb; + } + } + out << sp << nl << "public " << name << spar; vector<string> paramDecl; for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d) @@ -2694,14 +3343,19 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out << baseParamNames << epar << ';'; } - vector<string> paramNames; for(d = members.begin(); d != members.end(); ++d) { - paramNames.push_back(fixKwd((*d)->name())); - } - for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) - { - out << nl << "this." << *i << " = " << *i << ';'; + string paramName = fixKwd((*d)->name()); + if((*d)->optional()) + { + string capName = paramName; + capName[0] = toupper(static_cast<unsigned char>(capName[0])); + out << nl << "set" << capName << '(' << paramName << ");"; + } + else + { + out << nl << "this." << paramName << " = " << paramName << ';'; + } } out << eb; @@ -2710,13 +3364,13 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) // if(allDataMembers.size() < 254) { - paramDecl.push_back("Throwable cause"); + paramDecl.push_back("Throwable __cause"); out << sp << nl << "public " << name << spar; out << paramDecl << epar; out << sb; if(!base) { - out << nl << "super(cause);"; + out << nl << "super(__cause);"; } else { @@ -2727,12 +3381,22 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) { baseParamNames.push_back(fixKwd((*d)->name())); } - baseParamNames.push_back("cause"); + baseParamNames.push_back("__cause"); out << baseParamNames << epar << ';'; } - for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) + for(d = members.begin(); d != members.end(); ++d) { - out << nl << "this." << *i << " = " << *i << ';'; + string paramName = fixKwd((*d)->name()); + if((*d)->optional()) + { + string capName = paramName; + capName[0] = toupper(static_cast<unsigned char>(capName[0])); + out << nl << "set" << capName << '(' << paramName << ");"; + } + else + { + out << nl << "this." << paramName << " = " << paramName << ';'; + } } out << eb; } @@ -2758,143 +3422,91 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) string scoped = p->scoped(); string package = getPackage(p); ExceptionPtr base = p->base(); + bool basePreserved = p->inheritsMetaData("preserve-slice"); + bool preserved = basePreserved || p->hasMetaData("preserve-slice"); DataMemberList members = p->dataMembers(); + DataMemberList optionalMembers = p->orderedOptionalDataMembers(); DataMemberList::const_iterator d; int iter; out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)"; out << sb; - out << nl << "__os.writeString(\"" << scoped << "\");"; - out << nl << "__os.startWriteSlice();"; + if(preserved) + { + out << nl << "__os.startWriteException(__slicedData);"; + } + else + { + out << nl << "__os.startWriteException(null);"; + } + out << nl << "__writeImpl(__os);"; + out << nl << "__os.endWriteException();"; + out << eb; + + out << sp << nl << "public void" << nl << "__writeImpl(IceInternal.BasicStream __os)"; + out << sb; + out << nl << "__os.startWriteSlice(\"" << scoped << "\", " << (!base ? "true" : "false") << ");"; iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData); + if(!(*d)->optional()) + { + writeMarshalDataMember(out, package, *d, iter); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeMarshalDataMember(out, package, *d, iter); } out << nl << "__os.endWriteSlice();"; if(base) { - out << nl << "super.__write(__os);"; + out << nl << "super.__writeImpl(__os);"; + } + out << eb; + + out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is)"; + out << sb; + out << nl << "__is.startReadException();"; + out << nl << "__readImpl(__is);"; + if(preserved) + { + out << nl << "__slicedData = __is.endReadException(true);"; + } + else + { + out << nl << "__is.endReadException(false);"; } out << eb; DataMemberList allClassMembers = p->allClassDataMembers(); if(allClassMembers.size() != 0) { - out << sp << nl << "private class Patcher implements IceInternal.Patcher"; - if(_stream) - { - out << ", Ice.ReadObjectCallback"; - } - out << sb; - if(allClassMembers.size() > 1) - { - out << sp << nl << "Patcher(int member)"; - out << sb; - out << nl << "__member = member;"; - out << eb; - } - - out << sp << nl << "public void" << nl << "patch(Ice.Object v)"; - out << sb; - if(allClassMembers.size() > 1) - { - out << nl << "switch(__member)"; - out << sb; - } - int memberCount = 0; - for(d = allClassMembers.begin(); d != allClassMembers.end(); ++d) - { - if(allClassMembers.size() > 1) - { - out.dec(); - out << nl << "case " << memberCount << ":"; - out.inc(); - } - if(allClassMembers.size() > 1) - { - out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";"; - } - string memberName = fixKwd((*d)->name()); - string memberType = typeToString((*d)->type(), TypeModeMember, package); - out << nl << "if(v == null || v instanceof " << memberType << ")"; - out << sb; - out << nl << memberName << " = (" << memberType << ")v;"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; - out << eb; - if(allClassMembers.size() > 1) - { - out << nl << "break;"; - } - memberCount++; - } - if(allClassMembers.size() > 1) - { - out << eb; - } - out << eb; - - out << sp << nl << "public String" << nl << "type()"; - out << sb; - if(allClassMembers.size() > 1) - { - out << nl << "return __typeId;"; - } - else - { - out << nl << "return \"" << (*allClassMembers.begin())->type()->typeId() << "\";"; - } - out << eb; - - if(_stream) - { - out << sp << nl << "public void" << nl << "invoke(Ice.Object v)"; - out << sb; - out << nl << "patch(v);"; - out << eb; - } - - if(allClassMembers.size() > 1) - { - out << sp << nl << "private int __member;"; - out << nl << "private String __typeId;"; - } - out << eb; + writePatcher(out, package, allClassMembers, _stream); } - out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is, boolean __rid)"; - out << sb; - out << nl << "if(__rid)"; + out << sp << nl << "public void" << nl << "__readImpl(IceInternal.BasicStream __is)"; out << sb; - out << nl << "__is.readString();"; - out << eb; out << nl << "__is.startReadSlice();"; iter = 0; DataMemberList classMembers = p->classDataMembers(); - size_t classMemberCount = allClassMembers.size() - classMembers.size(); + int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); + const bool needCustomPatcher = classMembers.size() > 1 || allClassMembers.size() > 1; for(d = members.begin(); d != members.end(); ++d) { - ostringstream patchParams; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) + if(!(*d)->optional()) { - if(classMembers.size() > 1 || allClassMembers.size() > 1) - { - patchParams << "new Patcher(" << classMemberCount++ << ')'; - } + writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } - StringList metaData = (*d)->getMetaData(); - writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData, - patchParams.str()); + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } out << nl << "__is.endReadSlice();"; if(base) { - out << nl << "super.__read(__is, true);"; + out << nl << "super.__readImpl(__is);"; } out << eb; @@ -2902,49 +3514,74 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) { out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __outS)"; out << sb; - out << nl << "__outS.writeString(\"" << scoped << "\");"; - out << nl << "__outS.startSlice();"; + if(preserved) + { + out << nl << "__outS.startException(__slicedData);"; + } + else + { + out << nl << "__outS.startException(null);"; + } + out << nl << "__writeImpl(__outS);"; + out << nl << "__outS.endException();"; + out << eb; + + out << sp << nl << "public void" << nl << "__writeImpl(Ice.OutputStream __outS)"; + out << sb; + out << nl << "__outS.startSlice(\"" << scoped << "\", " << (!base ? "true" : "false") << ");"; iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, - metaData); + if(!(*d)->optional()) + { + writeStreamMarshalDataMember(out, package, *d, iter); + } + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeStreamMarshalDataMember(out, package, *d, iter); } out << nl << "__outS.endSlice();"; if(base) { - out << nl << "super.__write(__outS);"; + out << nl << "super.__writeImpl(__outS);"; } out << eb; - out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS, boolean __rid)"; - out << sb; - out << nl << "if(__rid)"; + out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS)"; out << sb; - out << nl << "__inS.readString();"; + out << nl << "__inS.startException();"; + out << nl << "__readImpl(__inS);"; + if(preserved) + { + out << nl << "__slicedData = __inS.endException(true);"; + } + else + { + out << nl << "__inS.endException(false);"; + } out << eb; + + out << sp << nl << "public void" << nl << "__readImpl(Ice.InputStream __inS)"; + out << sb; out << nl << "__inS.startSlice();"; iter = 0; + classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size()); for(d = members.begin(); d != members.end(); ++d) { - ostringstream patchParams; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) + if(!(*d)->optional()) { - if(classMembers.size() > 1 || allClassMembers.size() > 1) - { - patchParams << "new Patcher(" << classMemberCount++ << ')'; - } + writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } - StringList metaData = (*d)->getMetaData(); - writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, - metaData, patchParams.str()); + } + for(d = optionalMembers.begin(); d != optionalMembers.end(); ++d) + { + writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } out << nl << "__inS.endSlice();"; if(base) { - out << nl << "super.__read(__inS, true);"; + out << nl << "super.__readImpl(__inS);"; } out << eb; } @@ -2960,7 +3597,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) out << nl << "throw ex;"; out << eb; - out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS, boolean __rid)"; + out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS)"; out << sb; out << nl << "Ice.MarshalException ex = new Ice.MarshalException();"; out << nl << "ex.reason = \"exception " << scoped.substr(2) << " was not generated with stream support\";"; @@ -2968,15 +3605,9 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) out << eb; } - if(p->usesClasses()) + if(preserved && !basePreserved) { - if(!base || (base && !base->usesClasses())) - { - out << sp << nl << "public boolean" << nl << "__usesClasses()"; - out << sb; - out << nl << "return true;"; - out << eb; - } + out << sp << nl << "protected Ice.SlicedData __slicedData;"; } } @@ -3194,8 +3825,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData); + writeMarshalDataMember(out, package, *d, iter); } out << eb; @@ -3203,108 +3833,17 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) if(classMembers.size() != 0) { - out << sp << nl << "private class Patcher implements IceInternal.Patcher"; - if(_stream) - { - out << ", Ice.ReadObjectCallback"; - } - out << sb; - if(classMembers.size() > 1) - { - out << sp << nl << "Patcher(int member)"; - out << sb; - out << nl << "__member = member;"; - out << eb; - } - - out << sp << nl << "public void" << nl << "patch(Ice.Object v)"; - out << sb; - if(classMembers.size() > 1) - { - out << nl << "switch(__member)"; - out << sb; - } - int memberCount = 0; - for(d = classMembers.begin(); d != classMembers.end(); ++d) - { - if(classMembers.size() > 1) - { - out.dec(); - out << nl << "case " << memberCount << ":"; - out.inc(); - } - if(classMembers.size() > 1) - { - out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";"; - } - string memberName = fixKwd((*d)->name()); - string memberType = typeToString((*d)->type(), TypeModeMember, package); - out << nl << "if(v == null || v instanceof " << memberType << ")"; - out << sb; - out << nl << memberName << " = (" << memberType << ")v;"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; - out << eb; - if(classMembers.size() > 1) - { - out << nl << "break;"; - } - memberCount++; - } - if(classMembers.size() > 1) - { - out << eb; - } - out << eb; - - out << sp << nl << "public String" << nl << "type()"; - out << sb; - if(classMembers.size() > 1) - { - out << nl << "return __typeId;"; - } - else - { - out << nl << "return \"" << (*classMembers.begin())->type()->typeId() << "\";"; - } - out << eb; - - if(_stream) - { - out << sp << nl << "public void" << nl << "invoke(Ice.Object v)"; - out << sb; - out << nl << "patch(v);"; - out << eb; - } - - if(classMembers.size() > 1) - { - out << sp << nl << "private int __member;"; - out << nl << "private String __typeId;"; - } - out << eb; + writePatcher(out, package, classMembers, _stream); } out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is)"; out << sb; iter = 0; int classMemberCount = 0; + const bool needCustomPatcher = classMembers.size() > 1; for(d = members.begin(); d != members.end(); ++d) { - ostringstream patchParams; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) - { - if(classMembers.size() > 1) - { - patchParams << "new Patcher(" << classMemberCount++ << ')'; - } - } - StringList metaData = (*d)->getMetaData(); - writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData, - patchParams.str()); + writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } out << eb; @@ -3315,9 +3854,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) iter = 0; for(d = members.begin(); d != members.end(); ++d) { - StringList metaData = (*d)->getMetaData(); - writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, - metaData); + writeStreamMarshalDataMember(out, package, *d, iter); } out << eb; @@ -3327,25 +3864,13 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) classMemberCount = 0; for(d = members.begin(); d != members.end(); ++d) { - ostringstream patchParams; - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type())) - { - if(classMembers.size() > 1) - { - patchParams << "new Patcher(" << classMemberCount++ << ')'; - } - } - StringList metaData = (*d)->getMetaData(); - writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, - metaData, patchParams.str()); + writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, classMemberCount); } out << eb; } } - out << nl; - out << nl << "public static final long serialVersionUID = "; + out << sp << nl << "public static final long serialVersionUID = "; string serialVersionUID; if(p->findMetaData("java:serialVersionUID", serialVersionUID)) { @@ -3366,7 +3891,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) if(!IceUtilInternal::stringToInt64(serialVersionUID, v)) // conversion error { ostringstream os; - os << "ignoring invalid serialVersionUID for struct `" << p->scoped() << "'; generating default value"; + os << "ignoring invalid serialVersionUID for struct `" << p->scoped() + << "'; generating default value"; emitWarning("", "", os.str()); out << computeSerialVersionUUID(p); } @@ -3394,6 +3920,8 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) TypePtr type = p->type(); string s = typeToString(type, TypeModeMember, getPackage(contained), metaData); Output& out = output(); + const bool optional = p->optional(); + const bool getSet = p->hasMetaData(_getSetMetaData) || contained->hasMetaData(_getSetMetaData); out << sp; @@ -3409,15 +3937,24 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) { out << nl << "protected " << s << ' ' << name << ';'; } + else if(optional) + { + out << nl << "private " << s << ' ' << name << ';'; + } else { out << nl << "public " << s << ' ' << name << ';'; } + if(optional) + { + out << nl << "private boolean __has_" << p->name() << ';'; + } + // // Getter/Setter. // - if(p->hasMetaData(_getSetMetaData) || contained->hasMetaData(_getSetMetaData)) + if(getSet || optional) { string capName = p->name(); capName[0] = toupper(static_cast<unsigned char>(capName[0])); @@ -3433,8 +3970,14 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) ops = cls->allOperations(); file = p->file(); line = p->line(); - if(!validateGetterSetter(ops, "get" + capName, 0, file, line) || - !validateGetterSetter(ops, "set" + capName, 1, file, line)) + if(!validateMethod(ops, "get" + capName, 0, file, line) || + !validateMethod(ops, "set" + capName, 1, file, line)) + { + return; + } + if(optional && + (!validateMethod(ops, "has" + capName, 0, file, line) || + !validateMethod(ops, "clear" + capName, 0, file, line))) { return; } @@ -3445,9 +3988,16 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) // out << sp; writeDocComment(out, p, deprecateReason); - out << nl << "public " << s; - out << nl << "get" << capName << "()"; + out << nl << "public " << s + << nl << "get" << capName << "()"; out << sb; + if(optional) + { + out << nl << "if(!__has_" << p->name() << ')'; + out << sb; + out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << eb; + } out << nl << "return " << name << ';'; out << eb; @@ -3456,56 +4006,50 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) // out << sp; writeDocComment(out, p, deprecateReason); - out << nl << "public void"; - out << nl << "set" << capName << '(' << s << " _" << name << ')'; + out << nl << "public void" + << nl << "set" << capName << '(' << s << " _" << name << ')'; out << sb; + if(optional) + { + out << nl << "__has_" << p->name() << " = true;"; + } out << nl << name << " = _" << name << ';'; out << eb; // - // Check for bool type. + // Generate hasFoo and clearFoo for optional member. // - BuiltinPtr b = BuiltinPtr::dynamicCast(type); - if(b && b->kind() == Builtin::KindBool) + if(optional) { - if(cls && !validateGetterSetter(ops, "is" + capName, 0, file, line)) - { - return; - } out << sp; - if(!deprecateReason.empty()) - { - out << nl << "/**"; - out << nl << " * @deprecated " << deprecateReason; - out << nl << " **/"; - } - out << nl << "public boolean"; - out << nl << "is" << capName << "()"; + writeDocComment(out, p, deprecateReason); + out << nl << "public boolean" + << nl << "has" << capName << "()"; out << sb; - out << nl << "return " << name << ';'; + out << nl << "return __has_" << p->name() << ';'; + out << eb; + + out << sp; + writeDocComment(out, p, deprecateReason); + out << nl << "public void" + << nl << "clear" << capName << "()"; + out << sb; + out << nl << "__has_" << p->name() << " = false;"; out << eb; } - // - // Check for unmodified sequence type and emit indexing methods. - // - SequencePtr seq = SequencePtr::dynamicCast(type); - if(seq) + if(getSet) { - if(!hasTypeMetaData(seq, metaData)) + // + // Check for bool type. + // + BuiltinPtr b = BuiltinPtr::dynamicCast(type); + if(b && b->kind() == Builtin::KindBool) { - if(cls && - (!validateGetterSetter(ops, "get" + capName, 1, file, line) || - !validateGetterSetter(ops, "set" + capName, 2, file, line))) + if(cls && !validateMethod(ops, "is" + capName, 0, file, line)) { return; } - - string elem = typeToString(seq->type(), TypeModeMember, getPackage(contained)); - - // - // Indexed getter. - // out << sp; if(!deprecateReason.empty()) { @@ -3513,27 +4057,83 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) out << nl << " * @deprecated " << deprecateReason; out << nl << " **/"; } - out << nl << "public " << elem; - out << nl << "get" << capName << "(int _index)"; + out << nl << "public boolean"; + out << nl << "is" << capName << "()"; out << sb; - out << nl << "return " << name << "[_index];"; + if(optional) + { + out << nl << "if(!__has_" << p->name() << ')'; + out << sb; + out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << eb; + } + out << nl << "return " << name << ';'; out << eb; + } - // - // Indexed setter. - // - out << sp; - if(!deprecateReason.empty()) + // + // Check for unmodified sequence type and emit indexing methods. + // + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + if(!hasTypeMetaData(seq, metaData)) { - out << nl << "/**"; - out << nl << " * @deprecated " << deprecateReason; - out << nl << " **/"; + if(cls && + (!validateMethod(ops, "get" + capName, 1, file, line) || + !validateMethod(ops, "set" + capName, 2, file, line))) + { + return; + } + + string elem = typeToString(seq->type(), TypeModeMember, getPackage(contained)); + + // + // Indexed getter. + // + out << sp; + if(!deprecateReason.empty()) + { + out << nl << "/**"; + out << nl << " * @deprecated " << deprecateReason; + out << nl << " **/"; + } + out << nl << "public " << elem; + out << nl << "get" << capName << "(int _index)"; + out << sb; + if(optional) + { + out << nl << "if(!__has_" << p->name() << ')'; + out << sb; + out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << eb; + } + out << nl << "return " << name << "[_index];"; + out << eb; + + // + // Indexed setter. + // + out << sp; + if(!deprecateReason.empty()) + { + out << nl << "/**"; + out << nl << " * @deprecated " << deprecateReason; + out << nl << " **/"; + } + out << nl << "public void"; + out << nl << "set" << capName << "(int _index, " << elem << " _val)"; + out << sb; + if(optional) + { + out << nl << "if(!__has_" << p->name() << ')'; + out << sb; + out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << eb; + } + out << nl << name << "[_index] = _val;"; + out << eb; } - out << nl << "public void"; - out << nl << "set" << capName << "(int _index, " << elem << " _val)"; - out << sb; - out << nl << name << "[_index] = _val;"; - out << eb; } } } @@ -3579,34 +4179,16 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) { out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)"; out << sb; - if(sz <= 0x7f) - { - out << nl << "__os.writeByte((byte)ordinal());"; - } - else if(sz <= 0x7fff) - { - out << nl << "__os.writeShort((short)ordinal());"; - } - else - { - out << nl << "__os.writeInt(ordinal());"; - } + out << nl << "__os.writeEnum(ordinal(), " << sz << ");"; out << eb; out << sp << nl << "public static " << name << nl << "__read(IceInternal.BasicStream __is)"; out << sb; - if(sz <= 0x7f) - { - out << nl << "int __v = __is.readByte(" << sz << ");"; - } - else if(sz <= 0x7fff) - { - out << nl << "int __v = __is.readShort(" << sz << ");"; - } - else - { - out << nl << "int __v = __is.readInt(" << sz << ");"; - } + out << nl << "int __v = __is.readEnum(" << sz << ");"; + out << nl << "if(__v < 0 || __v >= " << sz << ')'; + out << sb; + out << nl << "throw new Ice.MarshalException(\"enumerator out of range\");"; + out << eb; out << nl << "return values()[__v];"; out << eb; @@ -3614,34 +4196,12 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) { out << sp << nl << "public void" << nl << "ice_write(Ice.OutputStream __outS)"; out << sb; - if(sz <= 0x7f) - { - out << nl << "__outS.writeByte((byte)ordinal());"; - } - else if(sz <= 0x7fff) - { - out << nl << "__outS.writeShort((short)ordinal());"; - } - else - { - out << nl << "__outS.writeInt(ordinal());"; - } + out << nl << "__outS.writeEnum(ordinal(), " << sz << ");"; out << eb; out << sp << nl << "public static " << name << nl << "ice_read(Ice.InputStream __inS)"; out << sb; - if(sz <= 0x7f) - { - out << nl << "int __v = __inS.readByte();"; - } - else if(sz <= 0x7fff) - { - out << nl << "int __v = __inS.readShort();"; - } - else - { - out << nl << "int __v = __inS.readInt();"; - } + out << nl << "int __v = __inS.readEnum(" << sz << ");"; out << nl << "if(__v < 0 || __v >= " << sz << ')'; out << sb; out << nl << "throw new Ice.MarshalException(\"enumerator out of range\");"; @@ -3678,8 +4238,8 @@ Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p) } bool -Slice::Gen::TypesVisitor::validateGetterSetter(const OperationList& ops, const std::string& name, int numArgs, - const string& file, const string& line) +Slice::Gen::TypesVisitor::validateMethod(const OperationList& ops, const std::string& name, int numArgs, + const string& file, const string& line) { for(OperationList::const_iterator i = ops.begin(); i != ops.end(); ++i) { @@ -3689,7 +4249,7 @@ Slice::Gen::TypesVisitor::validateGetterSetter(const OperationList& ops, const s if(numArgs >= numParams && numArgs - numParams <= 1) { ostringstream ostr; - ostr << "operation `" << name << "' conflicts with getter/setter method"; + ostr << "operation `" << name << "' conflicts with method for data member"; emitError(file, line, ostr.str()); return false; } @@ -3822,7 +4382,7 @@ Slice::Gen::HolderVisitor::writeHolder(const TypePtr& p) out << eb; out << nl << "else"; out << sb; - out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());"; + out << nl << "IceInternal.Ex.throwUOE(type(), v);"; out << eb; out << eb; out << sp << nl << "public String" << nl << "type()"; @@ -3902,11 +4462,13 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) ClassDefPtr cl = ClassDefPtr::dynamicCast(container); string opName = fixKwd(op->name()); TypePtr ret = op->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData()); + 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); + const bool optionalMapping = useOptionalMapping(op); + ExceptionList throws = op->throws(); throws.sort(); throws.unique(); @@ -3998,7 +4560,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; @@ -4087,22 +4649,30 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) out << sb; out << nl << "__result.__prepare(__" << op->name() << "_name, " << sliceModeToIceMode(op->sendMode()) << ", __ctx, __explicitCtx);"; - out << nl << "IceInternal.BasicStream __os = __result.__getOs();"; iter = 0; - for(pli = paramList.begin(); pli != paramList.end(); ++pli) + if(!inArgs.empty()) { - if(!(*pli)->isOutParam()) + out << nl << "IceInternal.BasicStream __os = __result.__startWriteParams();"; + FormatType format = op->format(); + if(op->sendsClasses() && format != DefaultFormat) { - StringList metaData = (*pli)->getMetaData(); - writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), true, iter, false, - metaData); + out << nl << "__os.format(" << formatTypeToString(format) << ");"; } + ParamDeclList pl; + for(pli = paramList.begin(); pli != paramList.end(); ++pli) + { + if(!(*pli)->isOutParam()) + { + pl.push_back(*pli); + } + } + writeMarshalUnmarshalParams(out, package, pl, 0, iter, true, optionalMapping); + out << nl << "__result.__endWriteParams();"; } - if(op->sendsClasses()) + else { - out << nl << "__os.writePendingObjects();"; + out << nl << "__result.__writeEmptyParams();"; } - out << nl << "__os.endWriteEncaps();"; out << nl << "__result.__send(true);"; out << eb; out << nl << "catch(Ice.LocalException __ex)"; @@ -4112,11 +4682,12 @@ 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 // + iter = 0; out << sp; writeDocCommentAsync(out, op, OutParam); out << nl << "public " << retS << " end_" << op->name() << spar << outParams << "Ice.AsyncResult __result" @@ -4157,59 +4728,30 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) out << eb; out << eb; - if(ret) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) - { - out << nl << retS << "Holder __ret = new " << retS << "Holder();"; - } - else - { - out << nl << retS << " __ret;"; - } - } - - out << nl << "IceInternal.BasicStream __is = __result.__getIs();"; if(ret || !outParams.empty()) { - out << nl << "__is.startReadEncaps();"; + out << nl << "IceInternal.BasicStream __is = __result.__startReadParams();"; + ParamDeclList pl; for(pli = paramList.begin(); pli != paramList.end(); ++pli) { if((*pli)->isOutParam()) { - writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), false, iter, - true, (*pli)->getMetaData()); - } - } - if(ret) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) - { - out << nl << "__is.readObject(__ret);"; + pl.push_back(*pli); } - else - { - writeMarshalUnmarshalCode(out, package, ret, "__ret", false, iter, false, - op->getMetaData()); - } - } - if(op->returnsClasses()) - { - out << nl << "__is.readPendingObjects();"; } - out << nl << "__is.endReadEncaps();"; + writeMarshalUnmarshalParams(out, package, pl, op, iter, false, true); + out << nl << "__result.__endReadParams();"; } else { - out << nl << "__is.skipEmptyEncaps();"; + out << nl << "__result.__readEmptyParams();"; } if(ret) { BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) + if(!op->returnIsOptional() && + ((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))) { out << nl << "return __ret.value;"; } @@ -4498,8 +5040,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) // // Avoid serialVersionUID warnings for Proxy Helper classes. // - out << nl; - out << nl << "public static final long serialVersionUID = 0L;"; + out << sp << nl << "public static final long serialVersionUID = 0L;"; out << eb; close(); @@ -4856,14 +5397,15 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) Output& out = output(); TypePtr ret = p->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, p->getMetaData()); - vector<string> params = getParams(p, package); + string retS = typeToString(ret, TypeModeReturn, package, p->getMetaData(), true, p->returnIsOptional()); + vector<string> params = getParamsProxy(p, package); ExceptionList throws = p->throws(); throws.sort(); throws.unique(); string deprecateReason = getDeprecateReason(p, cl, "operation"); string contextDoc = "@param __ctx The Context map to send with the invocation."; + string contextParam = "java.util.Map<String, String> __ctx"; // // Write two versions of the operation - with and without a @@ -4879,8 +5421,6 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) out << sp; writeDocComment(out, p, deprecateReason, contextDoc); - string contextParam = "java.util.Map<String, String> __ctx"; - out << nl << "public " << retS << ' ' << name << spar << params << contextParam << epar; writeThrowsClause(package, throws); out << ';'; @@ -4891,7 +5431,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."; @@ -4936,7 +5476,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); @@ -5017,9 +5557,9 @@ Slice::Gen::DelegateVisitor::visitClassDefStart(const ClassDefPtr& p) OperationPtr op = *r; string opName = fixKwd(op->name()); TypePtr ret = op->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData()); + 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(); @@ -5072,7 +5612,8 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) StringList opMetaData = op->getMetaData(); string opName = fixKwd(op->name()); TypePtr ret = op->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, opMetaData); + string retS = typeToString(ret, TypeModeReturn, package, opMetaData, true, op->returnIsOptional()); + const bool optionalMapping = useOptionalMapping(op); int iter = 0; ParamDeclList inParams; @@ -5107,7 +5648,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; @@ -5122,27 +5663,29 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) { out << nl << "try"; out << sb; - out << nl << "IceInternal.BasicStream __os = __og.os();"; - for(pli = inParams.begin(); pli != inParams.end(); ++pli) - { - writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), true, iter, false, - (*pli)->getMetaData()); - } - if(op->sendsClasses()) + out << nl << "IceInternal.BasicStream __os = __og.startWriteParams();"; + FormatType format = op->format(); + if(op->sendsClasses() && format != DefaultFormat) { - out << nl << "__os.writePendingObjects();"; + out << nl << "__os.format(" << formatTypeToString(format) << ");"; } + writeMarshalUnmarshalParams(out, package, inParams, 0, iter, true, optionalMapping); + out << nl << "__og.endWriteParams();"; out << eb; out << nl << "catch(Ice.LocalException __ex)"; out << sb; out << nl << "__og.abort(__ex);"; out << eb; } + else + { + out << nl << "__og.writeEmptyParams();"; + } out << nl << "boolean __ok = __og.invoke();"; if(!op->returnsData()) { - out << nl << "if(!__og.is().isEmpty())"; + out << nl << "if(__og.hasResponse())"; out << sb; } @@ -5168,42 +5711,20 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) out << eb; if(ret || !outParams.empty()) { - out << nl << "IceInternal.BasicStream __is = __og.is();"; - out << nl << "__is.startReadEncaps();"; - for(pli = outParams.begin(); pli != outParams.end(); ++pli) - { - writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), false, iter, true, - (*pli)->getMetaData()); - } - if(ret) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) - { - out << nl << retS << "Holder __ret = new " << retS << "Holder();"; - out << nl << "__is.readObject(__ret);"; - } - else - { - out << nl << retS << " __ret;"; - writeMarshalUnmarshalCode(out, package, ret, "__ret", false, iter, false, opMetaData); - } - } - if(op->returnsClasses()) - { - out << nl << "__is.readPendingObjects();"; - } - out << nl << "__is.endReadEncaps();"; + out << nl << "IceInternal.BasicStream __is = __og.startReadParams();"; + writeMarshalUnmarshalParams(out, package, outParams, op, iter, false, true); + out << nl << "__og.endReadParams();"; } else { - out << nl << "__og.is().skipEmptyEncaps();"; + out << nl << "__og.readEmptyParams();"; } if(ret) { BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) + if(!op->returnIsOptional() && + ((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))) { out << nl << "return __ret.value;"; } @@ -5273,7 +5794,8 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) ClassDefPtr cl = ClassDefPtr::dynamicCast(container); string opName = fixKwd(op->name()); TypePtr ret = op->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData()); + const bool optionalMapping = useOptionalMapping(op); + string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, op->returnIsOptional()); ExceptionList throws = op->throws(); throws.sort(); @@ -5292,8 +5814,7 @@ 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); out << sp; if(!deprecateReason.empty()) @@ -5314,11 +5835,12 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) out << nl << "__initCurrent(__current, \"" << op->name() << "\", " << sliceModeToIceMode(op->sendMode()) << ", __ctx);"; + + string resultType; if(ret) { - string resultTypeHolder = typeToString(ret, TypeModeOut, package, op->getMetaData()); - - out << nl << "final " << resultTypeHolder << " __result = new " << resultTypeHolder << "();"; + resultType = typeToString(ret, TypeModeOut, package, op->getMetaData(), true, op->returnIsOptional()); + out << nl << "final " << resultType << " __result = new " << resultType << "();"; } out << nl << "IceInternal.Direct __direct = null;"; @@ -5339,7 +5861,8 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) out << eb; out << nl << "else"; out << sb; - out << nl << "throw new Ice.OperationNotExistException(__current.id, __current.facet, __current.operation);"; + out << nl + << "throw new Ice.OperationNotExistException(__current.id, __current.facet, __current.operation);"; out << eb; if(!throws.empty()) @@ -5348,13 +5871,87 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) out << sb; } + // + // Collect the arguments that will be passed to the servant. + // + vector<string> args; + ParamDeclList paramList = op->parameters(); + ParamDeclList::const_iterator q; + for(q = paramList.begin(); q != paramList.end(); ++q) + { + string param = fixKwd((*q)->name()); + // + // For optional parameters, the proxy mapping can differ from the servant + // mapping, depending on whether the optional mapping is being used. + // + if((*q)->optional() && !optionalMapping) + { + if((*q)->isOutParam()) + { + param = "__" + (*q)->name(); + string typeS = typeToString((*q)->type(), TypeModeOut, package, (*q)->getMetaData()); + out << nl << typeS << ' ' << param << " = new " << typeS << "();"; + } + else + { + string typeS = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData(), true, true); + param = "new " + typeS + "(" + param + ")"; + } + } + args.push_back(param); + } + out << nl; if(ret) { - out << "__result.value = "; + if(op->returnIsOptional()) + { + if(optionalMapping) + { + out << resultType << " __r = "; + } + else + { + out << typeToString(ret, TypeModeIn, package, op->getMetaData()) << " __r = "; + } + } + else + { + out << "__result.value = "; + } } + out << "__servant." << opName << spar << args << "__current" << epar << ';'; + + for(q = paramList.begin(); q != paramList.end(); ++q) + { + // + // For optional parameters, the proxy mapping can differ from the servant + // mapping, depending on whether the optional mapping is being used. + // + if((*q)->optional() && !optionalMapping && (*q)->isOutParam()) + { + out << nl << fixKwd((*q)->name()) << ".set(__" << (*q)->name() << ".value);"; + } + } + + if(ret && op->returnIsOptional()) + { + if(optionalMapping) + { + out << nl << "if(__r != null && __r.isSet())"; + out << sb; + out << nl << "__result.set(__r.get());"; + out << eb; + } + else + { + out << nl << "__result.set(__r);"; + } + } + out << nl << "return Ice.DispatchStatus.DispatchOK;"; + if(!throws.empty()) { out << eb; @@ -5379,7 +5976,14 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) out << nl << "assert __status == Ice.DispatchStatus.DispatchOK;"; if(ret) { - out << nl << "return __result.value;"; + if(op->returnIsOptional()) + { + out << nl << "return __result;"; + } + else + { + out << nl << "return __result.value;"; + } } out << eb; @@ -5410,7 +6014,14 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p) } if(ret && !cl->hasMetaData("amd") && !op->hasMetaData("amd")) { - out << nl << "return __result.value;"; + if(op->returnIsOptional()) + { + out << nl << "return __result;"; + } + else + { + out << nl << "return __result.value;"; + } } out << eb; } @@ -5460,8 +6071,7 @@ Slice::Gen::DispatcherVisitor::visitClassDefStart(const ClassDefPtr& p) // // Avoid serialVersionUID warnings for dispatch classes. // - out << nl; - out << nl << "public static final long serialVersionUID = 0L;"; + out << sp << nl << "public static final long serialVersionUID = 0L;"; out << eb; close(); @@ -5475,129 +6085,144 @@ Slice::Gen::BaseImplVisitor::BaseImplVisitor(const string& dir) : void Slice::Gen::BaseImplVisitor::writeDecl(Output& out, const string& package, const string& name, const TypePtr& type, - const StringList& metaData) + const StringList& metaData, bool optional) { - out << nl << typeToString(type, TypeModeIn, package, metaData) << ' ' << name; + string typeS = typeToString(type, TypeModeIn, package, metaData, true, optional); + out << nl << typeS << ' ' << name; - BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); - if(builtin) + if(optional) { - switch(builtin->kind()) + out << " = new " << typeS << "();"; + } + else + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) { - case Builtin::KindBool: - { - out << " = false"; - break; - } - case Builtin::KindByte: - { - out << " = (byte)0"; - break; - } - case Builtin::KindShort: - { - out << " = (short)0"; - break; - } - case Builtin::KindInt: - case Builtin::KindLong: - { - out << " = 0"; - break; - } - case Builtin::KindFloat: - { - out << " = (float)0.0"; - break; - } - case Builtin::KindDouble: + switch(builtin->kind()) { - out << " = 0.0"; - break; + case Builtin::KindBool: + { + out << " = false"; + break; + } + case Builtin::KindByte: + { + out << " = (byte)0"; + break; + } + case Builtin::KindShort: + { + out << " = (short)0"; + break; + } + case Builtin::KindInt: + case Builtin::KindLong: + { + out << " = 0"; + break; + } + case Builtin::KindFloat: + { + out << " = (float)0.0"; + break; + } + case Builtin::KindDouble: + { + out << " = 0.0"; + break; + } + case Builtin::KindString: + { + out << " = \"\""; + break; + } + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + out << " = null"; + break; + } } - case Builtin::KindString: + } + else + { + EnumPtr en = EnumPtr::dynamicCast(type); + if(en) { - out << " = \"\""; - break; + EnumeratorList enumerators = en->getEnumerators(); + out << " = " << getAbsolute(en, package) << '.' << fixKwd(enumerators.front()->name()); } - case Builtin::KindObject: - case Builtin::KindObjectProxy: - case Builtin::KindLocalObject: + else { out << " = null"; - break; } } - } - else - { - EnumPtr en = EnumPtr::dynamicCast(type); - if(en) - { - EnumeratorList enumerators = en->getEnumerators(); - out << " = " << getAbsolute(en, package) << '.' << fixKwd(enumerators.front()->name()); - } - else - { - out << " = null"; - } - } - out << ';'; + out << ';'; + } } void -Slice::Gen::BaseImplVisitor::writeReturn(Output& out, const TypePtr& type) +Slice::Gen::BaseImplVisitor::writeReturn(Output& out, const TypePtr& type, bool optional) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); - if(builtin) + if(optional) { - switch(builtin->kind()) + out << nl << "return null;"; + } + else + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) { - case Builtin::KindBool: - { - out << nl << "return false;"; - break; - } - case Builtin::KindByte: - { - out << nl << "return (byte)0;"; - break; - } - case Builtin::KindShort: - { - out << nl << "return (short)0;"; - break; - } - case Builtin::KindInt: - case Builtin::KindLong: - { - out << nl << "return 0;"; - break; - } - case Builtin::KindFloat: - { - out << nl << "return (float)0.0;"; - break; - } - case Builtin::KindDouble: - { - out << nl << "return 0.0;"; - break; - } - case Builtin::KindString: - case Builtin::KindObject: - case Builtin::KindObjectProxy: - case Builtin::KindLocalObject: + switch(builtin->kind()) { - out << nl << "return null;"; - break; + case Builtin::KindBool: + { + out << nl << "return false;"; + break; + } + case Builtin::KindByte: + { + out << nl << "return (byte)0;"; + break; + } + case Builtin::KindShort: + { + out << nl << "return (short)0;"; + break; + } + case Builtin::KindInt: + case Builtin::KindLong: + { + out << nl << "return 0;"; + break; + } + case Builtin::KindFloat: + { + out << nl << "return (float)0.0;"; + break; + } + case Builtin::KindDouble: + { + out << nl << "return 0.0;"; + break; + } + case Builtin::KindString: + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + out << nl << "return null;"; + break; + } } + return; } - return; - } - out << nl << "return null;"; + out << nl << "return null;"; + } } void @@ -5606,8 +6231,10 @@ Slice::Gen::BaseImplVisitor::writeOperation(Output& out, const string& package, string opName = op->name(); TypePtr ret = op->returnType(); + const bool optionalMapping = useOptionalMapping(op); StringList opMetaData = op->getMetaData(); - string retS = typeToString(ret, TypeModeReturn, package, opMetaData); + string retS = typeToString(ret, TypeModeReturn, package, opMetaData, true, + optionalMapping && op->returnIsOptional()); vector<string> params = getParams(op, package); ContainerPtr container = op->container(); @@ -5652,13 +6279,14 @@ Slice::Gen::BaseImplVisitor::writeOperation(Output& out, const string& package, } if(ret) { - writeDecl(out, package, result, ret, opMetaData); + writeDecl(out, package, result, ret, opMetaData, optionalMapping && op->returnIsOptional()); } for(q = paramList.begin(); q != paramList.end(); ++q) { if((*q)->isOutParam()) { - writeDecl(out, package, fixKwd((*q)->name()), (*q)->type(), (*q)->getMetaData()); + writeDecl(out, package, fixKwd((*q)->name()), (*q)->type(), (*q)->getMetaData(), + optionalMapping && (*q)->optional()); } } @@ -5715,7 +6343,7 @@ Slice::Gen::BaseImplVisitor::writeOperation(Output& out, const string& package, // if(ret) { - writeReturn(out, ret); + writeReturn(out, ret, optionalMapping && op->returnIsOptional()); } out << eb; @@ -5916,7 +6544,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) ExceptionList throws = p->throws(); - vector<string> params = getParamsAsyncCB(p, classPkg); + vector<string> params = getParamsAsyncCB(p, classPkg, false); vector<string> args = getInOutArgs(p, OutParam); writeDocCommentOp(out, p); @@ -5937,13 +6565,14 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) out << nl << cl->name() << "Prx __proxy = (" << cl->name() << "Prx)__result.getProxy();"; if(ret) { - out << nl << typeToString(ret, TypeModeIn, classPkg, p->getMetaData()) << " __ret = " - << initValue(ret) << ';'; + out << nl << typeToString(ret, TypeModeIn, classPkg, p->getMetaData(), true, p->returnIsOptional()) + << " __ret = " << (p->returnIsOptional() ? "null" : initValue(ret)) << ';'; } for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - string holder = typeToString((*pli)->type(), TypeModeOut, classPkg, (*pli)->getMetaData()); - out << nl << holder << ' ' << fixKwd((*pli)->name()) << " = new " << holder << "();"; + string ts = typeToString((*pli)->type(), TypeModeOut, classPkg, (*pli)->getMetaData(), true, + (*pli)->optional()); + out << nl << ts << ' ' << fixKwd((*pli)->name()) << " = new " << ts << "();"; } out << nl << "try"; out << sb; @@ -5974,7 +6603,14 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) } for(pli = outParams.begin(); pli != outParams.end(); ++pli) { - out << fixKwd((*pli)->name()) + ".value"; + if((*pli)->optional()) + { + out << fixKwd((*pli)->name()); + } + else + { + out << fixKwd((*pli)->name()) + ".value"; + } } out << epar << ';'; out << eb; @@ -6005,7 +6641,7 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) ExceptionList throws = p->throws(); - vector<string> params = getParamsAsyncCB(p, classPkg); + vector<string> params = getParamsAsyncCB(p, classPkg, false); vector<string> args = getInOutArgs(p, OutParam); writeDocCommentOp(out, p); @@ -6072,7 +6708,9 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) string classNameAMDI = "_AMD_" + cl->name(); string absoluteAMDI = getAbsolute(cl, "", "_AMD_", "_" + name); - vector<string> paramsAMD = getParamsAsyncCB(p, classPkg); + vector<string> paramsAMD = getParamsAsyncCB(p, classPkg, true); + + const bool optionalMapping = useOptionalMapping(p); { open(absoluteAMD, p->file()); @@ -6142,34 +6780,29 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) iter = 0; out << nl << "if(__validateResponse(true))"; out << sb; + FormatType format = p->format(); if(ret || !outParams.empty()) { out << nl << "try"; out << sb; - out << nl << "IceInternal.BasicStream __os = this.__getOs();"; - for(pli = outParams.begin(); pli != outParams.end(); ++pli) + out << nl << "IceInternal.BasicStream __os = this.__startWriteParams();"; + if(p->returnsClasses() && format != DefaultFormat) { - StringList metaData = (*pli)->getMetaData(); - string typeS = typeToString((*pli)->type(), TypeModeIn, classPkg, metaData); - writeMarshalUnmarshalCode(out, classPkg, (*pli)->type(), fixKwd((*pli)->name()), true, iter, - false, metaData); - } - if(ret) - { - string retS = typeToString(ret, TypeModeIn, classPkg, opMetaData); - writeMarshalUnmarshalCode(out, classPkg, ret, "__ret", true, iter, false, opMetaData); - } - if(p->returnsClasses()) - { - out << nl << "__os.writePendingObjects();"; + out << nl << "__os.format(" << formatTypeToString(format) << ");"; } + writeMarshalUnmarshalParams(out, classPkg, outParams, p, iter, true, optionalMapping, false); + out << nl << "this.__endWriteParams(true);"; out << eb; out << nl << "catch(Ice.LocalException __ex)"; out << sb; out << nl << "ice_exception(__ex);"; out << eb; } - out << nl << "__response(true);"; + else + { + out << nl << "__writeEmptyParams();"; + } + out << nl << "__response();"; out << eb; out << eb; @@ -6189,8 +6822,14 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) out << sb; out << nl << "if(__validateResponse(false))"; out << sb; - out << nl << "__getOs().writeUserException(__ex);"; - out << nl << "__response(false);"; + out << nl << "IceInternal.BasicStream __os = __startWriteParams();"; + if(format != DefaultFormat) + { + out << nl << "__os.format(" << formatTypeToString(format) << ");"; + } + out << nl << "__os.writeUserException(__ex);"; + out << nl << "__endWriteParams(false);"; + out << nl << "__response();"; out << eb; out << eb; } |