summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-18 13:36:10 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-18 13:36:10 +0100
commit3e63d6539b9738018a4aca68d07a119e4402e9aa (patch)
tree81c19fb8114982b26863ce1418b67055867277fd /src/core
parent4e590891e9723c42858165a96c96a9f19d4e4c94 (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/core')
-rw-r--r--src/core/model/Domain.cpp78
-rw-r--r--src/core/model/Domain.hpp35
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>> &currentPath,
- std::set<std::string> ignoredFields,
- bool exploreSuperclass,
- bool exploreSubclasses) const
+ std::vector<Rooted<Node>> &currentPath) 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> &current,
+ 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> &current,
+ 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;