diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/model/Domain.cpp | 147 | ||||
| -rw-r--r-- | src/core/model/Domain.hpp | 47 | 
2 files changed, 164 insertions, 30 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index 0fc078f..50bde9c 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -55,6 +55,72 @@ FieldDescriptor::FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,  	}  } +bool FieldDescriptor::doValidate(Logger &logger) const +{ +	bool valid = true; +	// check parent type +	if(getParent() == nullptr){ +		logger.error("This field has no parent!"); +		valid = false; +	} else if (!getParent()->isa(RttiTypes::Descriptor)) { +		logger.error("The parent of this field is not a descriptor!"); +		valid = false; +	} +	// check name +	if (!getName().empty()) { +		valid = valid & validateName(logger); +	} +	// check consistency of FieldType with the rest of the FieldDescriptor. +	if (fieldType == FieldType::PRIMITIVE) { +		if (children.size() > 0) { +			logger.error( +			    "This field is supposed to be primitive but has " +			    "registered child classes!"); +			valid = false; +		} +		if (primitiveType == nullptr) { +			logger.error( +			    "This field is supposed to be primitive but has " +			    "no primitive type!"); +			valid = false; +		} +	} else { +		if (primitiveType != nullptr) { +			logger.error( +			    "This field is supposed to be non-primitive but has " +			    "a primitive type!"); +			valid = false; +		} +	} +	/* +	 * we are not allowed to call the validation functions of each child because +	 * this might lead to cycles. What we should do, however, is to check if +	 * there are no duplicates. +	 */ +	std::set<std::string> names; +	for (Handle<StructuredClass> c : children) { +		if (!names.insert(c->getName()).second) { +			logger.error(std::string("Field \"") + getName() + +			             "\" had multiple children with the name \"" + +			             c->getName() + "\""); +			valid = false; +		} +	} + +	return valid; +} + + +bool FieldDescriptor::removeChild(Handle<StructuredClass> c){ +	auto it = children.find(c); +	if(it != children.end()){ +		invalidate(); +		children.erase(it); +		return true; +	} +	return false; +} +  /* Class Descriptor */  void Descriptor::doResolve(ResolutionState &state) @@ -68,6 +134,40 @@ void Descriptor::doResolve(ResolutionState &state)  	                         state);  } +bool Descriptor::doValidate(Logger &logger) const +{ +	bool valid = true; +	// check parent type +	if(getParent() == nullptr){ +		logger.error("This Descriptor has no parent!"); +		valid = false; +	} else if (!getParent()->isa(RttiTypes::Domain)) { +		logger.error("The parent of this Descriptor is not a Domain!"); +		valid = false; +	} +	// check name +	if (getName().empty()) { +		logger.error("The name of this Descriptor is empty!"); +		valid = false; +	} else{ +		valid = valid & validateName(logger); +	} +	// check if all FieldDescriptors have this Descriptor as parent. +	for (Handle<FieldDescriptor> fd : fieldDescriptors) { +		if (fd->getParent() != this) { +			logger.error(std::string("Descriptor \"") + getName() + +			             "\" has " +			             "field \"" + +			             fd->getName() + +			             "\" as child but the field does not " +			             "have the Descriptor as parent."); +			valid = false; +		} +	} +	// check the FieldDescriptors themselves. +	return valid & continueValidationCheckDuplicates(fieldDescriptors, logger); +} +  std::vector<Rooted<Node>> Descriptor::pathTo(      Handle<StructuredClass> target) const  { @@ -184,19 +284,47 @@ StructuredClass::StructuredClass(Manager &mgr, std::string name,  	}  } +bool StructuredClass::doValidate(Logger &logger) const +{ +	bool valid = true; +	// check if all registered subclasses have this StructuredClass as parent. +	for (Handle<StructuredClass> sub : subclasses) { +		if (sub->getSuperclass() != this) { +			logger.error(std::string("Struct \"") + sub->getName() + +			             "\" is registered as subclass of \"" + getName() + +			             "\" but does not have it as superclass!"); +			valid = false; +		} +	} +	// check the validity of this superclass. +	if (superclass != nullptr) { +		valid = valid & superclass->validate(logger); +	} +	// check the validity as a Descriptor. +	/* +	 * Note that we do not check the validity of all subclasses. This is because +	 * it will lead to cycles as the subclasses would call validate on their +	 * superclass, which is this one. +	 */ +	return valid & Descriptor::doValidate(logger); +} +  void StructuredClass::setSuperclass(Handle<StructuredClass> sup)  {  	if (superclass == sup) {  		return;  	} -	invalidate(); -	if (sup != nullptr) { -		sup->addSubclass(this); -	} +	// remove this subclass from the old superclass.  	if (superclass != nullptr) {  		superclass->removeSubclass(this);  	} +	// set the new superclass  	superclass = acquire(sup); +	invalidate(); +	// add this class as new subclass of the new superclass. +	if (sup != nullptr) { +		sup->addSubclass(this); +	}  }  bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const @@ -287,6 +415,16 @@ void Domain::doResolve(ResolutionState &state)  	}  } +bool Domain::doValidate(Logger &logger) const +{ +	// check validity of name, of StructuredClasses, of AnnotationClasses and +	// TypeSystems. +	return validateName(logger) & +	       continueValidationCheckDuplicates(structuredClasses, logger) & +	       continueValidationCheckDuplicates(annotationClasses, logger) & +	       continueValidationCheckDuplicates(typesystems, logger); +} +  void Domain::addStructuredClass(Handle<StructuredClass> s)  {  	invalidate(); @@ -323,4 +461,3 @@ const Rtti Domain = RttiBuilder<model::Domain>("Domain")                          .composedOf({&StructuredClass, &AnnotationClass});  }  } - diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index e4a6967..e485171 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -271,13 +271,9 @@ private:  	Owned<Type> primitiveType;  	bool optional; -	/* -	 * TODO: doValidate with: -	 * # primitive and primitiveType set and no children XOR other FieldType and -	 *   no primitive type set -	 * # namecheck -	 * # parent typecheck -	 */ +protected: +	bool doValidate(Logger &logger) const override; +  public:  	/**  	 * This is the constructor for primitive fields. The type is automatically @@ -348,6 +344,17 @@ public:  	}  	/** +	 * Removes the given StructuredClass from the list of children of this +	 * FieldDescriptor. +	 * +	 * @param c some StructuredClass that shan't be a child of this +	 *          FieldDescriptor anymore. +	 * @return  true if the FieldDescriptor contained this child and false if it +	 *          did not. +	 */ +	bool removeChild(Handle<StructuredClass> c); + +	/**  	 * Returns the type of this field (not to be confused with the primitive  	 * type of this field).  	 * @@ -451,14 +458,8 @@ private:  protected:  	void doResolve(ResolutionState &state) override; -	/* -	 * TODO: doValidate with: -	 * # namecheck -	 * # FieldDescriptor name uniqueness -	 * # do all FieldDescriptors have this Descriptor as parent? -	 * # is the parent a domain? -	 * # is the attributes descriptor either not set or a StructType? -	 */ + +	bool doValidate(Logger &logger) const override;  public:  	Descriptor(Manager &mgr, std::string name, Handle<Domain> domain, @@ -584,12 +585,12 @@ public:   */  typedef RangeSet<size_t> Cardinality; -  /**   * This is the default cardinality.   */ -static Cardinality createAny(){ +static Cardinality createAny() +{  	Cardinality any;  	any.merge(Range<size_t>::typeRangeFrom(0));  	return std::move(any); @@ -685,14 +686,8 @@ private:  	    NodeVector<FieldDescriptor> ¤t,  	    std::set<std::string> &overriddenFields) const; -	 - -	/* -	 * TODO: doValidate with -	 * # does the subclasses have this class as superclass? -	 * # are the subclasses and the superclass valid? -	 * # is this a valid descriptor? -	 */ +protected: +	bool doValidate(Logger &logger) const override;  public:  	/** @@ -883,6 +878,8 @@ protected:  	 * # are all annotationclasses valid and have a unique name?  	 * # are all typesystems valid?  	 */ +	bool doValidate(Logger &logger) const override; +  public:  	/**  	 * The constructor for a new domain. Note that this is an empty Domain and  | 
