diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2014-12-28 12:46:10 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2014-12-28 12:46:10 +0100 |
commit | cb3189b43290cb5bdf3b699f0cda1b6b6a5b871b (patch) | |
tree | 47587ca0e798eab93dc0cf988f54f555be9b972a | |
parent | 171d6b233690f7b0ed01450e1d993b246fe42ed3 (diff) |
implemented and tested creation with parent type
-rw-r--r-- | src/core/model/Typesystem.cpp | 41 | ||||
-rw-r--r-- | src/core/model/Typesystem.hpp | 10 | ||||
-rw-r--r-- | test/core/model/TypesystemTest.cpp | 44 |
3 files changed, 89 insertions, 6 deletions
diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp index 561692a..812d85c 100644 --- a/src/core/model/Typesystem.cpp +++ b/src/core/model/Typesystem.cpp @@ -313,30 +313,50 @@ bool StructType::doBuild(Variant &data, Logger &logger) const return buildFromArrayOrMap(data, logger, false); } -Rooted<StructType> StructType::createValidated( - Manager &mgr, std::string name, Handle<Typesystem> system, - Handle<StructType> parent, NodeVector<Attribute> attributes, Logger &logger) +Rooted<StructType> StructType::createValidated(Manager &mgr, std::string name, + Handle<Typesystem> system, + Handle<StructType> parent, + NodeVector<Attribute> attributes, + Logger &logger) { // Check the attributes for validity and uniqueness std::map<std::string, size_t> attributeNames; + NodeVector<Attribute> collectedAttributes; + + // Copy the attributes from the parent structure + if (parent != nullptr) { + attributeNames = parent->attributeNames; + collectedAttributes = parent->attributes; + } + + // Check the attributes for validity and uniqueness for (size_t idx = 0; idx < attributes.size(); idx++) { // Check for valid attribute names const std::string &attrName = attributes[idx]->getName(); if (!Utils::isIdentifier(name)) { - logger.error(std::string("Invalid attribute name \"") + name + + logger.error(std::string("Invalid attribute name \"") + attrName + std::string("\"")); } // Check for uniqueness auto res = attributeNames.emplace(attrName, idx); if (!res.second) { - logger.error(std::string("Attribute with name \"") + name + + logger.error(std::string("Attribute with name \"") + attrName + std::string("\" defined multiple times")); + if (parent != nullptr && parent->indexOf(attrName) >= 0) { + logger.note(std::string("Attribute \"") + attrName + + std::string("\" was defined in parent class \"") + + parent->getName() + std::string("\"")); + } } + + // Store the attribute in the complete attribute list + collectedAttributes.push_back(attributes[idx]); } // Call the private constructor - return new StructType(mgr, name, system, parent, attributes, attributeNames); + return new StructType(mgr, name, system, parent, collectedAttributes, + attributeNames); } Variant StructType::create() const @@ -369,6 +389,15 @@ Variant StructType::cast(Variant &data, Logger &logger) const return buildFromArrayOrMap(data, logger, true); } +ssize_t StructType::indexOf(const std::string &name) const +{ + size_t res; + if (resolveIdentifierKey(name, res)) { + return res; + } + return -1; +} + /* Class ArrayType */ bool ArrayType::doBuild(Variant &data, Logger &logger) const diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp index 7eedc67..c279b5d 100644 --- a/src/core/model/Typesystem.hpp +++ b/src/core/model/Typesystem.hpp @@ -617,6 +617,16 @@ public: * struct type has no parent. */ Rooted<StructType> getParent() const { return parent; } + + /** + * Returns the index of the given attribute in a data array representing + * the StructType. + * + * @param name is the name of the attribute for which the index is + * requested. + * @return the index or -1 if the attribute does not exist. + */ + ssize_t indexOf(const std::string &name) const; }; /** diff --git a/test/core/model/TypesystemTest.cpp b/test/core/model/TypesystemTest.cpp index 4a37707..f995222 100644 --- a/test/core/model/TypesystemTest.cpp +++ b/test/core/model/TypesystemTest.cpp @@ -397,6 +397,21 @@ static Rooted<StructType> createStructType(Manager &mgr, Logger &logger) return structType; } +static Rooted<StructType> createStructTypeWithParent(Handle<StructType> parent, + Manager &mgr, + Logger &logger) +{ + Rooted<StringType> stringType{new StringType(mgr, nullptr)}; + Rooted<IntType> intType{new IntType(mgr, nullptr)}; + Rooted<StructType> structType{StructType::createValidated( + mgr, "struct", nullptr, parent, + NodeVector<Attribute>{new Attribute{mgr, "aa", stringType, "value1"}, + new Attribute{mgr, "bc", intType, 42}, + new Attribute{mgr, "cd", parent}}, + logger)}; + return structType; +} + TEST(StructType, rtti) { Logger logger; @@ -428,6 +443,35 @@ TEST(StructType, creation) ASSERT_EQ(0, arr[3].asInt()); } +TEST(StructType, creationWithParent) +{ + Logger logger; + Manager mgr; + Rooted<StructType> structType = createStructType(mgr, logger); + Rooted<StructType> structWithParentType = + createStructTypeWithParent(structType, mgr, logger); + + Variant val = structWithParentType->create(); + ASSERT_TRUE(val.isArray()); + ASSERT_EQ(7U, val.asArray().size()); + + const auto &arr = val.asArray(); + ASSERT_TRUE(arr[0].isString()); + ASSERT_TRUE(arr[1].isString()); + ASSERT_TRUE(arr[2].isInt()); + ASSERT_TRUE(arr[3].isInt()); + ASSERT_TRUE(arr[4].isString()); + ASSERT_TRUE(arr[5].isInt()); + ASSERT_TRUE(arr[6].isArray()); + + ASSERT_EQ("attr1default", arr[0].asString()); + ASSERT_EQ("", arr[1].asString()); + ASSERT_EQ(3, arr[2].asInt()); + ASSERT_EQ(0, arr[3].asInt()); + ASSERT_EQ("value1", arr[4].asString()); + ASSERT_EQ(42, arr[5].asInt()); +} + /* Class ArrayType */ TEST(ArrayType, rtti) |