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: