diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/parser/ParserScope.cpp | 21 | ||||
-rw-r--r-- | src/core/parser/ParserScope.hpp | 4 | ||||
-rw-r--r-- | src/core/resource/ResourceRequest.cpp | 10 |
3 files changed, 28 insertions, 7 deletions
diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp index ce3dc94..b0a4945 100644 --- a/src/core/parser/ParserScope.cpp +++ b/src/core/parser/ParserScope.cpp @@ -21,6 +21,7 @@ #include <core/common/VariantWriter.hpp> #include <core/model/Domain.hpp> #include <core/model/Typesystem.hpp> +#include <core/model/RootNode.hpp> #include "ParserScope.hpp" @@ -233,6 +234,13 @@ void ParserScope::pop() } flags.resize(newLen); + // Whenever a RootNode is popped from the stack, we have to perform deferred + // resolution -- however, postpone issuing error messages + if (nodes.back()->isa(&RttiTypes::RootNode)) { + Logger logger; + performDeferredResolution(logger, true); + } + // Remove the element from the stack nodes.pop_back(); } @@ -424,7 +432,7 @@ bool ParserScope::resolveTypeWithValue(const std::string &name, resultCallback); } -bool ParserScope::performDeferredResolution(Logger &logger) +bool ParserScope::performDeferredResolution(Logger &logger, bool postpone) { // Repeat the resolution process as long as something has changed in the // last iteration (resolving a node may cause other nodes to be resolvable). @@ -446,8 +454,9 @@ bool ParserScope::performDeferredResolution(Logger &logger) // Abort if nothing has changed in the last iteration if (!hasChange) { // In a last step, clear the "awaitingResolution" list to allow - // cyclical dependencies to be resolved - if (!awaitingResolution.empty()) { + // cyclical dependencies to be resolved -- if the postpone flag + // is set, do not do this + if (!awaitingResolution.empty() && !postpone) { awaitingResolution.clear(); } else { break; @@ -460,6 +469,12 @@ bool ParserScope::performDeferredResolution(Logger &logger) return true; } + // If the postpone flag is set to true, we'll abort here -- this function + // will be called again later + if (postpone) { + return false; + } + // Output error messages for all elements for which resolution did not // succeed. for (auto &failed : deferred) { diff --git a/src/core/parser/ParserScope.hpp b/src/core/parser/ParserScope.hpp index 185b845..24af6b8 100644 --- a/src/core/parser/ParserScope.hpp +++ b/src/core/parser/ParserScope.hpp @@ -797,8 +797,10 @@ public: * pending deferred resolutions is cleared after this function has run. * * @param logger is the logger instance into which errors should be logged. + * @param postpone if set to true, postpones issuing any error messages and + * waits for node resolution. */ - bool performDeferredResolution(Logger &logger); + bool performDeferredResolution(Logger &logger, bool postpone = false); }; } diff --git a/src/core/resource/ResourceRequest.cpp b/src/core/resource/ResourceRequest.cpp index 357f413..5e5bff3 100644 --- a/src/core/resource/ResourceRequest.cpp +++ b/src/core/resource/ResourceRequest.cpp @@ -152,6 +152,10 @@ bool ResourceRequest::deduce(Registry ®istry, Logger &logger) { bool ok = true; + // Check whether all node types are supported here -- this is indicated by + // supportedTypes containing the extremely general "Node" type. + bool supportsAllNodes = supportedTypes.count(&RttiTypes::Node) > 0U; + // Make sure the given file name is not empty if (path.empty()) { logger.error("Filename may not be empty"); @@ -227,7 +231,8 @@ bool ResourceRequest::deduce(Registry ®istry, Logger &logger) logger.error(std::string("Cannot parse files of type \"") + mimetype + std::string("\"")); ok = false; - } else if (!Rtti::setIsOneOf(supportedTypes, parserTypes)) { + } else if (!supportsAllNodes && + !Rtti::setIsOneOf(supportedTypes, parserTypes)) { logger.error(std::string("Resource of type \"") + mimetype + std::string("\" cannot be included here!")); ok = false; @@ -245,8 +250,7 @@ bool ResourceRequest::deduce(Registry ®istry, Logger &logger) std::string("\" cannot be included here")); ok = false; } - } else if (supportedTypes.size() != 1 || - *supportedTypes.begin() != &RttiTypes::Node) { + } else if (!supportsAllNodes) { logger.warning(std::string( "Ambiguous resource relationship, consider " "specifying one of ") + |