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; | 
