diff options
author | Mark Spruiell <mes@zeroc.com> | 2016-08-23 17:28:35 -0700 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2016-08-23 17:28:35 -0700 |
commit | e6cbf802f2977d06854a65036a860740e24d3151 (patch) | |
tree | 7e1a19dff8bb864a86da6699d0360c3d703e71c5 /cpp/src/Slice/Parser.cpp | |
parent | Small .gitignore cleanup (diff) | |
download | ice-e6cbf802f2977d06854a65036a860740e24d3151.tar.bz2 ice-e6cbf802f2977d06854a65036a860740e24d3151.tar.xz ice-e6cbf802f2977d06854a65036a860740e24d3151.zip |
Major changes in Java:
- Moved existing Java mapping sources to java-compat subdirectory
- Added new "Java 8" mapping in java subdirectory
- Significant features of Java 8 mapping:
- All classes in com.zeroc package (e.g., com.zeroc.Ice.Communicator)
- New AMI mapping that uses java.util.concurrent.CompletableFuture
- New AMD mapping that uses java.util.concurrent.CompletionStage
- New mapping for out parameters - "holder" types have been eliminated
- New mapping for optional types that uses JDK classes from java.util
(e.g., java.util.Optional)
- "TIE" classes are no longer supported or necessary; servant classes
now only need to implement a generated interface
- Moved IceGrid GUI to new mapping
- The "Java Compat" mapping is provided only for backward compatibility
to ease migration to Ice 3.7. The Slice compiler supports a new --compat
option to generate code for this mapping. However, users are encouraged
to migrate to the new mapping as soon as possible.
Diffstat (limited to 'cpp/src/Slice/Parser.cpp')
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 188 |
1 files changed, 184 insertions, 4 deletions
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 825c9c8e3fb..e4bb71d4824 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -63,6 +63,23 @@ filterOrderedOptionalDataMembers(const DataMemberList& members) return result; } +void +sortOptionalParameters(ParamDeclList& params) +{ + // + // Sort optional parameters by tag. + // + class SortFn + { + public: + static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + params.sort(SortFn::compare); +} + bool isMutableAfterReturnType(const TypePtr& type) { @@ -5136,7 +5153,7 @@ Slice::Operation::inParameters() const for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p) { ParamDeclPtr q = ParamDeclPtr::dynamicCast(*p); - if(!q->isOutParam()) + if(q && !q->isOutParam()) { result.push_back(q); } @@ -5144,6 +5161,25 @@ Slice::Operation::inParameters() const return result; } +void +Slice::Operation::inParameters(ParamDeclList& required, ParamDeclList& optional) const +{ + const ParamDeclList params = inParameters(); + for(ParamDeclList::const_iterator pli = params.begin(); pli != params.end(); ++pli) + { + if((*pli)->optional()) + { + optional.push_back(*pli); + } + else + { + required.push_back(*pli); + } + } + + sortOptionalParameters(optional); +} + ParamDeclList Slice::Operation::outParameters() const { @@ -5151,7 +5187,7 @@ Slice::Operation::outParameters() const for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p) { ParamDeclPtr q = ParamDeclPtr::dynamicCast(*p); - if(q->isOutParam()) + if(q && q->isOutParam()) { result.push_back(q); } @@ -5159,6 +5195,25 @@ Slice::Operation::outParameters() const return result; } +void +Slice::Operation::outParameters(ParamDeclList& required, ParamDeclList& optional) const +{ + const ParamDeclList params = outParameters(); + for(ParamDeclList::const_iterator pli = params.begin(); pli != params.end(); ++pli) + { + if((*pli)->optional()) + { + optional.push_back(*pli); + } + else + { + required.push_back(*pli); + } + } + + sortOptionalParameters(optional); +} + ExceptionList Slice::Operation::throws() const { @@ -5311,12 +5366,25 @@ Slice::Operation::returnsData() const } bool +Slice::Operation::returnsMultipleValues() const +{ + int count = outParameters().size(); + + if(returnType()) + { + ++count; + } + + return count > 1; +} + +bool Slice::Operation::sendsOptionals() const { - ParamDeclList pdl = parameters(); + ParamDeclList pdl = inParameters(); for(ParamDeclList::const_iterator i = pdl.begin(); i != pdl.end(); ++i) { - if(!(*i)->isOutParam() && (*i)->optional()) + if((*i)->optional()) { return true; } @@ -6207,6 +6275,11 @@ Slice::Unit::parse(const string& filename, FILE* file, bool debug, Slice::Featur popContainer(); assert(_definitionContextStack.size() == 1); popDefinitionContext(); + + if(!checkUndefinedTypes()) + { + status = EXIT_FAILURE; + } } Slice::unit = 0; @@ -6305,6 +6378,113 @@ Slice::Unit::eraseWhiteSpace(string& s) } } +bool +Slice::Unit::checkUndefinedTypes() +{ + class Visitor : public ParserVisitor + { + public: + + Visitor(int& errors) : + _errors(errors), + _local(false) + { + } + + virtual bool visitClassDefStart(const ClassDefPtr& p) + { + _local = p->isLocal(); + return true; + } + + virtual bool visitExceptionStart(const ExceptionPtr& p) + { + _local = p->isLocal(); + return true; + } + + virtual bool visitStructStart(const StructPtr& p) + { + _local = p->isLocal(); + return true; + } + + virtual void visitOperation(const OperationPtr& p) + { + if(p->returnType()) + { + checkUndefined(p->returnType(), "return type", p->file(), p->line()); + } + ParamDeclList params = p->parameters(); + for(ParamDeclList::const_iterator q = params.begin(); q != params.end(); ++q) + { + checkUndefined((*q)->type(), "parameter " + (*q)->name(), (*q)->file(), (*q)->line()); + } + } + + virtual void visitParamDecl(const ParamDeclPtr& p) + { + checkUndefined(p->type(), "parameter " + p->name(), p->file(), p->line()); + } + + virtual void visitDataMember(const DataMemberPtr& p) + { + checkUndefined(p->type(), "member " + p->name(), p->file(), p->line()); + } + + virtual void visitSequence(const SequencePtr& p) + { + _local = p->isLocal(); + checkUndefined(p->type(), "element type", p->file(), p->line()); + } + + virtual void visitDictionary(const DictionaryPtr& p) + { + _local = p->isLocal(); + checkUndefined(p->keyType(), "key type", p->file(), p->line()); + checkUndefined(p->valueType(), "value type", p->file(), p->line()); + } + + private: + + void checkUndefined(const TypePtr& type, const string& desc, const string& file, const string& line) + { + // + // See ICE-6867. Any use of a proxy requires the full type definition, as does any + // use of a class in a non-local context. + // + ProxyPtr p = ProxyPtr::dynamicCast(type); + if(p) + { + const ClassDeclPtr cl = p->_class(); + if(!cl->definition()) + { + ostringstream ostr; + ostr << desc << " uses a proxy for undefined type `" << cl->scoped() << "'"; + emitError(file, line, ostr.str()); + _errors++; + } + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + if(cl && !cl->definition() && !_local) + { + ostringstream ostr; + ostr << desc << " refers to undefined type `" << cl->scoped() << "'"; + emitError(file, line, ostr.str()); + _errors++; + } + } + + int& _errors; + bool _local; + }; + + Visitor v(_errors); + visit(&v, true); + return _errors == 0; +} + // ---------------------------------------------------------------------- // CICompare // ---------------------------------------------------------------------- |