diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-18 13:36:10 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-18 13:36:10 +0100 |
commit | 3e63d6539b9738018a4aca68d07a119e4402e9aa (patch) | |
tree | 81c19fb8114982b26863ce1418b67055867277fd /src | |
parent | 4e590891e9723c42858165a96c96a9f19d4e4c94 (diff) |
added the getEffectiveFieldDescriptors for StructuredClasses which returns the list of FieldDescriptors including all non-overridden fields of superclasses. This also made the continuePath function easier.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/model/Domain.cpp | 78 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 35 |
2 files changed, 68 insertions, 45 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index 2ac2d8d..17f3e02 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -36,7 +36,7 @@ static void checkUniqueName(Handle<Node> parent, NodeVector<T> vec, childNames.insert(c->getName()); } if (childNames.find(child->getName()) != childNames.end()) { - //TODO: Do we really want to have an exception here? + // TODO: Do we really want to have an exception here? throw OusiaException(std::string("The ") + parentClassName + " " + parent->getName() + " already has a " + childClassName + " with name " + child->getName()); @@ -97,10 +97,7 @@ std::vector<Rooted<Node>> Descriptor::pathTo( } bool Descriptor::continuePath(Handle<StructuredClass> target, - std::vector<Rooted<Node>> ¤tPath, - std::set<std::string> ignoredFields, - bool exploreSuperclass, - bool exploreSubclasses) const + std::vector<Rooted<Node>> ¤tPath) const { // check if we are at the target already if (this == target) { @@ -111,11 +108,16 @@ bool Descriptor::continuePath(Handle<StructuredClass> target, // the currently optimal path. std::vector<Rooted<Node>> optimum; // use recursive depth-first search from the top to reach the given child - for (auto &fd : fieldDescriptors) { - if (!(ignoredFields.insert(fd->getName()).second)) { - // if we want to ignore that field, we continue. - continue; - } + // get the list of effective FieldDescriptors. + NodeVector<FieldDescriptor> fields; + if (isa(RttiTypes::StructuredClass)) { + const StructuredClass *tis = static_cast<const StructuredClass *>(this); + fields = tis->getEffectiveFieldDescriptors(); + } else { + fields = getFieldDescriptors(); + } + + for (auto &fd : fields) { for (auto &c : fd->getChildren()) { // check if a child is the target node. if (c == target) { @@ -142,35 +144,17 @@ bool Descriptor::continuePath(Handle<StructuredClass> target, if (isa(RttiTypes::StructuredClass)) { const StructuredClass *tis = static_cast<const StructuredClass *>(this); - /* - * if this is a StructuredClass, we can also use the super class - * (at least for fields that are not overridden) - */ - if (exploreSuperclass && tis->getSuperclass() != nullptr) { + // if this is a StructuredClass we also can call the subclasses. + for (auto &c : tis->getSubclasses()) { // copy the path. std::vector<Rooted<Node>> cPath = currentPath; - if (tis->getSuperclass()->continuePath(target, cPath, ignoredFields, - true, false) && + if (c->continuePath(target, cPath) && (!found || optimum.size() > cPath.size())) { // look if this path is better than the current optimum. optimum = std::move(cPath); found = true; } } - - // we also can call the subclasses. - if (exploreSubclasses) { - for (auto &c : tis->getSubclasses()) { - // copy the path. - std::vector<Rooted<Node>> cPath = currentPath; - if (c->continuePath(target, cPath, {}, false) && - (!found || optimum.size() > cPath.size())) { - // look if this path is better than the current optimum. - optimum = std::move(cPath); - found = true; - } - } - } } // put the optimum in the given path reference. @@ -219,16 +203,42 @@ StructuredClass::StructuredClass(Manager &mgr, std::string name, } } -bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const{ - if(c == nullptr || superclass == nullptr){ +bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const +{ + if (c == nullptr || superclass == nullptr) { return false; } - if(c == superclass){ + if (c == superclass) { return true; } return superclass->isSubclassOf(c); } +const void StructuredClass::gatherFieldDescriptors( + NodeVector<FieldDescriptor> ¤t, + std::set<std::string> &overriddenFields) const +{ + // append all FieldDescriptors that are not overridden. + for (auto &f : Descriptor::getFieldDescriptors()) { + if (overriddenFields.insert(f->getName()).second) { + current.push_back(f); + } + } + if (superclass != nullptr) { + superclass->gatherFieldDescriptors(current, overriddenFields); + } +} + +NodeVector<FieldDescriptor> StructuredClass::getEffectiveFieldDescriptors() + const +{ + // in this case we return a NodeVector of Rooted entries without owner. + NodeVector<FieldDescriptor> vec; + std::set<std::string> overriddenFields; + gatherFieldDescriptors(vec, overriddenFields); + return std::move(vec); +} + /* Class AnnotationClass */ AnnotationClass::AnnotationClass( diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index ac02ec7..5cc7874 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -380,22 +380,18 @@ public: * */ class Descriptor : public Node { - -friend FieldDescriptor; + friend FieldDescriptor; private: Owned<StructType> attributesDescriptor; NodeVector<FieldDescriptor> fieldDescriptors; bool continuePath(Handle<StructuredClass> target, - std::vector<Rooted<Node>> &path, - std::set<std::string> ignoredFields = {}, - bool exploreSuperclass = true, - bool exploreSubclasses = true) const; + std::vector<Rooted<Node>> &path) const; protected: void continueResolve(ResolutionState &state) override; - + /** * Adds a FieldDescriptor and checks for name uniqueness. */ @@ -553,6 +549,13 @@ private: Owned<StructuredClass> superclass; NodeVector<StructuredClass> subclasses; + /** + * Helper method for getFieldDescriptors. + */ + const void gatherFieldDescriptors( + NodeVector<FieldDescriptor> ¤t, + std::set<std::string> &overriddenFields) const; + public: const bool transparent; // TODO: Is it possible to have root=true and cardinality other than 1? @@ -606,7 +609,7 @@ public: * @return the superclass of this StructuredClass. */ Rooted<StructuredClass> getSuperclass() const { return superclass; } - + /** * Returns true if this class is a subclass of the given class. It does not * return true if the other class is equal to the given class. @@ -635,6 +638,17 @@ public: { return subclasses; } + + /** + * Returns a const reference to the NodeVector of all FieldDescriptors of + * this StructuredClass. This does more than the getter for FieldDescriptor, + * because in this method we gather the FieldDescriptors of all superclasses + * as well that have not been overridden in child classes. + * + * @return a const reference to the NodeVector of all FieldDescriptors of + * this StructuredClass. + */ + NodeVector<FieldDescriptor> getEffectiveFieldDescriptors() const; }; /** @@ -670,9 +684,8 @@ public: * to certain Structures? */ class Domain : public Node { - -friend StructuredClass; -friend AnnotationClass; + friend StructuredClass; + friend AnnotationClass; private: NodeVector<StructuredClass> structuredClasses; |