diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-18 00:41:56 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-18 00:41:56 +0100 |
commit | 5c53ea8fb93f611a90099000fb0ba3b0874f99c5 (patch) | |
tree | 085c7e8d18cec1ad0d27d0729c2a310c546442b3 | |
parent | d935bf07d15ddd117d07d83bb3818b6abc23cc0b (diff) |
Implemented some helper functions to facilitate implementing doValidate methods. This includes the "validateName" function (which makes sure the Node has a valid identifier), the "continueValidation" function (which descends into the given list of child nodes) and the "continueValidationCheckDuplicates" which descends into the given child list and makes sure the names of the child nodes are unique.
-rw-r--r-- | src/core/model/Node.cpp | 24 | ||||
-rw-r--r-- | src/core/model/Node.hpp | 74 |
2 files changed, 94 insertions, 4 deletions
diff --git a/src/core/model/Node.cpp b/src/core/model/Node.cpp index 7565ba9..e432aff 100644 --- a/src/core/model/Node.cpp +++ b/src/core/model/Node.cpp @@ -23,6 +23,7 @@ #include <core/common/Logger.hpp> #include <core/common/Rtti.hpp> #include <core/common/TypedRttiBuilder.hpp> +#include <core/common/Utils.hpp> #include "Node.hpp" @@ -353,8 +354,31 @@ std::vector<ResolutionResult> Node::resolve(const std::string &name, return resolve(std::vector<std::string>{name}, type); } +bool Node::checkDuplicate(Handle<Node> elem, + std::unordered_set<std::string> &names, + Logger &logger) const +{ + const std::string &name = elem->getName(); + if (!names.emplace(name).second) { + logger.error(std::string("Element with name \"") + name + + std::string("\" defined multiple times.")); + return false; + } + return true; +} + bool Node::doValidate(Logger &logger) const { return true; } +bool Node::validateName(Logger &logger) const +{ + if (!Utils::isIdentifier(name)) { + logger.error(type().name + std::string(" name \"") + name + + std::string("\" is not a valid identifier")); + return false; + } + return true; +} + void Node::invalidate() { // Only perform the invalidation if necessary diff --git a/src/core/model/Node.hpp b/src/core/model/Node.hpp index f8893a7..0168a3e 100644 --- a/src/core/model/Node.hpp +++ b/src/core/model/Node.hpp @@ -31,6 +31,7 @@ #include <cstdint> #include <map> #include <set> +#include <unordered_set> #include <string> #include <vector> @@ -196,6 +197,19 @@ private: */ bool continueResolveIndex(const Index &index, ResolutionState &state); + /** + * Checks whether the name of the given node is already stored in the given + * set, if yes, logs a corresponding error message. + * + * @param node is the node of which the name should be checked. + * @param names is a set in which all encountered names are stored. + * @param logger is the logger instance to which error messages are written. + * @return true if the given node has a unique name, false otherwise. + */ + bool checkDuplicate(Handle<Node> node, + std::unordered_set<std::string> &names, + Logger &logger) const; + protected: /** * Function which should be overwritten by derived classes in order to @@ -329,6 +343,56 @@ protected: */ virtual bool doValidate(Logger &logger) const; + /** + * Makes sure the name of this node is a valid identifier and loggs a + * corresponding error message. + * + * @param logger is the logger to which the error message is logged. + * @return true if the name is valid, false otherwise. + */ + bool validateName(Logger &logger) const; + + /** + * Helper function that can be used to forward the validation process to + * child nodes. + * + * @tparam T is the type of the list that should be handled. + * @param list is a list of arbitrary kind. The "validate" function is + * called for all elementsd of the list. + * @param logger is the logger to which any errors should be reported. + */ + template <class T> + bool continueValidation(const T &list, Logger &logger) const + { + bool res = true; + for (auto elem : list) { + res = elem->validate(logger) & res; + } + return res; + } + + /** + * Helper function that can be used to forward the validation process to + * child nodes while at the same time checking that the children have no + * duplicated names. + * + * @tparam T is the type of the list that should be handled. + * @param list is a list of arbitrary kind. The "validate" function is + * called for all elementsd of the list. + * @param logger is the logger to which any errors should be reported. + */ + template <class T> + bool continueValidationCheckDuplicates(const T &list, Logger &logger) const + { + bool res = true; + std::unordered_set<std::string> names; + for (auto elem : list) { + res = elem->validate(logger) & checkDuplicate(elem, names, logger) & + res; + } + return res; + } + public: /** * Initializes the node with empty name and parent. @@ -460,8 +524,9 @@ class NodeVector : public ManagedGenericList<T, std::vector<Handle<T>>, ListAccessor<Handle<T>>, Listener> { public: - using ManagedGenericList<T, std::vector<Handle<T>>, ListAccessor<Handle<T>>, - Listener>::ManagedGenericList; + using Base = ManagedGenericList<T, std::vector<Handle<T>>, ListAccessor<Handle<T>>, + Listener>; + using Base::Base; /** * Returns the reference to the internal index. @@ -490,9 +555,10 @@ class NodeMap : public ManagedGenericMap<K, T, std::map<K, Handle<T>>, MapAccessor<std::pair<K, Handle<T>>>, Listener> { public: - using ManagedGenericMap<K, T, std::map<K, Handle<T>>, + using Base = ManagedGenericMap<K, T, std::map<K, Handle<T>>, MapAccessor<std::pair<K, Handle<T>>>, - Listener>::ManagedGenericMap; + Listener>; + using Base::Base; /** * Returns the reference to the internal index. |