diff options
Diffstat (limited to 'cpp/src/slice2java/Gen.cpp')
-rw-r--r-- | cpp/src/slice2java/Gen.cpp | 7049 |
1 files changed, 2562 insertions, 4487 deletions
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp index 35c8b12aa42..d91af385c73 100644 --- a/cpp/src/slice2java/Gen.cpp +++ b/cpp/src/slice2java/Gen.cpp @@ -14,7 +14,6 @@ #include <IceUtil/Iterator.h> #include <IceUtil/StringUtil.h> #include <IceUtil/InputUtil.h> -#include <IceUtil/Unicode.h> #include <cstring> #include <limits> @@ -24,558 +23,624 @@ using namespace Slice; using namespace IceUtil; using namespace IceUtilInternal; -string -u16CodePoint(unsigned short value) -{ - ostringstream s; - s << "\\u"; - s << hex; - s.width(4); - s.fill('0'); - s << value; - return s.str(); -} - -void -writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out) +namespace { - vector<unsigned short> u16buffer; - IceUtilInternal::ConversionResult result = convertUTF8ToUTF16(u8buffer, u16buffer, IceUtil::lenientConversion); - switch(result) - { - case conversionOK: - break; - case sourceExhausted: - throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted"); - case sourceIllegal: - throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal"); - default: - { - assert(0); - throw IceUtil::IllegalConversionException(__FILE__, __LINE__); - } - } - - for(vector<unsigned short>::const_iterator c = u16buffer.begin(); c != u16buffer.end(); ++c) - { - out << u16CodePoint(*c); - } -} -static string +string sliceModeToIceMode(Operation::Mode opMode) { - string mode; + string mode = "com.zeroc.Ice.OperationMode."; switch(opMode) { - case Operation::Normal: - { - mode = "Ice.OperationMode.Normal"; - break; - } - case Operation::Nonmutating: - { - mode = "Ice.OperationMode.Nonmutating"; - break; - } - case Operation::Idempotent: - { - mode = "Ice.OperationMode.Idempotent"; - break; - } - default: - { - assert(false); - break; - } + case Operation::Normal: + mode = "null"; // shorthand for most common case + break; + case Operation::Nonmutating: + mode += "Nonmutating"; + break; + case Operation::Idempotent: + mode += "Idempotent"; + break; + default: + assert(false); + break; } return mode; } -static string +string opFormatTypeToString(const OperationPtr& op) { + string format = "com.zeroc.Ice.FormatType."; switch(op->format()) { case DefaultFormat: - return "Ice.FormatType.DefaultFormat"; + format = "null"; // shorthand for most common case + break; case CompactFormat: - return "Ice.FormatType.CompactFormat"; + format += "CompactFormat"; + break; case SlicedFormat: - return "Ice.FormatType.SlicedFormat"; + format += "SlicedFormat"; + break; default: assert(false); + break; } - - return "???"; + return format; } -static string -getDeprecateReason(const ContainedPtr& p1, const ContainedPtr& p2, const string& type) +string +getEscapedParamName(const OperationPtr& p, const string& name) { - string deprecateMetadata, deprecateReason; - if(p1->findMetaData("deprecate", deprecateMetadata) || - (p2 != 0 && p2->findMetaData("deprecate", deprecateMetadata))) + ParamDeclList params = p->parameters(); + + for(ParamDeclList::const_iterator i = params.begin(); i != params.end(); ++i) { - deprecateReason = "This " + type + " has been deprecated."; - if(deprecateMetadata.find("deprecate:") == 0 && deprecateMetadata.size() > 10) + if((*i)->name() == name) { - deprecateReason = deprecateMetadata.substr(10); + return name + "_"; } } - return deprecateReason; + return name; +} + +bool +isDeprecated(const ContainedPtr& p1, const ContainedPtr& p2) +{ + string deprecateMetadata; + return p1->findMetaData("deprecate", deprecateMetadata) || + (p2 != 0 && p2->findMetaData("deprecate", deprecateMetadata)); +} + +bool isValue(const TypePtr& type) +{ + BuiltinPtr b = BuiltinPtr::dynamicCast(type); + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + return (b && b->usesClasses()) || cl; +} + +} + +Slice::JavaVisitor::JavaVisitor(const string& dir) : + JavaGenerator(dir) +{ +} + +Slice::JavaVisitor::~JavaVisitor() +{ } string -initValue(const TypePtr& p) +Slice::JavaVisitor::getResultType(const OperationPtr& op, const string& package, bool object, bool dispatch) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(p); - if(builtin) + if(dispatch && op->hasMarshaledResult()) { - switch(builtin->kind()) - { - case Builtin::KindBool: + const ClassDefPtr c = ClassDefPtr::dynamicCast(op->container()); + assert(c); + string abs; + if(c->isInterface()) { - return "false"; + abs = getAbsolute(c, package); } - case Builtin::KindByte: - { - return "(byte)0"; - } - case Builtin::KindShort: - { - return "(short)0"; - } - case Builtin::KindInt: - case Builtin::KindLong: + else { - return "0"; + abs = getAbsolute(c, package, "_", "Disp"); } - case Builtin::KindFloat: + string name = op->name(); + name[0] = toupper(static_cast<unsigned char>(name[0])); + return abs + "." + name + "MarshaledResult"; + } + else if(op->returnsMultipleValues()) + { + const ContainedPtr c = ContainedPtr::dynamicCast(op->container()); + assert(c); + const string abs = getAbsolute(c, package); + string name = op->name(); + name[0] = toupper(static_cast<unsigned char>(name[0])); + return abs + "." + name + "Result"; + } + else + { + TypePtr type = op->returnType(); + bool optional = op->returnIsOptional(); + if(!type) { - return "(float)0.0"; + const ParamDeclList outParams = op->outParameters(); + if(!outParams.empty()) + { + assert(outParams.size() == 1); + type = outParams.front()->type(); + optional = outParams.front()->optional(); + } } - case Builtin::KindDouble: + if(type) { - return "0.0"; + ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); + assert(cl); + if(optional) + { + return typeToString(type, TypeModeReturn, package, op->getMetaData(), true, true, cl->isLocal()); + } + else if(object) + { + return typeToObjectString(type, TypeModeReturn, package, op->getMetaData(), true, cl->isLocal()); + } + else + { + return typeToString(type, TypeModeReturn, package, op->getMetaData(), true, false, cl->isLocal()); + } } - case Builtin::KindString: - case Builtin::KindObject: - case Builtin::KindObjectProxy: - case Builtin::KindLocalObject: + else { - return "null"; - } + return object ? "Void" : "void"; } } - return "null"; } void -writeParamList(Output& out, vector<string> params, bool end = true, bool newLine = true) +Slice::JavaVisitor::writeResultType(Output& out, const OperationPtr& op, const string& package, const DocCommentPtr& dc) { - out << "("; - out.useCurrentPosAsIndent(); - for(vector<string>::const_iterator i = params.begin(); i != params.end();) + string opName = op->name(); + opName[0] = toupper(static_cast<unsigned char>(opName[0])); + + out << sp << nl << "public static class " << opName << "Result"; + out << sb; + + // + // Make sure none of the out parameters are named "returnValue". + // + string retval = "returnValue"; + const ParamDeclList outParams = op->outParameters(); + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) { - out << (*i); - if(++i != params.end() || !end) + if((*p)->name() == "returnValue") { - out << ", "; - if(newLine) + retval = "_returnValue"; + break; + } + } + + const TypePtr ret = op->returnType(); + const ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); + assert(cl); + + // + // Default constructor. + // + out << nl << "public " << opName << "Result()"; + out << sb; + out << eb; + + // + // One-shot constructor. + // + out << sp; + if(dc) + { + // + // Emit a doc comment for the constructor if necessary. + // + out << nl << "/**"; + out << nl << " * This constructor makes shallow copies of the results for operation " << opName << '.'; + + if(ret && !dc->returns.empty()) + { + out << nl << " * @param " << retval << ' '; + writeDocCommentLines(out, dc->returns); + } + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) + { + const string name = (*p)->name(); + map<string, string>::const_iterator q = dc->params.find(name); + if(q != dc->params.end() && !q->second.empty()) { - out << nl; + out << nl << " * @param " << fixKwd(q->first) << ' '; + writeDocCommentLines(out, q->second); } } + out << nl << " **/"; } - if(end) + out << nl << "public " << opName << "Result" << spar; + if(ret) { - out << ")"; - out.restoreIndent(); + out << (typeToString(ret, TypeModeIn, package, op->getMetaData(), true, op->returnIsOptional(), cl->isLocal()) + + " " + retval); } -} - -Slice::JavaVisitor::JavaVisitor(const string& dir) : - JavaGenerator(dir) -{ -} - -Slice::JavaVisitor::~JavaVisitor() -{ -} + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) + { + out << (typeToString((*p)->type(), TypeModeIn, package, (*p)->getMetaData(), true, (*p)->optional(), + cl->isLocal()) + " " + fixKwd((*p)->name())); + } + out << epar; + out << sb; + if(ret) + { + out << nl << "this." << retval << " = " << retval << ';'; + } + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) + { + const string name = fixKwd((*p)->name()); + out << nl << "this." << name << " = " << name << ';'; + } + out << eb; -ParamDeclList -Slice::JavaVisitor::getOutParams(const OperationPtr& op) -{ - ParamDeclList outParams; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator i = paramList.begin(); i != paramList.end(); ++i) + // + // Members. + // + out << sp; + if(ret) { - if((*i)->isOutParam()) + if(dc && !dc->returns.empty()) { - outParams.push_back(*i); + out << nl << "/**"; + out << nl << " * "; + writeDocCommentLines(out, dc->returns); + out << nl << " **/"; } + out << nl << "public " << typeToString(ret, TypeModeIn, package, op->getMetaData(), true, + op->returnIsOptional(), cl->isLocal()) + << ' ' << retval << ';'; } - return outParams; -} -vector<string> -Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package, bool local, bool optionalMapping) -{ - vector<string> params; - - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) { - StringList metaData = (*q)->getMetaData(); - bool optional = (*q)->optional(); - if(optional && (local || (*q)->isOutParam())) + if(dc) { - optional = optionalMapping; + const string name = (*p)->name(); + map<string, string>::const_iterator q = dc->params.find(name); + if(q != dc->params.end() && !q->second.empty()) + { + out << nl << "/**"; + out << nl << " * "; + writeDocCommentLines(out, q->second); + out << nl << " **/"; + } } - string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package, - metaData, true, optional); - params.push_back(typeString + ' ' + fixKwd((*q)->name())); + out << nl << "public " << typeToString((*p)->type(), TypeModeIn, package, (*p)->getMetaData(), true, + (*p)->optional(), cl->isLocal()) + << ' ' << fixKwd((*p)->name()) << ';'; } - return params; -} + if(!cl->isLocal()) + { + ParamDeclList required, optional; + op->outParameters(required, optional); -vector<string> -Slice::JavaVisitor::getParamsProxy(const OperationPtr& op, const string& package, bool final, bool optionalMapping) -{ - vector<string> params; + out << sp << nl << "public void write(com.zeroc.Ice.OutputStream ostr)"; + out << sb; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) - { - bool optional; - if((*q)->optional()) + int iter = 0; + for(ParamDeclList::const_iterator pli = required.begin(); pli != required.end(); ++pli) { - optional = (*q)->isOutParam() ? true : optionalMapping; + const string paramName = fixKwd((*pli)->name()); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalNone, false, 0, paramName, true, iter, "", + (*pli)->getMetaData()); } - else + + if(ret && !op->returnIsOptional()) { - optional = false; + writeMarshalUnmarshalCode(out, package, ret, OptionalNone, false, 0, retval, true, iter, "", op->getMetaData()); } - StringList metaData = (*q)->getMetaData(); - string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package, - metaData, true, optional); - if(final) + // + // Handle optional parameters. + // + bool checkReturnType = op->returnIsOptional(); + + for(ParamDeclList::const_iterator pli = optional.begin(); pli != optional.end(); ++pli) { - typeString = "final " + typeString; + if(checkReturnType && op->returnTag() < (*pli)->tag()) + { + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, true, op->returnTag(), retval, true, + iter, "", op->getMetaData()); + checkReturnType = false; + } + + const string paramName = fixKwd((*pli)->name()); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalOutParam, true, (*pli)->tag(), paramName, + true, iter, "", (*pli)->getMetaData()); } - params.push_back(typeString + ' ' + fixKwd((*q)->name())); - } - return params; -} + if(checkReturnType) + { + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, true, op->returnTag(), retval, true, iter, + "", op->getMetaData()); + } -vector<string> -Slice::JavaVisitor::getInOutParams(const OperationPtr& op, const string& package, ParamDir paramType, bool /*proxy*/, - bool optionalMapping) -{ - vector<string> params; + out << eb; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) - { - if((*q)->isOutParam() == (paramType == OutParam)) + out << sp << nl << "public void read(com.zeroc.Ice.InputStream istr)"; + out << sb; + + iter = 0; + for(ParamDeclList::const_iterator pli = required.begin(); pli != required.end(); ++pli) + { + const string paramName = fixKwd((*pli)->name()); + const string patchParams = getPatcher((*pli)->type(), package, paramName, false); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalNone, false, 0, paramName, false, iter, + "", (*pli)->getMetaData(), patchParams); + } + + if(ret && !op->returnIsOptional()) { - bool optional = optionalMapping && (*q)->optional(); - string typeString = typeToString((*q)->type(), paramType == InParam ? TypeModeIn : TypeModeOut, package, - (*q)->getMetaData(), true, optional); - params.push_back(typeString + ' ' + fixKwd((*q)->name())); + const string patchParams = getPatcher(ret, package, retval, false); + writeMarshalUnmarshalCode(out, package, ret, OptionalNone, false, 0, retval, false, iter, "", op->getMetaData(), + patchParams); } + + // + // Handle optional parameters. + // + checkReturnType = op->returnIsOptional(); + + for(ParamDeclList::const_iterator pli = optional.begin(); pli != optional.end(); ++pli) + { + if(checkReturnType && op->returnTag() < (*pli)->tag()) + { + const string patchParams = getPatcher(ret, package, retval, true); + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, true, op->returnTag(), retval, false, + iter, "", op->getMetaData(), patchParams); + checkReturnType = false; + } + + const string paramName = fixKwd((*pli)->name()); + const string patchParams = getPatcher((*pli)->type(), package, paramName, true); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalOutParam, true, (*pli)->tag(), paramName, + false, iter, "", (*pli)->getMetaData(), patchParams); + } + + if(checkReturnType) + { + const string patchParams = getPatcher(ret, package, retval, true); + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, true, op->returnTag(), retval, false, + iter, "", op->getMetaData(), patchParams); + } + + out << eb; } - return params; + out << eb; } -vector<string> -Slice::JavaVisitor::getParamsAsync(const OperationPtr& op, const string& package, bool amd, bool optionalMapping) +void +Slice::JavaVisitor::writeMarshaledResultType(Output& out, const OperationPtr& op, const string& package, + const DocCommentPtr& dc) { - vector<string> params = getInOutParams(op, package, InParam, !amd, optionalMapping); + string opName = op->name(); + opName[0] = toupper(static_cast<unsigned char>(opName[0])); - string name = op->name(); - ContainerPtr container = op->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - string classNameAsync = getAbsolute(cl, package, amd ? "AMD_" : "AMI_", '_' + name); - params.insert(params.begin(), classNameAsync + " __cb"); + out << sp << nl << "public static class " << opName << "MarshaledResult implements com.zeroc.Ice.MarshaledResult"; + out << sb; - return params; -} + const TypePtr ret = op->returnType(); + const ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); + assert(cl); + const ParamDeclList outParams = op->outParameters(); + const string retval = getEscapedParamName(op, "returnValue"); + const string currentParamName = getEscapedParamName(op, "current"); + const string currentParam = "com.zeroc.Ice.Current " + currentParamName; -vector<string> -Slice::JavaVisitor::getParamsAsyncCB(const OperationPtr& op, const string& package, bool /*amd*/, bool optionalMapping) -{ - vector<string> params; + out << sp; - TypePtr ret = op->returnType(); + // + // Emit a doc comment for the constructor if necessary. + // + if(dc) + { + out << nl << "/**"; + out << nl << " * This constructor marshals the results of operation " << opName << " immediately."; + + if(ret && !dc->returns.empty()) + { + out << nl << " * @param " << retval << ' '; + writeDocCommentLines(out, dc->returns); + } + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) + { + const string name = (*p)->name(); + map<string, string>::const_iterator q = dc->params.find(name); + if(q != dc->params.end() && !q->second.empty()) + { + out << nl << " * @param " << fixKwd(q->first) << ' '; + writeDocCommentLines(out, q->second); + } + } + out << nl << " * @param " << currentParamName << " The Current object for the invocation."; + out << nl << " **/"; + } + + out << nl << "public " << opName << "MarshaledResult" << spar; if(ret) { - string retS = typeToString(ret, TypeModeIn, package, op->getMetaData(), true, - optionalMapping && op->returnIsOptional()); - params.push_back(retS + " __ret"); + out << (typeToString(ret, TypeModeIn, package, op->getMetaData(), true, op->returnIsOptional(), cl->isLocal()) + + " " + retval); } + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) + { + out << (typeToString((*p)->type(), TypeModeIn, package, (*p)->getMetaData(), true, (*p)->optional(), + cl->isLocal()) + " " + fixKwd((*p)->name())); + } + out << currentParam << epar; + out << sb; + out << nl << "_ostr = com.zeroc.IceInternal.Incoming.createResponseOutputStream(" << currentParamName << ");"; + out << nl << "_ostr.startEncapsulation(" << currentParamName << ".encoding, " << opFormatTypeToString(op) << ");"; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + ParamDeclList required, optional; + op->outParameters(required, optional); + int iter = 0; + for(ParamDeclList::const_iterator pli = required.begin(); pli != required.end(); ++pli) + { + const string paramName = fixKwd((*pli)->name()); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalNone, false, 0, paramName, true, iter, + "_ostr", (*pli)->getMetaData()); + } + + if(ret && !op->returnIsOptional()) { - if((*q)->isOutParam()) + writeMarshalUnmarshalCode(out, package, ret, OptionalNone, false, 0, retval, true, iter, "_ostr", + op->getMetaData()); + } + + // + // Handle optional parameters. + // + bool checkReturnType = op->returnIsOptional(); + + for(ParamDeclList::const_iterator pli = optional.begin(); pli != optional.end(); ++pli) + { + if(checkReturnType && op->returnTag() < (*pli)->tag()) { - string typeString = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData(), true, - optionalMapping && (*q)->optional()); - params.push_back(typeString + ' ' + fixKwd((*q)->name())); + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, true, op->returnTag(), retval, true, + iter, "_ostr", op->getMetaData()); + checkReturnType = false; } + + const string paramName = fixKwd((*pli)->name()); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalOutParam, true, (*pli)->tag(), paramName, + true, iter, "_ostr", (*pli)->getMetaData()); } - return params; -} + if(checkReturnType) + { + writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, true, op->returnTag(), retval, true, iter, + "_ostr", op->getMetaData()); + } -namespace -{ + if(op->returnsClasses(false)) + { + out << nl << "_ostr.writePendingValues();"; + } -const char* builtinAsyncCallbackTable[] = -{ - "TwowayCallbackByte", - "TwowayCallbackBool", - "TwowayCallbackShort", - "TwowayCallbackInt", - "TwowayCallbackLong", - "TwowayCallbackFloat", - "TwowayCallbackDouble" -}; + out << nl << "_ostr.endEncapsulation();"; + + out << eb; + out << sp; + out << nl << "@Override" + << nl << "public com.zeroc.Ice.OutputStream getOutputStream()" + << sb + << nl << "return _ostr;" + << eb; + + out << sp; + out << nl << "private com.zeroc.Ice.OutputStream _ostr;"; + out << eb; } -string -Slice::JavaVisitor::getAsyncCallbackInterface(const OperationPtr& op, const string& package) +void +Slice::JavaVisitor::allocatePatcher(Output& out, const TypePtr& type, const string& package, const string& name) { - TypePtr ret = op->returnType(); - ParamDeclList outParams = getOutParams(op); - bool throws = !op->throws().empty(); - const string suffix = throws ? "UE" : ""; + BuiltinPtr b = BuiltinPtr::dynamicCast(type); + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + assert((b && b->usesClasses()) || cl); - if(!ret && outParams.empty()) + string clsName; + if(b || cl->isInterface()) { - return throws ? "Ice.TwowayCallbackVoidUE" : "Ice.OnewayCallback"; - } - else if((ret && outParams.empty()) || (!ret && outParams.size() == 1)) - { - TypePtr t = ret ? ret : outParams.front()->type(); - bool optional = ret ? op->returnIsOptional() : outParams.front()->optional(); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(t); - if(builtin && !optional) - { - const string prefix = "Ice."; - switch(builtin->kind()) - { - case Builtin::KindByte: - case Builtin::KindBool: - case Builtin::KindShort: - case Builtin::KindInt: - case Builtin::KindLong: - case Builtin::KindFloat: - case Builtin::KindDouble: - { - return prefix + builtinAsyncCallbackTable[builtin->kind()] + suffix; - } - default: - { - break; - } - } - } - - return "Ice.TwowayCallbackArg1" + suffix + "<" + - typeToString(t, TypeModeIn, package, op->getMetaData(), true, optional) + ">"; + clsName = "com.zeroc.Ice.Value"; } else { - ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); - return "_Callback_" + cl->name() + "_" + op->name(); + clsName = getAbsolute(cl, package); } + + out << nl << "com.zeroc.IceInternal.Patcher<" << clsName << "> " << name << " = new com.zeroc.IceInternal.Patcher<" + << clsName << ">(" << clsName << ".class, " << clsName << ".ice_staticId());"; } string -Slice::JavaVisitor::getAsyncCallbackBaseClass(const OperationPtr& op, bool functional) +Slice::JavaVisitor::getPatcher(const TypePtr& type, const string& package, const string& dest, bool optionalMapping) { - assert(op->returnsData()); - TypePtr ret = op->returnType(); - ParamDeclList outParams = getOutParams(op); - - bool throws = !op->throws().empty(); - const string suffix = throws ? "UE" : ""; - if(!ret && outParams.empty()) + BuiltinPtr b = BuiltinPtr::dynamicCast(type); + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + ostringstream ostr; + if((b && b->usesClasses()) || cl) { - assert(throws); - return functional ? - "IceInternal.Functional_TwowayCallbackVoidUE" : - "IceInternal.TwowayCallback implements Ice.TwowayCallbackVoidUE"; - } - else if((ret && outParams.empty()) || (!ret && outParams.size() == 1)) - { - TypePtr t = ret ? ret : outParams.front()->type(); - bool optional = ret ? op->returnIsOptional() : outParams.front()->optional(); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(t); - if(builtin && !optional) + string clsName; + if(b || cl->isInterface()) { - switch(builtin->kind()) - { - case Builtin::KindByte: - case Builtin::KindBool: - case Builtin::KindShort: - case Builtin::KindInt: - case Builtin::KindLong: - case Builtin::KindFloat: - case Builtin::KindDouble: - { - ostringstream os; - os << (functional ? "IceInternal.Functional_" : "IceInternal.TwowayCallback implements Ice.") - << builtinAsyncCallbackTable[builtin->kind()] + suffix; - return os.str(); - } - default: - { - break; - } - } - } - - ostringstream os; - if(functional) - { - os << "IceInternal.Functional_TwowayCallbackArg1"; + clsName = "com.zeroc.Ice.Value"; } else { - os << "IceInternal.TwowayCallback implements Ice.TwowayCallbackArg1"; + clsName = getAbsolute(cl, package); } - os << suffix << "<" << typeToString(t, TypeModeIn, getPackage(op), op->getMetaData(), true, optional) + ">"; - return os.str(); - } - else - { - ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); - ostringstream os; - if(functional) + + ostr << "new com.zeroc.IceInternal.Patcher<" << clsName << ">(" << clsName << ".class, " + << clsName << ".ice_staticId(), " << "v -> "; + if(optionalMapping) { - os << "IceInternal.Functional_TwowayCallback" << suffix << " implements "; + ostr << dest << " = java.util.Optional.ofNullable(v)"; } else { - os << "IceInternal.TwowayCallback implements "; + ostr << dest << " = v"; } - os << "_Callback_" << cl->name() << "_" << op->name(); - return os.str(); + ostr << ')'; } + return ostr.str(); } string -Slice::JavaVisitor::getLambdaResponseCB(const OperationPtr& op, const string& package) +Slice::JavaVisitor::getFutureType(const OperationPtr& op, const string& package) { - TypePtr ret = op->returnType(); - ParamDeclList outParams = getOutParams(op); - if(!ret && outParams.empty()) + if(op->returnType() || op->outParameters().size() > 0) { - return "IceInternal.Functional_VoidCallback"; - } - else if((ret && outParams.empty()) || (!ret && outParams.size() == 1)) - { - TypePtr t = ret ? ret : outParams.front()->type(); - bool optional = ret ? op->returnIsOptional() : outParams.front()->optional(); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(t); - if(builtin && !optional) - { - static const char* builtinTable[] = - { - "IceInternal.Functional_ByteCallback", - "IceInternal.Functional_BoolCallback", - "IceInternal.Functional_ShortCallback", - "IceInternal.Functional_IntCallback", - "IceInternal.Functional_LongCallback", - "IceInternal.Functional_FloatCallback", - "IceInternal.Functional_DoubleCallback" - }; - switch(builtin->kind()) - { - case Builtin::KindByte: - case Builtin::KindBool: - case Builtin::KindShort: - case Builtin::KindInt: - case Builtin::KindLong: - case Builtin::KindFloat: - case Builtin::KindDouble: - { - return builtinTable[builtin->kind()]; - } - default: - { - break; - } - } - } - - return "IceInternal.Functional_GenericCallback1<" + - typeToString(t, TypeModeIn, package, op->getMetaData(), true, optional) + ">"; + return "java.util.concurrent.CompletableFuture<" + getResultType(op, package, true, false) + ">"; } else { - ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); - return "FunctionalCallback_" + cl->name() + "_" + op->name() + "_Response"; + return "java.util.concurrent.CompletableFuture<Void>"; } } -vector<string> -Slice::JavaVisitor::getParamsAsyncLambda(const OperationPtr& op, const string& package, bool context, bool sentCB, - bool optionalMapping, bool inParams) +string +Slice::JavaVisitor::getFutureImplType(const OperationPtr& op, const string& package) { - vector<string> params; - - if(inParams) + if(op->returnType() || op->outParameters().size() > 0) { - params = getInOutParams(op, package, InParam, false, optionalMapping); + return "com.zeroc.IceInternal.OutgoingAsync<" + getResultType(op, package, true, false) + ">"; } - - if(context) + else { - params.push_back("java.util.Map<String, String> __ctx"); + return "com.zeroc.IceInternal.OutgoingAsync<Void>"; } +} - params.push_back(getLambdaResponseCB(op, package) + " __responseCb"); - - if(!op->throws().empty()) - { - params.push_back("IceInternal.Functional_GenericCallback1<Ice.UserException> __userExceptionCb"); - } +vector<string> +Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package) +{ + vector<string> params; - params.push_back("IceInternal.Functional_GenericCallback1<Ice.Exception> __exceptionCb"); + const ClassDefPtr cl = ClassDefPtr::dynamicCast(op->container()); + assert(cl); - if(sentCB) + const ParamDeclList paramList = op->inParameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) { - params.push_back("IceInternal.Functional_BoolCallback __sentCb"); + const string type = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData(), true, + (*q)->optional(), cl->isLocal()); + params.push_back(type + ' ' + fixKwd((*q)->name())); } return params; } vector<string> -Slice::JavaVisitor::getArgsAsyncLambda(const OperationPtr& op, const string& package, bool context, bool sentCB) +Slice::JavaVisitor::getParamsProxy(const OperationPtr& op, const string& package, bool optionalMapping, bool internal) { - vector<string> args = getInOutArgs(op, InParam); - args.push_back(context ? "__ctx" : "null"); - args.push_back(context ? "true" : "false"); - args.push_back("false"); // __synchronous - args.push_back("__responseCb"); - if(!op->throws().empty()) + vector<string> params; + + ParamDeclList inParams = op->inParameters(); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) { - args.push_back("__userExceptionCb"); + const string typeString = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData(), true, + optionalMapping && (*q)->optional()); + params.push_back(typeString + ' ' + (internal ? "iceP_" + (*q)->name() : fixKwd((*q)->name()))); } - args.push_back("__exceptionCb"); - args.push_back(sentCB ? "__sentCb" : "null"); - return args; + + return params; } vector<string> @@ -593,175 +658,186 @@ Slice::JavaVisitor::getArgs(const OperationPtr& op) } vector<string> -Slice::JavaVisitor::getInOutArgs(const OperationPtr& op, ParamDir paramType) +Slice::JavaVisitor::getInArgs(const OperationPtr& op, bool internal) { vector<string> args; - ParamDeclList paramList = op->parameters(); + ParamDeclList paramList = op->inParameters(); for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) { - if((*q)->isOutParam() == (paramType == OutParam)) - { - args.push_back(fixKwd((*q)->name())); - } + string s = internal ? "iceP_" + (*q)->name() : fixKwd((*q)->name()); + args.push_back(s); } return args; } -vector<string> -Slice::JavaVisitor::getArgsAsync(const OperationPtr& op) -{ - vector<string> args = getInOutArgs(op, InParam); - args.insert(args.begin(), "__cb"); - return args; -} - -vector<string> -Slice::JavaVisitor::getArgsAsyncCB(const OperationPtr& op) +void +Slice::JavaVisitor::writeMarshalProxyParams(Output& out, const string& package, const OperationPtr& op, + bool optionalMapping) { - vector<string> args; - - TypePtr ret = op->returnType(); - if(ret) + int iter = 0; + ParamDeclList required, optional; + op->inParameters(required, optional); + for(ParamDeclList::const_iterator pli = required.begin(); pli != required.end(); ++pli) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret)) - { - args.push_back("__ret.value"); - } - else - { - args.push_back("__ret"); - } + string paramName = "iceP_" + (*pli)->name(); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalNone, false, 0, paramName, true, + iter, "", (*pli)->getMetaData()); } - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + // + // Handle optional parameters. + // + for(ParamDeclList::const_iterator pli = optional.begin(); pli != optional.end(); ++pli) { - if((*q)->isOutParam()) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast((*q)->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*q)->type())) - { - args.push_back(fixKwd((*q)->name()) + ".value"); - } - else - { - args.push_back(fixKwd((*q)->name())); - } - } + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalInParam, optionalMapping, + (*pli)->tag(), "iceP_" + (*pli)->name(), true, iter, "", (*pli)->getMetaData()); } - return args; + if(op->sendsClasses(false)) + { + out << nl << "ostr.writePendingValues();"; + } } void -Slice::JavaVisitor::writeMarshalUnmarshalParams(Output& out, const string& package, const ParamDeclList& params, - const OperationPtr& op, int& iter, bool marshal, bool optionalMapping, - bool dispatch) +Slice::JavaVisitor::writeUnmarshalProxyResults(Output& out, const string& package, const OperationPtr& op) { - ParamDeclList optionals; - for(ParamDeclList::const_iterator pli = params.begin(); pli != params.end(); ++pli) + const ParamDeclList outParams = op->outParameters(); + const TypePtr ret = op->returnType(); + const string name = "ret"; + + if(op->returnsMultipleValues()) { - if((*pli)->optional()) + string resultType = getResultType(op, package, false, false); + out << nl << resultType << ' ' << name << " = new " << resultType << "();"; + out << nl << name << ".read(istr);"; + if(op->returnsClasses(false)) { - optionals.push_back(*pli); + out << nl << "istr.readPendingValues();"; + } + out << nl << "return " << name << ';'; + } + else + { + string resultType = getResultType(op, package, false, false); + + bool optional; + TypePtr type; + int tag; + StringList metaData; + if(ret) + { + type = ret; + optional = op->returnIsOptional(); + tag = op->returnTag(); + metaData = op->getMetaData(); } 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); + assert(outParams.size() == 1); + optional = outParams.front()->optional(); + type = outParams.front()->type(); + tag = outParams.front()->tag(); + metaData = outParams.front()->getMetaData(); } - } - TypePtr ret; - bool returnsObject = false; + const bool val = isValue(type); - 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; + int iter = 0; - if(!marshal) + if(optional) { - if(optional) + if(val) + { + allocatePatcher(out, type, package, name); + } + else { - out << nl << retS << " __ret = new " << retS << "();"; + out << nl << resultType << ' ' << name << ';'; } - else if(returnsObject) + writeMarshalUnmarshalCode(out, package, type, ret ? OptionalReturnParam : OptionalOutParam, true, + tag, name, false, iter, "", metaData, name); + } + else + { + if(val) { - out << nl << retS << "Holder __ret = new " << retS << "Holder();"; - holder = true; + allocatePatcher(out, type, package, name); } - else if(StructPtr::dynamicCast(ret)) + else if(StructPtr::dynamicCast(type)) { - out << nl << retS << " __ret = null;"; + out << nl << resultType << ' ' << name << " = null;"; } else { - out << nl << retS << " __ret;"; + out << nl << resultType << ' ' << name << ';'; } + writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, name, false, iter, "", metaData, name); } - if(!op->returnIsOptional()) + if(op->returnsClasses(false)) { - writeMarshalUnmarshalCode(out, package, ret, OptionalNone, false, 0, "__ret", marshal, iter, holder, - op->getMetaData()); + out << nl << "istr.readPendingValues();"; } - } - // - // Sort optional parameters by tag. - // - class SortFn - { - public: - static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + if(optional && val) { - return lhs->tag() < rhs->tag(); + out << nl << "return java.util.Optional.ofNullable(" << name << ".value);"; } - }; - optionals.sort(SortFn::compare); - - // - // Handle optional parameters. - // - bool checkReturnType = op && op->returnIsOptional(); + else if(val) + { + out << nl << "return " << name << ".value;"; + } + else + { + out << nl << "return " << name << ';'; + } + } +} - for(ParamDeclList::const_iterator pli = optionals.begin(); pli != optionals.end(); ++pli) +void +Slice::JavaVisitor::writeMarshalServantResults(Output& out, const string& package, const OperationPtr& op, + const string& param) +{ + if(op->returnsMultipleValues()) { - if(checkReturnType && op->returnTag() < (*pli)->tag()) + out << nl << param << ".write(ostr);"; + } + else + { + const ParamDeclList params = op->outParameters(); + bool optional; + OptionalMode mode; + TypePtr type; + int tag; + StringList metaData; + if(op->returnType()) + { + type = op->returnType(); + optional = op->returnIsOptional(); + mode = optional ? OptionalReturnParam : OptionalNone; + tag = op->returnTag(); + metaData = op->getMetaData(); + } + else { - writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, optionalMapping, op->returnTag(), - "__ret", marshal, iter, false, op->getMetaData()); - checkReturnType = false; + assert(params.size() == 1); + optional = params.front()->optional(); + mode = optional ? OptionalOutParam : OptionalNone; + type = params.front()->type(); + tag = params.front()->tag(); + metaData = params.front()->getMetaData(); } - 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()); + int iter = 0; + writeMarshalUnmarshalCode(out, package, type, mode, true, tag, param, true, iter, "", metaData); } - if(checkReturnType) + if(op->returnsClasses(false)) { - writeMarshalUnmarshalCode(out, package, ret, OptionalReturnParam, optionalMapping, op->returnTag(), "__ret", - marshal, iter, false, op->getMetaData()); + out << nl << "ostr.writePendingValues();"; } } @@ -790,291 +866,121 @@ Slice::JavaVisitor::writeThrowsClause(const string& package, const ExceptionList } void -Slice::JavaVisitor::writeMarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, int& iter) +Slice::JavaVisitor::writeMarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, int& iter, bool forStruct) { - if(!member->optional()) - { - writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, fixKwd(member->name()), - true, iter, false, member->getMetaData()); - } - else + if(member->optional()) { - out << nl << "if(__has_" << member->name() << " && __os.writeOpt(" << member->tag() << ", " + assert(!forStruct); + out << nl << "if(_" << member->name() << " && ostr_.writeOptional(" << member->tag() << ", " << getOptionalFormat(member->type()) << "))"; out << sb; writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), true, - iter, false, member->getMetaData()); + iter, "ostr_", 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) + else { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + string stream = forStruct ? "" : "ostr_"; + string memberName = fixKwd(member->name()); + if(forStruct) { - ostringstream ostr; - ostr << "new Patcher(" << patchIter++ << ')'; - patchParams = ostr.str(); + memberName = "this." + memberName; } - } - 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() << ", " - << getOptionalFormat(member->type()) << "))"; - out << sb; - writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), false, - iter, false, member->getMetaData(), patchParams); - out << eb; + writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, memberName, + true, iter, stream, member->getMetaData()); } } void -Slice::JavaVisitor::writeStreamMarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, - int& iter) +Slice::JavaVisitor::writeUnmarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, int& iter, bool forStruct) { - if(!member->optional()) - { - writeStreamMarshalUnmarshalCode(out, package, member->type(), false, 0, fixKwd(member->name()), true, - iter, false, member->getMetaData()); - } - else + // TBD: Handle passing interface-by-value + + const string patchParams = getPatcher(member->type(), package, fixKwd(member->name()), false); + + if(member->optional()) { - out << nl << "if(__has_" << member->name() << " && __outS.writeOptional(" << member->tag() << ", " + assert(!forStruct); + out << nl << "if(_" << member->name() << " = istr_.readOptional(" << member->tag() << ", " << getOptionalFormat(member->type()) << "))"; out << sb; - writeStreamMarshalUnmarshalCode(out, package, member->type(), true, member->tag(), fixKwd(member->name()), - true, iter, false, member->getMetaData()); + writeMarshalUnmarshalCode(out, package, member->type(), OptionalMember, false, 0, fixKwd(member->name()), false, + iter, "istr_", member->getMetaData(), patchParams); out << eb; } -} - -void -Slice::JavaVisitor::writeStreamUnmarshalDataMember(Output& out, const string& package, const DataMemberPtr& member, - int& iter, bool needPatcher, int& patchIter) -{ - string patchParams; - if(needPatcher) + else { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(member->type()); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(member->type())) + string stream = forStruct ? "" : "istr_"; + string memberName = fixKwd(member->name()); + if(forStruct) { - ostringstream ostr; - ostr << "new Patcher(" << patchIter++ << ')'; - patchParams = ostr.str(); + memberName = "this." + memberName; } - } - if(!member->optional()) - { - writeStreamMarshalUnmarshalCode(out, package, member->type(), false, 0, fixKwd(member->name()), false, - iter, false, member->getMetaData(), patchParams); - } - else - { - out << nl << "if(__has_" << member->name() << " = __inS.readOptional(" << member->tag() << ", " - << getOptionalFormat(member->type()) << "))"; - out << sb; - writeStreamMarshalUnmarshalCode(out, package, member->type(), true, member->tag(), fixKwd(member->name()), - false, iter, false, member->getMetaData(), patchParams); - out << eb; + writeMarshalUnmarshalCode(out, package, member->type(), OptionalNone, false, 0, memberName, false, + iter, stream, member->getMetaData(), patchParams); } } void -Slice::JavaVisitor::writePatcher(Output& out, const string& package, const DataMemberList& classMembers, - const DataMemberList& optionalMembers, bool stream) +Slice::JavaVisitor::writeDispatch(Output& out, const ClassDefPtr& p) { - out << sp << nl << "private class Patcher implements IceInternal.Patcher"; - if(stream) - { - out << ", Ice.ReadObjectCallback"; - } - out << sb; - if(classMembers.size() > 1) + const string name = fixKwd(p->name()); + const string package = getPackage(p); + const string scoped = p->scoped(); + const ClassList bases = p->bases(); + ClassDefPtr base; + if(!bases.empty() && !bases.front()->isInterface()) { - out << sp << nl << "Patcher(int member)"; - out << sb; - out << nl << "__member = member;"; - out << eb; + base = bases.front(); } + const OperationList ops = p->operations(); - 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) + for(OperationList::const_iterator r = ops.begin(); r != ops.end(); ++r) { - if((*d)->optional()) - { - continue; - } + OperationPtr op = *r; - BuiltinPtr b = BuiltinPtr::dynamicCast((*d)->type()); - if(b) - { - assert(b->kind() == Builtin::KindObject); - } + DocCommentPtr dc = parseDocComment(op); - if(classMembers.size() > 1) + // + // The "MarshaledResult" type is generated in the servant interface. + // + if(!p->isInterface() && op->hasMarshaledResult()) { - out.dec(); - out << nl << "case " << memberCount << ":"; - out.inc(); - if(b) - { - out << nl << "__typeId = Ice.ObjectImpl.ice_staticId();"; - } - else - { - out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";"; - } + writeMarshaledResultType(out, op, package, dc); } - 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; - } + vector<string> params = getParams(op, package); + const string currentParam = "com.zeroc.Ice.Current " + getEscapedParamName(op, "current"); - if(classMembers.size() > 1) - { - out << nl << "break;"; - } + const bool amd = p->hasMetaData("amd") || op->hasMetaData("amd"); - memberCount++; - } + ExceptionList throws = op->throws(); + throws.sort(); + throws.unique(); - for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) - { - BuiltinPtr b = BuiltinPtr::dynamicCast((*d)->type()); - if(b && b->kind() != Builtin::KindObject) + out << sp; + writeServantDocComment(out, op, package, dc, amd); + if(dc && dc->deprecated) { - continue; + out << nl << "@Deprecated"; } - TypePtr paramType = (*d)->type(); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) + if(amd) { - - 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() << "\";"; - } - } - - 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; - } - - if(classMembers.size() > 1) - { - out << nl << "break;"; - } - - memberCount++; + out << nl << "java.util.concurrent.CompletionStage<" << getResultType(op, package, true, true) << "> " + << op->name() << "Async" << spar << params << currentParam << epar; + writeThrowsClause(package, throws); + out << ';'; + } + else + { + out << nl << getResultType(op, package, false, true) << ' ' << fixKwd(op->name()) << spar << params + << currentParam << epar; + writeThrowsClause(package, throws); + out << ';'; } - } - - 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(); @@ -1086,12 +992,12 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& other.sort(); ids.merge(other); ids.unique(); - StringList::const_iterator firstIter = ids.begin(); +#ifndef NDEBUG StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), scoped); assert(scopedIter != ids.end()); - StringList::difference_type scopedPos = ::IceUtilInternal::distance(firstIter, scopedIter); +#endif - out << sp << nl << "public static final String[] __ids ="; + out << sp << nl << "static final String[] _iceIds ="; out << sb; for(StringList::const_iterator q = ids.begin(); q != ids.end();) @@ -1104,254 +1010,102 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& } out << eb << ';'; - out << sp << nl << "public boolean ice_isA(String s)"; - out << sb; - out << nl << "return java.util.Arrays.binarySearch(__ids, s) >= 0;"; - out << eb; - - out << sp << nl << "public boolean ice_isA(String s, Ice.Current __current)"; - out << sb; - out << nl << "return java.util.Arrays.binarySearch(__ids, s) >= 0;"; - out << eb; - - out << sp << nl << "public String[] ice_ids()"; - out << sb; - out << nl << "return __ids;"; - out << eb; - - out << sp << nl << "public String[] ice_ids(Ice.Current __current)"; - out << sb; - out << nl << "return __ids;"; - out << eb; - - out << sp << nl << "public String ice_id()"; + out << sp << nl << "@Override" << nl << "default String[] ice_ids(com.zeroc.Ice.Current current)"; out << sb; - out << nl << "return __ids[" << scopedPos << "];"; + out << nl << "return _iceIds;"; out << eb; - out << sp << nl << "public String ice_id(Ice.Current __current)"; + out << sp << nl << "@Override" << nl << "default String ice_id(com.zeroc.Ice.Current current)"; out << sb; - out << nl << "return __ids[" << scopedPos << "];"; + out << nl << "return ice_staticId();"; out << eb; - out << sp << nl << "public static String ice_staticId()"; + out << sp << nl; + out << "static String ice_staticId()"; out << sb; - out << nl << "return __ids[" << scopedPos << "];"; + if(p->isInterface()) + { + out << nl << "return \"" << p->scoped() << "\";"; + } + else + { + out << nl << "return " << fixKwd(p->name()) << ".ice_staticId();"; + } out << eb; - OperationList ops = p->allOperations(); - // - // Write the "no Current" implementation of each operation. + // Dispatch methods. We only generate methods for operations + // defined in this ClassDef, because we reuse existing methods + // for inherited operations. // for(OperationList::const_iterator r = ops.begin(); r != ops.end(); ++r) { OperationPtr op = *r; - string opName = op->name(); - - ContainerPtr container = op->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - assert(cl); - - string deprecateReason = getDeprecateReason(op, cl, "operation"); - - const bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); - const bool optionalMapping = useOptionalMapping(op); + StringList opMetaData = op->getMetaData(); - vector<string> params; - vector<string> args; - TypePtr ret; + DocCommentPtr dc = parseDocComment(op); - if(amd) + string opName = op->name(); + out << sp; + if(dc && dc->deprecated) { - opName += "_async"; - params = getParamsAsync(op, package, true, true); - args = getArgsAsync(op); + out << nl << "@Deprecated"; } - else + out << nl << "static java.util.concurrent.CompletionStage<com.zeroc.Ice.OutputStream> _iceD_" << opName << '('; + if(p->isInterface()) { - opName = fixKwd(opName); - ret = op->returnType(); - params = getParams(op, package, false, optionalMapping); - args = getArgs(op); + out << name; } - - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - - // - // Only generate a "no current" version of the operation if it hasn't been done in a base - // class already, because the "no current" version is final. - // - bool generateOperation = cl == p; // Generate if the operation is defined in this class. - if(!generateOperation) + else { - // - // The operation is not defined in this class. - // - if(!bases.empty()) - { - // - // Check if the operation is already implemented by a base class. - // - bool implementedByBase = false; - if(!bases.front()->isInterface()) - { - OperationList baseOps = bases.front()->allOperations(); - OperationList::const_iterator i; - for(i = baseOps.begin(); i != baseOps.end(); ++i) - { - if((*i)->name() == op->name()) - { - implementedByBase = true; - break; - } - } - if(i == baseOps.end()) - { - generateOperation = true; - } - } - if(!generateOperation && !implementedByBase) - { - // - // No base class defines the operation. Check if one of the - // interfaces defines it, in which case this class must provide it. - // - if(bases.front()->isInterface() || bases.size() > 1) - { - generateOperation = true; - } - } - } + out << '_' << p->name() << "Disp"; } - if(generateOperation) + out << " obj, final com.zeroc.IceInternal.Incoming inS, com.zeroc.Ice.Current current)"; + if(!op->throws().empty()) { - out << sp; - if(amd) - { - writeDocCommentAsync(out, op, InParam); - } - else - { - writeDocComment(out, op, deprecateReason); - } - out << nl << "public final " - << typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, - optionalMapping && op->returnIsOptional()) - << ' ' << opName << spar << params << epar; - if(op->hasMetaData("UserException")) - { - out.inc(); - out << nl << "throws Ice.UserException"; - out.dec(); - } - else - { - writeThrowsClause(package, throws); - } - out << sb << nl; - if(ret) - { - out << "return "; - } - out << opName << spar << args << "null" << epar << ';'; - out << eb; + out.inc(); + out << nl << "throws com.zeroc.Ice.UserException"; + out.dec(); } - } + out << sb; - // - // Dispatch operations. We only generate methods for operations - // defined in this ClassDef, because we reuse existing methods - // for inherited operations. - // - ops = p->operations(); - for(OperationList::const_iterator r = ops.begin(); r != ops.end(); ++r) - { - OperationPtr op = *r; - StringList opMetaData = op->getMetaData(); - ContainerPtr container = op->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - assert(cl); - string deprecateReason = getDeprecateReason(op, cl, "operation"); + const bool amd = p->hasMetaData("amd") || op->hasMetaData("amd"); - string opName = op->name(); - out << sp; - if(!deprecateReason.empty()) - { - out << nl << "/** @deprecated **/"; - } - out << nl << "public static Ice.DispatchStatus ___" << opName << '(' << name - << " __obj, IceInternal.Incoming __inS, Ice.Current __current)"; - out << sb; + const TypePtr ret = op->returnType(); - const bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); - const bool optionalMapping = useOptionalMapping(op); + const ParamDeclList inParams = op->inParameters(); + const ParamDeclList outParams = op->outParameters(); + + out << nl << "com.zeroc.Ice.Object._iceCheckMode(" << sliceModeToIceMode(op->mode()) << ", current.mode);"; - if(!amd) + if(!inParams.empty()) { - TypePtr ret = op->returnType(); + ParamDeclList values; - ParamDeclList inParams; - ParamDeclList outParams; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + // + // Declare 'in' parameters. + // + out << nl << "com.zeroc.Ice.InputStream istr = inS.startReadParams();"; + for(ParamDeclList::const_iterator pli = inParams.begin(); pli != inParams.end(); ++pli) { - if((*pli)->isOutParam()) + const TypePtr paramType = (*pli)->type(); + if(isValue(paramType)) { - outParams.push_back(*pli); + allocatePatcher(out, paramType, package, "icePP_" + (*pli)->name()); + values.push_back(*pli); } else { - inParams.push_back(*pli); - } - } - - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // -#if defined(__SUNPRO_CC) - throws.sort(Slice::derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - - int iter; - - out << nl << "__checkMode(" << sliceModeToIceMode(op->mode()) << ", __current.mode);"; - - if(!inParams.empty()) - { - // - // Unmarshal 'in' parameters. - // - out << nl << "IceInternal.BasicStream __is = __inS.startReadParams();"; - for(ParamDeclList::const_iterator pli = inParams.begin(); pli != inParams.end(); ++pli) - { - TypePtr paramType = (*pli)->type(); - string paramName = fixKwd((*pli)->name()); - string typeS = typeToString(paramType, TypeModeIn, package, (*pli)->getMetaData(), - true, (*pli)->optional()); + const string paramName = "iceP_" + (*pli)->name(); + const string typeS = typeToString(paramType, TypeModeIn, package, (*pli)->getMetaData(), true, + (*pli)->optional()); if((*pli)->optional()) { - out << nl << typeS << ' ' << paramName << " = new " << typeS << "();"; + out << nl << typeS << ' ' << paramName << ';'; } else { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) - { - out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();"; - } - else if(StructPtr::dynamicCast(paramType)) + if(StructPtr::dynamicCast(paramType)) { out << nl << typeS << ' ' << paramName << " = null;"; } @@ -1361,203 +1115,115 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& } } } - iter = 0; - writeMarshalUnmarshalParams(out, package, inParams, 0, iter, false, true, true); - if(op->sendsClasses(false)) - { - out << nl << "__is.readPendingObjects();"; - } - out << nl << "__inS.endReadParams();"; - } - else - { - out << nl << "__inS.readEmptyParams();"; } // - // Declare 'out' parameters. + // Unmarshal 'in' parameters. // - for(ParamDeclList::const_iterator pli = outParams.begin(); pli != outParams.end(); ++pli) + ParamDeclList required, optional; + op->inParameters(required, optional); + int iter = 0; + for(ParamDeclList::const_iterator pli = required.begin(); pli != required.end(); ++pli) { - string typeS = typeToString((*pli)->type(), TypeModeOut, package, (*pli)->getMetaData(), true, - optionalMapping && (*pli)->optional()); - out << nl << typeS << ' ' << fixKwd((*pli)->name()) << " = new " << typeS << "();"; + const string paramName = isValue((*pli)->type()) ? ("icePP_" + (*pli)->name()) : "iceP_" + (*pli)->name(); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalNone, false, 0, paramName, false, + iter, "", (*pli)->getMetaData(), paramName); } - - // - // Call on the servant. - // - if(!throws.empty()) + for(ParamDeclList::const_iterator pli = optional.begin(); pli != optional.end(); ++pli) { - out << nl << "try"; - out << sb; + const string paramName = isValue((*pli)->type()) ? ("icePP_" + (*pli)->name()) : "iceP_" + (*pli)->name(); + writeMarshalUnmarshalCode(out, package, (*pli)->type(), OptionalInParam, true, (*pli)->tag(), + paramName, false, iter, "", (*pli)->getMetaData(), paramName); } - out << nl; - if(ret) + if(op->sendsClasses(false)) { - string retS = typeToString(ret, TypeModeReturn, package, opMetaData, true, - optionalMapping && op->returnIsOptional()); - out << retS << " __ret = "; + out << nl << "istr.readPendingValues();"; } - out << "__obj." << fixKwd(opName) << '('; - for(ParamDeclList::const_iterator pli = inParams.begin(); pli != inParams.end(); ++pli) + out << nl << "inS.endReadParams();"; + + for(ParamDeclList::const_iterator pli = values.begin(); pli != values.end(); ++pli) { - TypePtr paramType = (*pli)->type(); - out << fixKwd((*pli)->name()); - if(!(*pli)->optional()) + const TypePtr paramType = (*pli)->type(); + const string paramName = "iceP_" + (*pli)->name(); + const string typeS = typeToString(paramType, TypeModeIn, package, (*pli)->getMetaData(), true, + (*pli)->optional()); + if((*pli)->optional()) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) - { - out << ".value"; - } + out << nl << typeS << ' ' << paramName << " = java.util.Optional.ofNullable(icePP_" << (*pli)->name() + << ".value);"; } - out << ", "; - } - for(ParamDeclList::const_iterator pli = outParams.begin(); pli != outParams.end(); ++pli) - { - out << fixKwd((*pli)->name()) << ", "; - } - out << "__current);"; - - // - // Marshal 'out' parameters and return value. - // - if(!outParams.empty() || ret) - { - out << nl << "IceInternal.BasicStream __os = __inS.__startWriteParams(" - << opFormatTypeToString(op) << ");"; - writeMarshalUnmarshalParams(out, package, outParams, op, iter, true, optionalMapping, true); - if(op->returnsClasses(false)) + else { - out << nl << "__os.writePendingObjects();"; + out << nl << typeS << ' ' << paramName << " = icePP_" << (*pli)->name() << ".value;"; } - out << nl << "__inS.__endWriteParams(true);"; } - else + } + else + { + out << nl << "inS.readEmptyParams();"; + } + + if(op->format() != DefaultFormat) + { + out << nl << "inS.setFormat(" << opFormatTypeToString(op) << ");"; + } + + if(amd) + { + if(op->hasMarshaledResult()) { - out << nl << "__inS.__writeEmptyParams();"; + out << nl << "return inS.setMarshaledResultFuture(obj." << opName << "Async" << spar + << getInArgs(op, true) << "current" << epar << ");"; } - out << nl << "return Ice.DispatchStatus.DispatchOK;"; - - // - // Handle user exceptions. - // - if(!throws.empty()) + else { - out << eb; - for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t) + out << nl << "return inS.setResultFuture(obj." << opName << "Async" << spar << getInArgs(op, true) + << "current" << epar; + if(ret || !outParams.empty()) { - string exS = getAbsolute(*t, package); - out << nl << "catch(" << exS << " ex)"; + out << ", (ostr, ret) ->"; + out.inc(); out << sb; - out << nl << "__inS.__writeUserException(ex, " << opFormatTypeToString(op) << ");"; - out << nl << "return Ice.DispatchStatus.DispatchUserException;"; + writeMarshalServantResults(out, package, op, "ret"); out << eb; + out.dec(); } + out << ");"; } - - out << eb; } else { - ParamDeclList inParams; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + // + // Call on the servant. + // + out << nl; + if(ret || !outParams.empty()) { - if(!(*pli)->isOutParam()) - { - inParams.push_back(*pli); - } + out << getResultType(op, package, false, true) << " ret = "; } + out << "obj." << fixKwd(opName) << spar << getInArgs(op, true) << "current" << epar << ';'; - int iter; - - out << nl << "__checkMode(" << sliceModeToIceMode(op->mode()) << ", __current.mode);"; - - if(!inParams.empty()) + // + // Marshal 'out' parameters and return value. + // + if(op->hasMarshaledResult()) { - // - // Unmarshal 'in' parameters. - // - out << nl << "IceInternal.BasicStream __is = __inS.startReadParams();"; - iter = 0; - for(ParamDeclList::const_iterator pli = inParams.begin(); pli != inParams.end(); ++pli) - { - TypePtr paramType = (*pli)->type(); - string paramName = fixKwd((*pli)->name()); - string typeS = typeToString(paramType, TypeModeIn, package, (*pli)->getMetaData(), - true, (*pli)->optional()); - if((*pli)->optional()) - { - out << nl << typeS << ' ' << paramName << " = new " << typeS << "();"; - } - else - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) - { - out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();"; - } - else if(StructPtr::dynamicCast(paramType)) - { - out << nl << typeS << ' ' << paramName << " = null;"; - } - else - { - out << nl << typeS << ' ' << paramName << ';'; - } - } - } - writeMarshalUnmarshalParams(out, package, inParams, 0, iter, false, true, true); - if(op->sendsClasses(false)) - { - out << nl << "__is.readPendingObjects();"; - } - out << nl << "__inS.endReadParams();"; + out << nl << "return inS.setMarshaledResult(ret);"; } - else + else if(ret || !outParams.empty()) { - out << nl << "__inS.readEmptyParams();"; + out << nl << "com.zeroc.Ice.OutputStream ostr = inS.startWriteParams();"; + writeMarshalServantResults(out, package, op, "ret"); + out << nl << "inS.endWriteParams(ostr);"; + out << nl << "return inS.setResult(ostr);"; } - - // - // Call on the servant. - // - string classNameAMD = "AMD_" + p->name(); - out << nl << '_' << classNameAMD << '_' << opName << " __cb = new _" << classNameAMD << '_' << opName - << "(__inS);"; - out << nl << "try"; - out << sb; - out << nl << "__obj." << (amd ? opName + "_async" : fixKwd(opName)) << (amd ? "(__cb, " : "("); - for(ParamDeclList::const_iterator pli = inParams.begin(); pli != inParams.end(); ++pli) + else { - TypePtr paramType = (*pli)->type(); - out << fixKwd((*pli)->name()); - if(!(*pli)->optional()) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType); - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType)) - { - out << ".value"; - } - } - out << ", "; + out << nl << "return inS.setResult(inS.writeEmptyParams());"; } - out << "__current);"; - out << eb; - out << nl << "catch(java.lang.Exception ex)"; - out << sb; - out << nl << "__cb.ice_exception(ex);"; - out << eb; - out << nl << "catch(java.lang.Error ex)"; - out << sb; - out << nl << "__cb.__error(ex);"; - out << eb; - out << nl << "return Ice.DispatchStatus.DispatchAsync;"; - - out << eb; } + + out << eb; } OperationList allOps = p->allOperations(); @@ -1572,7 +1238,7 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& allOpNames.sort(); allOpNames.unique(); - out << sp << nl << "private final static String[] __all ="; + out << sp << nl << "final static String[] _iceOps ="; out << sb; for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end();) { @@ -1594,19 +1260,24 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& ContainerPtr container = op->container(); ClassDefPtr cl = ClassDefPtr::dynamicCast(container); assert(cl); - string deprecateReason = getDeprecateReason(op, cl, "operation"); - if(!deprecateReason.empty()) + if(isDeprecated(op, cl)) { out << nl << "@SuppressWarnings(\"deprecation\")"; break; } } - out << nl << "public Ice.DispatchStatus __dispatch(IceInternal.Incoming in, Ice.Current __current)"; + out << nl << "@Override" << nl + << "default java.util.concurrent.CompletionStage<com.zeroc.Ice.OutputStream> _iceDispatch(" + << "com.zeroc.IceInternal.Incoming in, com.zeroc.Ice.Current current)"; + out.inc(); + out << nl << "throws com.zeroc.Ice.UserException"; + out.dec(); out << sb; - out << nl << "int pos = java.util.Arrays.binarySearch(__all, __current.operation);"; + out << nl << "int pos = java.util.Arrays.binarySearch(_iceOps, current.operation);"; out << nl << "if(pos < 0)"; out << sb; - out << nl << "throw new Ice.OperationNotExistException(__current.id, __current.facet, __current.operation);"; + out << nl << "throw new " + << "com.zeroc.Ice.OperationNotExistException(current.id, current.facet, current.operation);"; out << eb; out << sp << nl << "switch(pos)"; out << sb; @@ -1619,19 +1290,19 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& out << sb; if(opName == "ice_id") { - out << nl << "return ___ice_id(this, in, __current);"; + out << nl << "return com.zeroc.Ice.Object._iceD_ice_id(this, in, current);"; } else if(opName == "ice_ids") { - out << nl << "return ___ice_ids(this, in, __current);"; + out << nl << "return com.zeroc.Ice.Object._iceD_ice_ids(this, in, current);"; } else if(opName == "ice_isA") { - out << nl << "return ___ice_isA(this, in, __current);"; + out << nl << "return com.zeroc.Ice.Object._iceD_ice_isA(this, in, current);"; } else if(opName == "ice_ping") { - out << nl << "return ___ice_ping(this, in, __current);"; + out << nl << "return com.zeroc.Ice.Object._iceD_ice_ping(this, in, current);"; } else { @@ -1647,20 +1318,20 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& assert(cl); if(cl->scoped() == p->scoped()) { - out << nl << "return ___" << opName << "(this, in, __current);"; + out << nl << "return _iceD_" << opName << "(this, in, current);"; } else { string base; if(cl->isInterface()) { - base = getAbsolute(cl, package, "_", "Disp"); + base = getAbsolute(cl, package); } else { - base = getAbsolute(cl, package); + base = getAbsolute(cl, package, "_", "Disp"); } - out << nl << "return " << base << ".___" << opName << "(this, in, __current);"; + out << nl << "return " << base << "._iceD_" << opName << "(this, in, current);"; } break; } @@ -1670,7 +1341,8 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& } out << eb; out << sp << nl << "assert(false);"; - out << nl << "throw new Ice.OperationNotExistException(__current.id, __current.facet, __current.operation);"; + out << nl << "throw new " + << "com.zeroc.Ice.OperationNotExistException(current.id, current.facet, current.operation);"; out << eb; // @@ -1689,7 +1361,7 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& if(!attributesMap.empty()) { - out << sp << nl << "private final static int[] __operationAttributes ="; + out << sp << nl << "final static int[] _iceOperationAttributes ="; out << sb; for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end();) { @@ -1709,17 +1381,31 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& } out << eb << ';'; - out << sp << nl << "public int ice_operationAttributes(String operation)"; + out << sp << nl << "@Override" << nl << "default int ice_operationAttributes(String operation)"; out << sb; - out << nl << "int pos = java.util.Arrays.binarySearch(__all, operation);"; + out << nl << "int pos = java.util.Arrays.binarySearch(_iceOps, operation);"; out << nl << "if(pos < 0)"; out << sb; out << nl << "return -1;"; out << eb; - out << sp << nl << "return __operationAttributes[pos];"; + out << sp << nl << "return _iceOperationAttributes[pos];"; out << eb; } } +} + +void +Slice::JavaVisitor::writeMarshaling(Output& out, const ClassDefPtr& p) +{ + 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(); + } int iter; DataMemberList members = p->dataMembers(); @@ -1729,48 +1415,30 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& if(preserved && !basePreserved) { - out << sp << nl << "public void __write(IceInternal.BasicStream __os)"; + out << sp; + out << nl << "@Override"; + out << nl << "public void _iceWrite(com.zeroc.Ice.OutputStream ostr)"; out << sb; - out << nl << "__os.startWriteObject(__slicedData);"; - out << nl << "__writeImpl(__os);"; - out << nl << "__os.endWriteObject();"; + out << nl << "ostr.startValue(_iceSlicedData);"; + out << nl << "_iceWriteImpl(ostr);"; + out << nl << "ostr.endValue();"; out << eb; - out << sp << nl << "public void __read(IceInternal.BasicStream __is)"; + out << sp; + out << nl << "@Override"; + out << nl << "public void _iceRead(com.zeroc.Ice.InputStream istr)"; out << sb; - out << nl << "__is.startReadObject();"; - out << nl << "__readImpl(__is);"; - out << nl << "__slicedData = __is.endReadObject(true);"; + out << nl << "istr.startValue();"; + out << nl << "_iceReadImpl(istr);"; + out << nl << "_iceSlicedData = istr.endValue(true);"; out << eb; - - if(stream) - { - out << sp << nl << "public void __write(Ice.OutputStream __outS)"; - out << sb; - 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 __read(Ice.InputStream __inS)"; - out << sb; - out << nl << "__inS.startObject();"; - out << nl << "__readImpl(__inS);"; - out << nl << "__slicedData = __inS.endObject(true);"; - out << eb; - } } - out << sp << nl << "protected void __writeImpl(IceInternal.BasicStream __os)"; + out << sp; + out << nl << "@Override"; + out << nl << "protected void _iceWriteImpl(com.zeroc.Ice.OutputStream ostr_)"; out << sb; - out << nl << "__os.startWriteSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; + out << nl << "ostr_.startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; iter = 0; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { @@ -1783,97 +1451,45 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr& { writeMarshalDataMember(out, package, *d, iter); } - out << nl << "__os.endWriteSlice();"; + out << nl << "ostr_.endSlice();"; if(base) { - out << nl << "super.__writeImpl(__os);"; + out << nl << "super._iceWriteImpl(ostr_);"; } out << eb; DataMemberList classMembers = p->classDataMembers(); DataMemberList allClassMembers = p->allClassDataMembers(); - if(classMembers.size() != 0) - { - writePatcher(out, package, classMembers, optionalMembers, stream); - } - - out << sp << nl << "protected void __readImpl(IceInternal.BasicStream __is)"; + out << sp; + out << nl << "@Override"; + out << nl << "protected void _iceReadImpl(com.zeroc.Ice.InputStream istr_)"; out << sb; - out << nl << "__is.startReadSlice();"; + out << nl << "istr_.startSlice();"; - int patchIter = 0; - const bool needCustomPatcher = classMembers.size() > 1; iter = 0; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { if(!(*d)->optional()) { - writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); + writeUnmarshalDataMember(out, package, *d, iter); } } for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) { - writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); + writeUnmarshalDataMember(out, package, *d, iter); } - out << nl << "__is.endReadSlice();"; + + out << nl << "istr_.endSlice();"; if(base) { - out << nl << "super.__readImpl(__is);"; + out << nl << "super._iceReadImpl(istr_);"; } out << eb; - if(stream) - { - out << sp << nl << "protected void __writeImpl(Ice.OutputStream __outS)"; - out << sb; - out << nl << "__outS.startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; - iter = 0; - for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) - { - if(!(*d)->optional()) - { - writeStreamMarshalDataMember(out, package, *d, iter); - } - } - for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) - { - writeStreamMarshalDataMember(out, package, *d, iter); - } - out << nl << "__outS.endSlice();"; - if(base) - { - out << nl << "super.__writeImpl(__outS);"; - } - out << eb; - - out << sp << nl << "protected void __readImpl(Ice.InputStream __inS)"; - out << sb; - out << nl << "__inS.startSlice();"; - iter = 0; - patchIter = 0; - for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) - { - if(!(*d)->optional()) - { - writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); - } - } - for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) - { - writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); - } - out << nl << "__inS.endSlice();"; - if(base) - { - out << nl << "super.__readImpl(__inS);"; - } - out << eb; - } - if(preserved && !basePreserved) { - out << sp << nl << "protected Ice.SlicedData __slicedData;"; + out << sp << nl << "protected com.zeroc.Ice.SlicedData _iceSlicedData;"; } } @@ -1896,166 +1512,7 @@ Slice::JavaVisitor::writeConstantValue(Output& out, const TypePtr& type, const S { case Builtin::KindString: { - // - // Expand strings into the basic source character set. We can't use isalpha() and the like - // here because they are sensitive to the current locale. - // - static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - "_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' "; - static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end()); - out << "\""; - - vector<unsigned char> u8buffer; // Buffer to convert multibyte characters - - for(size_t i = 0; i < value.size();) - { - if(charSet.find(value[i]) == charSet.end()) - { - char c = value[i]; - if(static_cast<unsigned char>(c) < 128) // Single byte character - { - // - // Print as unicode if not in basic source character set - // - switch(c) - { - // - // Java doesn't want '\n' or '\r\n' encoded as universal - // characters, that gives an error "unclosed string literal" - // - case '\r': - { - out << "\\r"; - break; - } - case '\n': - { - out << "\\n"; - break; - } - default: - { - out << u16CodePoint(c); - break; - } - } - } - else - { - u8buffer.push_back(value[i]); - } - } - else - { - // - // Write any pedding characters in the utf8 buffer - // - if(!u8buffer.empty()) - { - writeU8Buffer(u8buffer, out); - u8buffer.clear(); - } - switch(value[i]) - { - case '\\': - { - string s = "\\"; - size_t j = i + 1; - for(; j < value.size(); ++j) - { - if(value[j] != '\\') - { - break; - } - s += "\\"; - } - - // - // An even number of slash \ will escape the backslash and - // the codepoint will be interpreted as its charaters - // - // \\U00000041 - ['\\', 'U', '0', '0', '0', '0', '0', '0', '4', '1'] - // \\\U00000041 - ['\\', 'A'] (41 is the codepoint for 'A') - // - if(s.size() % 2 != 0 && (value[j] == 'U' || value[j] == 'u')) - { - size_t sz = value[j] == 'U' ? 8 : 4; - out << s.substr(0, s.size() - 1); - i = j + 1; - - string codepoint = value.substr(j + 1, sz); - assert(codepoint.size() == sz); - - IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16); - - - // - // Java doesn't like this special characters encoded as universal characters - // - if(v == 0x5c) - { - out << "\\\\"; - } - else if(v == 0xa) - { - out << "\\n"; - } - else if(v == 0xd) - { - out << "\\r"; - } - else if(v == 0x22) - { - out << "\\\""; - } - // - // Unicode character in the range U+10000 to U+10FFFF is not permitted in a character literal - // and is represented using a Unicode surrogate pair. - // - else if(v > 0xFFFF) - { - unsigned int high = ((static_cast<unsigned int>(v) - 0x10000) / 0x400) + 0xD800; - unsigned int low = ((static_cast<unsigned int>(v) - 0x10000) % 0x400) + 0xDC00; - out << u16CodePoint(high); - out << u16CodePoint(low); - } - else - { - out << u16CodePoint(static_cast<unsigned int>(v)); - } - - i = j + 1 + sz; - } - else - { - out << s; - i = j; - } - continue; - } - case '"': - { - out << "\\"; - break; - } - } - out << value[i]; // Print normally if in basic source character set - } - i++; - } - - // - // Write any pedding characters in the utf8 buffer - // - if(!u8buffer.empty()) - { - writeU8Buffer(u8buffer, out); - u8buffer.clear(); - } - - out << "\""; + out << "\"" << toStringLiteral(value, "\b\f\n\r\t", "", ShortUCN, 0) << "\""; break; } case Builtin::KindByte: @@ -2080,6 +1537,7 @@ Slice::JavaVisitor::writeConstantValue(Output& out, const TypePtr& type, const S case Builtin::KindObject: case Builtin::KindObjectProxy: case Builtin::KindLocalObject: + case Builtin::KindValue: { out << value; break; @@ -2179,386 +1637,486 @@ Slice::JavaVisitor::splitComment(const ContainedPtr& p) return result; } -void -Slice::JavaVisitor::writeDocComment(Output& out, const ContainedPtr& p, const string& deprecateReason, - const string& extraParam) +Slice::JavaVisitor::DocCommentPtr +Slice::JavaVisitor::parseDocComment(const ContainedPtr& p) { - StringList lines = splitComment(p); - if(lines.empty()) + DocCommentPtr c = new DocComment; + c->deprecated = false; + + // + // First check metadata for a deprecated tag. + // + string deprecateMetadata; + if(p->findMetaData("deprecate", deprecateMetadata)) { - if(!deprecateReason.empty()) + c->deprecated = true; + if(deprecateMetadata.find("deprecate:") == 0 && deprecateMetadata.size() > 10) { - out << nl << "/**"; - out << nl << " * @deprecated " << deprecateReason; - out << nl << " **/"; + c->deprecateReason = IceUtilInternal::trim(deprecateMetadata.substr(10)); } - return; } - out << nl << "/**"; + const StringList lines = splitComment(p); + if(lines.empty()) + { + return c->deprecated ? c : DocCommentPtr(0); // Docs exist if it's deprecated. + } - bool doneExtraParam = false; - for(StringList::const_iterator i = lines.begin(); i != lines.end(); ++i) + StringList::const_iterator i; + for(i = lines.begin(); i != lines.end(); ++i) { - // - // @param must precede @return, so emit any extra parameter - // when @return is seen. - // - if(i->find("@return") != string::npos && !extraParam.empty()) + const string l = *i; + if(l[0] == '@') { - out << nl << " * " << extraParam; - doneExtraParam = true; + break; } - out << nl << " *"; - if(!(*i).empty()) + if(!c->overview.empty()) { - out << " " << *i; + c->overview += "\n"; } + c->overview += l; } - if(!doneExtraParam && !extraParam.empty()) + enum State { StateMisc, StateParam, StateThrows, StateReturn, StateDeprecated }; + State state = StateMisc; + string name; + const string ws = " \t"; + const string paramTag = "@param"; + const string throwsTag = "@throws"; + const string exceptionTag = "@exception"; + const string returnTag = "@return"; + const string deprecatedTag = "@deprecated"; + for(; i != lines.end(); ++i) { - // - // Above code doesn't emit the comment for the extra parameter - // if the operation returns a void or doesn't have an @return. - // - out << nl << " * " << extraParam; - } + const string l = *i; + if(l.find(paramTag) == 0) + { + state = StateMisc; + name.clear(); + string::size_type n = l.find_first_not_of(ws, paramTag.size()); + if(n == string::npos) + { + continue; // Malformed line, ignore it. + } + string::size_type end = l.find_first_of(ws, n); + if(end == string::npos) + { + continue; // Malformed line, ignore it. + } + name = l.substr(n, end - n); + state = StateParam; + n = l.find_first_not_of(ws, end); + if(n != string::npos) + { + c->params[name] = l.substr(n); // The first line of the description. + } + } + else if(l.find(throwsTag) == 0 || l.find(exceptionTag) == 0) + { + state = StateMisc; + name.clear(); + string::size_type n = + l.find_first_not_of(ws, l.find(throwsTag) == 0 ? throwsTag.size() : exceptionTag.size()); + if(n == string::npos) + { + continue; // Malformed line, ignore it. + } + string::size_type end = l.find_first_of(ws, n); + if(end == string::npos) + { + continue; // Malformed line, ignore it. + } + name = l.substr(n, end - n); + state = StateThrows; + n = l.find_first_not_of(ws, end); + if(n != string::npos) + { + c->exceptions[name] = l.substr(n); // The first line of the description. + } + } + else if(l.find(returnTag) == 0) + { + state = StateMisc; + name.clear(); + string::size_type n = l.find_first_not_of(ws, returnTag.size()); + if(n == string::npos) + { + continue; // Malformed line, ignore it. + } + state = StateReturn; + c->returns = l.substr(n); // The first line of the description. + } + else if(l.find(deprecatedTag) == 0) + { + state = StateMisc; + name.clear(); + string::size_type n = l.find_first_not_of(ws, deprecatedTag.size()); + if(n != string::npos) + { + c->deprecateReason = l.substr(n); // The first line of the description. + } + state = StateDeprecated; + c->deprecated = true; + } + else if(!l.empty()) + { + if(l[0] == '@') + { + // + // Treat all other tags as miscellaneous comments. + // + state = StateMisc; + } - if(!deprecateReason.empty()) - { - out << nl << " * @deprecated " << deprecateReason; + switch(state) + { + case StateMisc: + if(!c->misc.empty()) + { + c->misc += "\n"; + } + c->misc += l; + break; + case StateParam: + assert(!name.empty()); + if(c->params.find(name) == c->params.end()) + { + c->params[name] = ""; + } + if(!c->params[name].empty()) + { + c->params[name] += "\n"; + } + c->params[name] += l; + break; + case StateThrows: + assert(!name.empty()); + if(c->exceptions.find(name) == c->exceptions.end()) + { + c->exceptions[name] = ""; + } + if(!c->exceptions[name].empty()) + { + c->exceptions[name] += "\n"; + } + c->exceptions[name] += l; + break; + case StateReturn: + if(!c->returns.empty()) + { + c->returns += "\n"; + } + c->returns += l; + break; + case StateDeprecated: + if(!c->deprecateReason.empty()) + { + c->deprecateReason += "\n"; + } + c->deprecateReason += l; + break; + } + } } - out << nl << " **/"; + return c; } void -Slice::JavaVisitor::writeDocComment(Output& out, const string& deprecateReason, const string& summary) +Slice::JavaVisitor::writeDocCommentLines(Output& out, const string& text) { - vector<string> lines; - IceUtilInternal::splitString(summary, "\n", lines); - - out << nl << "/**"; - for(vector<string>::const_iterator i = lines.begin(); i != lines.end(); ++i) + // + // This method emits a block of text, prepending a leading " * " to the second and + // subsequent lines. We assume the caller prepended a leading " * " for the first + // line if necessary. + // + string::size_type start = 0; + string::size_type pos; + const string ws = "\n"; + pos = text.find_first_of(ws); + if(pos == string::npos) { - out << nl << " *"; - if(!(*i).empty()) - { - out << " " << *i; - } + out << text; } - - if(!deprecateReason.empty()) + else { - out << nl << " * @deprecated " << deprecateReason; + string s = IceUtilInternal::trim(text.substr(start, pos - start)); + out << s; // Emit the first line. + start = pos + 1; + while((pos = text.find_first_of(ws, start)) != string::npos) + { + out << nl << " * " << IceUtilInternal::trim(text.substr(start, pos - start)); + start = pos + 1; + } + if(start < text.size()) + { + out << nl << " * " << IceUtilInternal::trim(text.substr(start)); + } } - - out << nl << " **/"; } void -Slice::JavaVisitor::writeDocCommentOp(Output& out, const OperationPtr& p) +Slice::JavaVisitor::writeDocComment(Output& out, const DocCommentPtr& dc) { - ContainerPtr container = p->container(); - ContainedPtr contained = ContainedPtr::dynamicCast(container); - string deprecateReason = getDeprecateReason(p, contained, "operation"); - - StringList lines = splitComment(p); - - if(lines.empty() && deprecateReason.empty()) + if(!dc) { return; } + out << nl << "/**"; + if(!dc->overview.empty()) + { + out << nl << " * "; + writeDocCommentLines(out, dc->overview); + } - out << sp << nl << "/**"; - - // - // Output the leading comment block up until the first @tag. - // - bool done = false; - for(StringList::const_iterator i = lines.begin(); i != lines.end() && !done; ++i) + if(!dc->misc.empty()) { - if((*i)[0] == '@') - { - done = true; - } - else - { - out << nl << " * " << *i; - } + out << nl << " * "; + writeDocCommentLines(out, dc->misc); } - if(!deprecateReason.empty()) + if(!dc->deprecateReason.empty()) { - out << nl << " * @deprecated " << deprecateReason; + out << nl << " * @deprecated "; + writeDocCommentLines(out, dc->deprecateReason); } out << nl << " **/"; } void -Slice::JavaVisitor::writeDocCommentAsync(Output& out, const OperationPtr& p, ParamDir paramType, - const string& extraParam) +Slice::JavaVisitor::writeDocComment(Output& out, const string& text) { - ContainerPtr container = p->container(); - ClassDefPtr contained = ClassDefPtr::dynamicCast(container); - string deprecateReason = getDeprecateReason(p, contained, "operation"); + if(!text.empty()) + { + out << nl << "/**"; + out << nl << " * "; + writeDocCommentLines(out, text); + out << nl << " **/"; + } +} - StringList lines = splitComment(p); - if(lines.empty() && deprecateReason.empty()) +void +Slice::JavaVisitor::writeProxyDocComment(Output& out, const OperationPtr& p, const string& package, + const DocCommentPtr& dc, bool async, bool context) +{ + if(!dc) { return; } - out << nl << "/**"; + const string contextParam = " * @param context The Context map to send with the invocation."; - if(paramType == OutParam) + out << nl << "/**"; + if(!dc->overview.empty()) { - out << nl << " * ice_response indicates that"; - out << nl << " * the operation completed successfully."; + out << nl << " * "; + writeDocCommentLines(out, dc->overview); + } - // - // Find the comment for the return value (if any) and rewrite that as an @param comment. - // - const string returnTag = "@return"; - bool doneReturn = false; - bool foundReturn = false; - for(StringList::const_iterator i = lines.begin(); i != lines.end() && !doneReturn; ++i) + // + // Show in-params in order of declaration, but only those with docs. + // + const ParamDeclList paramList = p->inParameters(); + for(ParamDeclList::const_iterator i = paramList.begin(); i != paramList.end(); ++i) + { + const string name = (*i)->name(); + map<string, string>::const_iterator j = dc->params.find(name); + if(j != dc->params.end() && !j->second.empty()) { - if(!foundReturn) - { - if(i->find(returnTag) != string::npos) - { - foundReturn = true; - out << nl << " * @param __ret (return value)" << i->substr(returnTag.length()); - } - } - else - { - if((*i)[0] == '@') - { - doneReturn = true; - } - else - { - out << nl << " * " << *i; - } - } + out << nl << " * @param " << fixKwd(j->first) << ' '; + writeDocCommentLines(out, j->second); } } - else + if(context) { - // - // Output the leading comment block up until the first @tag. - // - bool done = false; - for(StringList::const_iterator i = lines.begin(); i != lines.end() && !done; ++i) - { - if((*i)[0] == '@') - { - done = true; - } - else - { - out << nl << " * " << *i; - } - } + out << nl << contextParam; } // - // Write the comments for the parameters. + // Handle the return value (if any). // - writeDocCommentParam(out, p, paramType); - - if(!extraParam.empty()) - { - out << nl << " * " << extraParam; - } - - if(paramType == InParam) + if(p->returnsMultipleValues()) { - if(!deprecateReason.empty()) + const string r = getResultType(p, package, true, false); + if(async) + { + out << nl << " * @return A future that will be completed with an instance of " << r << '.'; + } + else { - out << nl << " * @deprecated " << deprecateReason; + out << nl << " * @return An instance of " << r << '.'; } } - - out << nl << " **/"; -} - -void -Slice::JavaVisitor::writeDocCommentAMI(Output& out, const OperationPtr& p, ParamDir paramType, - const string& extraParam1, const string& extraParam2, const string& extraParam3, - const string& extraParam4, const string& extraParam5) -{ - ContainerPtr container = p->container(); - ClassDefPtr contained = ClassDefPtr::dynamicCast(container); - string deprecateReason = getDeprecateReason(p, contained, "operation"); - - StringList lines = splitComment(p); - if(lines.empty() && deprecateReason.empty()) + else if(p->returnType()) { - return; + if(!dc->returns.empty()) + { + out << nl << " * @return "; + writeDocCommentLines(out, dc->returns); + } + else if(async) + { + out << nl << " * @return A future that will be completed with the result."; + } } - - out << nl << "/**"; - - // - // Output the leading comment block up until the first @tag. - // - bool done = false; - for(StringList::const_iterator i = lines.begin(); i != lines.end() && !done; ++i) + else if(!p->outParameters().empty()) { - if((*i)[0] == '@') + assert(p->outParameters().size() == 1); + const ParamDeclPtr param = p->outParameters().front(); + map<string, string>::const_iterator j = dc->params.find(param->name()); + if(j != dc->params.end() && !j->second.empty()) { - done = true; + out << nl << " * @return "; + writeDocCommentLines(out, j->second); } - else + else if(async) { - out << nl << " * " << *i; + out << nl << " * @return A future that will be completed with the result."; } } + else if(async) + { + // + // No results but an async proxy operation still returns a future. + // + out << nl << " * @return A future that will be completed when the invocation completes."; + } // - // Write the comments for the parameters. + // Async proxy methods don't declare user exceptions. // - writeDocCommentParam(out, p, paramType, false); + if(!async) + { + for(map<string, string>::const_iterator i = dc->exceptions.begin(); i != dc->exceptions.end(); ++i) + { + out << nl << " * @throws " << fixKwd(i->first) << ' '; + writeDocCommentLines(out, i->second); + } + } - if(!extraParam1.empty()) + if(!dc->misc.empty()) { - out << nl << " * " << extraParam1; + out << nl << " * "; + writeDocCommentLines(out, dc->misc); } - if(!extraParam2.empty()) + if(!dc->deprecateReason.empty()) { - out << nl << " * " << extraParam2; + out << nl << " * @deprecated "; + writeDocCommentLines(out, dc->deprecateReason); } - if(!extraParam3.empty()) + out << nl << " **/"; +} + +void +Slice::JavaVisitor::writeServantDocComment(Output& out, const OperationPtr& p, const string& package, + const DocCommentPtr& dc, bool async) +{ + if(!dc) { - out << nl << " * " << extraParam3; + return; } - if(!extraParam4.empty()) + const ParamDeclList paramList = p->inParameters(); + const string currentParamName = getEscapedParamName(p, "current"); + const string currentParam = " * @param " + currentParamName + " The Current object for the invocation."; + + out << nl << "/**"; + if(!dc->overview.empty()) { - out << nl << " * " << extraParam4; + out << nl << " * "; + writeDocCommentLines(out, dc->overview); } - if(!extraParam5.empty()) + // + // Show in-params in order of declaration, but only those with docs. + // + for(ParamDeclList::const_iterator i = paramList.begin(); i != paramList.end(); ++i) { - out << nl << " * " << extraParam5; + const string name = (*i)->name(); + map<string, string>::const_iterator j = dc->params.find(name); + if(j != dc->params.end() && !j->second.empty()) + { + out << nl << " * @param " << fixKwd(j->first) << ' '; + writeDocCommentLines(out, j->second); + } } + out << nl << currentParam; - if(paramType == InParam) + // + // Handle the return value (if any). + // + if(p->returnsMultipleValues()) { - out << nl << " * @return The asynchronous result object."; - if(!deprecateReason.empty()) + const string r = getResultType(p, package, true, false); + if(async) + { + out << nl << " * @return A completion stage that the servant will complete with an instance of " << r + << '.'; + } + else { - out << nl << " * @deprecated " << deprecateReason; + out << nl << " * @return An instance of " << r << '.'; } } - else + else if(p->returnType()) { - out << nl << " * @param __result The asynchronous result object."; - // - // Print @return, @throws, and @see tags. - // - const string returnTag = "@return"; - const string throwsTag = "@throws"; - const string seeTag = "@see"; - bool found = false; - for(StringList::const_iterator i = lines.begin(); i != lines.end(); ++i) + if(!dc->returns.empty()) { - if(!found) - { - if(i->find(returnTag) != string::npos || i->find(throwsTag) != string::npos || - i->find(seeTag) != string::npos) - { - found = true; - } - } - - if(found) - { - out << nl << " * " << *i; - } + out << nl << " * @return "; + writeDocCommentLines(out, dc->returns); + } + else if(async) + { + out << nl << " * @return A completion stage that the servant will complete with the result."; } } - - out << nl << " **/"; -} - -void -Slice::JavaVisitor::writeDocCommentParam(Output& out, const OperationPtr& p, ParamDir paramType, bool cb) -{ - // - // Collect the names of the in- or -out parameters to be documented. - // - ParamDeclList tmp = p->parameters(); - vector<string> params; - for(ParamDeclList::const_iterator q = tmp.begin(); q != tmp.end(); ++q) + else if(!p->outParameters().empty()) { - if((*q)->isOutParam() && paramType == OutParam) + assert(p->outParameters().size() == 1); + const ParamDeclPtr param = p->outParameters().front(); + map<string, string>::const_iterator j = dc->params.find(param->name()); + if(j != dc->params.end() && !j->second.empty()) { - params.push_back((*q)->name()); + out << nl << " * @return "; + writeDocCommentLines(out, j->second); } - else if(!(*q)->isOutParam() && paramType == InParam) + else if(async) { - params.push_back((*q)->name()); + out << nl << " * @return A completion stage that the servant will complete with the result."; } } + else if(async) + { + // + // No results but an async operation still returns a completion stage. + // + out << nl << " * @return A completion stage that the servant will complete when the invocation completes."; + } - // - // Print a comment for the callback parameter. - // - if(cb && paramType == InParam) + // TBD: Check for UserException metadata + for(map<string, string>::const_iterator i = dc->exceptions.begin(); i != dc->exceptions.end(); ++i) { - out << nl << " * @param __cb The callback object for the operation."; + out << nl << " * @throws " << fixKwd(i->first) << ' '; + writeDocCommentLines(out, i->second); } - // - // Print the comments for all the parameters that appear in the parameter list. - // - const string paramTag = "@param"; - StringList lines = splitComment(p); - StringList::const_iterator i = lines.begin(); - while(i != lines.end()) + if(!dc->misc.empty()) { - string line = *i++; - if(line.find(paramTag) != string::npos) - { - string::size_type paramNamePos = line.find_first_not_of(" \t\n\r", paramTag.length()); - if(paramNamePos != string::npos) - { - string::size_type paramNameEndPos = line.find_first_of(" \t", paramNamePos); - string paramName = line.substr(paramNamePos, paramNameEndPos - paramNamePos); - if(std::find(params.begin(), params.end(), paramName) != params.end()) - { - out << nl << " * " << line; - StringList::const_iterator j; - if (i == lines.end()) - { - break; - } - j = i++; - while(j != lines.end()) - { - if((*j)[0] != '@') - { - i = j; - out << nl << " * " << *j++; - } - else - { - break; - } - } - } - } - } + out << nl << " * "; + writeDocCommentLines(out, dc->misc); + } + + if(!dc->deprecateReason.empty()) + { + out << nl << " * @deprecated "; + writeDocCommentLines(out, dc->deprecateReason); } + + out << nl << " **/"; } Slice::Gen::Gen(const string& /*name*/, const string& base, const vector<string>& includePaths, const string& dir) : @@ -2573,43 +2131,27 @@ Slice::Gen::~Gen() } void -Slice::Gen::generate(const UnitPtr& p, bool stream) +Slice::Gen::generate(const UnitPtr& p) { JavaGenerator::validateMetaData(p); - OpsVisitor opsVisitor(_dir); - p->visit(&opsVisitor, false); - PackageVisitor packageVisitor(_dir); p->visit(&packageVisitor, false); - TypesVisitor typesVisitor(_dir, stream); + TypesVisitor typesVisitor(_dir); p->visit(&typesVisitor, false); CompactIdVisitor compactIdVisitor(_dir); p->visit(&compactIdVisitor, false); - HolderVisitor holderVisitor(_dir); - p->visit(&holderVisitor, false); - - HelperVisitor helperVisitor(_dir, stream); + HelperVisitor helperVisitor(_dir); p->visit(&helperVisitor, false); ProxyVisitor proxyVisitor(_dir); p->visit(&proxyVisitor, false); - DispatcherVisitor dispatcherVisitor(_dir, stream); + DispatcherVisitor dispatcherVisitor(_dir); p->visit(&dispatcherVisitor, false); - - AsyncVisitor asyncVisitor(_dir); - p->visit(&asyncVisitor, false); -} - -void -Slice::Gen::generateTie(const UnitPtr& p) -{ - TieVisitor tieVisitor(_dir); - p->visit(&tieVisitor, false); } void @@ -2620,13 +2162,6 @@ Slice::Gen::generateImpl(const UnitPtr& p) } void -Slice::Gen::generateImplTie(const UnitPtr& p) -{ - ImplTieVisitor implTieVisitor(_dir); - p->visit(&implTieVisitor, false); -} - -void Slice::Gen::writeChecksumClass(const string& checksumClass, const string& dir, const ChecksumMap& m) { // @@ -2661,7 +2196,7 @@ Slice::Gen::writeChecksumClass(const string& checksumClass, const string& dir, c out << sp << nl << "public static final java.util.Map<String, String> checksums;"; out << sp << nl << "static"; out << sb; - out << nl << "java.util.Map<String, String> map = new java.util.HashMap<String, String>();"; + out << nl << "java.util.Map<String, String> map = new java.util.HashMap<>();"; for(ChecksumMap::const_iterator p = m.begin(); p != m.end(); ++p) { out << nl << "map.put(\"" << p->first << "\", \""; @@ -2681,360 +2216,6 @@ Slice::Gen::writeChecksumClass(const string& checksumClass, const string& dir, c out << nl; } -Slice::Gen::OpsVisitor::OpsVisitor(const string& dir) : - JavaVisitor(dir) -{ -} - -bool -Slice::Gen::OpsVisitor::visitClassDefStart(const ClassDefPtr& p) -{ - // - // Don't generate an Operations interface for non-abstract classes - // - if(!p->isAbstract()) - { - return false; - } - - if(!p->isLocal()) - { - writeOperations(p, false); - } - writeOperations(p, true); - - return false; -} - -void -Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent) -{ - string name = p->name(); - ClassList bases = p->bases(); - string package = getPackage(p); - string opIntfName = "Operations"; - if(noCurrent || p->isLocal()) - { - opIntfName += "NC"; - } - string absolute = getAbsolute(p, "", "_", opIntfName); - - open(absolute, p->file()); - - Output& out = output(); - - // - // Generate the operations interface - // - out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, p->isInterface() ? "interface" : "class")); - out << nl << "public interface " << '_' << name << opIntfName; - if((bases.size() == 1 && bases.front()->isAbstract()) || bases.size() > 1) - { - out << " extends "; - out.useCurrentPosAsIndent(); - bool first = true; - for(ClassList::const_iterator q = bases.begin(); q != bases.end();) - { - if((*q)->isAbstract()) - { - if(!first) - { - out << ',' << nl; - } - else - { - first = false; - } - out << getAbsolute(*q, package, "_", opIntfName); - } - ++q; - } - out.restoreIndent(); - } - out << sb; - - OperationList ops = p->operations(); - for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) - { - OperationPtr op = *r; - ContainerPtr container = op->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - string opname = op->name(); - - TypePtr ret; - vector<string> params; - - const bool amd = !p->isLocal() && (cl->hasMetaData("amd") || op->hasMetaData("amd")); - const bool optionalMapping = useOptionalMapping(op); - - if(amd) - { - params = getParamsAsync(op, package, true, true); - } - else - { - params = getParams(op, package, false, optionalMapping); - ret = op->returnType(); - } - - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, - optionalMapping && op->returnIsOptional()); - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - out << sp; - - string deprecateReason = getDeprecateReason(*r, p, "operation"); - string extraCurrent; - if(!noCurrent && !p->isLocal()) - { - extraCurrent = "@param __current The Current object for the invocation."; - } - if(amd) - { - writeDocCommentAsync(out, *r, InParam, extraCurrent); - } - else - { - writeDocComment(out, *r, deprecateReason, extraCurrent); - } - out << nl << retS << ' ' << (amd ? opname + "_async" : fixKwd(opname)) << spar << params; - if(!noCurrent && !p->isLocal()) - { - out << "Ice.Current __current"; - } - out << epar; - if(op->hasMetaData("UserException")) - { - out.inc(); - out << nl << "throws Ice.UserException"; - out.dec(); - } - else - { - writeThrowsClause(package, throws); - } - out << ';'; - } - - out << eb; - - close(); -} - -Slice::Gen::TieVisitor::TieVisitor(const string& dir) : - JavaVisitor(dir) -{ -} - -bool -Slice::Gen::TieVisitor::visitClassDefStart(const ClassDefPtr& p) -{ - string name = p->name(); - ClassList bases = p->bases(); - string package = getPackage(p); - string absolute = getAbsolute(p, "", "_", "Tie"); - string opIntfName = "Operations"; - if(p->isLocal()) - { - opIntfName += "NC"; - } - - // - // Don't generate a TIE class for a non-abstract class - // - if(!p->isAbstract()) - { - return false; - } - - open(absolute, p->file()); - - Output& out = output(); - - // - // Generate the TIE class - // - out << sp << nl << "public class " << '_' << name << "Tie"; - if(p->isInterface()) - { - if(p->isLocal()) - { - out << " implements " << fixKwd(name) << ", Ice.TieBase"; - } - else - { - out << " extends " << '_' << name << "Disp implements Ice.TieBase"; - } - } - else - { - out << " extends " << fixKwd(name) << " implements Ice.TieBase"; - } - - out << sb; - - out << sp << nl << "public _" << name << "Tie()"; - out << sb; - out << eb; - - out << sp << nl << "public _" << name << "Tie(" << '_' << name << opIntfName << " delegate)"; - out << sb; - out << nl << "_ice_delegate = delegate;"; - out << eb; - - out << sp << nl << "public java.lang.Object ice_delegate()"; - out << sb; - out << nl << "return _ice_delegate;"; - out << eb; - - out << sp << nl << "public void ice_delegate(java.lang.Object delegate)"; - out << sb; - out << nl << "_ice_delegate = (_" << name << opIntfName << ")delegate;"; - out << eb; - - out << sp << nl << "public boolean equals(java.lang.Object rhs)"; - out << sb; - out << nl << "if(this == rhs)"; - out << sb; - out << nl << "return true;"; - out << eb; - out << nl << "if(!(rhs instanceof " << '_' << name << "Tie))"; - out << sb; - out << nl << "return false;"; - out << eb; - out << sp << nl << "return _ice_delegate.equals(((" << '_' << name << "Tie)rhs)._ice_delegate);"; - out << eb; - - out << sp << nl << "public int hashCode()"; - out << sb; - out << nl << "return _ice_delegate.hashCode();"; - out << eb; - - if(p->isLocal()) - { - out << sp << nl << "public _" << name << "Tie clone()"; - out.inc(); - out << nl << "throws java.lang.CloneNotSupportedException"; - out.dec(); - out << sb; - out << nl << "return (_" << name << "Tie)super.clone();"; - out << eb; - } - - OperationList ops = p->allOperations(); - for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) - { - ContainerPtr container = (*r)->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - const bool hasAMD = cl->hasMetaData("amd") || (*r)->hasMetaData("amd"); - const bool optionalMapping = useOptionalMapping(*r); - - string opName = hasAMD ? (*r)->name() + "_async" : fixKwd((*r)->name()); - - TypePtr ret = (*r)->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, (*r)->getMetaData(), true, - optionalMapping && (*r)->returnIsOptional()); - - vector<string> params; - vector<string> args; - if(hasAMD) - { - params = getParamsAsync((*r), package, true, true); - args = getArgsAsync(*r); - } - else - { - params = getParams((*r), package, false, optionalMapping); - args = getArgs(*r); - } - - string deprecateReason = getDeprecateReason(*r, cl, "operation"); - - out << sp; - if(!deprecateReason.empty()) - { - out << nl << "@Deprecated"; - out << nl << "@SuppressWarnings(\"deprecation\")"; - } - out << nl << "public " << (hasAMD ? string("void") : retS) << ' ' << opName << spar << params; - if(!p->isLocal()) - { - out << "Ice.Current __current"; - } - out << epar; - - if((*r)->hasMetaData("UserException")) - { - out.inc(); - out << nl << "throws Ice.UserException"; - out.dec(); - } - else - { - ExceptionList throws = (*r)->throws(); - throws.sort(); - throws.unique(); - writeThrowsClause(package, throws); - } - out << sb; - out << nl; - if(ret && !hasAMD) - { - out << "return "; - } - out << "_ice_delegate." << opName << spar << args; - if(!p->isLocal()) - { - out << "__current"; - } - out << epar << ';'; - out << eb; - } - - out << sp << nl << "private " << '_' << name << opIntfName << " _ice_delegate;"; - out << sp << nl << "public static final long serialVersionUID = "; - string serialVersionUID; - if(p->findMetaData("java:serialVersionUID", serialVersionUID)) - { - string::size_type pos = serialVersionUID.rfind(":") + 1; - if(pos == string::npos) - { - ostringstream os; - os << "ignoring invalid serialVersionUID for class `" << p->scoped() << "'; generating default value"; - emitWarning("", "", os.str()); - out << computeSerialVersionUUID(p); - } - else - { - Int64 v = 0; - serialVersionUID = serialVersionUID.substr(pos); - if(serialVersionUID != "0") - { - if(!stringToInt64(serialVersionUID, v)) // conversion error - { - ostringstream os; - os << "ignoring invalid serialVersionUID for class `" << p->scoped() - << "'; generating default value"; - emitWarning("", "", os.str()); - out << computeSerialVersionUUID(p); - } - } - out << v; - } - } - else - { - out << computeSerialVersionUUID(p); - } - out << "L;"; - out << eb; - close(); - - return false; -} - Slice::Gen::PackageVisitor::PackageVisitor(const string& dir) : JavaVisitor(dir) { @@ -3060,8 +2241,8 @@ Slice::Gen::PackageVisitor::visitModuleStart(const ModulePtr& p) return false; } -Slice::Gen::TypesVisitor::TypesVisitor(const string& dir, bool stream) : - JavaVisitor(dir), _stream(stream) +Slice::Gen::TypesVisitor::TypesVisitor(const string& dir) : + JavaVisitor(dir) { } @@ -3085,11 +2266,17 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) Output& out = output(); + DocCommentPtr dc = parseDocComment(p); + // // Slice interfaces map to Java interfaces. // out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, p->isInterface() ? "interface" : "class")); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } if(p->isInterface()) { out << nl << "public interface " << fixKwd(name); @@ -3097,9 +2284,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) { out << " extends "; out.useCurrentPosAsIndent(); - out << "Ice.Object"; - out << "," << nl << '_' << name; - out << "Operations, _" << name << "OperationsNC"; + out << "com.zeroc.Ice.Object"; } else { @@ -3125,26 +2310,24 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) else { out << nl << "public "; - if(p->allOperations().size() > 0) // Don't use isAbstract() - see bug 3739 + if(p->isLocal() && !p->allOperations().empty()) { out << "abstract "; } out << "class " << fixKwd(name); out.useCurrentPosAsIndent(); - StringList implements; - bool implementsOnNewLine = true; + StringList implements; if(bases.empty() || bases.front()->isInterface()) { if(p->isLocal()) { - implementsOnNewLine = false; - implements.push_back("java.lang.Cloneable"); + implements.push_back("java.lang.Cloneable"); } else { - out << " extends Ice.ObjectImpl"; + out << " extends com.zeroc.Ice.Value"; } } else @@ -3154,161 +2337,11 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) bases.pop_front(); } - // - // Implement interfaces - // - - if(p->isAbstract()) - { - if(!p->isLocal()) - { - implements.push_back("_" + name + "Operations"); - implements.push_back("_" + name + "OperationsNC"); - } - } - if(!bases.empty()) - { - for(ClassList::const_iterator q = bases.begin(); q != bases.end();) - { - implements.push_back(getAbsolute(*q, package)); - q++; - } - } - - if(!implements.empty()) - { - if(implementsOnNewLine) - { - out << nl; - } - - out << " implements "; - out.useCurrentPosAsIndent(); - - for(StringList::const_iterator q = implements.begin(); q != implements.end();) - { - if(q != implements.begin()) - { - out << ',' << nl; - } - out << *q; - q++; - } - - out.restoreIndent(); - } - out.restoreIndent(); } out << sb; - // - // For local classes and interfaces, we don't use the OperationsNC interface. - // Instead, we generate the operation signatures directly into the class - // or interface. - // - if(p->isLocal()) - { - OperationList ops = p->operations(); - for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) - { - OperationPtr op = *r; - const ContainerPtr container = op->container(); - const ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - const string opname = op->name(); - const bool optionalMapping = useOptionalMapping(op); - - const TypePtr ret = op->returnType(); - vector<string> params = getParams(op, package, true, optionalMapping); - - string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, - optionalMapping && op->returnIsOptional()); - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - out << sp; - - writeDocComment(out, *r, getDeprecateReason(*r, p, "operation")); - out << nl; - if(!p->isInterface()) - { - out << "public abstract "; - } - out << retS << ' ' << fixKwd(opname) << spar << params << epar; - if(op->hasMetaData("UserException")) - { - out.inc(); - out << nl << "throws Ice.UserException"; - out.dec(); - } - else - { - writeThrowsClause(package, throws); - } - out << ';'; - - // - // Generate asynchronous API for local operations marked with "async" metadata. - // - if(p->hasMetaData("async") || op->hasMetaData("async")) - { - vector<string> inParams = getInOutParams(op, package, InParam, true, true); - - out << sp; - writeDocCommentAMI(out, op, InParam); - out << nl; - if(!p->isInterface()) - { - out << "public abstract "; - } - out << "Ice.AsyncResult begin_" << opname << spar << inParams << epar << ';'; - - out << sp; - writeDocCommentAMI(out, op, InParam); - out << nl; - if(!p->isInterface()) - { - out << "public abstract "; - } - out << "Ice.AsyncResult begin_" << opname << spar << inParams << "Ice.Callback __cb" << epar << ';'; - - out << sp; - writeDocCommentAMI(out, op, InParam); - out << nl; - if(!p->isInterface()) - { - out << "public abstract "; - } - string cb = "Callback_" + name + "_" + opname + " __cb"; - out << "Ice.AsyncResult begin_" << opname << spar << inParams << cb << epar << ';'; - - - out << sp; - writeDocCommentAMI(out, op, InParam); - out << nl; - if(!p->isInterface()) - { - out << "public abstract "; - } - out << nl << "Ice.AsyncResult begin_" << opname; - writeParamList(out, getParamsAsyncLambda(op, package, false, true)); - out << ';'; - - vector<string> outParams = getInOutParams(op, package, OutParam, true, true); - out << sp; - writeDocCommentAMI(out, op, OutParam); - out << nl; - if(!p->isInterface()) - { - out << "public abstract "; - } - - out << retS << " end_" << opname << spar << outParams << "Ice.AsyncResult __result" << epar << ';'; - } - } - } - if(!p->isInterface() && !allDataMembers.empty()) { bool hasOptionalMembers = false; @@ -3447,39 +2480,6 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) } } - // - // Default factory for non-abstract classes. - // - if(!p->isInterface() && p->allOperations().size() == 0 && !p->isLocal()) - { - out << sp; - out << nl << "private static class __F implements Ice.ObjectFactory"; - out << sb; - out << nl << "public Ice.Object create(String type)"; - out << sb; - out << nl << "assert(type.equals(ice_staticId()));"; - out << nl << "return new " << fixKwd(name) << "();"; - out << eb; - out << sp << nl << "public void destroy()"; - out << sb; - out << eb; - out << eb; - out << nl << "private static Ice.ObjectFactory _factory = new __F();"; - out << sp; - out << nl << "public static Ice.ObjectFactory" << nl << "ice_factory()"; - out << sb; - out << nl << "return _factory;"; - out << eb; - } - - // - // Marshalling & dispatch support. - // - if(!p->isInterface() && !p->isLocal()) - { - writeDispatchAndMarshalling(out, p, _stream); - } - return true; } @@ -3499,74 +2499,190 @@ Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p) if(!p->isInterface()) { - out << sp << nl << "public " << name << nl << "clone()"; - out << sb; + out << sp << nl << "public " << name << " clone()"; + out << sb; - if(p->isLocal() && !baseClass) - { - out << nl << name << " c = null;"; - out << nl << "try"; - out << sb; - out << nl << "c = (" << name << ")super.clone();"; - out << eb; - out << nl << "catch(CloneNotSupportedException ex)"; - out << sb; - out << nl << "assert false; // impossible"; - out << eb; - out << nl << "return c;"; + if(p->isLocal() && !baseClass) + { + out << nl << name << " c = null;"; + out << nl << "try"; + out << sb; + out << nl << "c = (" << name << ")super.clone();"; + out << eb; + out << nl << "catch(CloneNotSupportedException ex)"; + out << sb; + out << nl << "assert false; // impossible"; + out << eb; + out << nl << "return c;"; - } - else - { - out << nl << "return (" << name << ")super.clone();"; - } - out << eb; + } + else + { + out << nl << "return (" << name << ")super.clone();"; + } + out << eb; } - if(p->isInterface() && !p->isLocal()) + if(!p->isLocal()) { - out << sp << nl << "public static final String ice_staticId = \"" << p->scoped() << "\";"; + if(!p->isInterface()) + { + out << sp << nl << "public static String ice_staticId()"; + out << sb; + out << nl << "return \"" << p->scoped() << "\";"; + out << eb; + + out << sp << nl << "@Override"; + out << nl << "public String ice_id()"; + out << sb; + out << nl << "return ice_staticId();"; + out << eb; + } } - out << sp << nl << "public static final long serialVersionUID = "; - string serialVersionUID; - if(p->findMetaData("java:serialVersionUID", serialVersionUID)) + if(!p->isInterface()) { - string::size_type pos = serialVersionUID.rfind(":") + 1; - if(pos == string::npos) + out << sp << nl << "public static final long serialVersionUID = "; + string serialVersionUID; + if(p->findMetaData("java:serialVersionUID", serialVersionUID)) { - ostringstream os; - os << "ignoring invalid serialVersionUID for class `" << p->scoped() << "'; generating default value"; - emitWarning("", "", os.str()); - out << computeSerialVersionUUID(p); - } - else - { - Int64 v = 0; - serialVersionUID = serialVersionUID.substr(pos); - if(serialVersionUID != "0") + string::size_type pos = serialVersionUID.rfind(":") + 1; + if(pos == string::npos) { - if(!stringToInt64(serialVersionUID, v)) // conversion error + ostringstream os; + os << "ignoring invalid serialVersionUID for class `" << p->scoped() << "'; generating default value"; + emitWarning("", "", os.str()); + out << computeSerialVersionUUID(p); + } + else + { + Int64 v = 0; + serialVersionUID = serialVersionUID.substr(pos); + if(serialVersionUID != "0") { - ostringstream os; - os << "ignoring invalid serialVersionUID for class `" << p->scoped() - << "'; generating default value"; - emitWarning("", "", os.str()); - out << computeSerialVersionUUID(p); + if(!stringToInt64(serialVersionUID, v)) // conversion error + { + ostringstream os; + os << "ignoring invalid serialVersionUID for class `" << p->scoped() + << "'; generating default value"; + emitWarning("", "", os.str()); + out << computeSerialVersionUUID(p); + } } + out << v; } - out << v; } + else + { + out << computeSerialVersionUUID(p); + } + out << "L;"; } - else + + if(!p->isLocal()) { - out << computeSerialVersionUUID(p); + if(p->isInterface()) + { + writeDispatch(out, p); + } + else + { + writeMarshaling(out, p); + } } - out << "L;"; + out << eb; close(); } +void +Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p) +{ + // + // Generate the operation signature for a servant. + // + + ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container()); + assert(cl); + + const string package = getPackage(cl); + + Output& out = output(); + + DocCommentPtr dc = parseDocComment(p); + + // + // Generate the "Result" type needed by operations that return multiple values. + // + if(p->returnsMultipleValues()) + { + writeResultType(out, p, package, dc); + } + + // + // The "MarshaledResult" type is generated in the servant interface. + // + if(cl->isInterface() && p->hasMarshaledResult()) + { + writeMarshaledResultType(out, p, package, dc); + } + + if(cl->isLocal()) + { + const string opname = p->name(); + vector<string> params = getParams(p, package); + + const string retS = getResultType(p, package, false, false); + + ExceptionList throws = p->throws(); + throws.sort(); + throws.unique(); + out << sp; + + writeProxyDocComment(out, p, package, dc, false, false); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl; + if(!cl->isInterface()) + { + out << "public abstract "; + } + out << retS << ' ' << fixKwd(opname) << spar << params << epar; + if(p->hasMetaData("UserException")) + { + out.inc(); + out << nl << "throws com.zeroc.Ice.UserException"; + out.dec(); + } + else + { + writeThrowsClause(package, throws); + } + out << ';'; + + // + // Generate asynchronous API for local operations marked with "async-oneway" metadata. + // + if(cl->hasMetaData("async-oneway") || p->hasMetaData("async-oneway")) + { + out << sp; + writeProxyDocComment(out, p, package, dc, true, false); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl; + if(!cl->isInterface()) + { + out << "public abstract "; + } + out << getFutureType(p, package) << ' ' << opname << "Async" << spar << params << epar << ';'; + } + } +} + bool Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) { @@ -3584,7 +2700,12 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, "type")); + DocCommentPtr dc = parseDocComment(p); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } out << nl << "public class " << name << " extends "; @@ -3592,11 +2713,11 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) { if(p->isLocal()) { - out << "Ice.LocalException"; + out << "com.zeroc.Ice.LocalException"; } else { - out << "Ice.UserException"; + out << "com.zeroc.Ice.UserException"; } } else @@ -3619,9 +2740,9 @@ 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; @@ -3676,7 +2797,8 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) if(!(*d)->optional()) { string memberName = fixKwd((*d)->name()); - string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData()); + string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData(), + true, false, p->isLocal()); paramDecl.push_back(memberType + " " + memberName); } } @@ -3715,7 +2837,7 @@ 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; @@ -3730,12 +2852,12 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) baseParamNames.push_back(fixKwd((*d)->name())); } } - baseParamNames.push_back("__cause"); + baseParamNames.push_back("cause"); out << baseParamNames << epar << ';'; } else { - out << nl << "super(__cause);"; + out << nl << "super(cause);"; } for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { @@ -3755,7 +2877,8 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) for(DataMemberList::const_iterator d = allDataMembers.begin(); d != allDataMembers.end(); ++d) { string memberName = fixKwd((*d)->name()); - string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData()); + string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData(), true, + false, p->isLocal()); paramDecl.push_back(memberType + " " + memberName); } out << paramDecl << epar; @@ -3793,13 +2916,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 { @@ -3810,7 +2933,7 @@ 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(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) @@ -3832,9 +2955,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) } } - out << sp << nl << "public String" << nl << "ice_name()"; + out << sp << nl << "public String ice_id()"; out << sb; - out << nl << "return \"" << scoped.substr(2) << "\";"; + out << nl << "return \"" << scoped << "\";"; out << eb; return true; @@ -3860,42 +2983,30 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) if(preserved && !basePreserved) { - - out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)"; + out << sp; + out << nl << "@Override"; + out << nl << "public void _write(com.zeroc.Ice.OutputStream ostr)"; out << sb; - out << nl << "__os.startWriteException(__slicedData);"; - out << nl << "__writeImpl(__os);"; - out << nl << "__os.endWriteException();"; + out << nl << "ostr.startException(_slicedData);"; + out << nl << "_writeImpl(ostr);"; + out << nl << "ostr.endException();"; out << eb; - out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is)"; + out << sp; + out << nl << "@Override"; + out << nl << "public void _read(com.zeroc.Ice.InputStream istr)"; out << sb; - out << nl << "__is.startReadException();"; - out << nl << "__readImpl(__is);"; - out << nl << "__slicedData = __is.endReadException(true);"; + out << nl << "istr.startException();"; + out << nl << "_readImpl(istr);"; + out << nl << "_slicedData = istr.endException(true);"; out << eb; - - if(_stream) - { - out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __outS)"; - out << sb; - out << nl << "__outS.startException(__slicedData);"; - out << nl << "__writeImpl(__outS);"; - out << nl << "__outS.endException();"; - out << eb; - - out << sp << nl << "public void" << nl << "__read(Ice.InputStream __inS)"; - out << sb; - out << nl << "__inS.startException();"; - out << nl << "__readImpl(__inS);"; - out << nl << "__slicedData = __inS.endException(true);"; - out << eb; - } } - out << sp << nl << "protected void" << nl << "__writeImpl(IceInternal.BasicStream __os)"; + out << sp; + out << nl << "@Override"; + out << nl << "protected void _writeImpl(com.zeroc.Ice.OutputStream ostr_)"; out << sb; - out << nl << "__os.startWriteSlice(\"" << scoped << "\", -1, " << (!base ? "true" : "false") << ");"; + out << nl << "ostr_.startSlice(\"" << scoped << "\", -1, " << (!base ? "true" : "false") << ");"; iter = 0; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { @@ -3908,97 +3019,47 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) { writeMarshalDataMember(out, package, *d, iter); } - out << nl << "__os.endWriteSlice();"; + out << nl << "ostr_.endSlice();"; if(base) { - out << nl << "super.__writeImpl(__os);"; + out << nl << "super._writeImpl(ostr_);"; } out << eb; DataMemberList classMembers = p->classDataMembers(); DataMemberList allClassMembers = p->allClassDataMembers(); - if(classMembers.size() != 0) - { - writePatcher(out, package, classMembers, optionalMembers, _stream); - } - out << sp << nl << "protected void" << nl << "__readImpl(IceInternal.BasicStream __is)"; + out << sp; + out << nl << "@Override"; + out << nl << "protected void _readImpl(com.zeroc.Ice.InputStream istr_)"; out << sb; - out << nl << "__is.startReadSlice();"; + out << nl << "istr_.startSlice();"; iter = 0; - int patchIter = 0; - const bool needCustomPatcher = classMembers.size() > 1; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { if(!(*d)->optional()) { - writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); + writeUnmarshalDataMember(out, package, *d, iter); } } for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) { - writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); + writeUnmarshalDataMember(out, package, *d, iter); } - out << nl << "__is.endReadSlice();"; + out << nl << "istr_.endSlice();"; if(base) { - out << nl << "super.__readImpl(__is);"; + out << nl << "super._readImpl(istr_);"; } out << eb; - if(_stream) - { - out << sp << nl << "protected void" << nl << "__writeImpl(Ice.OutputStream __outS)"; - out << sb; - out << nl << "__outS.startSlice(\"" << scoped << "\", -1, " << (!base ? "true" : "false") << ");"; - iter = 0; - for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) - { - if(!(*d)->optional()) - { - writeStreamMarshalDataMember(out, package, *d, iter); - } - } - for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) - { - writeStreamMarshalDataMember(out, package, *d, iter); - } - out << nl << "__outS.endSlice();"; - if(base) - { - out << nl << "super.__writeImpl(__outS);"; - } - out << eb; - - out << sp << nl << "protected void" << nl << "__readImpl(Ice.InputStream __inS)"; - out << sb; - out << nl << "__inS.startSlice();"; - iter = 0; - patchIter = 0; - for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) - { - if(!(*d)->optional()) - { - writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); - } - } - for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d) - { - writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); - } - out << nl << "__inS.endSlice();"; - if(base) - { - out << nl << "super.__readImpl(__inS);"; - } - out << eb; - } - if(p->usesClasses(false)) { - if(!base || (base && !base->usesClasses(false))) + if(!base || (base && !base->usesClasses(false))) { - out << sp << nl << "public boolean" << nl << "__usesClasses()"; + out << sp; + out << nl << "@Override"; + out << nl << "public boolean _usesClasses()"; out << sb; out << nl << "return true;"; out << eb; @@ -4007,7 +3068,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) if(preserved && !basePreserved) { - out << sp << nl << "protected Ice.SlicedData __slicedData;"; + out << sp << nl << "protected com.zeroc.Ice.SlicedData _slicedData;"; } } @@ -4063,7 +3124,12 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p) out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, "type")); + DocCommentPtr dc = parseDocComment(p); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } out << nl << "public class " << name << " implements java.lang.Cloneable"; if(!p->isLocal()) @@ -4103,7 +3169,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { string memberName = fixKwd((*d)->name()); - string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData()); + string memberType = typeToString((*d)->type(), TypeModeMember, package, (*d)->getMetaData(), true, false, + p->isLocal()); paramDecl.push_back(memberType + " " + memberName); paramNames.push_back(memberName); } @@ -4117,18 +3184,18 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) out << eb; } - out << sp << nl << "public boolean" << nl << "equals(java.lang.Object rhs)"; + out << sp << nl << "public boolean equals(java.lang.Object rhs)"; out << sb; out << nl << "if(this == rhs)"; out << sb; out << nl << "return true;"; out << eb; - out << nl << typeS << " _r = null;"; + out << nl << typeS << " r = null;"; out << nl << "if(rhs instanceof " << typeS << ")"; out << sb; - out << nl << "_r = (" << typeS << ")rhs;"; + out << nl << "r = (" << typeS << ")rhs;"; out << eb; - out << sp << nl << "if(_r != null)"; + out << sp << nl << "if(r != null)"; out << sb; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { @@ -4146,7 +3213,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) case Builtin::KindFloat: case Builtin::KindDouble: { - out << nl << "if(" << memberName << " != _r." << memberName << ')'; + out << nl << "if(this." << memberName << " != r." << memberName << ')'; out << sb; out << nl << "return false;"; out << eb; @@ -4157,11 +3224,12 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) case Builtin::KindObject: case Builtin::KindObjectProxy: case Builtin::KindLocalObject: + case Builtin::KindValue: { - out << nl << "if(" << memberName << " != _r." << memberName << ')'; + out << nl << "if(this." << memberName << " != r." << memberName << ')'; out << sb; - out << nl << "if(" << memberName << " == null || _r." << memberName << " == null || !" - << memberName << ".equals(_r." << memberName << "))"; + out << nl << "if(this." << memberName << " == null || r." << memberName << " == null || !this." + << memberName << ".equals(r." << memberName << "))"; out << sb; out << nl << "return false;"; out << eb; @@ -4185,10 +3253,10 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) { if(hasTypeMetaData(seq, (*d)->getMetaData())) { - out << nl << "if(" << memberName << " != _r." << memberName << ')'; + out << nl << "if(this." << memberName << " != r." << memberName << ')'; out << sb; - out << nl << "if(" << memberName << " == null || _r." << memberName << " == null || !" - << memberName << ".equals(_r." << memberName << "))"; + out << nl << "if(this." << memberName << " == null || r." << memberName << " == null || !this." + << memberName << ".equals(r." << memberName << "))"; out << sb; out << nl << "return false;"; out << eb; @@ -4199,7 +3267,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) // // Arrays.equals() handles null values. // - out << nl << "if(!java.util.Arrays.equals(" << memberName << ", _r." << memberName << "))"; + out << nl << "if(!java.util.Arrays.equals(this." << memberName << ", r." << memberName << "))"; out << sb; out << nl << "return false;"; out << eb; @@ -4207,10 +3275,10 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) } else { - out << nl << "if(" << memberName << " != _r." << memberName << ')'; + out << nl << "if(this." << memberName << " != r." << memberName << ')'; out << sb; - out << nl << "if(" << memberName << " == null || _r." << memberName << " == null || !" - << memberName << ".equals(_r." << memberName << "))"; + out << nl << "if(this." << memberName << " == null || r." << memberName << " == null || !this." + << memberName << ".equals(r." << memberName << "))"; out << sb; out << nl << "return false;"; out << eb; @@ -4223,20 +3291,20 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) out << sp << nl << "return false;"; out << eb; - out << sp << nl << "public int" << nl << "hashCode()"; + out << sp << nl << "public int hashCode()"; out << sb; - out << nl << "int __h = 5381;"; - out << nl << "__h = IceInternal.HashUtil.hashAdd(__h, \"" << p->scoped() << "\");"; + out << nl << "int h_ = 5381;"; + out << nl << "h_ = com.zeroc.IceInternal.HashUtil.hashAdd(h_, \"" << p->scoped() << "\");"; iter = 0; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { string memberName = fixKwd((*d)->name()); - out << nl << "__h = IceInternal.HashUtil.hashAdd(__h, " << memberName << ");"; + out << nl << "h_ = com.zeroc.IceInternal.HashUtil.hashAdd(h_, " << memberName << ");"; } - out << nl << "return __h;"; + out << nl << "return h_;"; out << eb; - out << sp << nl << "public " << name << nl << "clone()"; + out << sp << nl << "public " << name << " clone()"; out << sb; out << nl << name << " c = null;"; out << nl << "try"; @@ -4252,103 +3320,49 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) if(!p->isLocal()) { - out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)"; + out << sp << nl << "public void ice_writeMembers(com.zeroc.Ice.OutputStream ostr)"; out << sb; iter = 0; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { - writeMarshalDataMember(out, package, *d, iter); + writeMarshalDataMember(out, package, *d, iter, true); } out << eb; DataMemberList classMembers = p->classDataMembers(); - if(classMembers.size() != 0) - { - writePatcher(out, package, classMembers, DataMemberList(), _stream); - } - - out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is)"; + out << sp << nl << "public void ice_readMembers(com.zeroc.Ice.InputStream istr)"; out << sb; iter = 0; - int patchIter = 0; - const bool needCustomPatcher = classMembers.size() > 1; for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) { - writeUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); + writeUnmarshalDataMember(out, package, *d, iter, true); } out << eb; - if(_stream) - { - out << sp << nl << "public void" << nl << "ice_write(Ice.OutputStream __outS)"; - out << sb; - iter = 0; - for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) - { - writeStreamMarshalDataMember(out, package, *d, iter); - } - out << eb; - - out << sp << nl << "public void" << nl << "ice_read(Ice.InputStream __inS)"; - out << sb; - iter = 0; - patchIter = 0; - for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d) - { - writeStreamUnmarshalDataMember(out, package, *d, iter, needCustomPatcher, patchIter); - } - out << eb; - } - - out << sp << nl << "static public void" << nl << "__write(IceInternal.BasicStream __os, " << name << " __v)"; + out << sp << nl << "static public void ice_write(com.zeroc.Ice.OutputStream ostr, " << name << " v)"; out << sb; - out << nl << "if(__v == null)"; + out << nl << "if(v == null)"; out << sb; - out << nl << "__nullMarshalValue.__write(__os);"; + out << nl << "_nullMarshalValue.ice_writeMembers(ostr);"; out << eb; out << nl << "else"; out << sb; - out << nl << "__v.__write(__os);"; + out << nl << "v.ice_writeMembers(ostr);"; out << eb; out << eb; - out << sp << nl << "static public " << name << nl << "__read(IceInternal.BasicStream __is, " << name << " __v)"; + out << sp << nl << "static public " << name << " ice_read(com.zeroc.Ice.InputStream istr, " << name << " v)"; out << sb; - out << nl << "if(__v == null)"; + out << nl << "if(v == null)"; out << sb; - out << nl << " __v = new " << name << "();"; + out << nl << " v = new " << name << "();"; out << eb; - out << nl << "__v.__read(__is);"; - out << nl << "return __v;"; + out << nl << "v.ice_readMembers(istr);"; + out << nl << "return v;"; out << eb; - if(_stream) - { - out << sp << nl << "static public void" << nl << "ice_write(Ice.OutputStream __outS, " << name << " __v)"; - out << sb; - out << nl << "if(__v == null)"; - out << sb; - out << nl << "__nullMarshalValue.ice_write(__outS);"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << "__v.ice_write(__outS);"; - out << eb; - out << eb; - - out << sp << nl << "static public " << name << nl << "ice_read(Ice.InputStream __inS, " << name << " __v)"; - out << sb; - out << nl << "if(__v == null)"; - out << sb; - out << nl << " __v = new " << name << "();"; - out << eb; - out << nl << "__v.ice_read(__inS);"; - out << nl << "return __v;"; - out << eb; - } - - out << nl << nl << "private static final " << name << " __nullMarshalValue = new " << name << "();"; + out << nl << nl << "private static final " << name << " _nullMarshalValue = new " << name << "();"; } out << sp << nl << "public static final long serialVersionUID = "; @@ -4394,27 +3408,53 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) void Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) { - string name = fixKwd(p->name()); - ContainerPtr container = p->container(); - ContainedPtr contained = ContainedPtr::dynamicCast(container); - StringList metaData = p->getMetaData(); - TypePtr type = p->type(); - string s = typeToString(type, TypeModeMember, getPackage(contained), metaData); - Output& out = output(); - const bool optional = p->optional(); + const ContainerPtr container = p->container(); + const ClassDefPtr cls = ClassDefPtr::dynamicCast(container); + const StructPtr st = StructPtr::dynamicCast(container); + const ExceptionPtr ex = ExceptionPtr::dynamicCast(container); + const ContainedPtr contained = ContainedPtr::dynamicCast(container); + + const string name = fixKwd(p->name()); + const StringList metaData = p->getMetaData(); const bool getSet = p->hasMetaData(_getSetMetaData) || contained->hasMetaData(_getSetMetaData); + const bool optional = p->optional(); + const TypePtr type = p->type(); + const BuiltinPtr b = BuiltinPtr::dynamicCast(type); + const bool classType = isValue(type); + + bool local; + if(cls) + { + local = cls->isLocal(); + } + else if(st) + { + local = st->isLocal(); + } + else + { + assert(ex); + local = ex->isLocal(); + } + + const string s = typeToString(type, TypeModeMember, getPackage(contained), metaData, true, false, local); + + Output& out = output(); out << sp; - string deprecateReason = getDeprecateReason(p, contained, "member"); - writeDocComment(out, p, deprecateReason); + DocCommentPtr dc = parseDocComment(p); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } // // Access visibility for class data members can be controlled by metadata. // If none is specified, the default is public. // - if(contained->containedType() == Contained::ContainedTypeClass && - (p->hasMetaData("protected") || contained->hasMetaData("protected"))) + if(cls && (p->hasMetaData("protected") || contained->hasMetaData("protected"))) { out << nl << "protected " << s << ' ' << name << ';'; } @@ -4429,7 +3469,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) if(optional) { - out << nl << "private boolean __has_" << p->name() << ';'; + out << nl << "private boolean _" << p->name() << ';'; } // @@ -4445,7 +3485,6 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) // OperationList ops; string file, line; - ClassDefPtr cls = ClassDefPtr::dynamicCast(container); if(cls) { ops = cls->allOperations(); @@ -4469,15 +3508,18 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) // Getter. // out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public " << s - << nl << "get" << capName << "()"; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public " << s << " get" << capName << "()"; out << sb; if(optional) { - out << nl << "if(!__has_" << p->name() << ')'; + out << nl << "if(!_" << p->name() << ')'; out << sb; - out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << nl << "throw new java.util.NoSuchElementException(\"" << name << " is not set\");"; out << eb; } out << nl << "return " << name << ';'; @@ -4487,15 +3529,18 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) // Setter. // out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public void" - << nl << "set" << capName << '(' << s << " _" << name << ')'; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public void set" << capName << '(' << s << " " << name << ')'; out << sb; if(optional) { - out << nl << "__has_" << p->name() << " = true;"; + out << nl << "_" << p->name() << " = true;"; } - out << nl << name << " = _" << name << ';'; + out << nl << "this." << name << " = " << name << ';'; out << eb; // @@ -4504,51 +3549,113 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) if(optional) { out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public boolean" - << nl << "has" << capName << "()"; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public boolean has" << capName << "()"; out << sb; - out << nl << "return __has_" << p->name() << ';'; + out << nl << "return _" << p->name() << ';'; out << eb; out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public void" - << nl << "clear" << capName << "()"; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public void clear" << capName << "()"; out << sb; - out << nl << "__has_" << p->name() << " = false;"; + out << nl << "_" << p->name() << " = false;"; out << eb; - const string optType = typeToString(type, TypeModeMember, getPackage(contained), metaData, true, true); + const string optType = + typeToString(type, TypeModeMember, getPackage(contained), metaData, true, true, local); out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public void" - << nl << "optional" << capName << '(' << optType << " __v)"; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public void optional" << capName << '(' << optType << " v)"; out << sb; - out << nl << "if(__v == null || !__v.isSet())"; + out << nl << "if(v == null || !v.isPresent())"; out << sb; - out << nl << "__has_" << p->name() << " = false;"; + out << nl << "_" << p->name() << " = false;"; out << eb; out << nl << "else"; out << sb; - out << nl << "__has_" << p->name() << " = true;"; - out << nl << name << " = __v.get();"; + out << nl << "_" << p->name() << " = true;"; + if(b && b->kind() == Builtin::KindInt) + { + out << nl << name << " = v.getAsInt();"; + } + else if(b && b->kind() == Builtin::KindLong) + { + out << nl << name << " = v.getAsLong();"; + } + else if(b && b->kind() == Builtin::KindDouble) + { + out << nl << name << " = v.getAsDouble();"; + } + else + { + out << nl << name << " = v.get();"; + } out << eb; out << eb; out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public " << optType - << nl << "optional" << capName << "()"; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public " << optType << " optional" << capName << "()"; out << sb; - out << nl << "if(__has_" << p->name() << ')'; + out << nl << "if(_" << p->name() << ')'; out << sb; - out << nl << "return new " << optType << '(' << name << ");"; + if(classType) + { + out << nl << "return java.util.Optional.ofNullable(" << name << ");"; + } + else if(b && b->kind() == Builtin::KindInt) + { + out << nl << "return java.util.OptionalInt.of(" << name << ");"; + } + else if(b && b->kind() == Builtin::KindLong) + { + out << nl << "return java.util.OptionalLong.of(" << name << ");"; + } + else if(b && b->kind() == Builtin::KindDouble) + { + out << nl << "return java.util.OptionalDouble.of(" << name << ");"; + } + else + { + out << nl << "return java.util.Optional.of(" << name << ");"; + } out << eb; out << nl << "else"; out << sb; - out << nl << "return new " << optType << "();"; + if(b && b->kind() == Builtin::KindInt) + { + out << nl << "return java.util.OptionalInt.empty();"; + } + else if(b && b->kind() == Builtin::KindLong) + { + out << nl << "return java.util.OptionalLong.empty();"; + } + else if(b && b->kind() == Builtin::KindDouble) + { + out << nl << "return java.util.OptionalDouble.empty();"; + } + else + { + out << nl << "return java.util.Optional.empty();"; + } out << eb; out << eb; } @@ -4556,7 +3663,6 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) // // Check for bool type. // - BuiltinPtr b = BuiltinPtr::dynamicCast(type); if(b && b->kind() == Builtin::KindBool) { if(cls && !validateMethod(ops, "is" + capName, 0, file, line)) @@ -4564,20 +3670,17 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) return; } out << sp; - if(!deprecateReason.empty()) + if(dc && dc->deprecated) { - out << nl << "/**"; - out << nl << " * @deprecated " << deprecateReason; - out << nl << " **/"; + out << nl << "@Deprecated"; } - out << nl << "public boolean"; - out << nl << "is" << capName << "()"; + out << nl << "public boolean is" << capName << "()"; out << sb; if(optional) { - out << nl << "if(!__has_" << p->name() << ')'; + out << nl << "if(!_" << p->name() << ')'; out << sb; - out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << nl << "throw new java.util.NoSuchElementException(\"" << name << " is not set\");"; out << eb; } out << nl << "return " << name << ';'; @@ -4599,52 +3702,47 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) return; } - string elem = typeToString(seq->type(), TypeModeMember, getPackage(contained)); + string elem = typeToString(seq->type(), TypeModeMember, getPackage(contained), StringList(), true, + false, local); // // Indexed getter. // out << sp; - if(!deprecateReason.empty()) + if(dc && dc->deprecated) { - out << nl << "/**"; - out << nl << " * @deprecated " << deprecateReason; - out << nl << " **/"; + out << nl << "@Deprecated"; } - out << nl << "public " << elem; - out << nl << "get" << capName << "(int _index)"; + out << nl << "public " << elem << " get" << capName << "(int index)"; out << sb; if(optional) { - out << nl << "if(!__has_" << p->name() << ')'; + out << nl << "if(!_" << p->name() << ')'; out << sb; - out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << nl << "throw new java.util.NoSuchElementException(\"" << name << " is not set\");"; out << eb; } - out << nl << "return " << name << "[_index];"; + out << nl << "return this." << name << "[index];"; out << eb; // // Indexed setter. // out << sp; - if(!deprecateReason.empty()) + if(dc && dc->deprecated) { - out << nl << "/**"; - out << nl << " * @deprecated " << deprecateReason; - out << nl << " **/"; + out << nl << "@Deprecated"; } - out << nl << "public void"; - out << nl << "set" << capName << "(int _index, " << elem << " _val)"; + out << nl << "public void set" << capName << "(int index, " << elem << " val)"; out << sb; if(optional) { - out << nl << "if(!__has_" << p->name() << ')'; + out << nl << "if(!_" << p->name() << ')'; out << sb; - out << nl << "throw new java.lang.IllegalStateException(\"" << name << " is not set\");"; + out << nl << "throw new java.util.NoSuchElementException(\"" << name << " is not set\");"; out << eb; } - out << nl << name << "[_index] = _val;"; + out << nl << "this." << name << "[index] = val;"; out << eb; } } @@ -4664,7 +3762,12 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, "type")); + DocCommentPtr dc = parseDocComment(p); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } out << nl << "public enum " << name; if(!p->isLocal()) @@ -4679,22 +3782,24 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) { out << ','; } - out << nl; - writeDocComment(out, *en, getDeprecateReason(*en, 0, "enumerator")); + DocCommentPtr edc = parseDocComment(*en); + writeDocComment(out, edc); + if(edc && edc->deprecated) + { + out << nl << "@Deprecated"; + } out << nl << fixKwd((*en)->name()) << '(' << (*en)->value() << ')'; } out << ';'; - out << sp << nl << "public int" - << nl << "value()"; + out << sp << nl << "public int value()"; out << sb; - out << nl << "return __value;"; + out << nl << "return _value;"; out << eb; - out << sp << nl << "public static " << name - << nl << "valueOf(int __v)"; + out << sp << nl << "public static " << name << " valueOf(int v)"; out << sb; - out << nl << "switch(__v)"; + out << nl << "switch(v)"; out << sb; out.dec(); for(EnumeratorList::const_iterator en = enumerators.begin(); en != enumerators.end(); ++en) @@ -4709,77 +3814,49 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << nl << "return null;"; out << eb; - out << sp << nl << "private" - << nl << name << "(int __v)"; + out << sp << nl << "private " << name << "(int v)"; out << sb; - out << nl << "__value = __v;"; + out << nl << "_value = v;"; out << eb; if(!p->isLocal()) { - out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)"; + out << sp << nl << "public void ice_write(com.zeroc.Ice.OutputStream ostr)"; out << sb; - out << nl << "__os.writeEnum(value(), " << p->maxValue() << ");"; + out << nl << "ostr.writeEnum(_value, " << p->maxValue() << ");"; out << eb; - out << sp << nl << "public static void" << nl << "__write(IceInternal.BasicStream __os, " << name << " __v)"; + out << sp << nl << "public static void ice_write(com.zeroc.Ice.OutputStream ostr, " << name << " v)"; out << sb; - out << nl << "if(__v == null)"; + out << nl << "if(v == null)"; out << sb; string firstEnum = fixKwd(enumerators.front()->name()); - out << nl << "__os.writeEnum(" << absolute << '.' << firstEnum << ".value(), " << p->maxValue() << ");"; + out << nl << "ostr.writeEnum(" << absolute << '.' << firstEnum << ".value(), " << p->maxValue() << ");"; out << eb; out << nl << "else"; out << sb; - out << nl << "__os.writeEnum(__v.value(), " << p->maxValue() << ");"; + out << nl << "ostr.writeEnum(v.value(), " << p->maxValue() << ");"; out << eb; out << eb; - out << sp << nl << "public static " << name << nl << "__read(IceInternal.BasicStream __is)"; + out << sp << nl << "public static " << name << " ice_read(com.zeroc.Ice.InputStream istr)"; out << sb; - out << nl << "int __v = __is.readEnum(" << p->maxValue() << ");"; - out << nl << "return __validate(__v);"; + out << nl << "int v = istr.readEnum(" << p->maxValue() << ");"; + out << nl << "return validate(v);"; out << eb; - if(_stream) - { - out << sp << nl << "public void" << nl << "ice_write(Ice.OutputStream __outS)"; - out << sb; - out << nl << "__outS.writeEnum(value(), " << p->maxValue() << ");"; - out << eb; - - out << sp << nl << "public static void" << nl << "ice_write(Ice.OutputStream __outS, " << name << " __v)"; - out << sb; - out << nl << "if(__v == null)"; - out << sb; - out << nl << "__outS.writeEnum(" << absolute << '.' << firstEnum << ".value(), " << p->maxValue() << ");"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << "__outS.writeEnum(__v.value(), " << p->maxValue() << ");"; - out << eb; - out << eb; - - out << sp << nl << "public static " << name << nl << "ice_read(Ice.InputStream __inS)"; - out << sb; - out << nl << "int __v = __inS.readEnum(" << p->maxValue() << ");"; - out << nl << "return __validate(__v);"; - out << eb; - } - - out << sp << nl << "private static " << name - << nl << "__validate(int __v)"; + out << sp << nl << "private static " << name << " validate(int v)"; out << sb; - out << nl << "final " << name << " __e = valueOf(__v);"; - out << nl << "if(__e == null)"; + out << nl << "final " << name << " e = valueOf(v);"; + out << nl << "if(e == null)"; out << sb; - out << nl << "throw new Ice.MarshalException(\"enumerator value \" + __v + \" is out of range\");"; + out << nl << "throw new com.zeroc.Ice.MarshalException(\"enumerator value \" + v + \" is out of range\");"; out << eb; - out << nl << "return __e;"; + out << nl << "return e;"; out << eb; } - out << sp << nl << "private final int __value;"; + out << sp << nl << "private final int _value;"; out << eb; close(); @@ -4798,7 +3875,14 @@ Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p) Output& out = output(); out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, "constant")); + + DocCommentPtr dc = parseDocComment(p); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public interface " << name; out << sb; out << nl << typeToString(type, TypeModeIn, package) << " value = "; @@ -4845,7 +3929,7 @@ Slice::Gen::CompactIdVisitor::visitClassDefStart(const ClassDefPtr& p) if(p->compactId() >= 0) { ostringstream os; - os << prefix << "IceCompactId.TypeId_" << p->compactId(); + os << prefix << "com.zeroc.IceCompactId.TypeId_" << p->compactId(); open(os.str(), p->file()); Output& out = output(); @@ -4859,679 +3943,11 @@ Slice::Gen::CompactIdVisitor::visitClassDefStart(const ClassDefPtr& p) return false; } -Slice::Gen::HolderVisitor::HolderVisitor(const string& dir) : +Slice::Gen::HelperVisitor::HelperVisitor(const string& dir) : JavaVisitor(dir) { } -bool -Slice::Gen::HolderVisitor::visitClassDefStart(const ClassDefPtr& p) -{ - ClassDeclPtr decl = p->declaration(); - writeHolder(decl); - - if(!p->isLocal()) - { - string name = p->name(); - string absolute = getAbsolute(p, "", "", "PrxHolder"); - - open(absolute, p->file()); - Output& out = output(); - - out << sp << nl << "public final class " << name << "PrxHolder"; - out << sb; - out << sp << nl << "public" << nl << name << "PrxHolder()"; - out << sb; - out << eb; - out << sp << nl << "public" << nl << name << "PrxHolder(" << name << "Prx value)"; - out << sb; - out << nl << "this.value = value;"; - out << eb; - out << sp << nl << "public " << name << "Prx value;"; - out << eb; - close(); - } - - return false; -} - -bool -Slice::Gen::HolderVisitor::visitStructStart(const StructPtr& p) -{ - writeHolder(p); - return false; -} - -void -Slice::Gen::HolderVisitor::visitSequence(const SequencePtr& p) -{ - if(sequenceHasHolder(p)) - { - writeHolder(p); - } -} - -void -Slice::Gen::HolderVisitor::visitDictionary(const DictionaryPtr& p) -{ - writeHolder(p); -} - -void -Slice::Gen::HolderVisitor::visitEnum(const EnumPtr& p) -{ - writeHolder(p); -} - -void -Slice::Gen::HolderVisitor::writeHolder(const TypePtr& p) -{ - ContainedPtr contained = ContainedPtr::dynamicCast(p); - assert(contained); - string name = contained->name(); - string absolute = getAbsolute(contained, "", "", "Holder"); - - - string file; - if(p->definitionContext()) - { - file = p->definitionContext()->filename(); - } - - open(absolute, file); - Output& out = output(); - - string typeS = typeToString(p, TypeModeIn, getPackage(contained)); - out << sp << nl << "public final class " << name << "Holder"; - BuiltinPtr builtin = BuiltinPtr::dynamicCast(p); - ClassDeclPtr cl = ClassDeclPtr::dynamicCast(p); - if(!p->isLocal() && ((builtin && builtin->kind() == Builtin::KindObject) || cl)) - { - out << " extends Ice.ObjectHolderBase<" << typeS << ">"; - } - else { - out << " extends Ice.Holder<" << typeS << ">"; - } - out << sb; - if(!p->isLocal() && ((builtin && builtin->kind() == Builtin::KindObject) || cl)) - { - out << sp << nl << "public" << nl << name << "Holder()"; - out << sb; - out << eb; - out << sp << nl << "public" << nl << name << "Holder(" << typeS << " value)"; - out << sb; - out << nl << "this.value = value;"; - out << eb; - - out << sp << nl << "public void"; - out << nl << "patch(Ice.Object v)"; - out << sb; - out << nl << "if(v == null || v instanceof " << typeS << ")"; - out << sb; - out << nl << "value = (" << typeS << ")v;"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << "IceInternal.Ex.throwUOE(type(), v);"; - out << eb; - out << eb; - out << sp << nl << "public String" << nl << "type()"; - out << sb; - if(cl) - { - if(cl->isInterface()) - { - out << nl << "return _" << cl->name() << "Disp.ice_staticId();"; - } - else - { - out << nl << "return " << typeS << ".ice_staticId();"; - } - } - else - { - out << nl << "return \"" << p->typeId() << "\";"; - } - out << eb; - } - else - { - out << sp << nl << "public" << nl << name << "Holder()"; - out << sb; - out << eb; - out << sp << nl << "public" << nl << name << "Holder(" << typeS << " value)"; - out << sb; - out << nl << "super(value);"; - out << eb; - } - out << eb; - close(); -} - -Slice::Gen::HelperVisitor::HelperVisitor(const string& dir, bool stream) : - JavaVisitor(dir), _stream(stream) -{ -} - -bool -Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) -{ - if(p->isLocal()) - { - return false; - } - - // - // Proxy helper - // - string name = p->name(); - string scoped = p->scoped(); - string package = getPackage(p); - string absolute = getAbsolute(p); - - open(getAbsolute(p, "", "", "PrxHelper"), p->file()); - Output& out = output(); - - // - // A proxy helper class serves two purposes: it implements the - // proxy interface, and provides static helper methods for use - // by applications (e.g., checkedCast, etc.) - // - out << sp; - writeDocComment(out, getDeprecateReason(p, 0, p->isInterface() ? "interface" : "class"), - "Provides type-specific helper functions."); - out << nl << "public final class " << name << "PrxHelper extends Ice.ObjectPrxHelperBase implements " << name - << "Prx"; - - out << sb; - - string contextParam = "java.util.Map<String, String> __ctx"; - string explicitContextParam = "boolean __explicitCtx"; - - OperationList ops = p->allOperations(); - for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) - { - OperationPtr op = *r; - const ContainerPtr container = op->container(); - const ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - - out << sp; - out << nl << "private static final String __" << op->name() << "_name = \"" << op->name() << "\";"; - - // - // Use the optional mapping by default. - // - writeOperation(p, package, op, true); - - // - // If the operation actually sends any optionals, we generated overloaded methods - // that use the required mapping. - // - if(op->sendsOptionals()) - { - writeOperation(p, package, op, false); - } - - // - // End method - // - vector<string> outParams = getInOutParams(op, package, OutParam, true, true); - int iter = 0; - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - const TypePtr ret = op->returnType(); - const string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, op->returnIsOptional()); - - out << sp; - out << nl << "public " << retS << " end_" << op->name() << spar << outParams << "Ice.AsyncResult __iresult" - << epar; - writeThrowsClause(package, throws); - out << sb; - if(op->returnsData()) - { - out << nl << "IceInternal.OutgoingAsync __result = IceInternal.OutgoingAsync.check(__iresult, this, __" - << op->name() << "_name);"; - out << nl << "try"; - out << sb; - - out << nl << "if(!__result.__wait())"; - out << sb; - out << nl << "try"; - out << sb; - out << nl << "__result.throwUserException();"; - out << eb; - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // -#if defined(__SUNPRO_CC) - throws.sort(Slice::derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - for(ExceptionList::const_iterator eli = throws.begin(); eli != throws.end(); ++eli) - { - out << nl << "catch(" << getAbsolute(*eli, package) << " __ex)"; - out << sb; - out << nl << "throw __ex;"; - out << eb; - } - out << nl << "catch(Ice.UserException __ex)"; - out << sb; - out << nl << "throw new Ice.UnknownUserException(__ex.ice_name(), __ex);"; - out << eb; - out << eb; - - if(ret || !outParams.empty()) - { - out << nl << "IceInternal.BasicStream __is = __result.startReadParams();"; - const ParamDeclList paramList = op->parameters(); - ParamDeclList pl; - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) - { - if((*pli)->isOutParam()) - { - pl.push_back(*pli); - } - } - writeMarshalUnmarshalParams(out, package, pl, op, iter, false, true); - if(op->returnsClasses(false)) - { - out << nl << "__is.readPendingObjects();"; - } - out << nl << "__result.endReadParams();"; - } - else - { - out << nl << "__result.readEmptyParams();"; - } - - if(ret) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret); - if(!op->returnIsOptional() && - ((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))) - { - out << nl << "return __ret.value;"; - } - else - { - out << nl << "return __ret;"; - } - } - - out << eb; - out << nl << "finally"; - out << sb; - out << nl << "if(__result != null)"; - out << sb; - out << nl << "__result.cacheMessageBuffers();"; - out << eb; - out << eb; - } - else - { - out << nl << "__end(__iresult, __" << op->name() << "_name);"; - } - out << eb; - - // - // The async callbacks implementation of __completed method delegate to the static - // __<op-name>_completed method implemented bellow. - // - if(op->returnsData()) - { - const ParamDeclList paramList = op->parameters(); - ParamDeclList outParams; - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) - { - if((*pli)->isOutParam()) - { - outParams.push_back(*pli); - } - } - - out << sp << nl << "static public void __" << op->name() << "_completed(" - << getAsyncCallbackInterface(op, package) << " __cb, Ice.AsyncResult __result)"; - out << sb; - out << nl << getAbsolute(cl, "", "", "Prx") << " __proxy = (" - << getAbsolute(cl, "", "", "Prx") << ")__result.getProxy();"; - - TypePtr ret = op->returnType(); - if(ret) - { - out << nl << typeToString(ret, TypeModeIn, package, op->getMetaData(), true, - op->returnIsOptional()) - << " __ret = " << (op->returnIsOptional() ? "null" : initValue(ret)) << ';'; - } - for(ParamDeclList::const_iterator pli = outParams.begin(); pli != outParams.end(); ++pli) - { - string ts = typeToString((*pli)->type(), TypeModeOut, package, (*pli)->getMetaData(), true, - (*pli)->optional()); - out << nl << ts << ' ' << fixKwd((*pli)->name()) << " = new " << ts << "();"; - } - out << nl << "try"; - out << sb; - out << nl; - if(op->returnType()) - { - out << "__ret = "; - } - out << "__proxy.end_" << op->name() << spar << getInOutArgs(op, OutParam) << "__result" << epar - << ';'; - - out << eb; - if(!throws.empty()) - { - out << nl << "catch(Ice.UserException __ex)"; - out << sb; - out << nl << "__cb.exception(__ex);"; - out << nl << "return;"; - out << eb; - } - out << nl << "catch(Ice.LocalException __ex)"; - out << sb; - out << nl << "__cb.exception(__ex);"; - out << nl << "return;"; - out << eb; - out << nl << "catch(Ice.SystemException __ex)"; - out << sb; - out << nl << "__cb.exception(__ex);"; - out << nl << "return;"; - out << eb; - - out << nl << "__cb.response" << spar; - if(op->returnType()) - { - out << "__ret"; - } - for(ParamDeclList::const_iterator pli = outParams.begin(); pli != outParams.end(); ++pli) - { - if((*pli)->optional()) - { - out << fixKwd((*pli)->name()); - } - else - { - out << fixKwd((*pli)->name()) + ".value"; - } - } - out << epar << ';'; - - out << eb; - } - } - - out << sp; - writeDocComment(out, "", - "Contacts the remote server to verify that the object implements this type.\n" - "Raises a local exception if a communication error occurs.\n" - "@param __obj The untyped proxy.\n" - "@return A proxy for this type, or null if the object does not support this type."); - out << nl << "public static " << name << "Prx checkedCast(Ice.ObjectPrx __obj)"; - out << sb; - out << nl << "return checkedCastImpl(__obj, ice_staticId(), " << name << "Prx.class, " - << name << "PrxHelper.class);"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Contacts the remote server to verify that the object implements this type.\n" - "Raises a local exception if a communication error occurs.\n" - "@param __obj The untyped proxy.\n" - "@param __ctx The Context map to send with the invocation.\n" - "@return A proxy for this type, or null if the object does not support this type."); - out << nl << "public static " << name << "Prx checkedCast(Ice.ObjectPrx __obj, " << contextParam << ')'; - out << sb; - out << nl << "return checkedCastImpl(__obj, __ctx, ice_staticId(), " << name - << "Prx.class, " << name << "PrxHelper.class);"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Contacts the remote server to verify that a facet of the object implements this type.\n" - "Raises a local exception if a communication error occurs.\n" - "@param __obj The untyped proxy.\n" - "@param __facet The name of the desired facet.\n" - "@return A proxy for this type, or null if the object does not support this type."); - out << nl << "public static " << name << "Prx checkedCast(Ice.ObjectPrx __obj, String __facet)"; - out << sb; - out << nl << "return checkedCastImpl(__obj, __facet, ice_staticId(), " << name - << "Prx.class, " << name << "PrxHelper.class);"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Contacts the remote server to verify that a facet of the object implements this type.\n" - "Raises a local exception if a communication error occurs.\n" - "@param __obj The untyped proxy.\n" - "@param __facet The name of the desired facet.\n" - "@param __ctx The Context map to send with the invocation.\n" - "@return A proxy for this type, or null if the object does not support this type."); - out << nl << "public static " << name << "Prx checkedCast(Ice.ObjectPrx __obj, String __facet, " - << contextParam << ')'; - out << sb; - out << nl << "return checkedCastImpl(__obj, __facet, __ctx, ice_staticId(), " << name - << "Prx.class, " << name << "PrxHelper.class);"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Downcasts the given proxy to this type without contacting the remote server.\n" - "@param __obj The untyped proxy.\n" - "@return A proxy for this type."); - out << nl << "public static " << name << "Prx uncheckedCast(Ice.ObjectPrx __obj)"; - out << sb; - out << nl << "return uncheckedCastImpl(__obj, " << name << "Prx.class, " << name - << "PrxHelper.class);"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Downcasts the given proxy to this type without contacting the remote server.\n" - "@param __obj The untyped proxy.\n" - "@param __facet The name of the desired facet.\n" - "@return A proxy for this type."); - out << nl << "public static " << name << "Prx uncheckedCast(Ice.ObjectPrx __obj, String __facet)"; - out << sb; - out << nl << "return uncheckedCastImpl(__obj, __facet, " << name << "Prx.class, " << name - << "PrxHelper.class);"; - out << eb; - - ClassList allBases = p->allBases(); - StringList ids; - transform(allBases.begin(), allBases.end(), back_inserter(ids), constMemFun(&Contained::scoped)); - StringList other; - other.push_back(scoped); - other.push_back("::Ice::Object"); - other.sort(); - ids.merge(other); - ids.unique(); - StringList::const_iterator firstIter = ids.begin(); - StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), scoped); - assert(scopedIter != ids.end()); - StringList::difference_type scopedPos = ::IceUtilInternal::distance(firstIter, scopedIter); - - out << sp << nl << "public static final String[] __ids ="; - out << sb; - - for(StringList::const_iterator q = ids.begin(); q != ids.end();) - { - out << nl << '"' << *q << '"'; - if(++q != ids.end()) - { - out << ','; - } - } - - out << eb << ';'; - - out << sp; - writeDocComment(out, "", - "Provides the Slice type ID of this type.\n" - "@return The Slice type ID."); - out << nl << "public static String ice_staticId()"; - out << sb; - out << nl << "return __ids[" << scopedPos << "];"; - out << eb; - - out << sp << nl << "public static void __write(IceInternal.BasicStream __os, " << name << "Prx v)"; - out << sb; - out << nl << "__os.writeProxy(v);"; - out << eb; - - out << sp << nl << "public static " << name << "Prx __read(IceInternal.BasicStream __is)"; - out << sb; - out << nl << "Ice.ObjectPrx proxy = __is.readProxy();"; - out << nl << "if(proxy != null)"; - out << sb; - out << nl << name << "PrxHelper result = new " << name << "PrxHelper();"; - out << nl << "result.__copyFrom(proxy);"; - out << nl << "return result;"; - out << eb; - out << nl << "return null;"; - out << eb; - - if(_stream) - { - out << sp; - writeDocComment(out, "", - "Writes the proxy to the stream.\n" - "@param __outS The output stream.\n" - "@param v The proxy to write. A null value is legal."); - out << nl << "public static void write(Ice.OutputStream __outS, " << name << "Prx v)"; - out << sb; - out << nl << "__outS.writeProxy(v);"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Reads a proxy from the stream.\n" - "@param __inS The input stream.\n" - "@return The proxy, which may be null."); - out << nl << "public static " << name << "Prx read(Ice.InputStream __inS)"; - out << sb; - out << nl << "Ice.ObjectPrx proxy = __inS.readProxy();"; - out << nl << "if(proxy != null)"; - out << sb; - out << nl << name << "PrxHelper result = new " << name << "PrxHelper();"; - out << nl << "result.__copyFrom(proxy);"; - out << nl << "return result;"; - out << eb; - out << nl << "return null;"; - out << eb; - - out << sp; - writeDocComment(out, "", - "Provides the optional format for a proxy of this type.\n" - "@return The optional format."); - out << nl << "public static Ice.OptionalFormat optionalFormat()"; - out << sb; - out << nl << "return Ice.OptionalFormat.FSize;"; - out << eb; - } - - // - // Avoid serialVersionUID warnings for Proxy Helper classes. - // - out << sp << nl << "public static final long serialVersionUID = 0L;"; - out << eb; - - close(); - - if(_stream) - { - // - // Class helper. - // - open(getAbsolute(p, "", "", "Helper"), p->file()); - - Output& out2 = output(); - - out2 << sp; - writeDocComment(out2, getDeprecateReason(p, 0, p->isInterface() ? "interface" : "class"), - "Provides type-specific helper functions."); - out2 << nl << "public final class " << name << "Helper"; - out2 << sb; - - out2 << sp; - writeDocComment(out2, "", - "Writes an instance to the stream.\n" - "@param __outS The output stream.\n" - "@param __v The instance to write. A null value is legal."); - out2 << nl << "public static void write(Ice.OutputStream __outS, " << fixKwd(name) << " __v)"; - out2 << sb; - out2 << nl << "__outS.writeObject(__v);"; - out2 << eb; - - out2 << sp; - writeDocComment(out2, "", - "Reads an instance from the stream.\n" - "@param __inS The input stream.\n" - "@param __h A holder to contain the instance when it is eventually unmarshaled."); - out2 << nl << "public static void read(Ice.InputStream __inS, " << name << "Holder __h)"; - out2 << sb; - out2 << nl << "__inS.readObject(__h);"; - out2 << eb; - - out2 << sp; - writeDocComment(out2, "", - "Provides the optional format for an instance of this type.\n" - "@return The optional format."); - out2 << nl << "public static Ice.OptionalFormat optionalFormat()"; - out2 << sb; - out2 << nl << "return " << getOptionalFormat(p->declaration()) << ';'; - out2 << eb; - - out2 << eb; - close(); - } - - return false; -} - -bool -Slice::Gen::HelperVisitor::visitStructStart(const StructPtr& p) -{ - if(!p->isLocal() && _stream) - { - string name = p->name(); - string fixedName = fixKwd(name); - - open(getAbsolute(p, "", "", "Helper"), p->file()); - - Output& out = output(); - - out << sp << nl << "public final class " << name << "Helper"; - out << sb; - - out << sp << nl << "public static void write(Ice.OutputStream __outS, " << fixedName << " __v)"; - out << sb; - out << nl << "__v.ice_write(__outS);"; - out << eb; - - out << sp << nl << "public static " << fixedName << " read(Ice.InputStream __inS)"; - out << sb; - out << nl << fixedName << " __v = new " << fixedName << "();"; - out << nl << "__v.ice_read(__inS);"; - out << nl << "return __v;"; - out << eb; - - out << sp << nl << "public static Ice.OptionalFormat optionalFormat()"; - out << sb; - out << nl << "return " << getOptionalFormat(p) << ';'; - out << eb; - - out << eb; - close(); - } - - return false; -} - void Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p) { @@ -5586,7 +4002,7 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p) bool suppressUnchecked = false; string instanceType, formalType; - bool customType = getSequenceTypes(p, "", StringList(), instanceType, formalType); + bool customType = getSequenceTypes(p, "", StringList(), instanceType, formalType, false); if(!customType) { @@ -5622,10 +4038,10 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p) out << sp << nl << "public final class " << name << "Helper"; out << sb; - out << nl << "public static void" << nl << "write(IceInternal.BasicStream __os, " << typeS << " __v)"; + out << nl << "public static void write(com.zeroc.Ice.OutputStream ostr, " << typeS << " v)"; out << sb; iter = 0; - writeSequenceMarshalUnmarshalCode(out, package, p, "__v", true, iter, false); + writeSequenceMarshalUnmarshalCode(out, package, p, "v", true, iter, false); out << eb; out << sp; @@ -5633,41 +4049,14 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p) { out << nl << "@SuppressWarnings(\"unchecked\")"; } - out << nl << "public static " << typeS << nl << "read(IceInternal.BasicStream __is)"; + out << nl << "public static " << typeS << " read(com.zeroc.Ice.InputStream istr)"; out << sb; - out << nl << typeS << " __v;"; + out << nl << typeS << " v;"; iter = 0; - writeSequenceMarshalUnmarshalCode(out, package, p, "__v", false, iter, false); - out << nl << "return __v;"; + writeSequenceMarshalUnmarshalCode(out, package, p, "v", false, iter, false); + out << nl << "return v;"; out << eb; - if(_stream) - { - out << sp << nl << "public static void write(Ice.OutputStream __outS, " << typeS << " __v)"; - out << sb; - iter = 0; - writeStreamSequenceMarshalUnmarshalCode(out, package, p, "__v", true, iter, false); - out << eb; - - out << sp; - if(suppressUnchecked) - { - out << nl << "@SuppressWarnings(\"unchecked\")"; - } - out << nl << "public static " << typeS << " read(Ice.InputStream __inS)"; - out << sb; - out << nl << typeS << " __v;"; - iter = 0; - writeStreamSequenceMarshalUnmarshalCode(out, package, p, "__v", false, iter, false); - out << nl << "return __v;"; - out << eb; - - out << sp << nl << "public static Ice.OptionalFormat optionalFormat()"; - out << sb; - out << nl << "return " << getOptionalFormat(p) << ';'; - out << eb; - } - out << eb; close(); } @@ -5701,881 +4090,980 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p) out << sp << nl << "public final class " << name << "Helper"; out << sb; - out << nl << "public static void" << nl << "write(IceInternal.BasicStream __os, " << formalType << " __v)"; + out << nl << "public static void write(com.zeroc.Ice.OutputStream ostr, " << formalType << " v)"; out << sb; iter = 0; - writeDictionaryMarshalUnmarshalCode(out, package, p, "__v", true, iter, false); + writeDictionaryMarshalUnmarshalCode(out, package, p, "v", true, iter, false); out << eb; - out << sp << nl << "public static " << formalType - << nl << "read(IceInternal.BasicStream __is)"; + out << sp << nl << "public static " << formalType << " read(com.zeroc.Ice.InputStream istr)"; out << sb; - out << nl << formalType << " __v;"; + out << nl << formalType << " v;"; iter = 0; - writeDictionaryMarshalUnmarshalCode(out, package, p, "__v", false, iter, false); - out << nl << "return __v;"; + writeDictionaryMarshalUnmarshalCode(out, package, p, "v", false, iter, false); + out << nl << "return v;"; out << eb; - if(_stream) - { - out << sp << nl << "public static void write(Ice.OutputStream __outS, " << formalType - << " __v)"; - out << sb; - iter = 0; - writeStreamDictionaryMarshalUnmarshalCode(out, package, p, "__v", true, iter, false); - out << eb; - - out << sp << nl << "public static " << formalType << " read(Ice.InputStream __inS)"; - out << sb; - out << nl << formalType << " __v;"; - iter = 0; - writeStreamDictionaryMarshalUnmarshalCode(out, package, p, "__v", false, iter, false); - out << nl << "return __v;"; - out << eb; - - out << sp << nl << "public static Ice.OptionalFormat optionalFormat()"; - out << sb; - out << nl << "return " << getOptionalFormat(p) << ';'; - out << eb; - } - out << eb; close(); } -void -Slice::Gen::HelperVisitor::visitEnum(const EnumPtr& p) +Slice::Gen::ProxyVisitor::ProxyVisitor(const string& dir) : + JavaVisitor(dir) { - if(!p->isLocal() && _stream) +} + +bool +Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + if(p->isLocal()) { - string name = p->name(); - string fixedName = fixKwd(name); + return false; + } - open(getAbsolute(p, "", "", "Helper"), p->file()); + // + // Don't generate a proxy interface for a class with no operations. + // + const OperationList ops = p->allOperations(); + if(!p->isInterface() && ops.empty()) + { + return false; + } - Output& out = output(); + string name = p->name(); + ClassList bases = p->bases(); + string package = getPackage(p); + string absolute = getAbsolute(p, "", "", "Prx"); - out << sp << nl << "public final class " << name << "Helper"; - out << sb; + open(absolute, p->file()); - out << sp << nl << "public static void write(Ice.OutputStream __outS, " << fixedName << " __v)"; - out << sb; - out << nl << "__v.ice_write(__outS);"; - out << eb; + Output& out = output(); - out << sp << nl << "public static " << fixedName << " read(Ice.InputStream __inS)"; - out << sb; - out << nl << "return " << fixedName << ".ice_read(__inS);"; - out << eb; + // + // For proxy purposes, we can ignore a base class if it has no operations. + // + if(!bases.empty() && !bases.front()->isInterface() && bases.front()->allOperations().empty()) + { + bases.pop_front(); + } - out << sp << nl << "public static Ice.OptionalFormat optionalFormat()"; - out << sb; - out << nl << "return " << getOptionalFormat(p) << ';'; - out << eb; + DocCommentPtr dc = parseDocComment(p); - out << eb; - close(); + // + // Generate a Java interface as the user-visible type + // + out << sp; + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; } + out << nl << "public interface " << name << "Prx extends "; + out.useCurrentPosAsIndent(); + if(bases.empty()) + { + out << "com.zeroc.Ice.ObjectPrx"; + } + else + { + for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) + { + if(q != bases.begin()) + { + out << ',' << nl; + } + out << getAbsolute(*q, package, "", "Prx"); + } + } + out.restoreIndent(); + + out << sb; + + return true; } void -Slice::Gen::HelperVisitor::writeOperation(const ClassDefPtr& p, const string& package, const OperationPtr& op, - bool optionalMapping) +Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p) { - const string name = p->name(); Output& out = output(); - const string contextParam = "java.util.Map<String, String> __ctx"; - const string explicitContextParam = "boolean __explicitCtx"; + DocCommentPtr dc = parseDocComment(p); - const ContainerPtr container = op->container(); + const string contextParam = "java.util.Map<String, String> context"; + + out << sp; + writeDocComment(out, + "Contacts the remote server to verify that the object implements this type.\n" + "Raises a local exception if a communication error occurs.\n" + "@param obj The untyped proxy.\n" + "@return A proxy for this type, or null if the object does not support this type."); + out << nl << "static " << p->name() << "Prx checkedCast(com.zeroc.Ice.ObjectPrx obj)"; + out << sb; + out << nl << "return com.zeroc.Ice.ObjectPrx._checkedCast(obj, ice_staticId(), " << p->name() + << "Prx.class, _" << p->name() << "PrxI.class);"; + out << eb; + + out << sp; + writeDocComment(out, + "Contacts the remote server to verify that the object implements this type.\n" + "Raises a local exception if a communication error occurs.\n" + "@param obj The untyped proxy.\n" + "@param context The Context map to send with the invocation.\n" + "@return A proxy for this type, or null if the object does not support this type."); + out << nl << "static " << p->name() << "Prx checkedCast(com.zeroc.Ice.ObjectPrx obj, " << contextParam << ')'; + out << sb; + out << nl << "return com.zeroc.Ice.ObjectPrx._checkedCast(obj, context, ice_staticId(), " << p->name() + << "Prx.class, _" << p->name() << "PrxI.class);"; + out << eb; + + out << sp; + writeDocComment(out, + "Contacts the remote server to verify that a facet of the object implements this type.\n" + "Raises a local exception if a communication error occurs.\n" + "@param obj The untyped proxy.\n" + "@param facet The name of the desired facet.\n" + "@return A proxy for this type, or null if the object does not support this type."); + out << nl << "static " << p->name() << "Prx checkedCast(com.zeroc.Ice.ObjectPrx obj, String facet)"; + out << sb; + out << nl << "return com.zeroc.Ice.ObjectPrx._checkedCast(obj, facet, ice_staticId(), " << p->name() + << "Prx.class, _" << p->name() << "PrxI.class);"; + out << eb; + + out << sp; + writeDocComment(out, + "Contacts the remote server to verify that a facet of the object implements this type.\n" + "Raises a local exception if a communication error occurs.\n" + "@param obj The untyped proxy.\n" + "@param facet The name of the desired facet.\n" + "@param context The Context map to send with the invocation.\n" + "@return A proxy for this type, or null if the object does not support this type."); + out << nl << "static " << p->name() << "Prx checkedCast(com.zeroc.Ice.ObjectPrx obj, String facet, " + << contextParam << ')'; + out << sb; + out << nl << "return com.zeroc.Ice.ObjectPrx._checkedCast(obj, facet, context, ice_staticId(), " << p->name() + << "Prx.class, _" << p->name() << "PrxI.class);"; + out << eb; + + out << sp; + writeDocComment(out, + "Downcasts the given proxy to this type without contacting the remote server.\n" + "@param obj The untyped proxy.\n" + "@return A proxy for this type."); + out << nl << "static " << p->name() << "Prx uncheckedCast(com.zeroc.Ice.ObjectPrx obj)"; + out << sb; + out << nl << "return com.zeroc.Ice.ObjectPrx._uncheckedCast(obj, " << p->name() << "Prx.class, _" + << p->name() << "PrxI.class);"; + out << eb; + + out << sp; + writeDocComment(out, + "Downcasts the given proxy to this type without contacting the remote server.\n" + "@param obj The untyped proxy.\n" + "@param facet The name of the desired facet.\n" + "@return A proxy for this type."); + out << nl << "static " << p->name() << "Prx uncheckedCast(com.zeroc.Ice.ObjectPrx obj, String facet)"; + out << sb; + out << nl << "return com.zeroc.Ice.ObjectPrx._uncheckedCast(obj, facet, " << p->name() << "Prx.class, _" + << p->name() << "PrxI.class);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the per-proxy context.\n" + "@param newContext The context for the new proxy.\n" + "@return A proxy with the specified per-proxy context."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_context(java.util.Map<String, String> newContext)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_context(newContext);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the adapter ID.\n" + "@param newAdapterId The adapter ID for the new proxy.\n" + "@return A proxy with the specified adapter ID."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_adapterId(String newAdapterId)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_adapterId(newAdapterId);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the endpoints.\n" + "@param newEndpoints The endpoints for the new proxy.\n" + "@return A proxy with the specified endpoints."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_endpoints(com.zeroc.Ice.Endpoint[] newEndpoints)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_endpoints(newEndpoints);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the locator cache timeout.\n" + "@param newTimeout The new locator cache timeout (in seconds).\n" + "@return A proxy with the specified locator cache timeout."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_locatorCacheTimeout(int newTimeout)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_locatorCacheTimeout(newTimeout);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the invocation timeout.\n" + "@param newTimeout The new invocation timeout (in seconds).\n" + "@return A proxy with the specified invocation timeout."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_invocationTimeout(int newTimeout)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_invocationTimeout(newTimeout);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for connection caching.\n" + "@param newCache <code>true</code> if the new proxy should cache connections; <code>false</code> otherwise.\n" + "@return A proxy with the specified caching policy."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_connectionCached(boolean newCache)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_connectionCached(newCache);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the endpoint selection policy.\n" + "@param newType The new endpoint selection policy.\n" + "@return A proxy with the specified endpoint selection policy."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_endpointSelection(com.zeroc.Ice.EndpointSelectionType newType)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_endpointSelection(newType);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for how it selects endpoints.\n" + "@param b If <code>b</code> is <code>true</code>, only endpoints that use a secure transport are\n" + "used by the new proxy. If <code>b</code> is false, the returned proxy uses both secure and\n" + "insecure endpoints.\n" + "@return A proxy with the specified selection policy."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_secure(boolean b)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_secure(b);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the encoding used to marshal parameters.\n" + "@param e The encoding version to use to marshal request parameters.\n" + "@return A proxy with the specified encoding version."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_encodingVersion(com.zeroc.Ice.EncodingVersion e)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_encodingVersion(e);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for its endpoint selection policy.\n" + "@param b If <code>b</code> is <code>true</code>, the new proxy will use secure endpoints for invocations\n" + "and only use insecure endpoints if an invocation cannot be made via secure endpoints. If <code>b</code> is\n" + "<code>false</code>, the proxy prefers insecure endpoints to secure ones.\n" + "@return A proxy with the specified selection policy."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_preferSecure(boolean b)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_preferSecure(b);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the router.\n" + "@param router The router for the new proxy.\n" + "@return A proxy with the specified router."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_router(com.zeroc.Ice.RouterPrx router)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_router(router);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for the locator.\n" + "@param locator The locator for the new proxy.\n" + "@return A proxy with the specified locator."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_locator(com.zeroc.Ice.LocatorPrx locator)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_locator(locator);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for collocation optimization.\n" + "@param b <code>true</code> if the new proxy enables collocation optimization; <code>false</code> otherwise.\n" + "@return A proxy with the specified collocation optimization."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_collocationOptimized(boolean b)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_collocationOptimized(b);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, but uses twoway invocations.\n" + "@return A proxy that uses twoway invocations."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_twoway()"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_twoway();"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, but uses oneway invocations.\n" + "@return A proxy that uses oneway invocations."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_oneway()"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_oneway();"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, but uses batch oneway invocations.\n" + "@return A proxy that uses batch oneway invocations."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_batchOneway()"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_batchOneway();"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, but uses datagram invocations.\n" + "@return A proxy that uses datagram invocations."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_datagram()"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_datagram();"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, but uses batch datagram invocations.\n" + "@return A proxy that uses batch datagram invocations."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_batchDatagram()"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_batchDatagram();"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for compression.\n" + "@param co <code>true</code> enables compression for the new proxy; <code>false</code> disables compression.\n" + "@return A proxy with the specified compression setting."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_compress(boolean co)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_compress(co);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for its connection timeout setting.\n" + "@param t The connection timeout for the proxy in milliseconds.\n" + "@return A proxy with the specified timeout."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_timeout(int t)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_timeout(t);"; + out << eb; + + out << sp; + writeDocComment(out, + "Returns a proxy that is identical to this proxy, except for its connection ID.\n" + "@param connectionId The connection ID for the new proxy. An empty string removes the connection ID.\n" + "@return A proxy with the specified connection ID."); + out << nl << "@Override"; + out << nl << "default " << p->name() << "Prx ice_connectionId(String connectionId)"; + out << sb; + out << nl << "return (" << p->name() << "Prx)_ice_connectionId(connectionId);"; + out << eb; + + out << sp; + out << nl << "static String ice_staticId()"; + out << sb; + out << nl << "return \"" << p->scoped() << "\";"; + out << eb; + + out << eb; + close(); + + string absolute = getAbsolute(p, "", "_", "PrxI"); + + open(absolute, p->file()); + + Output& outi = output(); + + outi << sp; + if(dc && dc->deprecated) + { + outi << nl << "@Deprecated"; + } + outi << nl << "public class _" << p->name() << "PrxI extends com.zeroc.Ice._ObjectPrxI implements " << p->name() + << "Prx"; + outi << sb; + outi << sp << nl << "public static final long serialVersionUID = 0L;"; + outi << eb; + close(); +} + +void +Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) +{ + const string name = fixKwd(p->name()); + const ContainerPtr container = p->container(); const ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - const string opName = fixKwd(op->name()); - const TypePtr ret = op->returnType(); - const string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData(), true, op->returnIsOptional()); + const string package = getPackage(cl); - vector<string> params = getParamsProxy(op, package, false, optionalMapping); - vector<string> args = getArgs(op); + Output& out = output(); - ParamDeclList inParams; - ParamDeclList outParams; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) + const TypePtr ret = p->returnType(); + const string retS = getResultType(p, package, false, false); + const bool returnsParams = ret || !p->outParameters().empty(); + const vector<string> params = getParamsProxy(p, package, false); + const bool sendsOptionals = p->sendsOptionals(); + vector<string> paramsOpt; + if(sendsOptionals) { - if((*pli)->isOutParam()) - { - outParams.push_back(*pli); - } - else - { - inParams.push_back(*pli); - } + paramsOpt = getParamsProxy(p, package, true); } + const vector<string> args = getInArgs(p); - ExceptionList throws = op->throws(); + ExceptionList throws = p->throws(); throws.sort(); throws.unique(); // - // Write two synchronous versions of the operation - with and without a - // context parameter. + // Arrange exceptions into most-derived to least-derived order. If we don't + // do this, a base exception handler can appear before a derived exception + // handler, causing compiler warnings and resulting in the base exception + // being marshaled instead of the derived exception. // - out << sp << nl << "public " << retS << ' ' << opName << spar << params << epar; - writeThrowsClause(package, throws); - out << sb; - out << nl; - if(ret) +#if defined(__SUNPRO_CC) + throws.sort(Slice::derivedToBaseCompare); +#else + throws.sort(Slice::DerivedToBaseCompare()); +#endif + + const string contextParamName = getEscapedParamName(p, "context"); + const string contextDoc = "@param " + contextParamName +" The Context map to send with the invocation."; + const string contextParam = "java.util.Map<String, String> " + contextParamName; + const string noExplicitContextArg = "com.zeroc.Ice.ObjectPrx.noExplicitContext"; + + DocCommentPtr dc = parseDocComment(p); + + // + // Synchronous methods with required parameters. + // + out << sp; + writeProxyDocComment(out, p, package, dc, false, false); + if(dc && dc->deprecated) { - out << "return "; + out << nl << "@Deprecated"; } - out << opName << spar << args << "null" << "false" << epar << ';'; - out << eb; - - out << sp << nl << "public " << retS << ' ' << opName << spar << params << contextParam << epar; + out << nl << "default " << retS << ' ' << name << spar << params << epar; writeThrowsClause(package, throws); out << sb; out << nl; - if(ret) + if(returnsParams) { out << "return "; } - out << opName << spar << args << "__ctx" << "true" << epar << ';'; + out << name << spar << args << noExplicitContextArg << epar << ';'; out << eb; out << sp; - out << nl << "private " << retS << ' ' << opName << spar << params << contextParam - << explicitContextParam << epar; - writeThrowsClause(package, throws); - out << sb; - - // This code replaces the synchronous calls with chained AMI calls. - if(op->returnsData()) + writeProxyDocComment(out, p, package, dc, false, true); + if(dc && dc->deprecated) { - out << nl << "__checkTwowayOnly(__" << op->name() << "_name);"; + out << nl << "@Deprecated"; } - - if(ret) + out << nl << "default " << retS << ' ' << name << spar << params << contextParam << epar; + writeThrowsClause(package, throws); + out << sb; + if(throws.empty()) { - out << nl << "return "; + out << nl; + if(returnsParams) + { + out << "return "; + } + out << "_iceI_" << p->name() << "Async" << spar << args << contextParamName << "true" << epar << ".waitForResponse();"; } else { + out << nl << "try"; + out << sb; out << nl; - } - - out << "end_" << op->name() << "("; - vector<string> inOutArgs = getInOutArgs(op, OutParam); - if(!inOutArgs.empty()) { - for(vector<string>::const_iterator p = inOutArgs.begin(); p != inOutArgs.end(); ++p) { - out << *p << ", "; + if(returnsParams) + { + out << "return "; } - } - vector<string> inArgs = getInOutArgs(op, InParam); - out << "begin_" << op->name() << "("; - if(!inArgs.empty()) - { - for(vector<string>::const_iterator p = inArgs.begin(); p != inArgs.end(); ++p) { - out << *p << ", "; + out << "_iceI_" << p->name() << "Async" << spar << args << contextParamName << "true" << epar << ".waitForResponseOrUserEx();"; + out << eb; + for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t) + { + string exS = getAbsolute(*t, package); + out << nl << "catch(" << exS << " ex)"; + out << sb; + out << nl << "throw ex;"; + out << eb; } + out << nl << "catch(com.zeroc.Ice.UserException ex)"; + out << sb; + out << nl << "throw new com.zeroc.Ice.UnknownUserException(ex.ice_id(), ex);"; + out << eb; } - out << "__ctx, __explicitCtx, true, null));"; out << eb; + // + // Synchronous methods using optional parameters (if any). + // + if(sendsOptionals) { - // - // Write the asynchronous begin methods. - // - vector<string> inParams = getInOutParams(op, package, InParam, true, optionalMapping); - vector<string> inArgs = getInOutArgs(op, InParam); - const string callbackParam = "Ice.Callback __cb"; - const ParamDeclList paramList = op->parameters(); - int iter; - - // - // Type-unsafe begin methods - // - out << sp << nl << "public Ice.AsyncResult begin_" << op->name() << spar << inParams << epar; + out << sp; + writeProxyDocComment(out, p, package, dc, false, false); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "default " << retS << ' ' << name << spar << paramsOpt << epar; + writeThrowsClause(package, throws); out << sb; - out << nl << "return begin_" << op->name() << spar << inArgs << "null" << "false" << "false" << "null" << epar - << ';'; + out << nl; + if(returnsParams) + { + out << "return "; + } + out << name << spar << args << noExplicitContextArg << epar << ';'; out << eb; - out << sp << nl << "public Ice.AsyncResult begin_" << op->name() << spar << inParams << contextParam << epar; + out << sp; + writeProxyDocComment(out, p, package, dc, false, true); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "default " << retS << ' ' << name << spar << paramsOpt << contextParam << epar; + writeThrowsClause(package, throws); out << sb; - out << nl << "return begin_" << op->name() << spar << inArgs << "__ctx" << "true" << "false" << "null" << epar - << ';'; + if(throws.empty()) + { + out << nl; + if(returnsParams) + { + out << "return "; + } + out << "_iceI_" << p->name() << "Async" << spar << args << contextParamName << "true" << epar << ".waitForResponse();"; + } + else + { + out << nl << "try"; + out << sb; + out << nl; + if(returnsParams) + { + out << "return "; + } + out << "_iceI_" << p->name() << "Async" << spar << args << contextParamName << "true" << epar << ".waitForResponseOrUserEx();"; + out << eb; + for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t) + { + string exS = getAbsolute(*t, package); + out << nl << "catch(" << exS << " ex)"; + out << sb; + out << nl << "throw ex;"; + out << eb; + } + out << nl << "catch(com.zeroc.Ice.UserException ex)"; + out << sb; + out << nl << "throw new com.zeroc.Ice.UnknownUserException(ex.ice_id(), ex);"; + out << eb; + } out << eb; + } - out << sp << nl << "public Ice.AsyncResult begin_" << op->name() << spar << inParams << callbackParam << epar; - out << sb; - out << nl << "return begin_" << op->name() << spar << inArgs << "null" << "false" << "false" << "__cb" << epar - << ';'; - out << eb; + // + // Asynchronous methods with required parameters. + // + out << sp; + writeProxyDocComment(out, p, package, dc, true, false); - out << sp << nl << "public Ice.AsyncResult begin_" << op->name() << spar << inParams << contextParam - << callbackParam << epar; - out << sb; - out << nl << "return begin_" << op->name() << spar << inArgs << "__ctx" << "true" << "false" << "__cb" << epar - << ';'; - out << eb; + const string future = getFutureType(p, package); - // - // Type-safe begin methods - // - string typeSafeCallbackParam; + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "default " << future << ' ' << p->name() << "Async" << spar << params << epar; + out << sb; + out << nl << "return _iceI_" << p->name() << "Async" << spar << args << noExplicitContextArg << "false" << epar << ';'; + out << eb; - // - // Get the name of the callback using the name of the class in which this - // operation was defined. - // - ContainerPtr container = op->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - string opClassName = getAbsolute(cl, package, "Callback_", '_' + op->name()); - typeSafeCallbackParam = opClassName + " __cb"; + out << sp; + writeProxyDocComment(out, p, package, dc, true, true); - out << sp << nl << "public Ice.AsyncResult begin_" << op->name() << spar << inParams << typeSafeCallbackParam - << epar; - out << sb; - out << nl << "return begin_" << op->name() << spar << inArgs << "null" << "false" << "false" << "__cb" << epar - << ';'; - out << eb; + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "default " << future << ' ' << p->name() << "Async" << spar << params << contextParam << epar; + out << sb; + out << nl << "return _iceI_" << p->name() << "Async" << spar << args << "context" << "false" << epar << ';'; + out << eb; - out << sp << nl << "public Ice.AsyncResult begin_" << op->name() << spar << inParams << contextParam - << typeSafeCallbackParam << epar; - out << sb; - out << nl << "return begin_" << op->name() << spar << inArgs << "__ctx" << "true" << "false" << "__cb" << epar - << ';'; - out << eb; + const string futureImpl = getFutureImplType(p, package); - // - // Async methods that accept Java 8 lambda callbacks. - // - out << sp; - out << nl << "public Ice.AsyncResult begin_" << op->name(); - writeParamList(out, getParamsAsyncLambda(op, package, false, false, optionalMapping)); - out << sb; - out << nl << "return begin_" << op->name() << spar << getArgsAsyncLambda(op, package) << epar << ';'; - out << eb; + out << sp; + out << nl << "default " << futureImpl << " _iceI_" << p->name() << "Async" << spar << getParamsProxy(p, package, false, true) + << "java.util.Map<String, String> context" + << "boolean sync" << epar; + out << sb; + out << nl << futureImpl << " f = new com.zeroc.IceInternal.OutgoingAsync<>(this, \"" << p->name() << "\", " + << sliceModeToIceMode(p->sendMode()) << ", sync, " + << (throws.empty() ? "null" : "_iceE_" + p->name()) << ");"; - out << sp; - out << nl << "public Ice.AsyncResult begin_" << op->name(); - writeParamList(out, getParamsAsyncLambda(op, package, false, true, optionalMapping)); - out << sb; - out << nl << "return begin_" << op->name() << spar << getArgsAsyncLambda(op, package, false, true) << epar - << ';'; - out << eb; + out << nl << "f.invoke("; + out.useCurrentPosAsIndent(); + out << (p->returnsData() ? "true" : "false") << ", context, " << opFormatTypeToString(p) + << ", "; + if(!p->inParameters().empty()) + { + out << "ostr -> {"; + out.inc(); + writeMarshalProxyParams(out, package, p, false); + out.dec(); + out << nl << '}'; + } + else + { + out << "null"; + } + out << ", "; + if(returnsParams) + { + out << "istr -> {"; + out.inc(); + writeUnmarshalProxyResults(out, package, p); + out.dec(); + out << nl << "}"; + } + else + { + out << "null"; + } + out.restoreIndent(); + out << ");"; + out << nl << "return f;"; + out << eb; - out << sp; - out << nl << "public Ice.AsyncResult begin_" << op->name(); - writeParamList(out, getParamsAsyncLambda(op, package, true, false, optionalMapping)); + if(!throws.empty()) + { + out << sp << nl << "static final Class<?>[] _iceE_" << p->name() << " ="; out << sb; - out << nl << "return begin_" << op->name() << spar << getArgsAsyncLambda(op, package, true) << epar << ';'; - out << eb; + for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t) + { + if(t != throws.begin()) + { + out << ","; + } + out << nl << getAbsolute(*t, package) << ".class"; + } + out << eb << ';'; + } + if(sendsOptionals) + { out << sp; - out << nl << "public Ice.AsyncResult begin_" << op->name(); - writeParamList(out, getParamsAsyncLambda(op, package, true, true, optionalMapping)); + writeProxyDocComment(out, p, package, dc, true, false); + + const string future = getFutureType(p, package); + + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "default " << future << ' ' << p->name() << "Async" << spar << paramsOpt << epar; out << sb; - out << nl << "return begin_" << op->name() << spar << getArgsAsyncLambda(op, package, true, true) << epar + out << nl << "return _iceI_" << p->name() << "Async" << spar << args << noExplicitContextArg << "false" << epar << ';'; out << eb; - vector<string> params = inParams; - params.push_back(contextParam); - params.push_back("boolean __explicitCtx"); - params.push_back("boolean __synchronous"); - vector<string> asyncParams = getParamsAsyncLambda(op, package, false, true, optionalMapping, false); - copy(asyncParams.begin(), asyncParams.end(), back_inserter(params)); - out << sp; - out << nl << "private Ice.AsyncResult begin_" << op->name(); - writeParamList(out, params); - out << sb; - - ParamDeclList outParams = getOutParams(op); + writeProxyDocComment(out, p, package, dc, true, true); - if(!op->returnsData()) + if(dc && dc->deprecated) { - params = getInOutArgs(op, InParam); - params.push_back("__ctx"); - params.push_back("__explicitCtx"); - params.push_back("__synchronous"); - params.push_back("new IceInternal.Functional_OnewayCallback(__responseCb, __exceptionCb, __sentCb)"); - out << nl << "return begin_" << op->name(); - writeParamList(out, params); - out << ';'; + out << nl << "@Deprecated"; } - else if((ret && !outParams.empty()) || (outParams.size() > 1)) - { - params.clear(); - params.push_back(getLambdaResponseCB(op, package) + " responseCb"); - if(!throws.empty()) - { - params.push_back("IceInternal.Functional_GenericCallback1<Ice.UserException> userExceptionCb"); - } - params.push_back("IceInternal.Functional_GenericCallback1<Ice.Exception> exceptionCb"); - params.push_back("IceInternal.Functional_BoolCallback sentCb"); - - out << sp; - out << nl << "class CB extends " << getAsyncCallbackBaseClass(op, true); - out << sb; - out << nl << "public CB"; - writeParamList(out, params); - out << sb; - out << nl << "super(responseCb != null, "; - if(!throws.empty()) - { - out << "userExceptionCb, "; - } - out << "exceptionCb, sentCb);"; - out << nl << "__responseCb = responseCb;"; - out << eb; - - out << sp; - out << nl << "public void response" << spar << getParamsAsyncCB(op, package, false, true) << epar; - out << sb; - out << nl << "if(__responseCb != null)"; - out << sb; - out << nl << "__responseCb.apply" << spar; - if(ret) - { - out << "__ret"; - } - out << getInOutArgs(op, OutParam) << epar << ';'; - out << eb; - out << eb; + out << nl << "default " << future << ' ' << p->name() << "Async" << spar << paramsOpt << contextParam << epar; + out << sb; + out << nl << "return _iceI_" << p->name() << "Async" << spar << args << contextParamName << "false" << epar << ';'; + out << eb; - out << sp; - out << nl << "public final void __completed(Ice.AsyncResult __result)"; - out << sb; - out << nl << p->name() << "PrxHelper.__" << op->name() << "_completed(this, __result);"; - out << eb; - out << sp; - out << nl << "private final " << getLambdaResponseCB(op, package) << " __responseCb;"; - out << eb; + out << sp; + out << nl << "default " << futureImpl << " _iceI_" << p->name() << "Async" << spar << getParamsProxy(p, package, true, true) + << "java.util.Map<String, String> context" + << "boolean sync" << epar; + out << sb; + out << nl << futureImpl << " f = new com.zeroc.IceInternal.OutgoingAsync<>(this, \"" << p->name() << "\", " + << sliceModeToIceMode(p->sendMode()) << ", sync, " + << (throws.empty() ? "null" : "_iceE_" + p->name()) << ");"; - out << nl << "return begin_" << op->name() << spar << getInOutArgs(op, InParam) << "__ctx" - << "__explicitCtx" - << "__synchronous" - << (throws.empty() ? "new CB(__responseCb, __exceptionCb, __sentCb)" : - "new CB(__responseCb, __userExceptionCb, __exceptionCb, __sentCb)") - << epar << ';'; - } - else + out << nl << "f.invoke("; + out.useCurrentPosAsIndent(); + out << (p->returnsData() ? "true" : "false") << ", context, " << opFormatTypeToString(p) << ", "; + if(!p->inParameters().empty()) { - params = getInOutArgs(op, InParam); - params.push_back("__ctx"); - params.push_back("__explicitCtx"); - params.push_back("__synchronous"); - - const string baseClass = getAsyncCallbackBaseClass(op, true); - out << nl << "return begin_" << op->name(); - writeParamList(out, params, false, false); - out << nl - << (throws.empty() ? "new " + baseClass + "(__responseCb, __exceptionCb, __sentCb)" : - "new " + baseClass + "(__responseCb, __userExceptionCb, __exceptionCb, __sentCb)"); + out << "ostr -> {"; out.inc(); - out << sb; - out << nl << "public final void __completed(Ice.AsyncResult __result)"; - out << sb; - out << nl << p->name() << "PrxHelper.__" << op->name() << "_completed(this, __result);"; - out << eb; - out << eb; - out << ");"; + writeMarshalProxyParams(out, package, p, true); out.dec(); - out.restoreIndent(); + out << nl << '}'; } - out << eb; - - // - // Implementation of begin method - // - params = inParams; - params.push_back(contextParam); - params.push_back("boolean __explicitCtx"); - params.push_back("boolean __synchronous"); - params.push_back("IceInternal.CallbackBase __cb"); - - out << sp; - out << nl << "private Ice.AsyncResult begin_" << op->name(); - writeParamList(out, params); - out << sb; - if(op->returnsData()) + else { - out << nl << "__checkAsyncTwowayOnly(__" << op->name() << "_name);"; + out << "null"; } - out << nl << "IceInternal.OutgoingAsync __result = getOutgoingAsync(__" << op->name() - << "_name, __cb);"; - out << nl << "try"; - out << sb; - - out << nl << "__result.prepare(__" << op->name() << "_name, " << sliceModeToIceMode(op->sendMode()) - << ", __ctx, __explicitCtx, __synchronous);"; - - iter = 0; - if(!inArgs.empty()) + out << ", "; + if(returnsParams) { - out << nl << "IceInternal.BasicStream __os = __result.startWriteParams(" - << opFormatTypeToString(op) << ");"; - ParamDeclList pl; - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) - { - if(!(*pli)->isOutParam()) - { - pl.push_back(*pli); - } - } - writeMarshalUnmarshalParams(out, package, pl, 0, iter, true, optionalMapping); - if(op->sendsClasses(false)) - { - out << nl << "__os.writePendingObjects();"; - } - out << nl << "__result.endWriteParams();"; + out << "istr -> {"; + out.inc(); + writeUnmarshalProxyResults(out, package, p); + out.dec(); + out << nl << "}"; } else { - out << nl << "__result.writeEmptyParams();"; + out << "null"; } - - out << nl << "__result.invoke();"; - out << eb; - out << nl << "catch(Ice.Exception __ex)"; - out << sb; - out << nl << "__result.abort(__ex);"; - out << eb; - out << nl << "return __result;"; + out.restoreIndent(); + out << ");"; + out << nl << "return f;"; out << eb; } } -Slice::Gen::ProxyVisitor::ProxyVisitor(const string& dir) : +Slice::Gen::DispatcherVisitor::DispatcherVisitor(const string& dir) : JavaVisitor(dir) { } bool -Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p) +Slice::Gen::DispatcherVisitor::visitClassDefStart(const ClassDefPtr& p) { - if(p->isLocal()) + if(p->isLocal() || p->isInterface() || p->allOperations().empty()) { return false; } - string name = p->name(); - ClassList bases = p->bases(); - string package = getPackage(p); - string absolute = getAbsolute(p, "", "", "Prx"); + const string name = p->name(); + const string absolute = getAbsolute(p, "", "_", "Disp"); + const string package = getPackage(p); open(absolute, p->file()); Output& out = output(); + out << sp; + DocCommentPtr dc = parseDocComment(p); + writeDocComment(out, dc); + if(dc && dc->deprecated) + { + out << nl << "@Deprecated"; + } + out << nl << "public interface _" << name << "Disp"; + // - // Generate a Java interface as the user-visible type + // For dispatch purposes, we can ignore a base class if it has no operations. // - out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, p->isInterface() ? "interface" : "class")); - out << nl << "public interface " << name << "Prx extends "; + ClassList bases = p->bases(); + if(!bases.empty() && !bases.front()->isInterface() && bases.front()->allOperations().empty()) + { + bases.pop_front(); + } + if(bases.empty()) { - out << "Ice.ObjectPrx"; + out << " extends com.zeroc.Ice.Object"; } else { + out << " extends "; out.useCurrentPosAsIndent(); - for(ClassList::const_iterator q = bases.begin(); q != bases.end();) + for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) { - out << getAbsolute(*q, package, "", "Prx"); - if(++q != bases.end()) + if(q != bases.begin()) { out << ',' << nl; } + if(!(*q)->isInterface()) + { + out << getAbsolute(*q, package, "_", "Disp"); + } + else + { + out << getAbsolute(*q, package); + } } out.restoreIndent(); } - out << sb; - return true; -} + writeDispatch(out, p); -void -Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr&) -{ - Output& out = output(); out << eb; close(); -} - -void -Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) -{ - string name = fixKwd(p->name()); - ContainerPtr container = p->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - string package = getPackage(cl); - - Output& out = output(); - TypePtr ret = p->returnType(); - string retS = typeToString(ret, TypeModeReturn, package, p->getMetaData(), true, p->returnIsOptional()); - vector<string> params = getParamsProxy(p, package, false, true); - 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"; - string lambdaResponseDoc = "@param __responseCb The lambda response callback."; - string lambdaUserExDoc = "@param __userExceptionCb The lambda user exception callback."; - string lambdaExDoc = "@param __exceptionCb The lambda exception callback."; - string lambdaSentDoc = "@param __sentCb The lambda sent callback."; - - const bool optional = p->sendsOptionals(); - - // - // Write two synchronous versions of the operation - with and without a context parameter. - // - out << sp; - writeDocComment(out, p, deprecateReason); - - out << nl << "public " << retS << ' ' << name << spar << params << epar; - writeThrowsClause(package, throws); - out << ';'; - - out << sp; - writeDocComment(out, p, deprecateReason, contextDoc); - - out << nl << "public " << retS << ' ' << name << spar << params << contextParam << epar; - writeThrowsClause(package, throws); - out << ';'; - - if(optional) - { - // - // Write overloaded versions of the methods using required params. - // - vector<string> reqParams = getParamsProxy(p, package, false, false); - - out << sp; - writeDocComment(out, p, deprecateReason); - out << nl << "public " << retS << ' ' << name << spar << reqParams << epar; - writeThrowsClause(package, throws); - out << ';'; - - out << sp; - writeDocComment(out, p, deprecateReason, contextDoc); - out << nl << "public " << retS << ' ' << name << spar << reqParams << contextParam << epar; - writeThrowsClause(package, throws); - out << ';'; - } - - { - // - // Write the asynchronous begin/end methods. - // - // Start with the type-unsafe begin methods. - // - vector<string> inParams = getInOutParams(p, package, InParam, true, true); - string callbackParam = "Ice.Callback __cb"; - string callbackDoc = "@param __cb The asynchronous callback object."; - - out << sp; - writeDocCommentAMI(out, p, InParam); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << callbackParam << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam << callbackParam - << epar << ';'; - - // - // Type-safe begin methods. - // - string typeSafeCallbackParam; - - // - // Get the name of the callback using the name of the class in which this - // operation was defined. - // - ContainerPtr container = p->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - string opClassName = getAbsolute(cl, package, "Callback_", '_' + p->name()); - typeSafeCallbackParam = opClassName + " __cb"; - - out << sp; - writeDocCommentAMI(out, p, InParam, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << typeSafeCallbackParam - << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam - << typeSafeCallbackParam << epar << ';'; - - // - // Generate the Callback Response interface if the operation has more than one - // return parameter. Operations with just one return parameter use one of the - // builtin async callback interfaces. - // - { - ParamDeclList outParams = getOutParams(p); - if((ret && !outParams.empty()) || outParams.size() > 1) - { - vector<string> params = getParamsAsyncCB(p, package, false, true); - out << sp; - out << nl << "public interface " << getLambdaResponseCB(p, package); - out << sb; - out << nl << "void apply" << spar << params << epar << ';'; - out << eb; - } - } - - // - // Async methods that accept Java 8 lambda callbacks. - // - { - out << sp; - writeDocCommentAMI(out, p, InParam, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, lambdaExDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, false, false, true)); - out << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, lambdaExDoc, - lambdaSentDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, false, true, true)); - out << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, - lambdaExDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, true, false, true)); - out << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, - lambdaExDoc, lambdaSentDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, true, true, true)); - out << ';'; - } - - vector<string> outParams = getInOutParams(p, package, OutParam, true, true); - - out << sp; - writeDocCommentAMI(out, p, OutParam); - out << nl << "public " << retS << " end_" << p->name() << spar << outParams << "Ice.AsyncResult __result" - << epar; - writeThrowsClause(package, throws); - out << ';'; - } - - if(optional) - { - // - // Write overloaded versions of the methods using required params. - // - vector<string> inParams = getInOutParams(p, package, InParam, true, false); - string callbackParam = "Ice.Callback __cb"; - string callbackDoc = "@param __cb The asynchronous callback object."; - - out << sp; - writeDocCommentAMI(out, p, InParam); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << callbackParam << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam << callbackParam - << epar << ';'; - - // - // Async methods that accept Java 8 lambda callbacks. - // - { - out << sp; - writeDocCommentAMI(out, p, InParam, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, lambdaExDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package)); - out << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, lambdaExDoc, - lambdaSentDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, false, true)); - out << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, - lambdaExDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, true)); - out << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, lambdaResponseDoc, throws.empty() ? "" : lambdaUserExDoc, - lambdaExDoc, lambdaSentDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name(); - writeParamList(out, getParamsAsyncLambda(p, package, true, true)); - out << ';'; - } - - // - // Type-safe begin methods. - // - string typeSafeCallbackParam; - - // - // Get the name of the callback using the name of the class in which this - // operation was defined. - // - ContainerPtr container = p->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - string opClassName = getAbsolute(cl, package, "Callback_", '_' + p->name()); - typeSafeCallbackParam = opClassName + " __cb"; - - out << sp; - writeDocCommentAMI(out, p, InParam, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << typeSafeCallbackParam - << epar << ';'; - - out << sp; - writeDocCommentAMI(out, p, InParam, contextDoc, callbackDoc); - out << nl << "public Ice.AsyncResult begin_" << p->name() << spar << inParams << contextParam - << typeSafeCallbackParam << epar << ';'; - } + return false; } -Slice::Gen::DispatcherVisitor::DispatcherVisitor(const string& dir, bool stream) : - JavaVisitor(dir), _stream(stream) +Slice::Gen::ImplVisitor::ImplVisitor(const string& dir) : + JavaVisitor(dir) { } bool -Slice::Gen::DispatcherVisitor::visitClassDefStart(const ClassDefPtr& p) +Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) { - if(p->isLocal() || !p->isInterface()) + if(!p->isAbstract()) { return false; } string name = p->name(); ClassList bases = p->bases(); - string absolute = getAbsolute(p, "", "_", "Disp"); + string package = getPackage(p); + string absolute = getAbsolute(p, "", "", "I"); open(absolute, p->file()); Output& out = output(); - out << sp; - writeDocComment(out, p, getDeprecateReason(p, 0, p->isInterface() ? "interface" : "class")); - out << nl << "public abstract class _" << name << "Disp extends Ice.ObjectImpl implements " << fixKwd(name); + out << sp << nl << "public final class " << name << 'I'; + if(p->isInterface()) + { + out << " implements " << fixKwd(name); + } + else + { + if(p->isLocal()) + { + out << " extends " << fixKwd(name); + } + else + { + out << " implements _" << name << "Disp"; + } + } out << sb; - out << sp << nl << "protected void" << nl << "ice_copyStateFrom(Ice.Object __obj)"; - out.inc(); - out << nl << "throws java.lang.CloneNotSupportedException"; - out.dec(); + out << nl << "public " << name << "I()"; out << sb; - out << nl << "throw new java.lang.CloneNotSupportedException();"; out << eb; - writeDispatchAndMarshalling(out, p, _stream); + OperationList ops = p->allOperations(); + for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) + { + writeOperation(out, package, *r, p->isLocal()); + } - // - // Avoid serialVersionUID warnings for dispatch classes. - // - out << sp << nl << "public static final long serialVersionUID = 0L;"; out << eb; close(); return false; } -Slice::Gen::BaseImplVisitor::BaseImplVisitor(const string& dir) : - JavaVisitor(dir) -{ -} - -void -Slice::Gen::BaseImplVisitor::writeDecl(Output& out, const string& package, const string& name, const TypePtr& type, - const StringList& metaData, bool optional) +string +Slice::Gen::ImplVisitor::getDefaultValue(const string& package, const TypePtr& type, bool optional) { - string typeS = typeToString(type, TypeModeIn, package, metaData, true, optional); - out << nl << typeS << ' ' << name; - + const BuiltinPtr b = BuiltinPtr::dynamicCast(type); if(optional) { - out << " = new " << typeS << "();"; + if(b && b->kind() == Builtin::KindDouble) + { + return "java.util.OptionalDouble.empty()"; + } + else if(b && b->kind() == Builtin::KindInt) + { + return "java.util.OptionalInt.empty()"; + } + else if(b && b->kind() == Builtin::KindLong) + { + return "java.util.OptionalLong.empty()"; + } + else + { + return "java.util.Optional.empty()"; + } } else { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); - if(builtin) + if(b) { - switch(builtin->kind()) + switch(b->kind()) { case Builtin::KindBool: { - out << " = false"; + return "false"; break; } case Builtin::KindByte: { - out << " = (byte)0"; + return "(byte)0"; break; } case Builtin::KindShort: { - out << " = (short)0"; + return "(short)0"; break; } case Builtin::KindInt: case Builtin::KindLong: { - out << " = 0"; + return "0"; break; } case Builtin::KindFloat: { - out << " = (float)0.0"; + return "(float)0.0"; break; } case Builtin::KindDouble: { - out << " = 0.0"; + return "0.0"; break; } case Builtin::KindString: { - out << " = \"\""; + return "\"\""; break; } case Builtin::KindObject: case Builtin::KindObjectProxy: case Builtin::KindLocalObject: + case Builtin::KindValue: { - out << " = null"; + return "null"; break; } } @@ -6586,576 +5074,163 @@ Slice::Gen::BaseImplVisitor::writeDecl(Output& out, const string& package, const if(en) { EnumeratorList enumerators = en->getEnumerators(); - out << " = " << getAbsolute(en, package) << '.' << fixKwd(enumerators.front()->name()); - } - else - { - out << " = null"; + return getAbsolute(en, package) + '.' + fixKwd(enumerators.front()->name()); } } - - out << ';'; } -} -void -Slice::Gen::BaseImplVisitor::writeReturn(Output& out, const TypePtr& type, bool optional) -{ - if(optional) - { - out << nl << "return null;"; - } - else - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); - if(builtin) - { - switch(builtin->kind()) - { - 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; - } - - out << nl << "return null;"; - } + return "null"; } -void -Slice::Gen::BaseImplVisitor::writeOperation(Output& out, const string& package, const OperationPtr& op, bool local) +bool +Slice::Gen::ImplVisitor::initResult(Output& out, const string& package, const OperationPtr& op) { - string opName = op->name(); - - const TypePtr ret = op->returnType(); - const bool optionalMapping = useOptionalMapping(op); - const StringList opMetaData = op->getMetaData(); - const string retS = typeToString(ret, TypeModeReturn, package, opMetaData, true, - optionalMapping && op->returnIsOptional()); - vector<string> params = getParams(op, package, false, optionalMapping); - - ContainerPtr container = op->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); + const string retS = getResultType(op, package, false, true); - if(!local && (cl->hasMetaData("amd") || op->hasMetaData("amd"))) + if(op->hasMarshaledResult()) { - vector<string> paramsAMD = getParamsAsync(op, package, true, true); - - out << sp << nl << "public void " << opName << "_async" << spar << paramsAMD << "Ice.Current __current" - << epar; - - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // -#if defined(__SUNPRO_CC) - throws.sort(Slice::derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - writeThrowsClause(package, throws); - - out << sb; - - string result = "__r"; - ParamDeclList paramList = op->parameters(); - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + out << nl << retS << " r = new " << retS << spar; + const ParamDeclList outParams = op->outParameters(); + if(op->returnType()) { - if((*q)->name() == result) - { - result = "_" + result; - break; - } + out << getDefaultValue(package, op->returnType(), op->returnIsOptional()); } - if(ret) + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) { - writeDecl(out, package, result, ret, opMetaData, optionalMapping && op->returnIsOptional()); + out << getDefaultValue(package, (*p)->type(), (*p)->optional()); } - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + out << "current" << epar << ';'; + } + else if(op->returnsMultipleValues()) + { + out << nl << retS << " r = new " << retS << "();"; + string retval = "returnValue"; + const ParamDeclList outParams = op->outParameters(); + for(ParamDeclList::const_iterator p = outParams.begin(); p != outParams.end(); ++p) { - if((*q)->isOutParam()) + out << nl << "r." << fixKwd((*p)->name()) << " = " + << getDefaultValue(package, (*p)->type(), (*p)->optional()) << ';'; + if((*p)->name() == "returnValue") { - writeDecl(out, package, fixKwd((*q)->name()), (*q)->type(), (*q)->getMetaData(), - optionalMapping && (*q)->optional()); + retval = "_returnValue"; } } - - out << nl << "__cb.ice_response("; - if(ret) + if(op->returnType()) { - out << result; + out << nl << "r." << retval << " = " + << getDefaultValue(package, op->returnType(), op->returnIsOptional()) << ';'; } - bool firstOutParam = true; - for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) - { - if((*q)->isOutParam()) - { - if(ret || !firstOutParam) - { - out << ", "; - } - out << fixKwd((*q)->name()); - firstOutParam = false; - } - } - out << ");"; - - out << eb; } else { - out << sp << nl << "public " << retS << nl << fixKwd(opName) << spar << params; - if(!local) + TypePtr type = op->returnType(); + bool optional = op->returnIsOptional(); + if(!type) { - out << "Ice.Current __current"; + const ParamDeclList outParams = op->outParameters(); + if(!outParams.empty()) + { + assert(outParams.size() == 1); + type = outParams.front()->type(); + optional = outParams.front()->optional(); + } } - out << epar; - - ExceptionList throws = op->throws(); - throws.sort(); - throws.unique(); - - if(op->hasMetaData("UserException")) + if(type) { - out.inc(); - out << nl << "throws Ice.UserException"; - out.dec(); + out << nl << retS << " r = " << getDefaultValue(package, type, optional) << ';'; } else { - writeThrowsClause(package, throws); + return false; } - - out << sb; - - // - // Return value - // - if(ret) - { - writeReturn(out, ret, optionalMapping && op->returnIsOptional()); - } - - out << eb; } -} -Slice::Gen::ImplVisitor::ImplVisitor(const string& dir) : - BaseImplVisitor(dir) -{ + return true; } -bool -Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) +void +Slice::Gen::ImplVisitor::writeOperation(Output& out, const string& package, const OperationPtr& op, bool local) { - if(!p->isAbstract()) - { - return false; - } - - string name = p->name(); - ClassList bases = p->bases(); - string package = getPackage(p); - string absolute = getAbsolute(p, "", "", "I"); + string opName = op->name(); - open(absolute, p->file()); + ExceptionList throws = op->throws(); + throws.sort(); + throws.unique(); - Output& out = output(); + const ContainerPtr container = op->container(); + const ClassDefPtr cl = ClassDefPtr::dynamicCast(container); + const vector<string> params = getParams(op, package); + const string currentParam = "com.zeroc.Ice.Current " + getEscapedParamName(op, "current"); - out << sp << nl << "public final class " << name << 'I'; - if(p->isInterface()) + if(local) { - if(p->isLocal()) + out << sp; + out << nl << "@Override"; + out << nl << "public " << getResultType(op, package, false, false) << ' ' << fixKwd(opName) << spar << params + << epar; + if(op->hasMetaData("UserException")) { - out << " implements " << fixKwd(name); + out.inc(); + out << nl << "throws com.zeroc.Ice.UserException"; + out.dec(); } else { - out << " extends _" << name << "Disp"; - } - } - else - { - out << " extends " << fixKwd(name); - } - out << sb; - - out << nl << "public" << nl << name << "I()"; - out << sb; - out << eb; - - OperationList ops = p->allOperations(); - for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) - { - writeOperation(out, package, *r, p->isLocal()); - } - - out << eb; - close(); - - return false; -} - -Slice::Gen::ImplTieVisitor::ImplTieVisitor(const string& dir) : - BaseImplVisitor(dir) -{ -} - -bool -Slice::Gen::ImplTieVisitor::visitClassDefStart(const ClassDefPtr& p) -{ - if(!p->isAbstract()) - { - return false; - } - - string name = p->name(); - ClassList bases = p->bases(); - string package = getPackage(p); - string absolute = getAbsolute(p, "", "", "I"); - - open(absolute, p->file()); - - Output& out = output(); - - // - // Use implementation inheritance in the following situations: - // - // * if a class extends another class - // * if a class implements a single interface - // * if an interface extends only one interface - // - bool inheritImpl = (!p->isInterface() && !bases.empty() && !bases.front()->isInterface()) || (bases.size() == 1); - - out << sp << nl << "public class " << name << 'I'; - if(inheritImpl) - { - out << " extends "; - if(bases.front()->isAbstract()) - { - out << bases.front()->name() << 'I'; + writeThrowsClause(package, throws); } - else + out << sb; + if(initResult(out, package, op)) { - out << fixKwd(bases.front()->name()); + out << nl << "return r;"; } - } - out << " implements " << '_' << name << "Operations"; - if(p->isLocal()) - { - out << "NC"; - } - out << sb; - - out << nl << "public" << nl << name << "I()"; - out << sb; - out << eb; - - OperationList ops = p->allOperations(); - ops.sort(); - - OperationList baseOps; - if(inheritImpl) - { - baseOps = bases.front()->allOperations(); - baseOps.sort(); - } + out << eb; - for(OperationList::iterator r = ops.begin(); r != ops.end(); ++r) - { - if(inheritImpl && binary_search(baseOps.begin(), baseOps.end(), *r)) + if(cl->hasMetaData("async-oneway") || op->hasMetaData("async-oneway")) { out << sp; - out << nl << "/*"; - out << nl << " * Implemented by " << bases.front()->name() << 'I'; - out << nl << " *"; - writeOperation(out, package, *r, p->isLocal()); - out << sp; - out << nl << "*/"; - } - else - { - writeOperation(out, package, *r, p->isLocal()); - } - } - - out << eb; - close(); - - return false; -} - -Slice::Gen::AsyncVisitor::AsyncVisitor(const string& dir) : - JavaVisitor(dir) -{ -} - -void -Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) -{ - ContainerPtr container = p->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); - - if(cl->isLocal()) - { - return; - } - - string name = p->name(); - string classPkg = getPackage(cl); - StringList opMetaData = p->getMetaData(); - - // - // Generate new-style callback. - // - { - TypePtr ret = p->returnType(); - ParamDeclList outParams; - ParamDeclList paramList = p->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) - { - if((*pli)->isOutParam()) - { - outParams.push_back(*pli); - } - } - - vector<string> params = getParamsAsyncCB(p, classPkg, false, true); - vector<string> args = getInOutArgs(p, OutParam); - ExceptionList throws = p->throws(); - - // - // If the operation has more than one return parameter we generate a Callback - // interface to use in the method signatures. - // - if(p->returnsData() && ((ret && !outParams.empty()) || outParams.size() > 1)) - { - open(getAbsolute(cl, "", "_Callback_", "_" + name), p->file()); - - Output& out = output(); - - writeDocCommentOp(out, p); - out << sp << nl << "public interface " << ("_Callback_" + cl->name()) << '_' << name - << " extends " << (throws.empty() ? "Ice.TwowayCallback" : "Ice.TwowayCallbackUE"); - out << sb; - out << nl << "public void response" << spar << params << epar << ';'; - out << eb; - - close(); - } - - string classNameAsync = "Callback_" + cl->name(); - string absoluteAsync = getAbsolute(cl, "", "Callback_", "_" + name); - - open(absoluteAsync, p->file()); - - Output& out = output(); - - writeDocCommentOp(out, p); - out << sp << nl << "public abstract class " << classNameAsync << '_' << name; - - if(p->returnsData()) - { - out.inc(); - out << nl << "extends " << getAsyncCallbackBaseClass(p, false); - out.dec(); - out << sb; - - out << sp << nl << "public final void __completed(Ice.AsyncResult __result)"; - out << sb; - out << nl << cl->name() << "PrxHelper.__" << p->name() << "_completed(this, __result);"; - out << eb; - - out << eb; - } - else - { - out << " extends Ice.OnewayCallback"; + out << nl << "@Override"; + out << nl << getFutureType(op, package) << ' ' << opName << "Async" << spar << params << epar; out << sb; + out << nl << "return null;"; out << eb; } - - close(); } - - if(cl->hasMetaData("amd") || p->hasMetaData("amd")) + else { - string classNameAMD = "AMD_" + cl->name(); - string absoluteAMD = getAbsolute(cl, "", "AMD_", "_" + name); - - string classNameAMDI = "_AMD_" + cl->name(); - string absoluteAMDI = getAbsolute(cl, "", "_AMD_", "_" + name); - - const bool optionalMapping = useOptionalMapping(p); - vector<string> paramsAMD = getParamsAsyncCB(p, classPkg, true, optionalMapping); + const bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd"); + if(amd) { - open(absoluteAMD, p->file()); - - Output& out = output(); - - writeDocCommentOp(out, p); - out << sp << nl << "public interface " << classNameAMD << '_' << name; - out << " extends Ice.AMDCallback"; - out << sb; + const string retS = getResultType(op, package, true, true); out << sp; - writeDocCommentAsync(out, p, OutParam); - out << nl << "void ice_response" << spar << paramsAMD << epar << ';'; - - out << eb; - - close(); - } - - { - open(absoluteAMDI, p->file()); - - Output& out = output(); - - TypePtr ret = p->returnType(); - - ParamDeclList outParams; - ParamDeclList paramList = p->parameters(); - for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli) - { - if((*pli)->isOutParam()) - { - outParams.push_back(*pli); - } - } - - ExceptionList throws = p->throws(); - throws.sort(); - throws.unique(); - - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // -#if defined(__SUNPRO_CC) - throws.sort(Slice::derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - - int iter; - - out << sp << nl << "final class " << classNameAMDI << '_' << name - << " extends IceInternal.IncomingAsync implements " << classNameAMD << '_' << name; - out << sb; - - out << sp << nl << "public " << classNameAMDI << '_' << name << "(IceInternal.Incoming in)"; - out << sb; - out << nl << "super(in);"; - out << eb; - - out << sp << nl << "public void ice_response" << spar << paramsAMD << epar; - out << sb; - iter = 0; - out << nl << "if(__validateResponse(true))"; + out << nl << "@Override"; + out << nl << "public java.util.concurrent.CompletionStage<" << retS << "> " << opName << "Async" << spar + << params << currentParam << epar; + writeThrowsClause(package, throws); out << sb; - if(ret || !outParams.empty()) + if(initResult(out, package, op)) { - out << nl << "try"; - out << sb; - out << nl << "IceInternal.BasicStream __os = this.__startWriteParams(" - << opFormatTypeToString(p) << ");"; - writeMarshalUnmarshalParams(out, classPkg, outParams, p, iter, true, optionalMapping, false); - if(p->returnsClasses(false)) - { - out << nl << "__os.writePendingObjects();"; - } - out << nl << "this.__endWriteParams(true);"; - out << eb; - out << nl << "catch(Ice.LocalException __ex)"; - out << sb; - out << nl << "__exception(__ex);"; - out << nl << "return;"; - out << eb; + out << nl << "return java.util.concurrent.CompletableFuture.completedFuture(r);"; } else { - out << nl << "__writeEmptyParams();"; + out << nl << "return java.util.concurrent.CompletableFuture.completedFuture((Void)null);"; } - out << nl << "__response();"; out << eb; - out << eb; - - if(!throws.empty()) + } + else + { + out << sp; + out << nl << "@Override"; + out << nl << "public " << getResultType(op, package, false, true) << ' ' << fixKwd(opName) << spar << params + << currentParam << epar; + writeThrowsClause(package, throws); + out << sb; + if(initResult(out, package, op)) { - out << sp << nl << "public void ice_exception(java.lang.Exception ex)"; - out << sb; - out << nl << "try"; - out << sb; - out << nl << "throw ex;"; - out << eb; - for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r) - { - string exS = getAbsolute(*r, classPkg); - out << nl << "catch(" << exS << " __ex)"; - out << sb; - out << nl << "if(__validateResponse(false))"; - out << sb; - out << nl << "__writeUserException(__ex, " << opFormatTypeToString(p) << ");"; - out << nl << "__response();"; - out << eb; - out << eb; - } - out << nl << "catch(java.lang.Exception __ex)"; - out << sb; - out << nl << "super.ice_exception(__ex);"; - out << eb; - out << eb; + out << nl << "return r;"; } - out << eb; - - close(); } } } |