summaryrefslogtreecommitdiff
path: root/src/core/model/Domain.cpp
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-13 23:46:31 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-13 23:46:31 +0100
commit04e64790c24f3665bdc7d0720d23079551565ba2 (patch)
tree7dc3cbdd319bd6b15d16e32f87fdd07384d7eef5 /src/core/model/Domain.cpp
parentc5345f13b3d33630d3e3d0021f10945627ae6e2d (diff)
parentc6b502d45d2bf916f747411df37df186c4ed4981 (diff)
Merge branch 'master' of somweyr.de:ousia
Diffstat (limited to 'src/core/model/Domain.cpp')
-rw-r--r--src/core/model/Domain.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index 17b1d2d..1fb057e 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -17,6 +17,7 @@
*/
#include <core/common/Rtti.hpp>
+#include <core/common/Exceptions.hpp>
#include "Domain.hpp"
@@ -38,6 +39,79 @@ void Descriptor::continueResolve(ResolutionState &state)
state);
}
+std::vector<Rooted<Node>> Descriptor::pathTo(
+ Handle<StructuredClass> target) const
+{
+ std::vector<Rooted<Node>> path;
+ continuePath(target, path);
+ return path;
+}
+
+static bool pathEquals(const Descriptor& a, const Descriptor& b)
+{
+ // We assume that two Descriptors are equal if their names and domain names
+ // are equal.
+ if (a.getName() != b.getName()) {
+ return false;
+ }
+ Handle<Domain> aDom = a.getParent().cast<Domain>();
+ Handle<Domain> bDom = b.getParent().cast<Domain>();
+ return aDom->getName() == bDom->getName();
+}
+
+//TODO: isa-handling.
+bool Descriptor::continuePath(Handle<StructuredClass> target,
+ std::vector<Rooted<Node>> &path) const
+{
+ // look if our current node is reachable using the parent references
+ for (auto &pfd : target->getParents()) {
+ Handle<Descriptor> p = pfd->getParent().cast<Descriptor>();
+ if (pathEquals(*this, *p)) {
+ // if we have made the connection, stop the search.
+ path.push_back(pfd);
+ return true;
+ }
+ // look for transparent intermediate nodes.
+ if (!p->isa(RttiTypes::StructuredClass)) {
+ continue;
+ }
+ Handle<StructuredClass> pc = p.cast<StructuredClass>();
+ if (pc->transparent) {
+ // recursion
+ std::vector<Rooted<Node>> cPath = path;
+ if (continuePath(pc, cPath)) {
+ path = std::move(cPath);
+ path.push_back(pc);
+ path.push_back(pfd);
+ return true;
+ }
+ }
+ }
+ // use recursive depth-first search from the top to reach the given child
+ for (auto &fd : fieldDescriptors) {
+ for (auto &c : fd->getChildren()) {
+ if (pathEquals(*c, *target)) {
+ // if we have made the connection, stop the search.
+ path.push_back(fd);
+ return true;
+ }
+ // look for transparent intermediate nodes.
+ if (c->transparent) {
+ // copy the path.
+ std::vector<Rooted<Node>> cPath = path;
+ cPath.push_back(fd);
+ cPath.push_back(c);
+ // recursion.
+ if (c->continuePath(target, cPath)) {
+ path = std::move(cPath);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
/* Class Domain */
void Domain::continueResolve(ResolutionState &state)