summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-18 16:20:39 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-18 16:20:39 +0100
commit1ebaaf08c0bc7de704a3c2a423f572c54c4a069b (patch)
treee8a577ecc8705d98b100a50ce269e4b0ce5b22b6
parentd55272760685f534954de9a334b0cc377326e852 (diff)
Made Attribute class mutable
-rw-r--r--src/core/model/Typesystem.cpp76
-rw-r--r--src/core/model/Typesystem.hpp109
-rw-r--r--test/core/model/TypesystemTest.cpp6
3 files changed, 145 insertions, 46 deletions
diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp
index a3d354c..13bb38c 100644
--- a/src/core/model/Typesystem.cpp
+++ b/src/core/model/Typesystem.cpp
@@ -149,11 +149,67 @@ EnumType::Ordinal EnumType::valueOf(const std::string &name) const
/* Class Attribute */
+Attribute::Attribute(Manager &mgr, std::string name, Handle<Type> type,
+ Variant defaultValue, bool optional)
+ : Node(mgr, std::move(name)),
+ type(acquire(type)),
+ rawDefaultValue(defaultValue),
+ optional(optional)
+{
+ ExceptionLogger logger;
+ initialize(logger);
+}
+
+Attribute::Attribute(Manager &mgr, std::string name, Handle<Type> type)
+ : Attribute(mgr, name, type, Variant{}, false)
+{
+}
+
+Attribute::Attribute(Manager &mgr, std::string name, Variant defaultValue,
+ bool optional)
+ : Attribute(mgr, name, new UnknownType(mgr), defaultValue, optional)
+{
+}
+
+void Attribute::initialize(Logger &logger)
+{
+ if (optional) {
+ defaultValue = rawDefaultValue;
+ type->build(defaultValue, logger);
+ }
+}
+
bool Attribute::doValidate(Logger &logger) const
{
return validateName(logger);
}
+void Attribute::setDefaultValue(const Variant &defaultValue, Logger &logger)
+{
+ invalidate();
+
+ rawDefaultValue = defaultValue;
+ optional = true;
+ initialize(logger);
+}
+
+void Attribute::removeDefaultValue()
+{
+ invalidate();
+
+ rawDefaultValue = nullptr;
+ defaultValue = nullptr;
+ optional = false;
+}
+
+void Attribute::setType(Handle<Type> type, Logger &logger)
+{
+ invalidate();
+
+ this->type = acquire(type);
+ initialize(logger);
+}
+
/* Class StructType */
bool StructType::resolveIndexKey(const std::string &key, size_t &idx) const
@@ -195,8 +251,8 @@ bool StructType::insertDefaults(Variant &data, const std::vector<bool> &set,
Variant::arrayType &arr = data.asArray();
for (size_t a = 0; a < arr.size(); a++) {
if (!set[a]) {
- if (attributes[a]->optional) {
- arr[a] = attributes[a]->defaultValue;
+ if (attributes[a]->isOptional()) {
+ arr[a] = attributes[a]->getDefaultValue();
} else {
ok = false;
arr[a] = attributes[a]->getType()->create();
@@ -333,7 +389,7 @@ bool StructType::doValidate(Logger &logger) const
Rooted<StructType> StructType::createValidated(
Manager &mgr, std::string name, Handle<Typesystem> system,
- Handle<StructType> parentStructure, NodeVector<Attribute> attributes,
+ Handle<StructType> parentStructure, const NodeVector<Attribute> &attributes,
Logger &logger)
{
Rooted<StructType> structType{new StructType(mgr, name, system)};
@@ -355,6 +411,16 @@ void StructType::setParentStructure(Handle<StructType> parentStructure,
initialize(logger);
}
+Rooted<Attribute> StructType::createAttribute(const std::string &name,
+ Variant defaultValue,
+ bool optional, Logger &logger)
+{
+ Rooted<Attribute> attribute =
+ new Attribute(getManager(), name, defaultValue, optional);
+ addAttribute(attribute, logger);
+ return attribute;
+}
+
void StructType::addAttribute(Handle<Attribute> attribute, Logger &logger,
bool fromInitialize)
{
@@ -398,8 +464,8 @@ Variant StructType::create() const
Variant::arrayType arr;
arr.resize(attributes.size());
for (size_t idx = 0; idx < attributes.size(); idx++) {
- if (attributes[idx]->optional) {
- arr[idx] = attributes[idx]->defaultValue;
+ if (attributes[idx]->isOptional()) {
+ arr[idx] = attributes[idx]->getDefaultValue();
} else {
arr[idx] = attributes[idx]->getType()->create();
}
diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp
index 64922f0..a4a679d 100644
--- a/src/core/model/Typesystem.hpp
+++ b/src/core/model/Typesystem.hpp
@@ -368,18 +368,6 @@ public:
*/
class Attribute : public Node {
private:
-
-
-protected:
- /**
- * Returns true if the name of the Attribute is a valid identifier.
- *
- * @param logger is the logger instance to which validation errors are
- * logged.
- */
- bool doValidate(Logger &logger) const override;
-
-public:
/**
* Reference to the actual type of the attribute.
*/
@@ -402,6 +390,25 @@ public:
bool optional;
/**
+ * Reinitializes the default value from the raw default value with the
+ * current type.
+ *
+ * @param logger is the logger instance to which errors while building the
+ * default value should be passed.
+ */
+ void initialize(Logger &logger);
+
+protected:
+ /**
+ * Returns true if the name of the Attribute is a valid identifier.
+ *
+ * @param logger is the logger instance to which validation errors are
+ * logged.
+ */
+ bool doValidate(Logger &logger) const override;
+
+public:
+ /**
* Constructor of the Attribute class.
*
* @param mgr is the Manager instance to be used for the Node.
@@ -414,13 +421,7 @@ public:
* be used.
*/
Attribute(Manager &mgr, std::string name, Handle<Type> type,
- Variant defaultValue, bool optional = true)
- : Node(mgr, std::move(name)),
- type(acquire(type)),
- defaultValue(defaultValue),
- optional(optional)
- {
- }
+ Variant defaultValue, bool optional = true);
/**
* Constructor of the Attribute class with no default value.
@@ -428,14 +429,22 @@ public:
* @param mgr is the Manager instance to be used for the Node.
* @param type holds a reference to the type descriptor holding the type
* of the attribute.
+ * @param name is the name of the Attribute. Should be a valid identifier.
*/
- Attribute(Manager &mgr, std::string name, Handle<Type> type)
- : Node(mgr, std::move(name)),
- type(acquire(type)),
- defaultValue(nullptr),
- optional(false)
- {
- }
+ Attribute(Manager &mgr, std::string name, Handle<Type> type);
+
+ /**
+ * Constructor of the Attribute class with default value but unknown type.
+ *
+ * @param mgr is the Manager instance to be used for the Node.
+ * @param name is the name of the Attribute. Should be a valid identifier.
+ * @param defaultValue is the default value of the attribute and must have
+ * been passed through the build of the specified type.
+ * @param optional should be set to true if the if the default value should
+ * be used.
+ */
+ Attribute(Manager &mgr, std::string name, Variant defaultValue,
+ bool optional);
/**
* Sets a new default value. This makes the Attribute optional. The given
@@ -454,7 +463,7 @@ public:
* @return the default value of the attribute. If no default value has been
* given a null variant is returned (the opposite does not hold).
*/
- Variant getDefaultValue() const;
+ Variant getDefaultValue() const { return defaultValue; }
/**
* Removes any default value from the attribute, making this attribute
@@ -468,7 +477,7 @@ public:
*
* @return true if the attribute is optional, false otherwise.
*/
- bool isOptional() const {return optional; }
+ bool isOptional() const { return optional; }
/**
* Sets the type of the attribute to the specified value. This will
@@ -653,9 +662,24 @@ public:
{
}
+ /**
+ * Creates a new instance of the StructType class and checks the given
+ * parameters for validity.
+ *
+ * @param mgr is the underlying Manager instance.
+ * @param name is the name of the EnumType instance. Should be a valid
+ * identifier.
+ * @param system is a reference to the parent Typesystem instance.
+ * @param parentStructure is a reference to the StructType this type is
+ * derived from, may be nullptr.
+ * @param attributes is a vector containing the struct type attributes.
+ * The attributes are checked for validity (their names must be a valid
+ * identifiers) and uniqueness (each value must exist exactly once).
+ * @param logger is the Logger instance into which errors should be written.
+ */
static Rooted<StructType> createValidated(
Manager &mgr, std::string name, Handle<Typesystem> system,
- Handle<StructType> parentStructure, NodeVector<Attribute> attributes,
+ Handle<StructType> parentStructure, const NodeVector<Attribute> &attributes,
Logger &logger);
/**
@@ -674,8 +698,23 @@ public:
void setParentStructure(Handle<StructType> parentStructure, Logger &logger);
/**
- * Adds an attribute. Throws an exception if the name of the attribute is
- * not unique.
+ * Creates a new attribute with unknown type and adds it to the attribute
+ * list.
+ *
+ * @param name is the name of the attribute.
+ * @param defaultValue is the default value of the attribute.
+ * @param optional specifies whether the attribute is optional or not.
+ * @param logger is the logger instance to which errors while creating or
+ * adding the attribute should be logged.
+ * @return a new instance of the Attribute class.
+ */
+ Rooted<Attribute> createAttribute(const std::string &name,
+ Variant defaultValue, bool optional,
+ Logger &logger);
+
+ /**
+ * Adds an attribute. Throws an exception if the name of the attribute
+ * is not unique.
*
* @param attribute is the attribute descriptor that should be added to the
* internal attribute list.
@@ -828,13 +867,8 @@ public:
* (yet) resolved type.
*
* @param mgr is the Manager instance to be used for the Node.
- * @param name is the name of the unresolved type which may be used later
- * to perform a complete resolution.
*/
- UnknownType(Manager &mgr, std::string name)
- : Type(mgr, std::move(name), nullptr, false)
- {
- }
+ UnknownType(Manager &mgr) : Type(mgr, "unknown", nullptr, false) {}
/**
* Returns a nullptr variant.
@@ -912,7 +946,6 @@ private:
NodeVector<Constant> constants;
protected:
-
void doResolve(ResolutionState &state) override;
bool doValidate(Logger &logger) const override;
diff --git a/test/core/model/TypesystemTest.cpp b/test/core/model/TypesystemTest.cpp
index 5a2efdd..a408700 100644
--- a/test/core/model/TypesystemTest.cpp
+++ b/test/core/model/TypesystemTest.cpp
@@ -846,7 +846,7 @@ TEST(ArrayType, conversion)
TEST(UnknownType, rtti)
{
Manager mgr;
- Rooted<UnknownType> unknownType{new UnknownType(mgr, "unknown")};
+ Rooted<UnknownType> unknownType{new UnknownType(mgr)};
ASSERT_TRUE(unknownType->isa(RttiTypes::UnknownType));
ASSERT_TRUE(unknownType->isa(typeOf<Type>()));
ASSERT_TRUE(unknownType->isa(typeOf<Node>()));
@@ -868,7 +868,7 @@ TEST(UnknownType, rtti)
TEST(UnknownType, creation)
{
Manager mgr;
- Rooted<UnknownType> unknownType{new UnknownType(mgr, "unknown")};
+ Rooted<UnknownType> unknownType{new UnknownType(mgr)};
Variant val = unknownType->create();
ASSERT_TRUE(val.isNull());
@@ -877,7 +877,7 @@ TEST(UnknownType, creation)
TEST(UnknownType, conversion)
{
Manager mgr;
- Rooted<UnknownType> unknownType{new UnknownType(mgr, "unknown")};
+ Rooted<UnknownType> unknownType{new UnknownType(mgr)};
{
Variant val1{{1, "test", false, 42.5}};