diff options
-rw-r--r-- | src/core/model/Domain.cpp | 49 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 31 | ||||
-rw-r--r-- | src/core/parser/stack/DocumentHandler.cpp | 2 | ||||
-rw-r--r-- | src/core/parser/stack/DomainHandler.cpp | 60 | ||||
-rw-r--r-- | test/core/model/DocumentTest.cpp | 8 | ||||
-rw-r--r-- | test/core/model/DomainTest.cpp | 30 | ||||
-rw-r--r-- | test/core/model/TestAdvanced.hpp | 2 | ||||
-rw-r--r-- | test/core/model/TestDomain.hpp | 14 |
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 |