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).
This commit is contained in:
Eberhard Graether
2014-07-26 02:26:59 +02:00
parent 4262be133a
commit 641acc2bde
29 changed files with 711 additions and 443 deletions
+3
View File
@@ -1,4 +1,7 @@
ConfigManager.cpp ERROR: value path/to/nowhere is not present in config. 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. 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: 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 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8
+12 -4
View File
@@ -71,10 +71,18 @@ add_files(
data/access/GraphAccessProxy.cpp data/access/GraphAccessProxy.cpp
data/access/GraphAccessProxy.h data/access/GraphAccessProxy.h
data/graph/edgeComponent/EdgeComponent.cpp data/graph/token_component/TokenComponent.cpp
data/graph/edgeComponent/EdgeComponent.h data/graph/token_component/TokenComponent.h
data/graph/edgeComponent/EdgeComponentDataType.cpp data/graph/token_component/TokenComponentAccess.cpp
data/graph/edgeComponent/EdgeComponentDataType.h 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.cpp
data/graph/Edge.h data/graph/Edge.h
+66 -52
View File
@@ -1,6 +1,8 @@
#include "data/Storage.h" #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/TokenLocation.h"
#include "data/location/TokenLocationFile.h" #include "data/location/TokenLocationFile.h"
#include "data/location/TokenLocationLine.h" #include "data/location/TokenLocationLine.h"
@@ -41,12 +43,9 @@ void Storage::onTypedefParsed(
){ ){
log("typedef", fullName + " -> " + underlyingType.getFullTypeName(), location); log("typedef", fullName + " -> " + underlyingType.getFullTypeName(), location);
Node* node = m_graph.createNodeHierarchy(fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_TYPEDEF, fullName);
node->setType(Node::NODE_TYPEDEF); addAccess(node, access);
node->setAccess(convertAccessType(access));
addTokenLocation(node, location); addTokenLocation(node, location);
addTypeEdge(node, Edge::EDGE_TYPEDEF_OF, underlyingType); 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); log("class", fullName, location);
Node* node = m_graph.createNodeHierarchy(fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_CLASS, fullName);
node->setType(Node::NODE_CLASS); addAccess(node, access);
node->setAccess(convertAccessType(access));
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -65,10 +62,8 @@ void Storage::onStructParsed(const ParseLocation& location, const std::string& f
{ {
log("struct", fullName, location); log("struct", fullName, location);
Node* node = m_graph.createNodeHierarchy(fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_STRUCT, fullName);
node->setType(Node::NODE_STRUCT); addAccess(node, access);
node->setAccess(convertAccessType(access));
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -76,12 +71,14 @@ void Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseV
{ {
log("global", variable.fullName, location); log("global", variable.fullName, location);
Node* node = m_graph.createNodeHierarchy(variable.fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, variable.fullName);
node->setType(Node::NODE_GLOBAL_VARIABLE);
node->setStatic(variable.isStatic); if (variable.isStatic)
{
node->addComponentStatic(std::make_shared<TokenComponentStatic>());
}
addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type); addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type);
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -89,19 +86,21 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
{ {
log("field", variable.fullName, location); log("field", variable.fullName, location);
Node* node = m_graph.createNodeHierarchy(variable.fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_FIELD, variable.fullName);
node->setType(Node::NODE_FIELD);
node->setStatic(variable.isStatic); if (variable.isStatic)
{
node->addComponentStatic(std::make_shared<TokenComponentStatic>());
}
if (access == ACCESS_NONE) if (access == ACCESS_NONE)
{ {
LOG_ERROR("Field needs to have access type [public, protected, private] but has none."); LOG_ERROR("Field needs to have access type [public, protected, private] but has none.");
return; return;
} }
node->setAccess(convertAccessType(access)); addAccess(node, access);
addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type); addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type);
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -113,11 +112,9 @@ void Storage::onFunctionParsed(
log("function", fullName, location); log("function", fullName, location);
Node* node = m_graph.createNodeHierarchyWithDistinctSignature( Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
fullName, Node::NODE_FUNCTION, fullName,
ParserClient::functionSignatureStr(returnType.type, fullName, parameters, false) ParserClient::functionSignatureStr(returnType.type, fullName, parameters, false)
); );
node->setType(Node::NODE_FUNCTION);
addTokenLocation(node, location); addTokenLocation(node, location);
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType); addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType);
@@ -136,20 +133,26 @@ void Storage::onMethodParsed(
log("method", fullName, location); log("method", fullName, location);
Node* node = m_graph.createNodeHierarchyWithDistinctSignature( Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
fullName, Node::NODE_METHOD, fullName,
ParserClient::functionSignatureStr(returnType.type, fullName, parameters, isConst) ParserClient::functionSignatureStr(returnType.type, fullName, parameters, isConst)
); );
node->setType(Node::NODE_METHOD); if (isConst)
node->setConst(isConst); {
node->setStatic(isStatic); node->addComponentConst(std::make_shared<TokenComponentConst>());
}
if (isStatic)
{
node->addComponentStatic(std::make_shared<TokenComponentStatic>());
}
if (access == ACCESS_NONE) if (access == ACCESS_NONE)
{ {
LOG_ERROR("Method needs to have access type [public, protected, private] but has none."); LOG_ERROR("Method needs to have access type [public, protected, private] but has none.");
return; return;
} }
node->setAccess(convertAccessType(access)); addAccess(node, access);
addTokenLocation(node, location); addTokenLocation(node, location);
@@ -164,9 +167,7 @@ void Storage::onNamespaceParsed(const ParseLocation& location, const std::string
{ {
log("namespace", fullName, location); log("namespace", fullName, location);
Node* node = m_graph.createNodeHierarchy(fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_NAMESPACE, fullName);
node->setType(Node::NODE_NAMESPACE);
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -174,10 +175,8 @@ void Storage::onEnumParsed(const ParseLocation& location, const std::string& ful
{ {
log("enum", fullName, location); log("enum", fullName, location);
Node* node = m_graph.createNodeHierarchy(fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_ENUM, fullName);
node->setType(Node::NODE_ENUM); addAccess(node, access);
node->setAccess(convertAccessType(access));
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -185,9 +184,7 @@ void Storage::onEnumFieldParsed(const ParseLocation& location, const std::string
{ {
log("enum field", fullName, location); log("enum field", fullName, location);
Node* node = m_graph.createNodeHierarchy(fullName); Node* node = m_graph.createNodeHierarchy(Node::NODE_FIELD, fullName);
node->setType(Node::NODE_FIELD);
addTokenLocation(node, location); addTokenLocation(node, location);
} }
@@ -200,7 +197,7 @@ void Storage::onInheritanceParsed(
Node* baseNode = m_graph.createNodeHierarchy(baseName); Node* baseNode = m_graph.createNodeHierarchy(baseName);
Edge* edge = m_graph.createEdge(Edge::EDGE_INHERITANCE, node, baseNode); Edge* edge = m_graph.createEdge(Edge::EDGE_INHERITANCE, node, baseNode);
edge->setAccess(convertAccessType(access)); edge->addComponentAccess(std::make_shared<TokenComponentAccess>(convertAccessType(access)));
addTokenLocation(edge, location); addTokenLocation(edge, location);
} }
@@ -448,26 +445,46 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile(
return ret; return ret;
} }
Edge::AccessType Storage::convertAccessType(ParserClient::AccessType access) const TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const
{ {
switch (access) switch (access)
{ {
case ACCESS_PUBLIC: case ACCESS_PUBLIC:
return Edge::ACCESS_PUBLIC; return TokenComponentAccess::ACCESS_PUBLIC;
case ACCESS_PROTECTED: case ACCESS_PROTECTED:
return Edge::ACCESS_PROTECTED; return TokenComponentAccess::ACCESS_PROTECTED;
case ACCESS_PRIVATE: case ACCESS_PRIVATE:
return Edge::ACCESS_PRIVATE; return TokenComponentAccess::ACCESS_PRIVATE;
case ACCESS_NONE: 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<TokenComponentAccess> ptr = std::make_shared<TokenComponentAccess>(convertAccessType(access));
node->getMemberEdge()->addComponentAccess(ptr);
return ptr.get();
}
return nullptr;
}
Edge* Storage::addTypeEdge(Node* node, Edge::EdgeType edgeType, const DataType& type) Edge* Storage::addTypeEdge(Node* node, Edge::EdgeType edgeType, const DataType& type)
{ {
Node* typeNode = m_graph.createNodeHierarchy(type.getRawTypeName()); Node* typeNode = m_graph.createNodeHierarchy(type.getRawTypeName());
Edge* edge = m_graph.createEdge(edgeType, node, typeNode); Edge* edge = m_graph.createEdge(edgeType, node, typeNode);
edge->addComponent(std::make_shared<EdgeComponentDataType>(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<TokenComponentDataType>())
{
edge->addComponentDataType(
std::make_shared<TokenComponentDataType>(type.getQualifierList(), type.getModifierStack())
);
}
return edge; return edge;
} }
@@ -478,10 +495,7 @@ Edge* Storage::addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeU
return nullptr; return nullptr;
} }
const DataType& type = typeUsage.type; Edge* edge = addTypeEdge(node, edgeType, typeUsage.type);
Node* typeNode = m_graph.createNodeHierarchy(type.getRawTypeName());
Edge* edge = m_graph.createEdge(edgeType, node, typeNode);
edge->addComponent(std::make_shared<EdgeComponentDataType>(type.getQualifierList(), type.getModifierStack()));
addTokenLocation(edge, typeUsage.location); addTokenLocation(edge, typeUsage.location);
return edge; return edge;
+3 -1
View File
@@ -7,6 +7,7 @@
#include "data/access/GraphAccess.h" #include "data/access/GraphAccess.h"
#include "data/access/LocationAccess.h" #include "data/access/LocationAccess.h"
#include "data/graph/Graph.h" #include "data/graph/Graph.h"
#include "data/graph/token_component/TokenComponentAccess.h"
#include "data/location/TokenLocationCollection.h" #include "data/location/TokenLocationCollection.h"
#include "data/parser/ParserClient.h" #include "data/parser/ParserClient.h"
@@ -87,7 +88,8 @@ public:
) const; ) const;
private: 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 DataType& type);
Edge* addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeUsage& typeUsage); Edge* addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeUsage& typeUsage);
TokenLocation* addTokenLocation(Token* token, const ParseLocation& location); TokenLocation* addTokenLocation(Token* token, const ParseLocation& location);
+44 -67
View File
@@ -3,45 +3,41 @@
#include <sstream> #include <sstream>
#include "data/graph/Node.h" #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" #include "utility/logging/logging.h"
Edge::Edge(EdgeType type, Node* from, Node* to) Edge::Edge(EdgeType type, Node* from, Node* to)
: m_type(type) : m_type(type)
, m_from(from) , m_from(from)
, m_to(to) , m_to(to)
, m_access(ACCESS_NONE)
{ {
m_from->addEdge(this); m_from->addEdge(this);
m_to->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() Edge::~Edge()
{ {
m_from->removeEdge(this); m_from->removeEdge(this);
m_to->removeEdge(this); m_to->removeEdge(this);
} }
std::shared_ptr<Edge> 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> edge(new Edge(getId(), m_type, from, to));
edge->setAccess(m_access);
for (std::shared_ptr<EdgeComponent> component: m_components)
{
edge->addComponent(component->copy());
}
return edge;
}
Edge::EdgeType Edge::getType() const Edge::EdgeType Edge::getType() const
{ {
return m_type; return m_type;
@@ -67,24 +63,37 @@ bool Edge::isEdge() const
return true; return true;
} }
Edge::AccessType Edge::getAccess() const void Edge::addComponentAccess(std::shared_ptr<TokenComponentAccess> component)
{ {
return m_access; if (getComponent<TokenComponentAccess>())
{
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<TokenComponentDataType> component)
{ {
if (access != ACCESS_NONE && m_type != EDGE_MEMBER && m_type != EDGE_INHERITANCE) if (getComponent<TokenComponentDataType>())
{ {
LOG_ERROR("Setting access on wrong edge type."); LOG_ERROR("TokenComponentDataType has been set before!");
return;
} }
else if (m_type != EDGE_TYPEDEF_OF && m_type != EDGE_TYPE_OF
if (m_access != ACCESS_NONE && access != m_access) && 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 std::string Edge::getTypeString() const
@@ -111,52 +120,20 @@ std::string Edge::getTypeString() const
return ""; 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::string Edge::getAsString() const
{ {
std::stringstream str; std::stringstream str;
str << "[" << getId() << "] \"" << m_from->getName() << "\" " << getTypeString() << " \"" + m_to->getName() << "\""; str << "[" << getId() << "] \"" << m_from->getName() << "\" " << getTypeString() << " \"" + m_to->getName() << "\"";
if (m_access != ACCESS_NONE) TokenComponentAccess* component = getComponent<TokenComponentAccess>();
if (component)
{ {
str << " " << getAccessString(); str << " " << component->getAccessString();
} }
return str.str(); return str.str();
} }
void Edge::addComponent(std::shared_ptr<EdgeComponent> 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) std::ostream& operator<<(std::ostream& ostream, const Edge& edge)
{ {
ostream << edge.getAsString(); ostream << edge.getAsString();
+7 -50
View File
@@ -7,7 +7,8 @@
#include "data/graph/Token.h" #include "data/graph/Token.h"
class Node; class Node;
class EdgeComponent; class TokenComponentAccess;
class TokenComponentDataType;
class Edge: public Token class Edge: public Token
{ {
@@ -24,19 +25,10 @@ public:
EDGE_TYPEDEF_OF EDGE_TYPEDEF_OF
}; };
enum AccessType
{
ACCESS_PUBLIC,
ACCESS_PROTECTED,
ACCESS_PRIVATE,
ACCESS_NONE
};
Edge(EdgeType type, Node* from, Node* to); Edge(EdgeType type, Node* from, Node* to);
Edge(const Edge& other, Node* from, Node* to);
virtual ~Edge(); virtual ~Edge();
std::shared_ptr<Edge> createPlainCopy(Node* from, Node* to) const;
EdgeType getType() const; EdgeType getType() const;
Node* getFrom() const; Node* getFrom() const;
@@ -46,58 +38,23 @@ public:
virtual bool isNode() const; virtual bool isNode() const;
virtual bool isEdge() const; virtual bool isEdge() const;
// Additional field accessors for different EdgeTypes. // Component setters
AccessType getAccess() const; void addComponentAccess(std::shared_ptr<TokenComponentAccess> component);
void setAccess(AccessType access); void addComponentDataType(std::shared_ptr<TokenComponentDataType> component);
// Logging. // Logging.
std::string getTypeString() const; std::string getTypeString() const;
std::string getAccessString() const;
std::string getAsString() const; std::string getAsString() const;
void addComponent(std::shared_ptr<EdgeComponent> component);
template <typename ComponentType>
std::shared_ptr<ComponentType> getComponent() const;
template <typename ComponentType>
bool hasComponent() const;
private: private:
// Constructor for plain copies. void operator=(const Node&);
Edge(Id id, EdgeType type, Node* from, Node* to);
const EdgeType m_type; const EdgeType m_type;
Node* const m_from; Node* const m_from;
Node* const m_to; Node* const m_to;
// Additional fields for different EdgeTypes.
AccessType m_access;
std::vector<std::shared_ptr<EdgeComponent>> m_components;
}; };
template <typename ComponentType>
std::shared_ptr<ComponentType> Edge::getComponent() const
{
std::shared_ptr<ComponentType> component;
for (std::shared_ptr<EdgeComponent> c: m_components)
{
component = std::dynamic_pointer_cast<ComponentType>(c);
if (component)
break;
}
return component;
}
template <typename ComponentType>
bool Edge::hasComponent() const
{
return (getComponent<ComponentType>());
}
std::ostream& operator<<(std::ostream& ostream, const Edge& edge); std::ostream& operator<<(std::ostream& ostream, const Edge& edge);
#endif // EDGE_H #endif // EDGE_H
+48 -21
View File
@@ -1,5 +1,6 @@
#include "data/graph/Graph.h" #include "data/graph/Graph.h"
#include "data/graph/token_component/TokenComponentSignature.h"
#include "utility/logging/logging.h" #include "utility/logging/logging.h"
#include "utility/utilityString.h" #include "utility/utilityString.h"
@@ -65,33 +66,52 @@ Token* Graph::getTokenById(Id id) const
Node* Graph::createNodeHierarchy(const std::string& fullName) Node* Graph::createNodeHierarchy(const std::string& fullName)
{ {
Node* node = getNode(fullName); return createNodeHierarchy(Node::NODE_UNDEFINED, fullName);
if (node)
{
return node;
}
return insertNodeHierarchy(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); Node* node = getNode(fullName);
if (node) 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<TokenComponentSignature>()->getSignature() == signature)
{
if (type != Node::NODE_UNDEFINED)
{
node->setType(type);
}
return node; return node;
} }
node = insertNode(fullName, node->getParentNode()); node = insertNode(type, fullName, node->getParentNode());
} }
else else
{ {
node = insertNodeHierarchy(fullName); node = insertNodeHierarchy(type, fullName);
} }
node->setSignature(signature); node->addComponentSignature(std::make_shared<TokenComponentSignature>(signature));
return node; return node;
} }
@@ -268,7 +288,7 @@ Node* Graph::addNodeAsPlainCopy(Node* node)
return n; return n;
} }
std::shared_ptr<Node> copy = node->createPlainCopy(); std::shared_ptr<Node> copy = std::make_shared<Node>(*node);
m_nodes.push_back(copy); m_nodes.push_back(copy);
return copy.get(); return copy.get();
} }
@@ -284,32 +304,39 @@ Edge* Graph::addEdgeAsPlainCopy(Edge* edge)
Node* from = addNodeAsPlainCopy(edge->getFrom()); Node* from = addNodeAsPlainCopy(edge->getFrom());
Node* to = addNodeAsPlainCopy(edge->getTo()); Node* to = addNodeAsPlainCopy(edge->getTo());
std::shared_ptr<Edge> copy = edge->createPlainCopy(from, to); std::shared_ptr<Edge> copy = std::make_shared<Edge>(*edge, from, to);
m_edges.push_back(copy); m_edges.push_back(copy);
return copy.get(); return copy.get();
} }
const std::string Graph::DELIMITER = "::"; 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; Node* node = nullptr;
std::vector<std::string> names = utility::split(fullName, DELIMITER); std::vector<std::string> names = utility::split(fullName, DELIMITER);
std::string name; std::string name;
for (std::vector<std::string>::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 += DELIMITER;
} }
name += *it; name += names[i];
Node* childNode = getNode(name); Node* childNode = getNode(name);
if (!childNode) 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; node = childNode;
@@ -318,9 +345,9 @@ Node* Graph::insertNodeHierarchy(const std::string& fullName)
return node; 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<Node> nodePtr = std::make_shared<Node>(Node::NODE_UNDEFINED, fullName); std::shared_ptr<Node> nodePtr = std::make_shared<Node>(type, fullName);
m_nodes.push_back(nodePtr); m_nodes.push_back(nodePtr);
Node* node = nodePtr.get(); Node* node = nodePtr.get();
+8 -2
View File
@@ -22,7 +22,13 @@ public:
Token* getTokenById(Id id) const; Token* getTokenById(Id id) const;
Node* createNodeHierarchy(const std::string& fullName); 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(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); Edge* createEdge(Edge::EdgeType type, Node* from, Node* to);
void removeNode(Node* node); void removeNode(Node* node);
@@ -48,8 +54,8 @@ protected:
private: private:
static const std::string DELIMITER; static const std::string DELIMITER;
Node* insertNodeHierarchy(const std::string& fullName); Node* insertNodeHierarchy(Node::NodeType type, const std::string& fullName);
Node* insertNode(const std::string& fullName, Node* parentNode); Node* insertNode(Node::NodeType type, const std::string& fullName, Node* parentNode);
Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to); Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to);
void removeEdgeInternal(Edge* edge); void removeEdgeInternal(Edge* edge);
+44 -100
View File
@@ -2,13 +2,21 @@
#include <sstream> #include <sstream>
#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" #include "utility/logging/logging.h"
Node::Node(NodeType type, const std::string& name) Node::Node(NodeType type, const std::string& name)
: m_type(type) : m_type(type)
, m_name(name) , 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> Node::createPlainCopy() const
{
std::shared_ptr<Node> node(new Node(getId(), m_type, m_name));
node->setConst(m_isConst);
node->setStatic(m_isStatic);
return node;
}
Node::NodeType Node::getType() const Node::NodeType Node::getType() const
{ {
return m_type; return m_type;
@@ -33,11 +31,12 @@ Node::NodeType Node::getType() const
void Node::setType(NodeType type) 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( LOG_WARNING(
"Changing NodeType after it was already set, from " + getTypeString(m_type) + " to " + getTypeString(type) "Changing NodeType after it was already set, from " + getTypeString(m_type) + " to " + getTypeString(type)
); );
return;
} }
m_type = type; m_type = type;
} }
@@ -148,98 +147,52 @@ bool Node::isEdge() const
return false; return false;
} }
void Node::setAccess(Edge::AccessType access) void Node::addComponentConst(std::shared_ptr<TokenComponentConst> component)
{ {
if (access != Edge::ACCESS_NONE) if (getComponent<TokenComponentConst>())
{ {
if (!getMemberEdge()) LOG_ERROR("TokenComponentConst has been set before!");
{ }
LOG_WARNING("Can't set access on node " + getName() + ", because it is not a child."); else if (m_type != NODE_METHOD)
return; {
} LOG_ERROR("TokenComponentConst can't be set on node of type: " + getTypeString(m_type));
getMemberEdge()->setAccess(access); }
else
{
addComponent(component);
} }
} }
bool Node::isConst() const void Node::addComponentStatic(std::shared_ptr<TokenComponentStatic> component)
{ {
return m_isConst; if (getComponent<TokenComponentStatic>())
}
void Node::setConst(bool isConst)
{
if (isConst && m_type != NODE_GLOBAL_VARIABLE && m_type != NODE_FIELD && m_type != NODE_METHOD)
{ {
LOG_ERROR("Setting const on wrong node of type " + getTypeString(m_type)); LOG_ERROR("TokenComponentStatic has been set before!");
return;
} }
else if (m_type != NODE_GLOBAL_VARIABLE && m_type != NODE_FIELD && m_type != NODE_FUNCTION && m_type != NODE_METHOD)
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)
{ {
LOG_ERROR("Setting static on wrong node of type " + getTypeString(m_type)); LOG_ERROR("TokenComponentStatic can't be set on node of type: " + getTypeString(m_type));
return; }
else
{
addComponent(component);
} }
m_isStatic = isStatic;
} }
std::string Node::getSignature() const void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> component)
{ {
// Signature generation from edges failed, because parameter edges to same type are bundled. if (getComponent<TokenComponentSignature>())
// std::string str;
// Edge* returnTypeEdge = findEdgeOfType(Edge::EDGE_RETURN_TYPE_OF);
// str += returnTypeEdge->getComponent<EdgeComponentDataType>()->getDataType().getFullTypeName() + " " + m_name + "(";
// forEachEdgeOfType(Edge::EDGE_PARAMETER_TYPE_OF,
// [&str](Edge* edge)
// {
// str += edge->getComponent<EdgeComponentDataType>()->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)
{ {
LOG_ERROR("Signature is not supported on node of type " + getTypeString(m_type)); LOG_ERROR("TokenComponentSignature has been set before!");
return;
} }
else if (m_type != NODE_FUNCTION && m_type != NODE_METHOD)
if (m_signature.size())
{ {
LOG_ERROR("Signature was already set before."); LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString(m_type));
return; }
else
{
addComponent(component);
} }
m_signature = signature;
} }
std::string Node::getTypeString(NodeType type) const std::string Node::getTypeString(NodeType type) const
@@ -247,7 +200,7 @@ std::string Node::getTypeString(NodeType type) const
switch (type) switch (type)
{ {
case NODE_UNDEFINED: case NODE_UNDEFINED:
return "type"; return "undefined";
case NODE_CLASS: case NODE_CLASS:
return "class"; return "class";
case NODE_STRUCT: case NODE_STRUCT:
@@ -275,12 +228,12 @@ std::string Node::getAsString() const
std::stringstream str; std::stringstream str;
str << "[" << getId() << "] " << getTypeString(m_type) << ": " << "\"" << getName() << "\""; str << "[" << getId() << "] " << getTypeString(m_type) << ": " << "\"" << getName() << "\"";
if (isStatic()) if (getComponent<TokenComponentStatic>())
{ {
str << " static"; str << " static";
} }
if (isConst()) if (getComponent<TokenComponentConst>())
{ {
str << " const"; str << " const";
} }
@@ -288,15 +241,6 @@ std::string Node::getAsString() const
return str.str(); 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) std::ostream& operator<<(std::ostream& ostream, const Node& node)
{ {
ostream << node.getAsString(); ostream << node.getAsString();
+10 -21
View File
@@ -9,6 +9,10 @@
#include "data/graph/Edge.h" #include "data/graph/Edge.h"
#include "data/graph/Token.h" #include "data/graph/Token.h"
class TokenComponentConst;
class TokenComponentStatic;
class TokenComponentSignature;
class Node: public Token class Node: public Token
{ {
public: public:
@@ -27,10 +31,9 @@ public:
}; };
Node(NodeType type, const std::string& name); Node(NodeType type, const std::string& name);
Node(const Node& other);
virtual ~Node(); virtual ~Node();
std::shared_ptr<Node> createPlainCopy() const;
NodeType getType() const; NodeType getType() const;
void setType(NodeType type); void setType(NodeType type);
@@ -54,36 +57,22 @@ public:
virtual bool isNode() const; virtual bool isNode() const;
virtual bool isEdge() const; virtual bool isEdge() const;
// Additional field accessors for different NodeTypes. // Component setters.
void setAccess(Edge::AccessType access); void addComponentConst(std::shared_ptr<TokenComponentConst> component);
void addComponentStatic(std::shared_ptr<TokenComponentStatic> component);
bool isConst() const; void addComponentSignature(std::shared_ptr<TokenComponentSignature> component);
void setConst(bool isConst);
bool isStatic() const;
void setStatic(bool isStatic);
std::string getSignature() const;
void setSignature(const std::string& signature);
// Logging. // Logging.
std::string getTypeString(NodeType type) const; std::string getTypeString(NodeType type) const;
std::string getAsString() const; std::string getAsString() const;
private: private:
// Constructor for plain copies. void operator=(const Node&);
Node(Id id, NodeType type, const std::string& name);
NodeType m_type; NodeType m_type;
std::string m_name; std::string m_name;
std::vector<Edge*> m_edges; std::vector<Edge*> 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); std::ostream& operator<<(std::ostream& ostream, const Node& node);
+11 -2
View File
@@ -41,9 +41,18 @@ void Token::removeLocationId(Id locationId)
LOG_ERROR("Location Id was not referenced by this Token."); LOG_ERROR("Location Id was not referenced by this Token.");
} }
Token::Token(Id id) Token::Token(const Token& other)
: m_id(id) : m_id(other.m_id)
{ {
for (std::shared_ptr<TokenComponent> component: other.m_components)
{
addComponent(component->copy());
}
}
void Token::addComponent(std::shared_ptr<TokenComponent> component)
{
m_components.push_back(component);
} }
Id Token::s_nextId = 1; Id Token::s_nextId = 1;
+41 -3
View File
@@ -1,8 +1,10 @@
#ifndef TOKEN_H #ifndef TOKEN_H
#define TOKEN_H #define TOKEN_H
#include <typeinfo>
#include <vector> #include <vector>
#include "data/graph/token_component/TokenComponent.h"
#include "utility/types.h" #include "utility/types.h"
class Token class Token
@@ -21,19 +23,55 @@ public:
void addLocationId(Id locationId); void addLocationId(Id locationId);
void removeLocationId(Id locationId); void removeLocationId(Id locationId);
template <typename ComponentType>
ComponentType* getComponent() const;
template <typename ComponentType>
std::shared_ptr<ComponentType> removeComponent();
protected: protected:
// Constructor for plain copies of Node and Edge Token(const Token& other);
Token(Id id);
void addComponent(std::shared_ptr<TokenComponent> component);
void copyComponentsFrom(const Token& other);
private: private:
static Id s_nextId; static Id s_nextId;
Token(const Token&);
void operator=(const Token&); void operator=(const Token&);
const Id m_id; // own id const Id m_id; // own id
std::vector<Id> m_locationIds; std::vector<Id> m_locationIds;
std::vector<std::shared_ptr<TokenComponent>> m_components;
}; };
template <typename ComponentType>
ComponentType* Token::getComponent() const
{
for (std::shared_ptr<TokenComponent> component: m_components)
{
if (typeid(ComponentType) == typeid(*(component.get())))
{
return dynamic_cast<ComponentType*>(component.get());
}
}
return nullptr;
}
template <typename ComponentType>
std::shared_ptr<ComponentType> Token::removeComponent()
{
for (size_t i = 0; i < m_components.size(); i++)
{
std::shared_ptr<TokenComponent> component = m_components[i];
if (typeid(ComponentType) == typeid(*(component.get())))
{
m_components.erase(m_components.begin() + i);
return std::dynamic_pointer_cast<ComponentType>(component);
}
}
return nullptr;
}
#endif // TOKEN_H #endif // TOKEN_H
@@ -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;
}
@@ -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<EdgeComponent> copy() const = 0;
void setEdge(Edge* edge);
protected:
Edge* getEdge() const;
private:
Edge* m_edge;
};
#endif // EDGE_COMPONENT_H
@@ -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<EdgeComponent> EdgeComponentDataType::copy() const
{
return std::make_shared<EdgeComponentDataType>(m_qualifierList, m_modifierStack);
}
DataType EdgeComponentDataType::getDataType() const
{
return DataType(getEdge()->getTo()->getName(), m_qualifierList, m_modifierStack);
}
@@ -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<EdgeComponent> copy() const;
DataType getDataType() const;
private:
const DataTypeQualifierList m_qualifierList;
const DataTypeModifierStack m_modifierStack;
};
#endif // EDGE_COMPONENT_DATA_TYPE_H
@@ -0,0 +1,5 @@
#include "data/graph/token_component/TokenComponent.h"
TokenComponent::~TokenComponent()
{
}
@@ -0,0 +1,13 @@
#ifndef TOKEN_COMPONENT_H
#define TOKEN_COMPONENT_H
#include <memory>
class TokenComponent
{
public:
virtual ~TokenComponent();
virtual std::shared_ptr<TokenComponent> copy() const = 0;
};
#endif // TOKEN_COMPONENT_H
@@ -0,0 +1,36 @@
#include "data/graph/token_component/TokenComponentAccess.h"
TokenComponentAccess::TokenComponentAccess(AccessType access)
: m_access(access)
{
}
TokenComponentAccess::~TokenComponentAccess()
{
}
std::shared_ptr<TokenComponent> TokenComponentAccess::copy() const
{
return std::make_shared<TokenComponentAccess>(*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 "";
}
@@ -0,0 +1,33 @@
#ifndef TOKEN_COMPONENT_ACCESS
#define TOKEN_COMPONENT_ACCESS
#include <string>
#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<TokenComponent> copy() const;
AccessType getAccess() const;
std::string getAccessString() const;
private:
const AccessType m_access;
};
#endif // TOKEN_COMPONENT_ACCESS
@@ -0,0 +1,6 @@
#include "data/graph/token_component/TokenComponentConst.h"
std::shared_ptr<TokenComponent> TokenComponentConst::copy() const
{
return std::make_shared<TokenComponentConst>(*this);
}
@@ -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<TokenComponent> copy() const;
};
#endif // TOKEN_COMPONENT_CONST
@@ -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<TokenComponent> TokenComponentDataType::copy() const
{
return std::make_shared<TokenComponentDataType>(*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));
}
@@ -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<TokenComponent> 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
@@ -0,0 +1,20 @@
#include "data/graph/token_component/TokenComponentSignature.h"
TokenComponentSignature::TokenComponentSignature(std::string signature)
: m_signature(signature)
{
}
TokenComponentSignature::~TokenComponentSignature()
{
}
std::shared_ptr<TokenComponent> TokenComponentSignature::copy() const
{
return std::make_shared<TokenComponentSignature>(*this);
}
const std::string& TokenComponentSignature::getSignature() const
{
return m_signature;
}
@@ -0,0 +1,23 @@
#ifndef TOKEN_COMPONENT_SIGNATURE
#define TOKEN_COMPONENT_SIGNATURE
#include <string>
#include "data/graph/token_component/TokenComponent.h"
class TokenComponentSignature
: public TokenComponent
{
public:
TokenComponentSignature(std::string signature);
virtual ~TokenComponentSignature();
virtual std::shared_ptr<TokenComponent> copy() const;
const std::string& getSignature() const;
private:
const std::string m_signature;
};
#endif // TOKEN_COMPONENT_SIGNATURE
@@ -0,0 +1,6 @@
#include "data/graph/token_component/TokenComponentStatic.h"
std::shared_ptr<TokenComponent> TokenComponentStatic::copy() const
{
return std::make_shared<TokenComponentStatic>(*this);
}
@@ -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<TokenComponent> copy() const;
};
#endif // TOKEN_COMPONENT_STATIC
+189 -29
View File
@@ -1,32 +1,153 @@
#include "cxxtest/TestSuite.h" #include "cxxtest/TestSuite.h"
#include "data/graph/Graph.h" #include "data/graph/Graph.h"
#include "data/graph/edgeComponent/EdgeComponentDataType.h"
#include "data/type/modifier/DataTypeModifierPointer.h"
class GraphTestSuite : public CxxTest::TestSuite class GraphTestSuite : public CxxTest::TestSuite
{ {
public: public:
void test_tokens_get_unique_id() void test_tokens_get_unique_id()
{ {
Node a(Node::NODE_UNDEFINED, "A"); TestToken a;
Node b(Node::NODE_UNDEFINED, "B"); TestToken b;
Node c(Node::NODE_UNDEFINED, "C"); TestToken c;
TS_ASSERT_DIFFERS(a.getId(), c.getId()); TS_ASSERT_DIFFERS(a.getId(), c.getId());
TS_ASSERT_DIFFERS(a.getId(), b.getId()); TS_ASSERT_DIFFERS(a.getId(), b.getId());
TS_ASSERT_DIFFERS(b.getId(), c.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"); TestToken a;
TS_ASSERT_EQUALS(Node::NODE_NAMESPACE, n.getType()); 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<TestComponent> component = std::make_shared<TestComponent>();
a.addComponent(component);
TS_ASSERT(a.getComponent<TestComponent>());
TS_ASSERT(!a.getComponent<Test2Component>());
TS_ASSERT_EQUALS(a.getComponent<TestComponent>(), component.get());
}
void test_token_saves_multiple_components()
{
TestToken a;
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
a.addComponent(component2);
a.addComponent(component);
TS_ASSERT(a.getComponent<TestComponent>());
TS_ASSERT(a.getComponent<Test2Component>());
TS_ASSERT_EQUALS(a.getComponent<TestComponent>(), component.get());
TS_ASSERT_EQUALS(a.getComponent<Test2Component>(), component2.get());
}
void test_token_removes_component()
{
TestToken a;
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
a.addComponent(component2);
a.addComponent(component);
std::shared_ptr<TestComponent> component3 = a.removeComponent<TestComponent>();
TS_ASSERT(!a.getComponent<TestComponent>());
TS_ASSERT(a.getComponent<Test2Component>());
TS_ASSERT_EQUALS(component3.get(), component.get());
TS_ASSERT_EQUALS(a.getComponent<Test2Component>(), component2.get());
}
void test_token_copies_components_when_token_is_copied()
{
TestToken a;
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
a.addComponent(component2);
a.addComponent(component);
TestToken b(a);
TS_ASSERT(b.getComponent<TestComponent>());
TS_ASSERT(b.getComponent<Test2Component>());
TS_ASSERT_DIFFERS(b.getComponent<TestComponent>(), component.get());
TS_ASSERT_DIFFERS(b.getComponent<Test2Component>(), 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); n.setType(Node::NODE_CLASS);
TS_ASSERT_EQUALS(Node::NODE_CLASS, n.getType()); 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() void test_get_type_of_edges()
{ {
Node a(Node::NODE_UNDEFINED, "A"); Node a(Node::NODE_UNDEFINED, "A");
@@ -36,19 +157,16 @@ public:
TS_ASSERT_EQUALS(Edge::EDGE_TYPE_OF, e.getType()); 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"); Node a(Node::NODE_UNDEFINED, "A");
TS_ASSERT(!n.isConst()); Node b(Node::NODE_UNDEFINED, "B");
TS_ASSERT(!n.isStatic()); Edge e(Edge::EDGE_TYPE_OF, &a, &b);
Edge e2(e, &a, &b);
n.setConst(true); TS_ASSERT_DIFFERS(&e, &e2);
TS_ASSERT(n.isConst()); TS_ASSERT_EQUALS(e.getId(), e2.getId());
TS_ASSERT(!n.isStatic()); TS_ASSERT_EQUALS(e.getType(), e2.getType());
n.setStatic(true);
TS_ASSERT(n.isConst());
TS_ASSERT(n.isStatic());
} }
void test_graph_saves_nodes() void test_graph_saves_nodes()
@@ -197,14 +315,6 @@ public:
TS_ASSERT_EQUALS(Node::NODE_UNDEFINED, graph.getNode("A::B::C::D::E")->getType()); 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() void test_visit_each_token_on_graph()
{ {
TestGraph graph; TestGraph graph;
@@ -251,7 +361,6 @@ public:
{ {
TestGraph graph; TestGraph graph;
Node* b = graph.createNodeHierarchy("A::B"); Node* b = graph.createNodeHierarchy("A::B");
b->getMemberEdge()->setAccess(Edge::ACCESS_PUBLIC);
graph.createNodeHierarchy("A::B::C"); graph.createNodeHierarchy("A::B::C");
Node* d = graph.createNodeHierarchy("D"); Node* d = graph.createNodeHierarchy("D");
Node* e = graph.createNodeHierarchy("E"); Node* e = graph.createNodeHierarchy("E");
@@ -279,10 +388,61 @@ public:
TS_ASSERT(plainGraph.getNode("A::B::C")); TS_ASSERT(plainGraph.getNode("A::B::C"));
TS_ASSERT(plainGraph.getNode("D")); TS_ASSERT(plainGraph.getNode("D"));
TS_ASSERT(!plainGraph.getNode("E")); TS_ASSERT(!plainGraph.getNode("E"));
TS_ASSERT_EQUALS(Edge::ACCESS_PUBLIC, plainGraph.getNode("A::B")->getMemberEdge()->getAccess());
} }
private: 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<TokenComponent> component)
{
Token::addComponent(component);
}
template<typename ComponentType>
std::shared_ptr<ComponentType> removeComponent()
{
return Token::removeComponent<ComponentType>();
}
};
class TestComponent: public TokenComponent
{
public:
virtual std::shared_ptr<TokenComponent> copy() const
{
return std::make_shared<TestComponent>(*this);
}
};
class Test2Component: public TokenComponent
{
public:
virtual std::shared_ptr<TokenComponent> copy() const
{
return std::make_shared<Test2Component>(*this);
}
};
class TestGraph: public Graph class TestGraph: public Graph
{ {
public: public: