From dbf2eebdd88118dca79045ad0524061f8078e668 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Thu, 12 Feb 2015 10:38:16 +0100 Subject: refactored FieldDescriptor resolution into own function in ParserScope for more cleanliness and less overhead. --- src/core/parser/ParserScope.cpp | 48 ++++++++++++++++++++++++++++++----------- src/core/parser/ParserScope.hpp | 41 ++++++++++++++++++++++++++++++++--- src/plugins/xml/XmlParser.cpp | 2 +- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp index 5440b9c..3929abf 100644 --- a/src/core/parser/ParserScope.cpp +++ b/src/core/parser/ParserScope.cpp @@ -38,19 +38,6 @@ Rooted ParserScopeBase::resolve(const Rtti *type, const std::vector &path, Logger &logger) { - // if the last element of the path is the default field name, we want to - // resolve the parent descriptor first. - if (type == &RttiTypes::FieldDescriptor && - path.back() == DEFAULT_FIELD_NAME) { - std::vector descPath; - descPath.insert(descPath.end(), path.begin(), path.end() - 1); - Rooted res = resolve(&RttiTypes::Descriptor, descPath, logger); - if (res == nullptr) { - return nullptr; - } - return res.cast()->getFieldDescriptor(); - } - // Go up the stack and try to resolve the for (auto it = nodes.rbegin(); it != nodes.rend(); it++) { std::vector res = (*it)->resolve(type, path); @@ -486,5 +473,40 @@ bool ParserScope::performDeferredResolution(Logger &logger) deferred.clear(); return false; } + +bool ParserScope::resolveFieldDescriptor( + const std::vector &path, Handle owner, Logger &logger, + ResolutionResultCallback resultCallback) +{ + // if the last element of the path is the default field name, we want to + // resolve the parent descriptor first. + if (path.back() == DEFAULT_FIELD_NAME) { + std::vector descPath; + descPath.insert(descPath.end(), path.begin(), path.end() - 1); + return resolve(&RttiTypes::Descriptor, descPath, owner, logger, + [resultCallback](Handle resolved, + Handle owner, Logger &logger) { + if (resolved != nullptr) { + resultCallback( + resolved.cast()->getFieldDescriptor(), owner, + logger); + } else { + resultCallback(nullptr, owner, logger); + } + }); + } + + // If it is not the default field, we can just forward to resolve + return resolve(&RttiTypes::FieldDescriptor, path, owner, logger, + resultCallback); +} + +bool ParserScope::resolveFieldDescriptor( + const std::string &name, Handle owner, Logger &logger, + ResolutionResultCallback resultCallback) +{ + return resolveFieldDescriptor(Utils::split(name, '.'), owner, logger, + resultCallback); +} } diff --git a/src/core/parser/ParserScope.hpp b/src/core/parser/ParserScope.hpp index bd6a29f..58fc037 100644 --- a/src/core/parser/ParserScope.hpp +++ b/src/core/parser/ParserScope.hpp @@ -679,7 +679,6 @@ public: * Resolves a typesystem type. Makes sure an array type is returned if an * array type is requested. * - * @tparam T is the type of the node that should be resolved. * @param name is the path for which a node should be resolved. The name is * split at '.' to form a path. * @param owner is the node for which the resolution takes place. @@ -715,7 +714,6 @@ public: * Resolves a type and makes sure the corresponding value is of the correct * type. * - * @tparam T is the type of the node that should be resolved. * @param path is the path for which a node should be resolved. * @param owner is the node for which the resolution takes place. * @param value is a reference at the Variant that represents the value for @@ -739,7 +737,6 @@ public: * Resolves a type and makes sure the corresponding value is of the correct * type. * - * @tparam T is the type of the node that should be resolved. * @param name is the path for which a node should be resolved. The name is * split at '.' to form a path. * @param owner is the node for which the resolution takes place. @@ -759,6 +756,44 @@ public: Variant &value, Logger &logger, ResolutionResultCallback resultCallback); + /** + * Resolves a FieldDescriptor. Makes sure that the default field can be + * handled. + * + * @param path is the path for which a node should be resolved. + * @param owner is the node for which the resolution takes place. + * @param logger is the logger instance into which resolution problems + * should be logged. + * @param resultCallback is the callback function to which the result of + * the resolution process is passed. This function is called once the + * resolution was successful. + * @return true if the resolution was immediately successful. This does not + * mean, that the resolved object does not exist, as it may be resolved + * later. + */ + bool resolveFieldDescriptor(const std::vector &path, + Handle owner, Logger &logger, + ResolutionResultCallback resultCallback); + + /** + * Resolves a FieldDescriptor. Makes sure that the default field can be + * handled. + * + * @param name is the path for which a node should be resolved. The name is + * split at '.' to form a path. + * @param owner is the node for which the resolution takes place. + * @param logger is the logger instance into which resolution problems + * should be logged. + * @param resultCallback is the callback function to which the result of + * the resolution process is passed. This function is called once the + * resolution was successful. + * @return true if the resolution was immediately successful. This does not + * mean, that the resolved object does not exist, as it may be resolved + * later. + */ + bool resolveFieldDescriptor(const std::string &name, Handle owner, + Logger &logger, + ResolutionResultCallback resultCallback); /** * Tries to resolve all currently deferred resolution steps. The list of * pending deferred resolutions is cleared after this function has run. diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index e0346ab..c51ca8c 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -598,7 +598,7 @@ public: Rooted parent = scope().selectOrThrow(); const std::string &name = args["ref"].asString(); - scope().resolve( + scope().resolveFieldDescriptor( name, parent, logger(), [](Handle field, Handle parent, Logger &logger) { if (field != nullptr) { -- cgit v1.2.3