summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/model/Domain.cpp26
-rw-r--r--src/core/model/Domain.hpp27
-rw-r--r--src/plugins/xml/XmlParser.cpp2
-rw-r--r--test/plugins/xml/XmlParserTest.cpp23
4 files changed, 54 insertions, 24 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index 9368005..f8c0779 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -155,19 +155,6 @@ bool Descriptor::doValidate(Logger &logger) const
} 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.",
- *this);
- valid = false;
- }
- }
// check the FieldDescriptors themselves.
return valid & continueValidationCheckDuplicates(fieldDescriptors, logger);
}
@@ -248,6 +235,7 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,
return found;
}
+
void Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd)
{
// only add it if we need to.
@@ -255,6 +243,18 @@ void Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd)
invalidate();
fieldDescriptors.push_back(fd);
}
+ if (fd->getParent() == nullptr) {
+ fd->setParent(this);
+ }
+}
+
+void Descriptor::moveFieldDescriptor(Handle<FieldDescriptor> fd)
+{
+ // only add it if we need to.
+ if (fieldDescriptors.find(fd) == fieldDescriptors.end()) {
+ invalidate();
+ fieldDescriptors.push_back(fd);
+ }
Handle<Managed> par = fd->getParent();
if (par != this) {
if (par != nullptr) {
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index bef7919..dd0af4c 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -509,12 +509,33 @@ public:
/**
* Adds the given FieldDescriptor to this Descriptor. This also sets the
+ * parent of the given FieldDescriptor if it is not set yet.
+ *
+ * @param fd is a FieldDescriptor.
+ */
+ void addFieldDescriptor(Handle<FieldDescriptor> fd);
+
+ /**
+ * Adds the given FieldDescriptors to this Descriptor. This also sets the
+ * parent of each given FieldDescriptor if it is not set yet.
+ *
+ * @param fds are FieldDescriptors.
+ */
+ void addFieldDescriptors(const std::vector<Handle<FieldDescriptor>> &fds)
+ {
+ for (Handle<FieldDescriptor> fd : fds) {
+ addFieldDescriptor(fd);
+ }
+ }
+
+ /**
+ * Adds the given FieldDescriptor to this Descriptor. This also sets the
* parent of the given FieldDescriptor if it is not set to this Descriptor
* already and removes it from the old parent Descriptor.
*
* @param fd is a FieldDescriptor.
*/
- void addFieldDescriptor(Handle<FieldDescriptor> fd);
+ void moveFieldDescriptor(Handle<FieldDescriptor> fd);
/**
* Adds the given FieldDescriptors to this Descriptor. This also sets the
@@ -523,10 +544,10 @@ public:
*
* @param fds are FieldDescriptors.
*/
- void addFieldDescriptors(const std::vector<Handle<FieldDescriptor>> &fds)
+ void moveFieldDescriptors(const std::vector<Handle<FieldDescriptor>> &fds)
{
for (Handle<FieldDescriptor> fd : fds) {
- addFieldDescriptor(fd);
+ moveFieldDescriptor(fd);
}
}
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp
index c288f40..2d62c11 100644
--- a/src/plugins/xml/XmlParser.cpp
+++ b/src/plugins/xml/XmlParser.cpp
@@ -411,7 +411,7 @@ public:
name, parent, logger(),
[](Handle<Node> field, Handle<Node> parent, Logger &logger) {
if (field != nullptr) {
- parent.cast<StructuredClass>()->copyFieldDescriptor(
+ parent.cast<StructuredClass>()->addFieldDescriptor(
field.cast<FieldDescriptor>());
}
});
diff --git a/test/plugins/xml/XmlParserTest.cpp b/test/plugins/xml/XmlParserTest.cpp
index 6619199..0512fd0 100644
--- a/test/plugins/xml/XmlParserTest.cpp
+++ b/test/plugins/xml/XmlParserTest.cpp
@@ -156,14 +156,25 @@ static void checkFieldDescriptor(
}
static void checkFieldDescriptor(
- Handle<Descriptor> desc, NodeVector<StructuredClass> children,
+ Handle<Descriptor> desc, Handle<Descriptor> parent,
+ NodeVector<StructuredClass> children,
const std::string &name = DEFAULT_FIELD_NAME,
FieldDescriptor::FieldType type = FieldDescriptor::FieldType::TREE,
Handle<Type> primitiveType = nullptr, bool optional = false)
{
auto res = desc->resolve(RttiTypes::FieldDescriptor, name);
ASSERT_EQ(1, res.size());
- checkFieldDescriptor(res[0].node, name, desc, children, type, primitiveType,
+ checkFieldDescriptor(res[0].node, name, parent, children, type,
+ primitiveType, optional);
+}
+
+static void checkFieldDescriptor(
+ Handle<Descriptor> desc, NodeVector<StructuredClass> children,
+ const std::string &name = DEFAULT_FIELD_NAME,
+ FieldDescriptor::FieldType type = FieldDescriptor::FieldType::TREE,
+ Handle<Type> primitiveType = nullptr, bool optional = false)
+{
+ checkFieldDescriptor(desc, desc, children, name, type, primitiveType,
optional);
}
@@ -216,8 +227,8 @@ TEST(XmlParser, domainParsing)
Rooted<StructuredClass> heading =
checkStructuredClass("heading", "heading", headings_domain, single,
nullptr, nullptr, true, false);
- // which should allow text content
- checkFieldDescriptor(heading, {text});
+ // which should be a reference to the paragraph descriptor.
+ checkFieldDescriptor(heading, paragraph, {text});
// and each struct in the book domain (except for text) should have a
// heading field now.
checkFieldDescriptor(book, {heading}, "heading",
@@ -261,9 +272,7 @@ TEST(XmlParser, domainParsing)
// paragraph should have comment as child now as well.
checkFieldDescriptor(paragraph, {text, comment});
// as should heading, because it references the paragraph default field.
- // TODO: This does not work as of now, because in fact fields get copied,
- // not referenced. Should we reference fields, though?
- //checkFieldDescriptor(heading, {text, comment});
+ checkFieldDescriptor(heading, paragraph, {text, comment});
}
}