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