summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Slice/JavaUtil.cpp134
-rw-r--r--cpp/src/slice2java/Gen.cpp132
-rw-r--r--cpp/src/slice2java/Gen.h8
3 files changed, 235 insertions, 39 deletions
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
index ea1e7c1407f..a03e26191b5 100644
--- a/cpp/src/Slice/JavaUtil.cpp
+++ b/cpp/src/Slice/JavaUtil.cpp
@@ -148,6 +148,8 @@ Slice::JavaOutput::printHeader()
print(ICE_STRING_VERSION);
}
+const string Slice::JavaGenerator::_getSetMetaData = "java:getset";
+
Slice::JavaGenerator::JavaGenerator(const string& dir) :
_featureProfile(Slice::Ice),
_dir(dir),
@@ -2888,7 +2890,7 @@ Slice::JavaGenerator::findMetaData(const StringList& metaData)
for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
{
string str = *q;
- if(str.find(prefix) == 0)
+ if(str.find(prefix) == 0 && str != _getSetMetaData)
{
string::size_type pos = str.find(':', prefix.size());
if(pos != string::npos)
@@ -2956,7 +2958,8 @@ Slice::JavaGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
}
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
return true;
}
@@ -2964,14 +2967,16 @@ void
Slice::JavaGenerator::MetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
bool
Slice::JavaGenerator::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
return true;
}
@@ -2979,7 +2984,8 @@ bool
Slice::JavaGenerator::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
return true;
}
@@ -2987,7 +2993,8 @@ bool
Slice::JavaGenerator::MetaDataVisitor::visitStructStart(const StructPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
return true;
}
@@ -3000,12 +3007,19 @@ Slice::JavaGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
if(!returnType)
{
- cout << p->definitionContext()->filename() << ":" << p->line()
- << ": warning: invalid metadata for operation" << endl;
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
+ {
+ if(q->find("java:type:", 0) == 0)
+ {
+ cout << p->definitionContext()->filename() << ":" << p->line()
+ << ": warning: invalid metadata for operation" << endl;
+ break;
+ }
+ }
}
else
{
- validate(returnType, metaData, p->definitionContext()->filename(), p->line());
+ validateType(returnType, metaData, p->definitionContext()->filename(), p->line());
}
}
@@ -3013,43 +3027,50 @@ Slice::JavaGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
{
metaData = getMetaData(*q);
- validate((*q)->type(), metaData, p->definitionContext()->filename(), (*q)->line());
+ validateType((*q)->type(), metaData, p->definitionContext()->filename(), (*q)->line());
}
+
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
void
Slice::JavaGenerator::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p->type(), metaData, p->definitionContext()->filename(), p->line());
+ validateType(p->type(), metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
void
Slice::JavaGenerator::MetaDataVisitor::visitSequence(const SequencePtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
void
Slice::JavaGenerator::MetaDataVisitor::visitDictionary(const DictionaryPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
void
Slice::JavaGenerator::MetaDataVisitor::visitEnum(const EnumPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
void
Slice::JavaGenerator::MetaDataVisitor::visitConst(const ConstPtr& p)
{
StringList metaData = getMetaData(p);
- validate(p, metaData, p->definitionContext()->filename(), p->line());
+ validateType(p, metaData, p->definitionContext()->filename(), p->line());
+ validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
}
StringList
@@ -3075,12 +3096,20 @@ Slice::JavaGenerator::MetaDataVisitor::getMetaData(const ContainedPtr& cont)
{
if(s.size() > prefix.size())
{
- cout << file << ":" << cont->line() << ": warning: metadata `" << s
- << "' uses deprecated syntax" << endl;
- //
- // Translate java:X into java:type:X.
- //
- result.push_back(prefix + "type:" + s.substr(prefix.size()));
+ string rest = s.substr(prefix.size());
+ if(rest == "getset")
+ {
+ result.push_back(s);
+ }
+ else
+ {
+ cout << file << ":" << cont->line() << ": warning: metadata `" << s
+ << "' uses deprecated syntax" << endl;
+ //
+ // Translate java:X into java:type:X.
+ //
+ result.push_back(prefix + "type:" + rest);
+ }
continue;
}
}
@@ -3101,26 +3130,59 @@ Slice::JavaGenerator::MetaDataVisitor::getMetaData(const ContainedPtr& cont)
}
void
-Slice::JavaGenerator::MetaDataVisitor::validate(const SyntaxTreeBasePtr& p, const StringList& metaData,
- const string& file, const string& line)
+Slice::JavaGenerator::MetaDataVisitor::validateType(const SyntaxTreeBasePtr& p, const StringList& metaData,
+ const string& file, const string& line)
{
- //
- // Currently only sequence and dictionary types can be affected by metadata.
- //
- if(!metaData.empty() && !SequencePtr::dynamicCast(p) && !DictionaryPtr::dynamicCast(p))
+ for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
{
- string str;
- ContainedPtr cont = ContainedPtr::dynamicCast(p);
- if(cont)
+ //
+ // Type metadata ("java:type:Foo") is only supported by sequences and dictionaries.
+ //
+ if(i->find("java:type:", 0) == 0 && (!SequencePtr::dynamicCast(p) && !DictionaryPtr::dynamicCast(p)))
{
- str = cont->kindOf();
+ string str;
+ ContainedPtr cont = ContainedPtr::dynamicCast(p);
+ if(cont)
+ {
+ str = cont->kindOf();
+ }
+ else
+ {
+ BuiltinPtr b = BuiltinPtr::dynamicCast(p);
+ assert(b);
+ str = b->typeId();
+ }
+ cout << file << ":" << line << ": warning: invalid metadata for " << str << endl;
}
- else
+ }
+}
+
+void
+Slice::JavaGenerator::MetaDataVisitor::validateGetSet(const SyntaxTreeBasePtr& p, const StringList& metaData,
+ const string& file, const string& line)
+{
+ for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
+ {
+ //
+ // The "getset" metadata can only be specified on a class, struct, exception or data member.
+ //
+ if((*i) == "java:getset" &&
+ (!ClassDefPtr::dynamicCast(p) && !StructPtr::dynamicCast(p) && !ExceptionPtr::dynamicCast(p) &&
+ !DataMemberPtr::dynamicCast(p)))
{
- BuiltinPtr b = BuiltinPtr::dynamicCast(p);
- assert(b);
- str = b->typeId();
+ string str;
+ ContainedPtr cont = ContainedPtr::dynamicCast(p);
+ if(cont)
+ {
+ str = cont->kindOf();
+ }
+ else
+ {
+ BuiltinPtr b = BuiltinPtr::dynamicCast(p);
+ assert(b);
+ str = b->typeId();
+ }
+ cout << file << ":" << line << ": warning: invalid metadata for " << str << endl;
}
- cout << file << ":" << line << ": warning: invalid metadata for " << str << endl;
}
}
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index 106063d4602..33089017a35 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -527,7 +527,7 @@ Slice::JavaVisitor::writeDispatch(Output& out, const ClassDefPtr& p)
out << sb << nl;
if(ret)
{
- out << nl << "return ";
+ out << "return ";
}
out << opName << spar << args << "null" << epar << ';';
out << eb;
@@ -2455,9 +2455,116 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
ContainerPtr container = p->container();
ContainedPtr contained = ContainedPtr::dynamicCast(container);
StringList metaData = p->getMetaData();
- string s = typeToString(p->type(), TypeModeMember, getPackage(contained), metaData);
+ TypePtr type = p->type();
+ string s = typeToString(type, TypeModeMember, getPackage(contained), metaData);
Output& out = output();
out << sp << nl << "public " << s << ' ' << name << ';';
+
+ //
+ // Getter/Setter.
+ //
+ if(p->hasMetaData(_getSetMetaData) || contained->hasMetaData(_getSetMetaData))
+ {
+ string capName = p->name();
+ capName[0] = toupper(capName[0]);
+
+ //
+ // If container is a class, get all of its operations so that we can check for conflicts.
+ //
+ OperationList ops;
+ string file, line;
+ ClassDefPtr cls = ClassDefPtr::dynamicCast(container);
+ if(cls)
+ {
+ ops = cls->allOperations();
+ DefinitionContextPtr dc = p->definitionContext();
+ file = dc->filename();
+ line = p->line();
+ if(!validateGetterSetter(ops, "get" + capName, 0, file, line) ||
+ !validateGetterSetter(ops, "set" + capName, 1, file, line))
+ {
+ return;
+ }
+ }
+
+ //
+ // Getter.
+ //
+ out << sp << nl << "public " << s;
+ out << nl << "get" << capName << "()";
+ out << sb;
+ out << nl << "return " << name << ';';
+ out << eb;
+
+ //
+ // Setter.
+ //
+ out << sp << nl << "public void";
+ out << nl << "set" << capName << '(' << s << " _" << name << ')';
+ out << sb;
+ out << nl << name << " = _" << name << ';';
+ out << eb;
+
+ //
+ // Check for bool type.
+ //
+ BuiltinPtr b = BuiltinPtr::dynamicCast(type);
+ if(b && b->kind() == Builtin::KindBool)
+ {
+ if(cls && !validateGetterSetter(ops, "is" + capName, 0, file, line))
+ {
+ return;
+ }
+ out << sp << nl << "public boolean";
+ out << nl << "is" << capName << "()";
+ out << sb;
+ out << nl << "return " << name << ';';
+ out << eb;
+ }
+
+ //
+ // Check for unmodified sequence type and emit indexing methods.
+ //
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ string md = findMetaData(metaData);
+ if(md.empty())
+ {
+ StringList l = seq->getMetaData();
+ md = findMetaData(l);
+ }
+ if(md.empty())
+ {
+ if(cls &&
+ (!validateGetterSetter(ops, "get" + capName, 1, file, line) ||
+ !validateGetterSetter(ops, "set" + capName, 2, file, line)))
+ {
+ return;
+ }
+
+ string elem = typeToString(seq->type(), TypeModeMember, getPackage(contained));
+
+ //
+ // Indexed getter.
+ //
+ out << sp << nl << "public " << elem;
+ out << nl << "get" << capName << "(int _index)";
+ out << sb;
+ out << nl << "return " << name << "[_index];";
+ out << eb;
+
+ //
+ // Indexed setter.
+ //
+ out << sp << nl << "public void";
+ out << nl << "set" << capName << "(int _index, " << elem << " _val)";
+ out << sb;
+ out << nl << name << "[_index] = _val;";
+ out << eb;
+ }
+ }
+ }
}
void
@@ -2733,6 +2840,27 @@ Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
close();
}
+bool
+Slice::Gen::TypesVisitor::validateGetterSetter(const OperationList& ops, const std::string& name, int numArgs,
+ const string& file, const string& line)
+{
+ for(OperationList::const_iterator i = ops.begin(); i != ops.end(); ++i)
+ {
+ if((*i)->name() == name)
+ {
+ int numParams = static_cast<int>((*i)->parameters().size());
+ if(numArgs >= numParams && numArgs - numParams <= 1)
+ {
+ cerr << file << ":" << line
+ << ": error: operation `" << name << "' conflicts with getter/setter method" << endl;
+ return false;
+ }
+ break;
+ }
+ }
+ return true;
+}
+
Slice::Gen::HolderVisitor::HolderVisitor(const string& dir, bool stream) :
JavaVisitor(dir), _stream(stream)
{
diff --git a/cpp/src/slice2java/Gen.h b/cpp/src/slice2java/Gen.h
index 54e5c0edac1..1e629bb2316 100644
--- a/cpp/src/slice2java/Gen.h
+++ b/cpp/src/slice2java/Gen.h
@@ -131,12 +131,18 @@ private:
virtual void visitExceptionEnd(const ExceptionPtr&);
virtual bool visitStructStart(const StructPtr&);
virtual void visitStructEnd(const StructPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
virtual void visitEnum(const EnumPtr&);
virtual void visitConst(const ConstPtr&);
- virtual void visitDataMember(const DataMemberPtr&);
private:
+ //
+ // Verifies that a getter/setter method does not conflict with an operation.
+ //
+ bool validateGetterSetter(const OperationList&, const std::string&, int, const std::string&,
+ const std::string&);
+
bool _stream;
};