summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/model/Domain.cpp49
-rw-r--r--src/core/model/Domain.hpp31
-rw-r--r--src/core/parser/stack/DocumentHandler.cpp2
-rw-r--r--src/core/parser/stack/DomainHandler.cpp60
-rw-r--r--test/core/model/DocumentTest.cpp8
-rw-r--r--test/core/model/DomainTest.cpp30
-rw-r--r--test/core/model/TestAdvanced.hpp2
-rw-r--r--test/core/model/TestDomain.hpp14
8 files changed, 115 insertions, 81 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index ac0699e..f6c3956 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -558,7 +558,7 @@ Rooted<FieldDescriptor> Descriptor::getFieldDescriptor(
}
}
-void Descriptor::addAndSortFieldDescriptor(Handle<FieldDescriptor> fd,
+bool Descriptor::addAndSortFieldDescriptor(Handle<FieldDescriptor> fd,
Logger &logger)
{
// only add it if we need to.
@@ -571,37 +571,25 @@ void Descriptor::addAndSortFieldDescriptor(Handle<FieldDescriptor> fd,
fd->getFieldType() != FieldDescriptor::FieldType::TREE) {
// if so we add the new field before the TREE field.
fieldDescriptors.insert(fieldDescriptors.end() - 1, fd);
-
- // if the new field was from the same domain we warn the user
- // because that is bad coding style.
- if (fd->getParent() != nullptr &&
- fd->getParent().cast<Descriptor>()->getParent() ==
- getParent()) {
- logger.warning(
- std::string("Field \"") + fd->getName() +
- "\" was declared after main field \"" +
- fds.back()->getName() +
- "\". The order of fields was changed to make the "
- "main field the last field.",
- *fd);
- }
+ return true;
} else {
fieldDescriptors.push_back(fd);
}
}
+ return false;
}
-void Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
+bool Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
{
- addAndSortFieldDescriptor(fd, logger);
if (fd->getParent() == nullptr) {
fd->setParent(this);
}
+ return addAndSortFieldDescriptor(fd, logger);
}
-void Descriptor::moveFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
+bool Descriptor::moveFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
{
- addAndSortFieldDescriptor(fd, logger);
+ bool sorted = addAndSortFieldDescriptor(fd, logger);
Handle<Managed> par = fd->getParent();
if (par != this) {
if (par != nullptr) {
@@ -610,9 +598,10 @@ void Descriptor::moveFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
}
fd->setParent(this);
}
+ return sorted;
}
-void Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
+bool Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
{
Rooted<FieldDescriptor> copy;
if (fd->isPrimitive()) {
@@ -631,7 +620,7 @@ void Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
copy->addChild(c);
}
}
- addFieldDescriptor(copy, logger);
+ return addFieldDescriptor(copy, logger);
}
bool Descriptor::removeFieldDescriptor(Handle<FieldDescriptor> fd)
@@ -646,25 +635,27 @@ bool Descriptor::removeFieldDescriptor(Handle<FieldDescriptor> fd)
return false;
}
-Rooted<FieldDescriptor> Descriptor::createPrimitiveFieldDescriptor(
- Handle<Type> primitiveType, Logger &logger,
- FieldDescriptor::FieldType fieldType, std::string name, bool optional)
+std::pair<Rooted<FieldDescriptor>, bool>
+Descriptor::createPrimitiveFieldDescriptor(Handle<Type> primitiveType,
+ Logger &logger,
+ FieldDescriptor::FieldType fieldType,
+ std::string name, bool optional)
{
Rooted<FieldDescriptor> fd{new FieldDescriptor(getManager(), primitiveType,
this, fieldType,
std::move(name), optional)};
- addFieldDescriptor(fd, logger);
- return fd;
+ bool sorted = addFieldDescriptor(fd, logger);
+ return std::make_pair(fd, sorted);
}
-Rooted<FieldDescriptor> Descriptor::createFieldDescriptor(
+std::pair<Rooted<FieldDescriptor>, bool> Descriptor::createFieldDescriptor(
Logger &logger, FieldDescriptor::FieldType fieldType, std::string name,
bool optional)
{
Rooted<FieldDescriptor> fd{new FieldDescriptor(
getManager(), this, fieldType, std::move(name), optional)};
- addFieldDescriptor(fd, logger);
- return fd;
+ bool sorted = addFieldDescriptor(fd, logger);
+ return std::make_pair(fd, sorted);
}
/* Class StructuredClass */
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 350c7ba..476a38c 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -469,7 +469,7 @@ private:
Owned<StructType> attributesDescriptor;
NodeVector<FieldDescriptor> fieldDescriptors;
- void addAndSortFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
+ bool addAndSortFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
protected:
void doResolve(ResolutionState &state) override;
@@ -557,8 +557,11 @@ public:
* parent of the given FieldDescriptor if it is not set yet.
*
* @param fd is a FieldDescriptor.
+ * @return returns true if the given FieldDescriptor was not added at the
+ * end one place before because a TREE field already existed and
+ * the TREE field has to be at the end.
*/
- void addFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
+ bool addFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
/**
* Adds the given FieldDescriptor to this Descriptor. This also sets the
@@ -566,16 +569,22 @@ public:
* already and removes it from the old parent Descriptor.
*
* @param fd is a FieldDescriptor.
+ * @return returns true if the given FieldDescriptor was not added at the
+ * end one place before because a TREE field already existed and
+ * the TREE field has to be at the end.
*/
- void moveFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
+ bool moveFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
/**
* Copies a FieldDescriptor that belongs to another Descriptor to this
* Descriptor.
*
* @param fd some FieldDescriptor belonging to another Descriptor.
+ * @return returns true if the given FieldDescriptor was not added at the
+ * end one place before because a TREE field already existed and
+ * the TREE field has to be at the end.
*/
- void copyFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
+ bool copyFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger);
/**
* Removes the given FieldDescriptor from this Descriptor. This also sets
@@ -598,9 +607,12 @@ public:
* filled in order for an instance of the parent
* Descriptor to be valid.
*
- * @return the newly created FieldDescriptor.
+ * @return the newly created FieldDescriptor and a bool
+ * indicating whether the order of FieldDescriptors had
+ * to be changed for the TREE field to be in the last
+ * spot.
*/
- Rooted<FieldDescriptor> createPrimitiveFieldDescriptor(
+ std::pair<Rooted<FieldDescriptor>, bool> createPrimitiveFieldDescriptor(
Handle<Type> primitiveType, Logger &logger,
FieldDescriptor::FieldType fieldType = FieldDescriptor::FieldType::TREE,
std::string name = "", bool optional = false);
@@ -617,9 +629,12 @@ public:
* filled in order for an instance of the parent
* Descriptor to be valid.
*
- * @return the newly created FieldDescriptor.
+ * @return the newly created FieldDescriptor and a bool
+ * indicating whether the order of FieldDescriptors had
+ * to be changed for the TREE field to be in the last
+ * spot.
*/
- Rooted<FieldDescriptor> createFieldDescriptor(
+ std::pair<Rooted<FieldDescriptor>, bool> createFieldDescriptor(
Logger &logger,
FieldDescriptor::FieldType fieldType = FieldDescriptor::FieldType::TREE,
std::string name = "", bool optional = false);
diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp
index d514701..41ca8ec 100644
--- a/src/core/parser/stack/DocumentHandler.cpp
+++ b/src/core/parser/stack/DocumentHandler.cpp
@@ -348,4 +348,4 @@ namespace RttiTypes {
const Rtti DocumentField = RttiBuilder<ousia::parser_stack::DocumentField>(
"DocumentField").parent(&Node);
}
-}
+} \ No newline at end of file
diff --git a/src/core/parser/stack/DomainHandler.cpp b/src/core/parser/stack/DomainHandler.cpp
index a2c8eec..ddec1ee 100644
--- a/src/core/parser/stack/DomainHandler.cpp
+++ b/src/core/parser/stack/DomainHandler.cpp
@@ -133,11 +133,18 @@ bool DomainFieldHandler::start(Variant::mapType &args)
Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
- Rooted<FieldDescriptor> field = parent->createFieldDescriptor(
+ auto res = parent->createFieldDescriptor(
logger(), type, args["name"].asString(), args["optional"].asBool());
- field->setLocation(location());
+ res.first->setLocation(location());
+ if (res.second) {
+ logger().warning(
+ std::string("Field \"") + res.first->getName() +
+ "\" was declared after main field. The order of fields "
+ "was changed to make the main field the last field.",
+ *res.first);
+ }
- scope().push(field);
+ scope().push(res.first);
return true;
}
@@ -150,14 +157,24 @@ bool DomainFieldRefHandler::start(Variant::mapType &args)
Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
const std::string &name = args["ref"].asString();
- scope().resolveFieldDescriptor(
- name, parent, logger(),
- [](Handle<Node> field, Handle<Node> parent, Logger &logger) {
- if (field != nullptr) {
- parent.cast<StructuredClass>()->addFieldDescriptor(
- field.cast<FieldDescriptor>(), logger);
- }
- });
+
+ auto loc = location();
+
+ scope().resolveFieldDescriptor(name, parent, logger(),
+ [loc](Handle<Node> field,
+ Handle<Node> parent, Logger &logger) {
+ if (field != nullptr) {
+ if (parent.cast<StructuredClass>()->addFieldDescriptor(
+ field.cast<FieldDescriptor>(), logger)) {
+ logger.warning(
+ std::string("Field \"") + field->getName() +
+ "\" was referenced after main field was declared. The "
+ "order of fields was changed to make the main field "
+ "the last field.",
+ loc);
+ }
+ }
+ });
return true;
}
@@ -176,13 +193,20 @@ bool DomainPrimitiveHandler::start(Variant::mapType &args)
fieldType = FieldDescriptor::FieldType::TREE;
}
- Rooted<FieldDescriptor> field = parent->createPrimitiveFieldDescriptor(
+ auto res = parent->createPrimitiveFieldDescriptor(
new UnknownType(manager()), logger(), fieldType,
args["name"].asString(), args["optional"].asBool());
- field->setLocation(location());
+ res.first->setLocation(location());
+ if (res.second) {
+ logger().warning(
+ std::string("Field \"") + res.first->getName() +
+ "\" was declared after main field. The order of fields "
+ "was changed to make the main field the last field.",
+ *res.first);
+ }
const std::string &type = args["type"].asString();
- scope().resolve<Type>(type, field, logger(),
+ scope().resolve<Type>(type, res.first, logger(),
[](Handle<Node> type, Handle<Node> field,
Logger &logger) {
if (type != nullptr) {
@@ -190,7 +214,7 @@ bool DomainPrimitiveHandler::start(Variant::mapType &args)
}
});
- scope().push(field);
+ scope().push(res.first);
return true;
}
@@ -254,8 +278,8 @@ bool DomainParentFieldHandler::start(Variant::mapType &args)
Logger &logger) {
if (parent != nullptr) {
Rooted<FieldDescriptor> field =
- parent.cast<Descriptor>()->createFieldDescriptor(
- logger, type, name, optional);
+ (parent.cast<Descriptor>()->createFieldDescriptor(
+ logger, type, name, optional)).first;
field->addChild(strct.cast<StructuredClass>());
}
});
@@ -390,4 +414,4 @@ namespace RttiTypes {
const Rtti DomainParent = RttiBuilder<ousia::parser_stack::DomainParent>(
"DomainParent").parent(&Node);
}
-}
+} \ No newline at end of file
diff --git a/test/core/model/DocumentTest.cpp b/test/core/model/DocumentTest.cpp
index 0c6eea6..1bb2356 100644
--- a/test/core/model/DocumentTest.cpp
+++ b/test/core/model/DocumentTest.cpp
@@ -147,7 +147,7 @@ TEST(Document, validate)
// now let's extend the rootClass with a default field.
Rooted<FieldDescriptor> rootField =
- rootClass->createFieldDescriptor(logger);
+ rootClass->createFieldDescriptor(logger).first;
// and add a child class for it.
Rooted<StructuredClass> childClass{
new StructuredClass(mgr, "child", domain, single)};
@@ -194,7 +194,7 @@ TEST(Document, validate)
* instances now.
*/
Rooted<FieldDescriptor> childField =
- childClass->createFieldDescriptor(logger);
+ childClass->createFieldDescriptor(logger).first;
childField->addChild(childClass);
{
/*
@@ -214,7 +214,7 @@ TEST(Document, validate)
*/
Rooted<FieldDescriptor> childSubField =
childSubClass->createFieldDescriptor(
- logger, FieldDescriptor::FieldType::TREE, "dummy", true);
+ logger, FieldDescriptor::FieldType::TREE, "dummy", true).first;
// add a child pro forma to make it valid.
childSubField->addChild(childSubClass);
{
@@ -234,7 +234,7 @@ TEST(Document, validate)
Rooted<FieldDescriptor> primitive_field =
childSubClass->createPrimitiveFieldDescriptor(
sys->getIntType(), logger, FieldDescriptor::FieldType::SUBTREE,
- "int", false);
+ "int", false).first;
{
/*
* Now a document with one instance of the Child subclass should be
diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp
index 4cb4331..d68648e 100644
--- a/test/core/model/DomainTest.cpp
+++ b/test/core/model/DomainTest.cpp
@@ -186,21 +186,21 @@ TEST(Descriptor, pathToAdvanced)
new StructuredClass(mgr, "target", domain, Cardinality::any())};
// We create a field for A
- Rooted<FieldDescriptor> A_field = A->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> A_field = A->createFieldDescriptor(logger).first;
A_field->addChild(B);
A_field->addChild(D);
// We create no field for B
// One for C
- Rooted<FieldDescriptor> C_field = C->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> C_field = C->createFieldDescriptor(logger).first;
C_field->addChild(target);
// One for D
- Rooted<FieldDescriptor> D_field = D->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> D_field = D->createFieldDescriptor(logger).first;
D_field->addChild(E);
// One for E
- Rooted<FieldDescriptor> E_field = E->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> E_field = E->createFieldDescriptor(logger).first;
E_field->addChild(target);
ASSERT_TRUE(domain->validate(logger));
@@ -239,7 +239,7 @@ TEST(Descriptor, getDefaultFields)
// create a field.
Rooted<FieldDescriptor> A_prim_field =
- A->createPrimitiveFieldDescriptor(sys->getStringType(), logger);
+ A->createPrimitiveFieldDescriptor(sys->getStringType(), logger).first;
// now we should find that.
auto fields = A->getDefaultFields();
ASSERT_EQ(1U, fields.size());
@@ -262,7 +262,7 @@ TEST(Descriptor, getDefaultFields)
ASSERT_EQ(A_prim_field, fields[0]);
// and we should not be able to find it if we override the field.
- Rooted<FieldDescriptor> A_field = A->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> A_field = A->createFieldDescriptor(logger).first;
ASSERT_TRUE(A->getDefaultFields().empty());
// add a transparent child class.
@@ -273,7 +273,7 @@ TEST(Descriptor, getDefaultFields)
// add a primitive field for it.
Rooted<FieldDescriptor> C_field =
- C->createPrimitiveFieldDescriptor(sys->getStringType(), logger);
+ C->createPrimitiveFieldDescriptor(sys->getStringType(), logger).first;
// now we should find that.
fields = A->getDefaultFields();
@@ -285,14 +285,14 @@ TEST(Descriptor, getDefaultFields)
Rooted<StructuredClass> D{new StructuredClass(
mgr, "D", domain, Cardinality::any(), nullptr, true, false)};
A_field->addChild(D);
- Rooted<FieldDescriptor> D_field = D->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> D_field = D->createFieldDescriptor(logger).first;
Rooted<StructuredClass> E{new StructuredClass(
mgr, "E", domain, Cardinality::any(), nullptr, true, false)};
D_field->addChild(E);
Rooted<StructuredClass> F{new StructuredClass(
mgr, "E", domain, Cardinality::any(), E, true, false)};
Rooted<FieldDescriptor> F_field =
- F->createPrimitiveFieldDescriptor(sys->getStringType(), logger);
+ F->createPrimitiveFieldDescriptor(sys->getStringType(), logger).first;
// now we should find both primitive fields, but the C field first.
fields = A->getDefaultFields();
@@ -436,7 +436,7 @@ TEST(Domain, validate)
ASSERT_TRUE(domain->validate(logger));
// Let's add a primitive field (without a primitive type at first)
Rooted<FieldDescriptor> base_field =
- base->createPrimitiveFieldDescriptor(nullptr, logger);
+ base->createPrimitiveFieldDescriptor(nullptr, logger).first;
// this should not be valid.
ASSERT_EQ(ValidationState::UNKNOWN, domain->getValidationState());
ASSERT_FALSE(domain->validate(logger));
@@ -464,7 +464,8 @@ TEST(Domain, validate)
ASSERT_TRUE(domain->validate(logger));
ASSERT_EQ(base, sub->getSuperclass());
// add a non-primitive field to the child class.
- Rooted<FieldDescriptor> sub_field = sub->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> sub_field =
+ sub->createFieldDescriptor(logger).first;
// this should not be valid because we allow no children.
ASSERT_EQ(ValidationState::UNKNOWN, domain->getValidationState());
ASSERT_FALSE(domain->validate(logger));
@@ -489,8 +490,9 @@ TEST(Domain, validate)
ASSERT_EQ(ValidationState::UNKNOWN, domain->getValidationState());
ASSERT_TRUE(domain->validate(logger));
// It should be invalid if we set another TREE field.
- Rooted<FieldDescriptor> sub_field2 = sub->createFieldDescriptor(
- logger, FieldDescriptor::FieldType::TREE, "test", false);
+ Rooted<FieldDescriptor> sub_field2 =
+ sub->createFieldDescriptor(logger, FieldDescriptor::FieldType::TREE,
+ "test", false).first;
ASSERT_EQ(ValidationState::UNKNOWN, domain->getValidationState());
ASSERT_FALSE(domain->validate(logger));
// but valid again if we remove it
@@ -499,4 +501,4 @@ TEST(Domain, validate)
ASSERT_TRUE(domain->validate(logger));
}
}
-}
+} \ No newline at end of file
diff --git a/test/core/model/TestAdvanced.hpp b/test/core/model/TestAdvanced.hpp
index 27f33cc..8e81554 100644
--- a/test/core/model/TestAdvanced.hpp
+++ b/test/core/model/TestAdvanced.hpp
@@ -66,7 +66,7 @@ static Rooted<Domain> constructHeadingDomain(Manager &mgr,
for (auto &s : secclasses) {
Rooted<StructuredClass> desc = resolveDescriptor(bookDomain, s);
Rooted<FieldDescriptor> heading_field = desc->createFieldDescriptor(
- logger, FieldDescriptor::FieldType::SUBTREE, "heading", true);
+ logger, FieldDescriptor::FieldType::SUBTREE, "heading", true).first;
heading_field->addChild(heading);
}
return domain;
diff --git a/test/core/model/TestDomain.hpp b/test/core/model/TestDomain.hpp
index c107a0d..779ef03 100644
--- a/test/core/model/TestDomain.hpp
+++ b/test/core/model/TestDomain.hpp
@@ -42,7 +42,8 @@ static Rooted<Domain> constructBookDomain(Manager &mgr,
mgr, "book", domain, single, {nullptr}, false, true)};
// The structure field of it.
- Rooted<FieldDescriptor> book_field = book->createFieldDescriptor(logger);
+ Rooted<FieldDescriptor> book_field =
+ book->createFieldDescriptor(logger).first;
// From there on the "section".
Rooted<StructuredClass> section{
@@ -51,7 +52,7 @@ static Rooted<Domain> constructBookDomain(Manager &mgr,
// And the field of it.
Rooted<FieldDescriptor> section_field =
- section->createFieldDescriptor(logger);
+ section->createFieldDescriptor(logger).first;
// We also add the "paragraph", which is transparent.
Rooted<StructuredClass> paragraph{new StructuredClass(
@@ -61,7 +62,7 @@ static Rooted<Domain> constructBookDomain(Manager &mgr,
// And the field of it.
Rooted<FieldDescriptor> paragraph_field =
- paragraph->createFieldDescriptor(logger);
+ paragraph->createFieldDescriptor(logger).first;
// We append "subsection" to section.
Rooted<StructuredClass> subsection{
@@ -70,7 +71,7 @@ static Rooted<Domain> constructBookDomain(Manager &mgr,
// And the field of it.
Rooted<FieldDescriptor> subsection_field =
- subsection->createFieldDescriptor(logger);
+ subsection->createFieldDescriptor(logger).first;
// and we add the paragraph to subsections fields
subsection_field->addChild(paragraph);
@@ -82,10 +83,11 @@ static Rooted<Domain> constructBookDomain(Manager &mgr,
// ... and has a primitive field.
Rooted<FieldDescriptor> text_field =
- text->createPrimitiveFieldDescriptor(sys->getStringType(), logger);
+ text->createPrimitiveFieldDescriptor(sys->getStringType(), logger)
+ .first;
return domain;
}
}
-#endif /* _TEST_DOMAIN_HPP_ */
+#endif /* _TEST_DOMAIN_HPP_ */ \ No newline at end of file