summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-28 12:46:10 +0100
committerAndreas Stöckel <andreas@somweyr.de>2014-12-28 12:46:10 +0100
commitcb3189b43290cb5bdf3b699f0cda1b6b6a5b871b (patch)
tree47587ca0e798eab93dc0cf988f54f555be9b972a
parent171d6b233690f7b0ed01450e1d993b246fe42ed3 (diff)
implemented and tested creation with parent type
-rw-r--r--src/core/model/Typesystem.cpp41
-rw-r--r--src/core/model/Typesystem.hpp10
-rw-r--r--test/core/model/TypesystemTest.cpp44
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)