diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/JavaUtil.cpp | 134 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.cpp | 132 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.h | 8 |
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; }; |