diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-09 14:55:10 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2015-01-09 14:55:10 +0100 |
commit | b7f67dc04857e8d303f94cbfa246a10bcfec4817 (patch) | |
tree | cb05a161e2bba6f94784bc241b6bfe1457817c47 /src/core/model | |
parent | 4b8f07b478015196de3db8dbaf91e176cdc4a6f0 (diff) |
Added new unit tests for the Node.resolve function and fixed the behaviour for not following references if a compositum was found
Diffstat (limited to 'src/core/model')
-rw-r--r-- | src/core/model/Node.cpp | 98 |
1 files changed, 56 insertions, 42 deletions
diff --git a/src/core/model/Node.cpp b/src/core/model/Node.cpp index d12e92b..930fbff 100644 --- a/src/core/model/Node.cpp +++ b/src/core/model/Node.cpp @@ -102,57 +102,52 @@ public: * resolving Node instances by name. */ class ResolutionState { -private: - /** - * Constructor of the ResolutionState class. - * - * @param shared is the shared, path independent state. - * @param resolutionRoot is the current resolution root node. - */ - ResolutionState(SharedResolutionState &shared, int idx, - Node *resolutionRoot) - : shared(shared), idx(idx), resolutionRoot(resolutionRoot) - { - } - public: /** - * Constructor of the ResolutionState class. - * - * @param shared is the shared, path independent state. - * @param resolutionRoot is the current resolution root node. - */ - ResolutionState(SharedResolutionState &shared, - Node *resolutionRoot = nullptr, bool atStartNode = true) - : shared(shared), - idx(0), - resolutionRoot(resolutionRoot), - atStartNode(atStartNode) - { - } - - /** * Reference at the resolution state that is shared between the various * resolution paths. */ SharedResolutionState &shared; /** + * Current resolution root node or nullptr if no resolution root node has + * been set yet. + */ + Node *resolutionRoot; + + /** * Current index within the given path. */ int idx; /** - * Current resolution root node or nullptr if no resolution root node has - * been set yet. + * Set to true if the resolution currently is in the subtree in which the + * node resolution process was started (no reference boundary has been + * passed yet). */ - Node *resolutionRoot; + bool inStartTree; /** - * Set to true if the resolution currently is at the node at which the - * resolution process was started. + * Set to true, once a compositum has been found. */ - bool atStartNode; + bool foundCompositum; + + /** + * Constructor of the ResolutionState class. + * + * @param shared is the shared, path independent state. + * @param resolutionRoot is the current resolution root node. + */ + ResolutionState(SharedResolutionState &shared, + Node *resolutionRoot = nullptr, int idx = 0, + bool inStartTree = true) + : shared(shared), + resolutionRoot(resolutionRoot), + idx(idx), + inStartTree(inStartTree), + foundCompositum(false) + { + } /** * Adds a node to the result. @@ -193,21 +188,31 @@ public: */ bool typeMatches(const RttiBase &type) { return type.isa(shared.type); } + bool canContainType(const RttiBase &type) + { + return type.composedOf(shared.type); + } + const std::string ¤tName() { return shared.path[idx]; } ResolutionState advance() { - return ResolutionState{shared, idx + 1, resolutionRoot}; + return ResolutionState{shared, resolutionRoot, idx + 1, false}; } ResolutionState fork(Node *newResolutionRoot) { - return ResolutionState{shared, newResolutionRoot, false}; + return ResolutionState{shared, newResolutionRoot, 0, false}; } - bool canFollowReferences() { return idx == 0 && atStartNode; } + bool canFollowReferences() + { + return idx == 0 && inStartTree && !foundCompositum; + } bool canFollowComposita() { return idx == 0; } + + size_t resultCount() { return shared.result.size(); } }; /* Class Node */ @@ -249,7 +254,8 @@ bool Node::resolve(ResolutionState &state) { // Try to mark this note as visited, do nothing if already has been visited if (state.markVisited(this)) { - std::cout << "visiting " << name << std::endl; + std::cout << "visiting " << name << " (" << state.idx << ")" + << std::endl; // Add this node to the result if it matches the current description if (state.atEndOfPath()) { @@ -259,7 +265,9 @@ bool Node::resolve(ResolutionState &state) return true; } } else { + size_t resCount = state.resultCount(); continueResolve(state); + return state.resultCount() > resCount; } } return false; @@ -275,7 +283,10 @@ bool Node::continueResolveIndex(const Index &index, ResolutionState &state) Rooted<Node> h = index.resolve(state.currentName()); if (h != nullptr) { ResolutionState advancedState = state.advance(); - return h->resolve(advancedState); + if (h->resolve(advancedState)) { + state.foundCompositum = true; + return true; + } } return false; } @@ -287,6 +298,7 @@ bool Node::continueResolveCompositum(Handle<Node> h, ResolutionState &state) if (h->getName() == state.currentName()) { ResolutionState advancedState = state.advance(); if (h->resolve(advancedState)) { + state.foundCompositum = true; return true; } } @@ -302,8 +314,10 @@ bool Node::continueResolveCompositum(Handle<Node> h, ResolutionState &state) bool Node::continueResolveReference(Handle<Node> h, ResolutionState &state) { // We can only follow references if we currently are at the beginning of the - // path and this node is the root node - if (canFollowReferences(state)) { + // path and this node is the root node. Additionally only follow a reference + // if the node the reference points to is known to contain the type that is + // currently asked for in the resolution process + if (canFollowReferences(state) && state.canContainType(h->type())) { std::cout << "following reference to " << h->getName() << std::endl; ResolutionState forkedState = state.fork(this); return continueResolveCompositum(h, forkedState); @@ -321,7 +335,7 @@ std::vector<ResolutionResult> Node::resolve( // Kickstart the resolution process by treating this very node as compositum std::cout << "------------" << std::endl; std::cout << "resolving: "; - for (auto s: path) { + for (auto s : path) { std::cout << s << " "; } std::cout << " of type " << type.name << std::endl; |