From 641acc2bde4ca8fe807fea577d3c2a20a67849b6 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Sat, 26 Jul 2014 02:26:59 +0200 Subject: [PATCH] data: Moved EdgeComponent system to Token and extended it to cover all type specific Edge and Token fields This change moves the EdgeComponent system to Token and redefines them as TokenComponents. * Performance tests on the side showed that using typeid() in getComponent() is faster than dynamically casting every pointer. * The hasComponent() method was deliberately left out in the implementation, because it used to look up the right component and discard it again. This check for presence can also be achieved by just using getComponent(). * The method addComponent() is protected in Token, so that Node and Edge can guard which Component is set on which type by implementing specific setters for each Component. * The GraphTestSuite was extended to include tests for the Component implementation (and missing tests for locationIds in Token and copying of Node and Edge were added). --- bin/test/data/log/test_log.txt | 3 + src/lib/CMakeLists.txt | 16 +- src/lib/data/Storage.cpp | 118 +++++----- src/lib/data/Storage.h | 4 +- src/lib/data/graph/Edge.cpp | 111 ++++----- src/lib/data/graph/Edge.h | 57 +---- src/lib/data/graph/Graph.cpp | 69 ++++-- src/lib/data/graph/Graph.h | 10 +- src/lib/data/graph/Node.cpp | 144 ++++-------- src/lib/data/graph/Node.h | 31 +-- src/lib/data/graph/Token.cpp | 13 +- src/lib/data/graph/Token.h | 44 +++- .../graph/edgeComponent/EdgeComponent.cpp | 19 -- .../data/graph/edgeComponent/EdgeComponent.h | 23 -- .../edgeComponent/EdgeComponentDataType.cpp | 24 -- .../edgeComponent/EdgeComponentDataType.h | 25 -- .../graph/token_component/TokenComponent.cpp | 5 + .../graph/token_component/TokenComponent.h | 13 ++ .../token_component/TokenComponentAccess.cpp | 36 +++ .../token_component/TokenComponentAccess.h | 33 +++ .../token_component/TokenComponentConst.cpp | 6 + .../token_component/TokenComponentConst.h | 13 ++ .../TokenComponentDataType.cpp | 30 +++ .../token_component/TokenComponentDataType.h | 27 +++ .../TokenComponentSignature.cpp | 20 ++ .../token_component/TokenComponentSignature.h | 23 ++ .../token_component/TokenComponentStatic.cpp | 6 + .../token_component/TokenComponentStatic.h | 13 ++ src/test/GraphTestSuite.h | 218 +++++++++++++++--- 29 files changed, 711 insertions(+), 443 deletions(-) delete mode 100644 src/lib/data/graph/edgeComponent/EdgeComponent.cpp delete mode 100644 src/lib/data/graph/edgeComponent/EdgeComponent.h delete mode 100644 src/lib/data/graph/edgeComponent/EdgeComponentDataType.cpp delete mode 100644 src/lib/data/graph/edgeComponent/EdgeComponentDataType.h create mode 100644 src/lib/data/graph/token_component/TokenComponent.cpp create mode 100644 src/lib/data/graph/token_component/TokenComponent.h create mode 100644 src/lib/data/graph/token_component/TokenComponentAccess.cpp create mode 100644 src/lib/data/graph/token_component/TokenComponentAccess.h create mode 100644 src/lib/data/graph/token_component/TokenComponentConst.cpp create mode 100644 src/lib/data/graph/token_component/TokenComponentConst.h create mode 100644 src/lib/data/graph/token_component/TokenComponentDataType.cpp create mode 100644 src/lib/data/graph/token_component/TokenComponentDataType.h create mode 100644 src/lib/data/graph/token_component/TokenComponentSignature.cpp create mode 100644 src/lib/data/graph/token_component/TokenComponentSignature.h create mode 100644 src/lib/data/graph/token_component/TokenComponentStatic.cpp create mode 100644 src/lib/data/graph/token_component/TokenComponentStatic.h diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index 988d0b56..cd08873e 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -1,4 +1,7 @@ ConfigManager.cpp ERROR: value path/to/nowhere is not present in config. +Token.cpp ERROR: Location Id was not referenced by this Token. +Node.cpp WARNING: Changing NodeType after it was already set, from namespace to class +Edge.cpp ERROR: Nodes are not plain copies. Graph.cpp ERROR: Can't remove member edge, without removing the child node. TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index fd674434..edb582c6 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -71,10 +71,18 @@ add_files( data/access/GraphAccessProxy.cpp data/access/GraphAccessProxy.h - data/graph/edgeComponent/EdgeComponent.cpp - data/graph/edgeComponent/EdgeComponent.h - data/graph/edgeComponent/EdgeComponentDataType.cpp - data/graph/edgeComponent/EdgeComponentDataType.h + data/graph/token_component/TokenComponent.cpp + data/graph/token_component/TokenComponent.h + data/graph/token_component/TokenComponentAccess.cpp + data/graph/token_component/TokenComponentAccess.h + data/graph/token_component/TokenComponentConst.cpp + data/graph/token_component/TokenComponentConst.h + data/graph/token_component/TokenComponentDataType.cpp + data/graph/token_component/TokenComponentDataType.h + data/graph/token_component/TokenComponentSignature.cpp + data/graph/token_component/TokenComponentSignature.h + data/graph/token_component/TokenComponentStatic.cpp + data/graph/token_component/TokenComponentStatic.h data/graph/Edge.cpp data/graph/Edge.h diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 157cdfe9..808f31ab 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -1,6 +1,8 @@ #include "data/Storage.h" -#include "data/graph/edgeComponent/EdgeComponentDataType.h" +#include "data/graph/token_component/TokenComponentConst.h" +#include "data/graph/token_component/TokenComponentDataType.h" +#include "data/graph/token_component/TokenComponentStatic.h" #include "data/location/TokenLocation.h" #include "data/location/TokenLocationFile.h" #include "data/location/TokenLocationLine.h" @@ -41,12 +43,9 @@ void Storage::onTypedefParsed( ){ log("typedef", fullName + " -> " + underlyingType.getFullTypeName(), location); - Node* node = m_graph.createNodeHierarchy(fullName); - node->setType(Node::NODE_TYPEDEF); - node->setAccess(convertAccessType(access)); - + Node* node = m_graph.createNodeHierarchy(Node::NODE_TYPEDEF, fullName); + addAccess(node, access); addTokenLocation(node, location); - addTypeEdge(node, Edge::EDGE_TYPEDEF_OF, underlyingType); } @@ -54,10 +53,8 @@ void Storage::onClassParsed(const ParseLocation& location, const std::string& fu { log("class", fullName, location); - Node* node = m_graph.createNodeHierarchy(fullName); - node->setType(Node::NODE_CLASS); - node->setAccess(convertAccessType(access)); - + Node* node = m_graph.createNodeHierarchy(Node::NODE_CLASS, fullName); + addAccess(node, access); addTokenLocation(node, location); } @@ -65,10 +62,8 @@ void Storage::onStructParsed(const ParseLocation& location, const std::string& f { log("struct", fullName, location); - Node* node = m_graph.createNodeHierarchy(fullName); - node->setType(Node::NODE_STRUCT); - node->setAccess(convertAccessType(access)); - + Node* node = m_graph.createNodeHierarchy(Node::NODE_STRUCT, fullName); + addAccess(node, access); addTokenLocation(node, location); } @@ -76,12 +71,14 @@ void Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseV { log("global", variable.fullName, location); - Node* node = m_graph.createNodeHierarchy(variable.fullName); - node->setType(Node::NODE_GLOBAL_VARIABLE); - node->setStatic(variable.isStatic); + Node* node = m_graph.createNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, variable.fullName); + + if (variable.isStatic) + { + node->addComponentStatic(std::make_shared()); + } addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type); - addTokenLocation(node, location); } @@ -89,19 +86,21 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable& { log("field", variable.fullName, location); - Node* node = m_graph.createNodeHierarchy(variable.fullName); - node->setType(Node::NODE_FIELD); - node->setStatic(variable.isStatic); + Node* node = m_graph.createNodeHierarchy(Node::NODE_FIELD, variable.fullName); + + if (variable.isStatic) + { + node->addComponentStatic(std::make_shared()); + } if (access == ACCESS_NONE) { LOG_ERROR("Field needs to have access type [public, protected, private] but has none."); return; } - node->setAccess(convertAccessType(access)); + addAccess(node, access); addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type); - addTokenLocation(node, location); } @@ -113,11 +112,9 @@ void Storage::onFunctionParsed( log("function", fullName, location); Node* node = m_graph.createNodeHierarchyWithDistinctSignature( - fullName, + Node::NODE_FUNCTION, fullName, ParserClient::functionSignatureStr(returnType.type, fullName, parameters, false) ); - node->setType(Node::NODE_FUNCTION); - addTokenLocation(node, location); addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType); @@ -136,20 +133,26 @@ void Storage::onMethodParsed( log("method", fullName, location); Node* node = m_graph.createNodeHierarchyWithDistinctSignature( - fullName, + Node::NODE_METHOD, fullName, ParserClient::functionSignatureStr(returnType.type, fullName, parameters, isConst) ); - node->setType(Node::NODE_METHOD); - node->setConst(isConst); - node->setStatic(isStatic); + if (isConst) + { + node->addComponentConst(std::make_shared()); + } + + if (isStatic) + { + node->addComponentStatic(std::make_shared()); + } if (access == ACCESS_NONE) { LOG_ERROR("Method needs to have access type [public, protected, private] but has none."); return; } - node->setAccess(convertAccessType(access)); + addAccess(node, access); addTokenLocation(node, location); @@ -164,9 +167,7 @@ void Storage::onNamespaceParsed(const ParseLocation& location, const std::string { log("namespace", fullName, location); - Node* node = m_graph.createNodeHierarchy(fullName); - node->setType(Node::NODE_NAMESPACE); - + Node* node = m_graph.createNodeHierarchy(Node::NODE_NAMESPACE, fullName); addTokenLocation(node, location); } @@ -174,10 +175,8 @@ void Storage::onEnumParsed(const ParseLocation& location, const std::string& ful { log("enum", fullName, location); - Node* node = m_graph.createNodeHierarchy(fullName); - node->setType(Node::NODE_ENUM); - node->setAccess(convertAccessType(access)); - + Node* node = m_graph.createNodeHierarchy(Node::NODE_ENUM, fullName); + addAccess(node, access); addTokenLocation(node, location); } @@ -185,9 +184,7 @@ void Storage::onEnumFieldParsed(const ParseLocation& location, const std::string { log("enum field", fullName, location); - Node* node = m_graph.createNodeHierarchy(fullName); - node->setType(Node::NODE_FIELD); - + Node* node = m_graph.createNodeHierarchy(Node::NODE_FIELD, fullName); addTokenLocation(node, location); } @@ -200,7 +197,7 @@ void Storage::onInheritanceParsed( Node* baseNode = m_graph.createNodeHierarchy(baseName); Edge* edge = m_graph.createEdge(Edge::EDGE_INHERITANCE, node, baseNode); - edge->setAccess(convertAccessType(access)); + edge->addComponentAccess(std::make_shared(convertAccessType(access))); addTokenLocation(edge, location); } @@ -448,26 +445,46 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile( return ret; } -Edge::AccessType Storage::convertAccessType(ParserClient::AccessType access) const +TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const { switch (access) { case ACCESS_PUBLIC: - return Edge::ACCESS_PUBLIC; + return TokenComponentAccess::ACCESS_PUBLIC; case ACCESS_PROTECTED: - return Edge::ACCESS_PROTECTED; + return TokenComponentAccess::ACCESS_PROTECTED; case ACCESS_PRIVATE: - return Edge::ACCESS_PRIVATE; + return TokenComponentAccess::ACCESS_PRIVATE; case ACCESS_NONE: - return Edge::ACCESS_NONE; + return TokenComponentAccess::ACCESS_NONE; } } +TokenComponentAccess* Storage::addAccess(Node* node, ParserClient::AccessType access) +{ + if (access != ACCESS_NONE) + { + std::shared_ptr ptr = std::make_shared(convertAccessType(access)); + node->getMemberEdge()->addComponentAccess(ptr); + return ptr.get(); + } + return nullptr; +} + Edge* Storage::addTypeEdge(Node* node, Edge::EdgeType edgeType, const DataType& type) { Node* typeNode = m_graph.createNodeHierarchy(type.getRawTypeName()); Edge* edge = m_graph.createEdge(edgeType, node, typeNode); - edge->addComponent(std::make_shared(type.getQualifierList(), type.getModifierStack())); + + // FIXME: When a function uses the same type multiple times then we still only use one edge to save this, + // but we can't store multiple DataTypes on this edge at the moment. + if (!edge->getComponent()) + { + edge->addComponentDataType( + std::make_shared(type.getQualifierList(), type.getModifierStack()) + ); + } + return edge; } @@ -478,10 +495,7 @@ Edge* Storage::addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeU return nullptr; } - const DataType& type = typeUsage.type; - Node* typeNode = m_graph.createNodeHierarchy(type.getRawTypeName()); - Edge* edge = m_graph.createEdge(edgeType, node, typeNode); - edge->addComponent(std::make_shared(type.getQualifierList(), type.getModifierStack())); + Edge* edge = addTypeEdge(node, edgeType, typeUsage.type); addTokenLocation(edge, typeUsage.location); return edge; diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 8244060b..4e45deac 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -7,6 +7,7 @@ #include "data/access/GraphAccess.h" #include "data/access/LocationAccess.h" #include "data/graph/Graph.h" +#include "data/graph/token_component/TokenComponentAccess.h" #include "data/location/TokenLocationCollection.h" #include "data/parser/ParserClient.h" @@ -87,7 +88,8 @@ public: ) const; private: - Edge::AccessType convertAccessType(ParserClient::AccessType access) const; + TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const; + TokenComponentAccess* addAccess(Node* node, ParserClient::AccessType access); Edge* addTypeEdge(Node* node, Edge::EdgeType edgeType, const DataType& type); Edge* addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeUsage& typeUsage); TokenLocation* addTokenLocation(Token* token, const ParseLocation& location); diff --git a/src/lib/data/graph/Edge.cpp b/src/lib/data/graph/Edge.cpp index 3359cb6d..0853c60a 100644 --- a/src/lib/data/graph/Edge.cpp +++ b/src/lib/data/graph/Edge.cpp @@ -3,45 +3,41 @@ #include #include "data/graph/Node.h" -#include "data/graph/edgeComponent/EdgeComponent.h" +#include "data/graph/token_component/TokenComponentAccess.h" +#include "data/graph/token_component/TokenComponentDataType.h" #include "utility/logging/logging.h" Edge::Edge(EdgeType type, Node* from, Node* to) : m_type(type) , m_from(from) , m_to(to) - , m_access(ACCESS_NONE) { m_from->addEdge(this); m_to->addEdge(this); } +Edge::Edge(const Edge& other, Node* from, Node* to) + : Token(other) + , m_type(other.m_type) + , m_from(from) + , m_to(to) +{ + m_from->addEdge(this); + m_to->addEdge(this); + + if (m_from == other.m_from || m_to == other.m_to || + m_from->getId() != other.m_from->getId() || m_to->getId() != other.m_to->getId()) + { + LOG_ERROR("Nodes are not plain copies."); + } +} + Edge::~Edge() { m_from->removeEdge(this); m_to->removeEdge(this); } -std::shared_ptr Edge::createPlainCopy(Node* from, Node* to) const -{ - if (from == m_from || to == m_to || from->getId() != m_from->getId() || to->getId() != m_to->getId()) - { - LOG_ERROR("Nodes are not plain copies."); - return nullptr; - } - - std::shared_ptr edge(new Edge(getId(), m_type, from, to)); - - edge->setAccess(m_access); - - for (std::shared_ptr component: m_components) - { - edge->addComponent(component->copy()); - } - - return edge; -} - Edge::EdgeType Edge::getType() const { return m_type; @@ -67,24 +63,37 @@ bool Edge::isEdge() const return true; } -Edge::AccessType Edge::getAccess() const +void Edge::addComponentAccess(std::shared_ptr component) { - return m_access; + if (getComponent()) + { + LOG_ERROR("TokenComponentAccess has been set before!"); + } + else if (m_type != EDGE_MEMBER && m_type != EDGE_INHERITANCE) + { + LOG_ERROR("TokenComponentAccess can't be set on edge of type: " + getTypeString()); + } + else + { + addComponent(component); + } } -void Edge::setAccess(AccessType access) +void Edge::addComponentDataType(std::shared_ptr component) { - if (access != ACCESS_NONE && m_type != EDGE_MEMBER && m_type != EDGE_INHERITANCE) + if (getComponent()) { - LOG_ERROR("Setting access on wrong edge type."); - return; + LOG_ERROR("TokenComponentDataType has been set before!"); } - - if (m_access != ACCESS_NONE && access != m_access) + else if (m_type != EDGE_TYPEDEF_OF && m_type != EDGE_TYPE_OF + && m_type != EDGE_RETURN_TYPE_OF && m_type != EDGE_PARAMETER_TYPE_OF) { - LOG_WARNING("Different AccessType was already set before."); + LOG_ERROR("TokenComponentDataType can't be set on edge of type: " + getTypeString()); + } + else + { + addComponent(component); } - m_access = access; } std::string Edge::getTypeString() const @@ -111,52 +120,20 @@ std::string Edge::getTypeString() const return ""; } -std::string Edge::getAccessString() const -{ - switch (m_access) - { - case ACCESS_PUBLIC: - return "public"; - case ACCESS_PROTECTED: - return "protected"; - case ACCESS_PRIVATE: - return "private"; - case ACCESS_NONE: - return ""; - } - return ""; -} - std::string Edge::getAsString() const { std::stringstream str; str << "[" << getId() << "] \"" << m_from->getName() << "\" " << getTypeString() << " \"" + m_to->getName() << "\""; - if (m_access != ACCESS_NONE) + TokenComponentAccess* component = getComponent(); + if (component) { - str << " " << getAccessString(); + str << " " << component->getAccessString(); } return str.str(); } -void Edge::addComponent(std::shared_ptr component) -{ - m_components.push_back(component); - component->setEdge(this); -} - -Edge::Edge(Id id, EdgeType type, Node* from, Node* to) - : Token(id) - , m_type(type) - , m_from(from) - , m_to(to) - , m_access(ACCESS_NONE) -{ - m_from->addEdge(this); - m_to->addEdge(this); -} - std::ostream& operator<<(std::ostream& ostream, const Edge& edge) { ostream << edge.getAsString(); diff --git a/src/lib/data/graph/Edge.h b/src/lib/data/graph/Edge.h index 4a15f202..344f9088 100644 --- a/src/lib/data/graph/Edge.h +++ b/src/lib/data/graph/Edge.h @@ -7,7 +7,8 @@ #include "data/graph/Token.h" class Node; -class EdgeComponent; +class TokenComponentAccess; +class TokenComponentDataType; class Edge: public Token { @@ -24,19 +25,10 @@ public: EDGE_TYPEDEF_OF }; - enum AccessType - { - ACCESS_PUBLIC, - ACCESS_PROTECTED, - ACCESS_PRIVATE, - ACCESS_NONE - }; - Edge(EdgeType type, Node* from, Node* to); + Edge(const Edge& other, Node* from, Node* to); virtual ~Edge(); - std::shared_ptr createPlainCopy(Node* from, Node* to) const; - EdgeType getType() const; Node* getFrom() const; @@ -46,58 +38,23 @@ public: virtual bool isNode() const; virtual bool isEdge() const; - // Additional field accessors for different EdgeTypes. - AccessType getAccess() const; - void setAccess(AccessType access); + // Component setters + void addComponentAccess(std::shared_ptr component); + void addComponentDataType(std::shared_ptr component); // Logging. std::string getTypeString() const; - std::string getAccessString() const; std::string getAsString() const; - - void addComponent(std::shared_ptr component); - - template - std::shared_ptr getComponent() const; - - template - bool hasComponent() const; - private: - // Constructor for plain copies. - Edge(Id id, EdgeType type, Node* from, Node* to); + void operator=(const Node&); const EdgeType m_type; Node* const m_from; Node* const m_to; - - // Additional fields for different EdgeTypes. - AccessType m_access; - - std::vector> m_components; }; -template -std::shared_ptr Edge::getComponent() const -{ - std::shared_ptr component; - for (std::shared_ptr c: m_components) - { - component = std::dynamic_pointer_cast(c); - if (component) - break; - } - return component; -} - -template -bool Edge::hasComponent() const -{ - return (getComponent()); -} - std::ostream& operator<<(std::ostream& ostream, const Edge& edge); #endif // EDGE_H diff --git a/src/lib/data/graph/Graph.cpp b/src/lib/data/graph/Graph.cpp index 28ed0b6e..0a679360 100644 --- a/src/lib/data/graph/Graph.cpp +++ b/src/lib/data/graph/Graph.cpp @@ -1,5 +1,6 @@ #include "data/graph/Graph.h" +#include "data/graph/token_component/TokenComponentSignature.h" #include "utility/logging/logging.h" #include "utility/utilityString.h" @@ -65,33 +66,52 @@ Token* Graph::getTokenById(Id id) const Node* Graph::createNodeHierarchy(const std::string& fullName) { - Node* node = getNode(fullName); - if (node) - { - return node; - } - - return insertNodeHierarchy(fullName); + return createNodeHierarchy(Node::NODE_UNDEFINED, fullName); } -Node* Graph::createNodeHierarchyWithDistinctSignature(const std::string& fullName, const std::string& signature) +Node* Graph::createNodeHierarchy(Node::NodeType type, const std::string& fullName) { Node* node = getNode(fullName); if (node) { - if (node->getSignature() == signature) + if (type != Node::NODE_UNDEFINED) { + node->setType(type); + } + return node; + } + + return insertNodeHierarchy(type, fullName); +} + +Node* Graph::createNodeHierarchyWithDistinctSignature(const std::string& fullName, const std::string& signature) +{ + return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED, fullName, signature); +} + +Node* Graph::createNodeHierarchyWithDistinctSignature( + Node::NodeType type, const std::string& fullName, const std::string& signature +){ + Node* node = getNode(fullName); + if (node) + { + if (node->getComponent()->getSignature() == signature) + { + if (type != Node::NODE_UNDEFINED) + { + node->setType(type); + } return node; } - node = insertNode(fullName, node->getParentNode()); + node = insertNode(type, fullName, node->getParentNode()); } else { - node = insertNodeHierarchy(fullName); + node = insertNodeHierarchy(type, fullName); } - node->setSignature(signature); + node->addComponentSignature(std::make_shared(signature)); return node; } @@ -268,7 +288,7 @@ Node* Graph::addNodeAsPlainCopy(Node* node) return n; } - std::shared_ptr copy = node->createPlainCopy(); + std::shared_ptr copy = std::make_shared(*node); m_nodes.push_back(copy); return copy.get(); } @@ -284,32 +304,39 @@ Edge* Graph::addEdgeAsPlainCopy(Edge* edge) Node* from = addNodeAsPlainCopy(edge->getFrom()); Node* to = addNodeAsPlainCopy(edge->getTo()); - std::shared_ptr copy = edge->createPlainCopy(from, to); + std::shared_ptr copy = std::make_shared(*edge, from, to); m_edges.push_back(copy); return copy.get(); } const std::string Graph::DELIMITER = "::"; -Node* Graph::insertNodeHierarchy(const std::string& fullName) +Node* Graph::insertNodeHierarchy(Node::NodeType type, const std::string& fullName) { Node* node = nullptr; std::vector names = utility::split(fullName, DELIMITER); std::string name; - for (std::vector::iterator it = names.begin(); it != names.end(); it++) + for (size_t i = 0; i < names.size(); i++) { - if (name.size() > 0) + if (i > 0) { name += DELIMITER; } - name += *it; + name += names[i]; Node* childNode = getNode(name); if (!childNode) { - childNode = insertNode(name, node); + if (i == names.size() - 1) + { + childNode = insertNode(type, name, node); + } + else + { + childNode = insertNode(Node::NODE_UNDEFINED, name, node); + } } node = childNode; @@ -318,9 +345,9 @@ Node* Graph::insertNodeHierarchy(const std::string& fullName) return node; } -Node* Graph::insertNode(const std::string& fullName, Node* parentNode) +Node* Graph::insertNode(Node::NodeType type, const std::string& fullName, Node* parentNode) { - std::shared_ptr nodePtr = std::make_shared(Node::NODE_UNDEFINED, fullName); + std::shared_ptr nodePtr = std::make_shared(type, fullName); m_nodes.push_back(nodePtr); Node* node = nodePtr.get(); diff --git a/src/lib/data/graph/Graph.h b/src/lib/data/graph/Graph.h index 4b64a548..fb264e6a 100644 --- a/src/lib/data/graph/Graph.h +++ b/src/lib/data/graph/Graph.h @@ -22,7 +22,13 @@ public: Token* getTokenById(Id id) const; Node* createNodeHierarchy(const std::string& fullName); + Node* createNodeHierarchy(Node::NodeType type, const std::string& fullName); + Node* createNodeHierarchyWithDistinctSignature(const std::string& fullName, const std::string& signature); + Node* createNodeHierarchyWithDistinctSignature( + Node::NodeType type, const std::string& fullName, const std::string& signature + ); + Edge* createEdge(Edge::EdgeType type, Node* from, Node* to); void removeNode(Node* node); @@ -48,8 +54,8 @@ protected: private: static const std::string DELIMITER; - Node* insertNodeHierarchy(const std::string& fullName); - Node* insertNode(const std::string& fullName, Node* parentNode); + Node* insertNodeHierarchy(Node::NodeType type, const std::string& fullName); + Node* insertNode(Node::NodeType type, const std::string& fullName, Node* parentNode); Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to); void removeEdgeInternal(Edge* edge); diff --git a/src/lib/data/graph/Node.cpp b/src/lib/data/graph/Node.cpp index 314d991c..ce91d567 100644 --- a/src/lib/data/graph/Node.cpp +++ b/src/lib/data/graph/Node.cpp @@ -2,13 +2,21 @@ #include +#include "data/graph/token_component/TokenComponentConst.h" +#include "data/graph/token_component/TokenComponentStatic.h" +#include "data/graph/token_component/TokenComponentSignature.h" #include "utility/logging/logging.h" Node::Node(NodeType type, const std::string& name) : m_type(type) , m_name(name) - , m_isConst(false) - , m_isStatic(false) +{ +} + +Node::Node(const Node& other) + : Token(other) + , m_type(other.m_type) + , m_name(other.m_name) { } @@ -16,16 +24,6 @@ Node::~Node() { } -std::shared_ptr Node::createPlainCopy() const -{ - std::shared_ptr node(new Node(getId(), m_type, m_name)); - - node->setConst(m_isConst); - node->setStatic(m_isStatic); - - return node; -} - Node::NodeType Node::getType() const { return m_type; @@ -33,11 +31,12 @@ Node::NodeType Node::getType() const void Node::setType(NodeType type) { - if (type != m_type && m_type != NODE_NAMESPACE && m_type != NODE_UNDEFINED) + if (type != m_type && m_type != NODE_UNDEFINED) { LOG_WARNING( "Changing NodeType after it was already set, from " + getTypeString(m_type) + " to " + getTypeString(type) ); + return; } m_type = type; } @@ -148,98 +147,52 @@ bool Node::isEdge() const return false; } -void Node::setAccess(Edge::AccessType access) +void Node::addComponentConst(std::shared_ptr component) { - if (access != Edge::ACCESS_NONE) + if (getComponent()) { - if (!getMemberEdge()) - { - LOG_WARNING("Can't set access on node " + getName() + ", because it is not a child."); - return; - } - getMemberEdge()->setAccess(access); + LOG_ERROR("TokenComponentConst has been set before!"); + } + else if (m_type != NODE_METHOD) + { + LOG_ERROR("TokenComponentConst can't be set on node of type: " + getTypeString(m_type)); + } + else + { + addComponent(component); } } -bool Node::isConst() const +void Node::addComponentStatic(std::shared_ptr component) { - return m_isConst; -} - -void Node::setConst(bool isConst) -{ - if (isConst && m_type != NODE_GLOBAL_VARIABLE && m_type != NODE_FIELD && m_type != NODE_METHOD) + if (getComponent()) { - LOG_ERROR("Setting const on wrong node of type " + getTypeString(m_type)); - return; + LOG_ERROR("TokenComponentStatic has been set before!"); } - - m_isConst = isConst; -} - -bool Node::isStatic() const -{ - return m_isStatic; -} - -void Node::setStatic(bool isStatic) -{ - if (isStatic && m_type != NODE_GLOBAL_VARIABLE && m_type != NODE_FIELD && m_type != NODE_METHOD) + else if (m_type != NODE_GLOBAL_VARIABLE && m_type != NODE_FIELD && m_type != NODE_FUNCTION && m_type != NODE_METHOD) { - LOG_ERROR("Setting static on wrong node of type " + getTypeString(m_type)); - return; + LOG_ERROR("TokenComponentStatic can't be set on node of type: " + getTypeString(m_type)); + } + else + { + addComponent(component); } - - m_isStatic = isStatic; } -std::string Node::getSignature() const +void Node::addComponentSignature(std::shared_ptr component) { - // Signature generation from edges failed, because parameter edges to same type are bundled. - // std::string str; - - // Edge* returnTypeEdge = findEdgeOfType(Edge::EDGE_RETURN_TYPE_OF); - // str += returnTypeEdge->getComponent()->getDataType().getFullTypeName() + " " + m_name + "("; - - // forEachEdgeOfType(Edge::EDGE_PARAMETER_TYPE_OF, - // [&str](Edge* edge) - // { - // str += edge->getComponent()->getDataType().getFullTypeName() + ", "; - // } - // ); - - // if (*str.rbegin() == ' ') - // { - // str.pop_back(); - // str.pop_back(); - // } - // str += ")"; - - // if (isConst()) - // { - // str += " const"; - // } - - // return str; - - return m_signature; -} - -void Node::setSignature(const std::string& signature) -{ - if (m_type != NODE_FUNCTION && m_type != NODE_METHOD && m_type != NODE_UNDEFINED) + if (getComponent()) { - LOG_ERROR("Signature is not supported on node of type " + getTypeString(m_type)); - return; + LOG_ERROR("TokenComponentSignature has been set before!"); } - - if (m_signature.size()) + else if (m_type != NODE_FUNCTION && m_type != NODE_METHOD) { - LOG_ERROR("Signature was already set before."); - return; + LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString(m_type)); + } + else + { + addComponent(component); } - - m_signature = signature; } std::string Node::getTypeString(NodeType type) const @@ -247,7 +200,7 @@ std::string Node::getTypeString(NodeType type) const switch (type) { case NODE_UNDEFINED: - return "type"; + return "undefined"; case NODE_CLASS: return "class"; case NODE_STRUCT: @@ -275,12 +228,12 @@ std::string Node::getAsString() const std::stringstream str; str << "[" << getId() << "] " << getTypeString(m_type) << ": " << "\"" << getName() << "\""; - if (isStatic()) + if (getComponent()) { str << " static"; } - if (isConst()) + if (getComponent()) { str << " const"; } @@ -288,15 +241,6 @@ std::string Node::getAsString() const return str.str(); } -Node::Node(Id id, NodeType type, const std::string& name) - : Token(id) - , m_type(type) - , m_name(name) - , m_isConst(false) - , m_isStatic(false) -{ -} - std::ostream& operator<<(std::ostream& ostream, const Node& node) { ostream << node.getAsString(); diff --git a/src/lib/data/graph/Node.h b/src/lib/data/graph/Node.h index 1e0526d1..dcfc9d5c 100644 --- a/src/lib/data/graph/Node.h +++ b/src/lib/data/graph/Node.h @@ -9,6 +9,10 @@ #include "data/graph/Edge.h" #include "data/graph/Token.h" +class TokenComponentConst; +class TokenComponentStatic; +class TokenComponentSignature; + class Node: public Token { public: @@ -27,10 +31,9 @@ public: }; Node(NodeType type, const std::string& name); + Node(const Node& other); virtual ~Node(); - std::shared_ptr createPlainCopy() const; - NodeType getType() const; void setType(NodeType type); @@ -54,36 +57,22 @@ public: virtual bool isNode() const; virtual bool isEdge() const; - // Additional field accessors for different NodeTypes. - void setAccess(Edge::AccessType access); - - bool isConst() const; - void setConst(bool isConst); - - bool isStatic() const; - void setStatic(bool isStatic); - - std::string getSignature() const; - void setSignature(const std::string& signature); + // Component setters. + void addComponentConst(std::shared_ptr component); + void addComponentStatic(std::shared_ptr component); + void addComponentSignature(std::shared_ptr component); // Logging. std::string getTypeString(NodeType type) const; std::string getAsString() const; private: - // Constructor for plain copies. - Node(Id id, NodeType type, const std::string& name); + void operator=(const Node&); NodeType m_type; std::string m_name; std::vector m_edges; - - // Additional fields for different NodeTypes. - bool m_isConst; - bool m_isStatic; - - std::string m_signature; }; std::ostream& operator<<(std::ostream& ostream, const Node& node); diff --git a/src/lib/data/graph/Token.cpp b/src/lib/data/graph/Token.cpp index db0f48a3..f43e4f55 100644 --- a/src/lib/data/graph/Token.cpp +++ b/src/lib/data/graph/Token.cpp @@ -41,9 +41,18 @@ void Token::removeLocationId(Id locationId) LOG_ERROR("Location Id was not referenced by this Token."); } -Token::Token(Id id) - : m_id(id) +Token::Token(const Token& other) + : m_id(other.m_id) { + for (std::shared_ptr component: other.m_components) + { + addComponent(component->copy()); + } +} + +void Token::addComponent(std::shared_ptr component) +{ + m_components.push_back(component); } Id Token::s_nextId = 1; diff --git a/src/lib/data/graph/Token.h b/src/lib/data/graph/Token.h index d8489b07..24f80e48 100644 --- a/src/lib/data/graph/Token.h +++ b/src/lib/data/graph/Token.h @@ -1,8 +1,10 @@ #ifndef TOKEN_H #define TOKEN_H +#include #include +#include "data/graph/token_component/TokenComponent.h" #include "utility/types.h" class Token @@ -21,19 +23,55 @@ public: void addLocationId(Id locationId); void removeLocationId(Id locationId); + template + ComponentType* getComponent() const; + + template + std::shared_ptr removeComponent(); + protected: - // Constructor for plain copies of Node and Edge - Token(Id id); + Token(const Token& other); + + void addComponent(std::shared_ptr component); + void copyComponentsFrom(const Token& other); private: static Id s_nextId; - Token(const Token&); void operator=(const Token&); const Id m_id; // own id std::vector m_locationIds; + std::vector> m_components; }; +template +ComponentType* Token::getComponent() const +{ + for (std::shared_ptr component: m_components) + { + if (typeid(ComponentType) == typeid(*(component.get()))) + { + return dynamic_cast(component.get()); + } + } + return nullptr; +} + +template +std::shared_ptr Token::removeComponent() +{ + for (size_t i = 0; i < m_components.size(); i++) + { + std::shared_ptr component = m_components[i]; + if (typeid(ComponentType) == typeid(*(component.get()))) + { + m_components.erase(m_components.begin() + i); + return std::dynamic_pointer_cast(component); + } + } + return nullptr; +} + #endif // TOKEN_H diff --git a/src/lib/data/graph/edgeComponent/EdgeComponent.cpp b/src/lib/data/graph/edgeComponent/EdgeComponent.cpp deleted file mode 100644 index c533fdf5..00000000 --- a/src/lib/data/graph/edgeComponent/EdgeComponent.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "data/graph/edgeComponent/EdgeComponent.h" - -EdgeComponent::EdgeComponent() -{ -} - -EdgeComponent::~EdgeComponent() -{ -} - -void EdgeComponent::setEdge(Edge* edge) -{ - m_edge = edge; -} - -Edge* EdgeComponent::getEdge() const -{ - return m_edge; -} diff --git a/src/lib/data/graph/edgeComponent/EdgeComponent.h b/src/lib/data/graph/edgeComponent/EdgeComponent.h deleted file mode 100644 index 1e5255c3..00000000 --- a/src/lib/data/graph/edgeComponent/EdgeComponent.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef EDGE_COMPONENT_H -#define EDGE_COMPONENT_H - -#include "data/graph/Edge.h" - -class EdgeComponent -{ -public: - EdgeComponent(); - virtual ~EdgeComponent(); - - virtual std::shared_ptr copy() const = 0; - - void setEdge(Edge* edge); - -protected: - Edge* getEdge() const; - -private: - Edge* m_edge; -}; - -#endif // EDGE_COMPONENT_H diff --git a/src/lib/data/graph/edgeComponent/EdgeComponentDataType.cpp b/src/lib/data/graph/edgeComponent/EdgeComponentDataType.cpp deleted file mode 100644 index b5438c31..00000000 --- a/src/lib/data/graph/edgeComponent/EdgeComponentDataType.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "data/graph/edgeComponent/EdgeComponentDataType.h" - -#include "data/type/DataType.h" -#include "data/graph/Node.h" - -EdgeComponentDataType::EdgeComponentDataType(const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack) - : m_qualifierList(qualifierList) - , m_modifierStack(modifierStack) -{ -} - -EdgeComponentDataType::~EdgeComponentDataType() -{ -} - -std::shared_ptr EdgeComponentDataType::copy() const -{ - return std::make_shared(m_qualifierList, m_modifierStack); -} - -DataType EdgeComponentDataType::getDataType() const -{ - return DataType(getEdge()->getTo()->getName(), m_qualifierList, m_modifierStack); -} diff --git a/src/lib/data/graph/edgeComponent/EdgeComponentDataType.h b/src/lib/data/graph/edgeComponent/EdgeComponentDataType.h deleted file mode 100644 index 9653a6a4..00000000 --- a/src/lib/data/graph/edgeComponent/EdgeComponentDataType.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef EDGE_COMPONENT_DATA_TYPE_H -#define EDGE_COMPONENT_DATA_TYPE_H - -#include "data/graph/edgeComponent/EdgeComponent.h" -#include "data/type/DataTypeModifierStack.h" -#include "data/type/DataTypeQualifierList.h" - -class DataType; - -class EdgeComponentDataType: public EdgeComponent -{ -public: - EdgeComponentDataType(const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack); - virtual ~EdgeComponentDataType(); - - virtual std::shared_ptr copy() const; - - DataType getDataType() const; - -private: - const DataTypeQualifierList m_qualifierList; - const DataTypeModifierStack m_modifierStack; -}; - -#endif // EDGE_COMPONENT_DATA_TYPE_H diff --git a/src/lib/data/graph/token_component/TokenComponent.cpp b/src/lib/data/graph/token_component/TokenComponent.cpp new file mode 100644 index 00000000..37abdc8c --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponent.cpp @@ -0,0 +1,5 @@ +#include "data/graph/token_component/TokenComponent.h" + +TokenComponent::~TokenComponent() +{ +} diff --git a/src/lib/data/graph/token_component/TokenComponent.h b/src/lib/data/graph/token_component/TokenComponent.h new file mode 100644 index 00000000..a1da8d2b --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponent.h @@ -0,0 +1,13 @@ +#ifndef TOKEN_COMPONENT_H +#define TOKEN_COMPONENT_H + +#include + +class TokenComponent +{ +public: + virtual ~TokenComponent(); + virtual std::shared_ptr copy() const = 0; +}; + +#endif // TOKEN_COMPONENT_H diff --git a/src/lib/data/graph/token_component/TokenComponentAccess.cpp b/src/lib/data/graph/token_component/TokenComponentAccess.cpp new file mode 100644 index 00000000..ba3b6a5e --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentAccess.cpp @@ -0,0 +1,36 @@ +#include "data/graph/token_component/TokenComponentAccess.h" + +TokenComponentAccess::TokenComponentAccess(AccessType access) + : m_access(access) +{ +} + +TokenComponentAccess::~TokenComponentAccess() +{ +} + +std::shared_ptr TokenComponentAccess::copy() const +{ + return std::make_shared(*this); +} + +TokenComponentAccess::AccessType TokenComponentAccess::getAccess() const +{ + return m_access; +} + +std::string TokenComponentAccess::getAccessString() const +{ + switch (m_access) + { + case ACCESS_PUBLIC: + return "public"; + case ACCESS_PROTECTED: + return "protected"; + case ACCESS_PRIVATE: + return "private"; + case ACCESS_NONE: + return ""; + } + return ""; +} diff --git a/src/lib/data/graph/token_component/TokenComponentAccess.h b/src/lib/data/graph/token_component/TokenComponentAccess.h new file mode 100644 index 00000000..61a28f33 --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentAccess.h @@ -0,0 +1,33 @@ +#ifndef TOKEN_COMPONENT_ACCESS +#define TOKEN_COMPONENT_ACCESS + +#include + +#include "data/graph/token_component/TokenComponent.h" + +class TokenComponentAccess + : public TokenComponent +{ +public: + enum AccessType + { + ACCESS_PUBLIC, + ACCESS_PROTECTED, + ACCESS_PRIVATE, + ACCESS_NONE + }; + + TokenComponentAccess(AccessType access); + virtual ~TokenComponentAccess(); + + virtual std::shared_ptr copy() const; + + AccessType getAccess() const; + + std::string getAccessString() const; + +private: + const AccessType m_access; +}; + +#endif // TOKEN_COMPONENT_ACCESS diff --git a/src/lib/data/graph/token_component/TokenComponentConst.cpp b/src/lib/data/graph/token_component/TokenComponentConst.cpp new file mode 100644 index 00000000..4de24da5 --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentConst.cpp @@ -0,0 +1,6 @@ +#include "data/graph/token_component/TokenComponentConst.h" + +std::shared_ptr TokenComponentConst::copy() const +{ + return std::make_shared(*this); +} diff --git a/src/lib/data/graph/token_component/TokenComponentConst.h b/src/lib/data/graph/token_component/TokenComponentConst.h new file mode 100644 index 00000000..301041ce --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentConst.h @@ -0,0 +1,13 @@ +#ifndef TOKEN_COMPONENT_CONST +#define TOKEN_COMPONENT_CONST + +#include "data/graph/token_component/TokenComponent.h" + +class TokenComponentConst + : public TokenComponent +{ +public: + virtual std::shared_ptr copy() const; +}; + +#endif // TOKEN_COMPONENT_CONST diff --git a/src/lib/data/graph/token_component/TokenComponentDataType.cpp b/src/lib/data/graph/token_component/TokenComponentDataType.cpp new file mode 100644 index 00000000..7800dc99 --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentDataType.cpp @@ -0,0 +1,30 @@ +#include "data/graph/token_component/TokenComponentDataType.h" + +#include "data/type/DataType.h" + +TokenComponentDataType::TokenComponentDataType( + const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack +) + : m_qualifierList(qualifierList) + , m_modifierStack(modifierStack) +{ +} + +TokenComponentDataType::~TokenComponentDataType() +{ +} + +std::shared_ptr TokenComponentDataType::copy() const +{ + return std::make_shared(*this); +} + +DataType TokenComponentDataType::getDataType(const std::string& typeName) const +{ + return DataType(typeName, m_qualifierList, m_modifierStack); +} + +std::string TokenComponentDataType::getQualifiedTypeName(const std::string& typeName) const +{ + return m_modifierStack.applyTo(m_qualifierList.applyTo(typeName)); +} diff --git a/src/lib/data/graph/token_component/TokenComponentDataType.h b/src/lib/data/graph/token_component/TokenComponentDataType.h new file mode 100644 index 00000000..5f1c3eae --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentDataType.h @@ -0,0 +1,27 @@ +#ifndef TOKEN_COMPONENT_DATA_TYPE +#define TOKEN_COMPONENT_DATA_TYPE + +#include "data/graph/token_component/TokenComponent.h" +#include "data/type/DataTypeModifierStack.h" +#include "data/type/DataTypeQualifierList.h" + +class DataType; + +class TokenComponentDataType + : public TokenComponent +{ +public: + TokenComponentDataType(const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack); + virtual ~TokenComponentDataType(); + + virtual std::shared_ptr copy() const; + + DataType getDataType(const std::string& typeName) const; + std::string getQualifiedTypeName(const std::string& typeName) const; + +private: + const DataTypeQualifierList m_qualifierList; + const DataTypeModifierStack m_modifierStack; +}; + +#endif // TOKEN_COMPONENT_DATA_TYPE diff --git a/src/lib/data/graph/token_component/TokenComponentSignature.cpp b/src/lib/data/graph/token_component/TokenComponentSignature.cpp new file mode 100644 index 00000000..5ced7273 --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentSignature.cpp @@ -0,0 +1,20 @@ +#include "data/graph/token_component/TokenComponentSignature.h" + +TokenComponentSignature::TokenComponentSignature(std::string signature) + : m_signature(signature) +{ +} + +TokenComponentSignature::~TokenComponentSignature() +{ +} + +std::shared_ptr TokenComponentSignature::copy() const +{ + return std::make_shared(*this); +} + +const std::string& TokenComponentSignature::getSignature() const +{ + return m_signature; +} diff --git a/src/lib/data/graph/token_component/TokenComponentSignature.h b/src/lib/data/graph/token_component/TokenComponentSignature.h new file mode 100644 index 00000000..bbd0384e --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentSignature.h @@ -0,0 +1,23 @@ +#ifndef TOKEN_COMPONENT_SIGNATURE +#define TOKEN_COMPONENT_SIGNATURE + +#include + +#include "data/graph/token_component/TokenComponent.h" + +class TokenComponentSignature + : public TokenComponent +{ +public: + TokenComponentSignature(std::string signature); + virtual ~TokenComponentSignature(); + + virtual std::shared_ptr copy() const; + + const std::string& getSignature() const; + +private: + const std::string m_signature; +}; + +#endif // TOKEN_COMPONENT_SIGNATURE diff --git a/src/lib/data/graph/token_component/TokenComponentStatic.cpp b/src/lib/data/graph/token_component/TokenComponentStatic.cpp new file mode 100644 index 00000000..19c3e862 --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentStatic.cpp @@ -0,0 +1,6 @@ +#include "data/graph/token_component/TokenComponentStatic.h" + +std::shared_ptr TokenComponentStatic::copy() const +{ + return std::make_shared(*this); +} diff --git a/src/lib/data/graph/token_component/TokenComponentStatic.h b/src/lib/data/graph/token_component/TokenComponentStatic.h new file mode 100644 index 00000000..c8d1d2d9 --- /dev/null +++ b/src/lib/data/graph/token_component/TokenComponentStatic.h @@ -0,0 +1,13 @@ +#ifndef TOKEN_COMPONENT_STATIC +#define TOKEN_COMPONENT_STATIC + +#include "data/graph/token_component/TokenComponent.h" + +class TokenComponentStatic + : public TokenComponent +{ +public: + virtual std::shared_ptr copy() const; +}; + +#endif // TOKEN_COMPONENT_STATIC diff --git a/src/test/GraphTestSuite.h b/src/test/GraphTestSuite.h index 9145c8d8..1b9239af 100644 --- a/src/test/GraphTestSuite.h +++ b/src/test/GraphTestSuite.h @@ -1,32 +1,153 @@ #include "cxxtest/TestSuite.h" #include "data/graph/Graph.h" -#include "data/graph/edgeComponent/EdgeComponentDataType.h" -#include "data/type/modifier/DataTypeModifierPointer.h" class GraphTestSuite : public CxxTest::TestSuite { public: void test_tokens_get_unique_id() { - Node a(Node::NODE_UNDEFINED, "A"); - Node b(Node::NODE_UNDEFINED, "B"); - Node c(Node::NODE_UNDEFINED, "C"); + TestToken a; + TestToken b; + TestToken c; TS_ASSERT_DIFFERS(a.getId(), c.getId()); TS_ASSERT_DIFFERS(a.getId(), b.getId()); TS_ASSERT_DIFFERS(b.getId(), c.getId()); } - void test_get_and_set_type_of_nodes() + void test_tokens_save_location_ids() { - Node n(Node::NODE_NAMESPACE, "A"); - TS_ASSERT_EQUALS(Node::NODE_NAMESPACE, n.getType()); + TestToken a; + a.addLocationId(23); + a.addLocationId(5); + TS_ASSERT_EQUALS(a.getLocationIds().size(), 2); + TS_ASSERT_EQUALS(a.getLocationIds()[0], 23); + TS_ASSERT_EQUALS(a.getLocationIds()[1], 5); + } + + void test_tokens_remove_location_ids() + { + TestToken a; + a.addLocationId(23); + a.addLocationId(5); + a.removeLocationId(42); + a.removeLocationId(5); + + TS_ASSERT_EQUALS(a.getLocationIds().size(), 1); + TS_ASSERT_EQUALS(a.getLocationIds()[0], 23); + } + + void test_token_saves_component() + { + TestToken a; + std::shared_ptr component = std::make_shared(); + a.addComponent(component); + + TS_ASSERT(a.getComponent()); + TS_ASSERT(!a.getComponent()); + + TS_ASSERT_EQUALS(a.getComponent(), component.get()); + } + + void test_token_saves_multiple_components() + { + TestToken a; + std::shared_ptr component = std::make_shared(); + std::shared_ptr component2 = std::make_shared(); + a.addComponent(component2); + a.addComponent(component); + + TS_ASSERT(a.getComponent()); + TS_ASSERT(a.getComponent()); + + TS_ASSERT_EQUALS(a.getComponent(), component.get()); + TS_ASSERT_EQUALS(a.getComponent(), component2.get()); + } + + void test_token_removes_component() + { + TestToken a; + std::shared_ptr component = std::make_shared(); + std::shared_ptr component2 = std::make_shared(); + a.addComponent(component2); + a.addComponent(component); + std::shared_ptr component3 = a.removeComponent(); + + TS_ASSERT(!a.getComponent()); + TS_ASSERT(a.getComponent()); + + TS_ASSERT_EQUALS(component3.get(), component.get()); + TS_ASSERT_EQUALS(a.getComponent(), component2.get()); + } + + void test_token_copies_components_when_token_is_copied() + { + TestToken a; + std::shared_ptr component = std::make_shared(); + std::shared_ptr component2 = std::make_shared(); + a.addComponent(component2); + a.addComponent(component); + + TestToken b(a); + + TS_ASSERT(b.getComponent()); + TS_ASSERT(b.getComponent()); + + TS_ASSERT_DIFFERS(b.getComponent(), component.get()); + TS_ASSERT_DIFFERS(b.getComponent(), component2.get()); + } + + void test_nodes_are_nodes() + { + Node a(Node::NODE_UNDEFINED, "A"); + + TS_ASSERT(a.isNode()); + TS_ASSERT(!a.isEdge()); + } + + void test_edges_are_edges() + { + Node a(Node::NODE_UNDEFINED, "A"); + Node b(Node::NODE_UNDEFINED, "B"); + Edge e(Edge::EDGE_TYPE_OF, &a, &b); + + TS_ASSERT(!e.isNode()); + TS_ASSERT(e.isEdge()); + } + + void test_set_type_of_node_from_constructor() + { + Node n(Node::NODE_FUNCTION, "A"); + TS_ASSERT_EQUALS(Node::NODE_FUNCTION, n.getType()); + } + + void test_set_type_of_node_from_undefined() + { + Node n(Node::NODE_UNDEFINED, "A"); n.setType(Node::NODE_CLASS); TS_ASSERT_EQUALS(Node::NODE_CLASS, n.getType()); } + void test_can_not_change_type_of_node_after_it_was_set() + { + Node n(Node::NODE_NAMESPACE, "A"); + n.setType(Node::NODE_CLASS); + TS_ASSERT_DIFFERS(Node::NODE_CLASS, n.getType()); + } + + void test_node_can_be_copied_and_keeps_same_id() + { + Node n(Node::NODE_NAMESPACE, "A"); + Node n2(n); + + TS_ASSERT_DIFFERS(&n, &n2); + TS_ASSERT_EQUALS(n.getId(), n2.getId()); + TS_ASSERT_EQUALS(n.getName(), n2.getName()); + TS_ASSERT_EQUALS(n.getType(), n2.getType()); + } + void test_get_type_of_edges() { Node a(Node::NODE_UNDEFINED, "A"); @@ -36,19 +157,16 @@ public: TS_ASSERT_EQUALS(Edge::EDGE_TYPE_OF, e.getType()); } - void test_get_and_set_const_and_static_of_nodes() + void test_edge_can_be_copied_and_keeps_same_id() { - Node n(Node::NODE_GLOBAL_VARIABLE, "A"); - TS_ASSERT(!n.isConst()); - TS_ASSERT(!n.isStatic()); + Node a(Node::NODE_UNDEFINED, "A"); + Node b(Node::NODE_UNDEFINED, "B"); + Edge e(Edge::EDGE_TYPE_OF, &a, &b); + Edge e2(e, &a, &b); - n.setConst(true); - TS_ASSERT(n.isConst()); - TS_ASSERT(!n.isStatic()); - - n.setStatic(true); - TS_ASSERT(n.isConst()); - TS_ASSERT(n.isStatic()); + TS_ASSERT_DIFFERS(&e, &e2); + TS_ASSERT_EQUALS(e.getId(), e2.getId()); + TS_ASSERT_EQUALS(e.getType(), e2.getType()); } void test_graph_saves_nodes() @@ -197,14 +315,6 @@ public: TS_ASSERT_EQUALS(Node::NODE_UNDEFINED, graph.getNode("A::B::C::D::E")->getType()); } - void test_set_access_on_child_edge_via_node() - { - TestGraph graph; - Node* b = graph.createNodeHierarchy("A::B"); - b->getMemberEdge()->setAccess(Edge::ACCESS_PRIVATE); - TS_ASSERT_EQUALS(Edge::ACCESS_PRIVATE, b->getMemberEdge()->getAccess()); - } - void test_visit_each_token_on_graph() { TestGraph graph; @@ -251,7 +361,6 @@ public: { TestGraph graph; Node* b = graph.createNodeHierarchy("A::B"); - b->getMemberEdge()->setAccess(Edge::ACCESS_PUBLIC); graph.createNodeHierarchy("A::B::C"); Node* d = graph.createNodeHierarchy("D"); Node* e = graph.createNodeHierarchy("E"); @@ -279,10 +388,61 @@ public: TS_ASSERT(plainGraph.getNode("A::B::C")); TS_ASSERT(plainGraph.getNode("D")); TS_ASSERT(!plainGraph.getNode("E")); - TS_ASSERT_EQUALS(Edge::ACCESS_PUBLIC, plainGraph.getNode("A::B")->getMemberEdge()->getAccess()); } private: + class TestToken: public Token + { + public: + TestToken() + { + } + + TestToken(const TestToken& other) + : Token(other) + { + } + + virtual bool isNode() const + { + return false; + } + + virtual bool isEdge() const + { + return false; + } + + void addComponent(std::shared_ptr component) + { + Token::addComponent(component); + } + + template + std::shared_ptr removeComponent() + { + return Token::removeComponent(); + } + }; + + class TestComponent: public TokenComponent + { + public: + virtual std::shared_ptr copy() const + { + return std::make_shared(*this); + } + }; + + class Test2Component: public TokenComponent + { + public: + virtual std::shared_ptr copy() const + { + return std::make_shared(*this); + } + }; + class TestGraph: public Graph { public: