summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/Parser.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2016-08-23 17:28:35 -0700
committerMark Spruiell <mes@zeroc.com>2016-08-23 17:28:35 -0700
commite6cbf802f2977d06854a65036a860740e24d3151 (patch)
tree7e1a19dff8bb864a86da6699d0360c3d703e71c5 /cpp/src/Slice/Parser.cpp
parentSmall .gitignore cleanup (diff)
downloadice-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.cpp188
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
// ----------------------------------------------------------------------