summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/model/Document.cpp8
-rw-r--r--src/core/model/Domain.cpp61
-rw-r--r--src/core/model/Domain.hpp23
-rw-r--r--src/core/model/Typesystem.cpp28
-rw-r--r--src/core/model/Typesystem.hpp34
-rw-r--r--test/core/model/DomainTest.cpp72
6 files changed, 84 insertions, 142 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index f40e452..e43337f 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -93,18 +93,14 @@ static Rooted<StructuredClass> resolveDescriptor(
// iterate over all domains.
for (auto &d : domains) {
// use the actual resolve method.
- std::vector<Rooted<Managed>> resolved = d->resolve(className);
+ std::vector<ResolutionResult> resolved = d->resolve(className, typeOf<StructuredClass>());
// if we don't find anything, continue.
if (resolved.size() == 0) {
continue;
}
// Otherwise take the first valid result.
for (auto &r : resolved) {
- Managed *m = &(*r);
- StructuredClass *c = dynamic_cast<StructuredClass *>(m);
- if (c != nullptr) {
- return Rooted<StructuredClass>(c);
- }
+ return r.node.cast<StructuredClass>();
}
}
return {nullptr};
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index e2aaba4..f03bd7a 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -23,59 +23,28 @@
namespace ousia {
namespace model {
-void FieldDescriptor::doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path,
- Filter filter, void *filterData, unsigned idx,
- VisitorSet &visited)
-{
- // We call resolve for the children, but give them the field name as
- // alias.
- for (auto &c : children) {
- c->resolve(res, path, filter, filterData, idx, visited, &getNameRef());
- }
-}
+/* Class FieldDescriptor */
-// TODO: better alias?
-static std::string DESCRIPTOR_ATTRIBUTES_ALIAS{"attributes"};
+/* Class Descriptor */
-void Descriptor::doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx, VisitorSet &visited)
+void Descriptor::continueResolve(ResolutionState &state)
{
- // TODO: This could be a problem, because the name of the field might be
- // needed in the path.
- for (auto &fd : fieldDescriptors) {
- fd->resolve(res, path, filter, filterData, idx, visited, nullptr);
- }
- // TODO: This throws a SEGFAULT for some reason.
- // attributesDescriptor->resolve(res, path, filter, filterData, idx,
- // visited,
- // &DESCRIPTOR_ATTRIBUTES_ALIAS);
+ const NodeVector<Attribute> &attributes =
+ attributesDescriptor->getAttributes();
+ continueResolveComposita(attributes, attributes.getIndex(), state);
+ continueResolveComposita(fieldDescriptors, fieldDescriptors.getIndex(),
+ state);
}
-void StructuredClass::doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path,
- Filter filter, void *filterData, unsigned idx,
- VisitorSet &visited)
-{
- Descriptor::doResolve(res, path, filter, filterData, idx, visited);
- if (!isa.isNull()) {
- isa->doResolve(res, path, filter, filterData, idx, visited);
- }
-}
+/* Class Domain */
-void Domain::doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx, VisitorSet &visited)
+void Domain::continueResolve(ResolutionState &state)
{
- for (auto &s : structureClasses) {
- s->resolve(res, path, filter, filterData, idx, visited, nullptr);
- }
- for (auto &a : annotationClasses) {
- a->resolve(res, path, filter, filterData, idx, visited, nullptr);
- }
- for (auto &t : typesystems) {
- t->resolve(res, path, filter, filterData, idx, visited, nullptr);
+ if (!continueResolveComposita(structureClasses, structureClasses.getIndex(),
+ state) |
+ continueResolveComposita(annotationClasses,
+ annotationClasses.getIndex(), state)) {
+ continueResolveReferences(typesystems, state);
}
}
}
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 6995d14..18ebfb4 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -254,12 +254,6 @@ private:
FieldType fieldType;
Owned<Type> primitiveType;
-protected:
- void doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx,
- VisitorSet &visited) override;
-
public:
const bool optional;
@@ -310,7 +304,6 @@ public:
: Node(mgr, std::move(name), parent),
children(this),
fieldType(fieldType),
- // TODO: What would be a wise initialization of the primitiveType?
optional(optional)
{
}
@@ -360,10 +353,7 @@ private:
NodeVector<FieldDescriptor> fieldDescriptors;
protected:
- void doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx,
- VisitorSet &visited) override;
+ void continueResolve(ResolutionState &state) override;
public:
Descriptor(Manager &mgr, std::string name, Handle<Domain> domain,
@@ -467,12 +457,6 @@ private:
Owned<StructuredClass> isa;
NodeVector<FieldDescriptor> parents;
-protected:
- void doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx,
- VisitorSet &visited) override;
-
public:
const bool transparent;
// TODO: Is it possible to have root=true and cardinality other than 1?
@@ -553,10 +537,7 @@ private:
NodeVector<Typesystem> typesystems;
protected:
- void doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx,
- VisitorSet &visited) override;
+ void continueResolve(ResolutionState &state) override;
public:
Domain(Manager &mgr, Handle<SystemTypesystem> sys, std::string name)
diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp
index a852294..f082f39 100644
--- a/src/core/model/Typesystem.cpp
+++ b/src/core/model/Typesystem.cpp
@@ -318,20 +318,19 @@ 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> parentStructure, 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;
+ if (parentStructure != nullptr) {
+ attributeNames = parentStructure->attributeNames;
+ collectedAttributes = parentStructure->attributes;
}
// Check the attributes for validity and uniqueness
@@ -348,10 +347,11 @@ Rooted<StructType> StructType::createValidated(Manager &mgr, std::string name,
if (!res.second) {
logger.error(std::string("Attribute with name \"") + attrName +
std::string("\" defined multiple times"));
- if (parent != nullptr && parent->indexOf(attrName) >= 0) {
+ if (parentStructure != nullptr &&
+ parentStructure->indexOf(attrName) >= 0) {
logger.note(std::string("Attribute \"") + attrName +
std::string("\" was defined in parent class \"") +
- parent->getName() + std::string("\""));
+ parentStructure->getName() + std::string("\""));
}
}
@@ -360,8 +360,8 @@ Rooted<StructType> StructType::createValidated(Manager &mgr, std::string name,
}
// Call the private constructor
- return new StructType(mgr, name, system, parent, collectedAttributes,
- attributeNames);
+ return new StructType(mgr, name, system, parentStructure,
+ collectedAttributes, attributeNames);
}
Variant StructType::create() const
@@ -383,8 +383,8 @@ bool StructType::derivedFrom(Handle<StructType> other) const
if (other == this) {
return true;
}
- if (parent != nullptr) {
- return parent->derivedFrom(other);
+ if (parentStructure != nullptr) {
+ return parentStructure->derivedFrom(other);
}
return false;
}
diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp
index b492b25..c0e0fb1 100644
--- a/src/core/model/Typesystem.hpp
+++ b/src/core/model/Typesystem.hpp
@@ -432,7 +432,7 @@ private:
* Reference to the parent structure type (or nullptr if the struct type is
* not derived from any other struct type).
*/
- const Owned<StructType> parent;
+ const Owned<StructType> parentStructure;
/**
* Vector containing references to all attribute descriptors.
@@ -530,15 +530,16 @@ private:
* @param name is the name of the EnumType instance. Should be a valid
* identifier.
* @param system is a reference to the parent Typesystem instance.
- * @param parent is a reference to the StructType this type is derived from,
- * may be nullptr.
+ * @param parentStructure is a reference to the StructType this type is
+ * derived from, may be nullptr.
* @param attributes is a vector containing the struct type attributes.
*/
StructType(Manager &mgr, std::string name, Handle<Typesystem> system,
- Handle<StructType> parent, NodeVector<Attribute> attributes,
+ Handle<StructType> parentStructure,
+ NodeVector<Attribute> attributes,
std::map<std::string, size_t> attributeNames)
: Type(mgr, std::move(name), system, false),
- parent(acquire(parent)),
+ parentStructure(acquire(parentStructure)),
attributes(this, std::move(attributes)),
attributeNames(std::move(attributeNames))
{
@@ -569,18 +570,17 @@ public:
* @param name is the name of the EnumType instance. Should be a valid
* identifier.
* @param system is a reference to the parent Typesystem instance.
- * @param parent is a reference to the StructType this type is derived from,
- * may be nullptr.
+ * @param parentStructure is a reference to the StructType this type is
+ * derived from, may be nullptr.
* @param attributes is a vector containing the struct type attributes.
* The attributes are checked for validity (their names must be a valid
* identifiers) and uniqueness (each value must exist exactly once).
* @param logger is the Logger instance into which errors should be written.
*/
- static Rooted<StructType> createValidated(Manager &mgr, std::string name,
- Handle<Typesystem> system,
- Handle<StructType> parent,
- NodeVector<Attribute> attributes,
- Logger &logger);
+ static Rooted<StructType> createValidated(
+ Manager &mgr, std::string name, Handle<Typesystem> system,
+ Handle<StructType> parentStructure, NodeVector<Attribute> attributes,
+ Logger &logger);
/**
* Creates a Variant containing a valid representation of a data instance of
@@ -618,7 +618,14 @@ public:
* @return a rooted handle pointing at the parent type or nullptr, if this
* struct type has no parent.
*/
- Rooted<StructType> getParent() const { return parent; }
+ Rooted<StructType> getParentStructure() const { return parentStructure; }
+
+ /**
+ * Returns a reference at the list containing all attributes.
+ *
+ * @return a const reference pointing at the attribute list.
+ */
+ const NodeVector<Attribute> &getAttributes() const { return attributes; }
/**
* Returns the index of the given attribute in a data array representing
@@ -973,7 +980,6 @@ extern const Rtti<model::Typesystem> Typesystem;
* Type information for the SystemTypesystem class.
*/
extern const Rtti<model::SystemTypesystem> SystemTypesystem;
-
}
}
diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp
index f937842..9cd5bec 100644
--- a/test/core/model/DomainTest.cpp
+++ b/test/core/model/DomainTest.cpp
@@ -28,19 +28,14 @@
namespace ousia {
namespace model {
-void assert_path(std::vector<Rooted<Managed>> &result, size_t idx,
- const RttiBase &expected_type,
+void assert_path(const ResolutionResult &res, const RttiBase &expected_type,
std::vector<std::string> expected_path)
{
- ASSERT_TRUE(result.size() > idx);
- // check class/type
- ASSERT_TRUE(result[idx]->isa(expected_type));
- // cast to node
- Rooted<Node> n = result[idx].cast<Node>();
- // extract actual path
- std::vector<std::string> actual_path = n->path();
- // check path
- ASSERT_EQ(expected_path, actual_path);
+ // Check class/type
+ ASSERT_TRUE(res.node->isa(expected_type));
+
+ // Check path
+ ASSERT_EQ(expected_path, res.node->path());
}
TEST(Domain, testDomainResolving)
@@ -52,43 +47,38 @@ TEST(Domain, testDomainResolving)
// Get the domain.
Rooted<Domain> domain = constructBookDomain(mgr, sys, logger);
- /*
- * Start with the "book" search keyword. This should resolve to the domain
- * itself (because it is called "book"), as well as the structure "book"
- * node.
- */
- std::vector<Rooted<Managed>> res =
- domain->resolve(std::vector<std::string>{"book"});
+ std::vector<ResolutionResult> res;
+
+ // There is one domain called "book"
+ res = domain->resolve("book", typeOf<Domain>());
+ ASSERT_EQ(1U, res.size());
+ assert_path(res[0], typeOf<Domain>(), {"book"});
- // First we expect the book domain.
- assert_path(res, 0, typeOf<Domain>(), {"book"});
- // Then the book structure.
- assert_path(res, 1, typeOf<StructuredClass>(), {"book", "book"});
- ASSERT_EQ(2, res.size());
+ // There is one domain called "book"
+ res = domain->resolve("book", typeOf<StructuredClass>());
+ ASSERT_EQ(1U, res.size());
+ assert_path(res[0], typeOf<StructuredClass>(), {"book", "book"});
// If we explicitly ask for the "book, book" path, then only the
// StructuredClass should be returned.
- res = domain->resolve(std::vector<std::string>{"book", "book"});
- assert_path(res, 0, typeOf<StructuredClass>(), {"book", "book"});
- ASSERT_EQ(1, res.size());
+ res = domain->resolve(std::vector<std::string>{"book", "book"},
+ typeOf<Domain>());
+ ASSERT_EQ(0U, res.size());
+
+ res = domain->resolve(std::vector<std::string>{"book", "book"},
+ typeOf<StructuredClass>());
+ ASSERT_EQ(1U, res.size());
// If we ask for "section" the result should be unique as well.
- res = domain->resolve(std::vector<std::string>{"section"});
- // TODO: Is that the path result we want?
- assert_path(res, 0, typeOf<StructuredClass>(), {"book", "section"});
- ASSERT_EQ(1, res.size());
-
- // If we ask for the path "book", "book", "" we reference the
- // FieldDescriptor of the StructuredClass "book".
- res = domain->resolve(std::vector<std::string>{"book", "book", ""});
- assert_path(res, 0, typeOf<FieldDescriptor>(), {"book", "book", ""});
- ASSERT_EQ(1, res.size());
-
- // If we ask for "paragraph" it is references two times in the Domain graph,
+ res = domain->resolve("section", typeOf<StructuredClass>());
+ ASSERT_EQ(1U, res.size());
+ assert_path(res[0], typeOf<StructuredClass>(), {"book", "section"});
+
+ // If we ask for "paragraph" it is referenced two times in the Domain graph,
// but should be returned only once.
- res = domain->resolve("paragraph");
- assert_path(res, 0, typeOf<StructuredClass>(), {"book", "paragraph"});
- ASSERT_EQ(1, res.size());
+ res = domain->resolve("paragraph", typeOf<StructuredClass>());
+ ASSERT_EQ(1U, res.size());
+ assert_path(res[0], typeOf<StructuredClass>(), {"book", "paragraph"});
}
}
}