data: cleaned up Graph classes

* removed self assignment of id from Token
* removed FilterableGraph interface from Graph
* creating Nodes and Edges on Graph with addNode and addGraph methods
* removed obsolete Aggregation edge filtering
* fixed clang warnings
* fixed memory leak for Node creation
This commit is contained in:
Eberhard Graether
2015-08-27 17:25:52 +02:00
parent e628241b02
commit 2044ff9723
16 changed files with 253 additions and 332 deletions
-2
View File
@@ -88,8 +88,6 @@ void Project::clearStorage()
{
m_storage = std::make_shared<Storage>();
m_storageAccessProxy->setSubject(m_storage.get());
Token::resetNextId();
}
void Project::parseCode()
+23 -38
View File
@@ -537,8 +537,6 @@ Id Storage::getIdForEdgeWithName(const std::string& name) const
int sourceId = getIdForNodeWithName(sourceName);
int targetId = getIdForNodeWithName(targetName);
int sourceId2 = m_sqliteStorage.getNodeByName(sourceName).id;
int targetId2 = m_sqliteStorage.getNodeByName(targetName).id;
return m_sqliteStorage.getEdgeBySourceTargetType(sourceId, targetId, type).id;
}
@@ -586,13 +584,10 @@ std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& qu
std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const
{
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
std::shared_ptr<Graph> g = std::make_shared<Graph>();
Graph* graph = g.get();
if (tokenIds.size() == 0)
{
return graph;
}
else if (tokenIds.size() == 1)
if (tokenIds.size() == 1)
{
const Id elementId = tokenIds[0];
@@ -605,16 +600,12 @@ std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>&
std::vector<StorageEdge> edges = m_sqliteStorage.getEdgesBySourceId(node.id);
utility::append(edges, m_sqliteStorage.getEdgesByTargetId(node.id));
const Node::NodeTypeMask varFuncMask =
Node::NODE_UNDEFINED_FUNCTION | Node::NODE_FUNCTION | Node::NODE_METHOD |
Node::NODE_UNDEFINED_VARIABLE | Node::NODE_GLOBAL_VARIABLE | Node::NODE_FIELD;
const Node::NodeTypeMask typeMask = Node::NODE_STRUCT | Node::NODE_CLASS;
const Node::NodeTypeMask nodeTypeMask = Node::NODE_STRUCT | Node::NODE_CLASS;
const Edge::EdgeTypeMask edgeTypeMask = Edge::EDGE_TYPE_USAGE | Edge::EDGE_TYPE_OF;
for (size_t i = 0; i < edges.size(); i++)
{
if (((node.type & varFuncMask) > 0 && ((edges[i].type & Edge::EDGE_AGGREGATION) > 0)) || // TODO: remove this since we do not save any aggregation edges
((node.type & typeMask) > 0 && ((edges[i].type & (Edge::EDGE_TYPE_USAGE | Edge::EDGE_TYPE_OF)) > 0)))
if ((node.type & nodeTypeMask) > 0 && (edges[i].type & edgeTypeMask) > 0)
{
continue;
}
@@ -645,7 +636,7 @@ std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>&
}
}
return graph;
return g;
}
std::vector<Id> Storage::getActiveTokenIdsForId(Id tokenId, Id* declarationId) const // TODO: rename: getActiveElementIdsForId; TODO: make separate function for declarationId
@@ -695,7 +686,7 @@ std::vector<Id> Storage::getTokenIdsForQuery(std::string query) const // TODO: r
}
std::string tokenName = tokenizedQuery[0];
tokenName.erase(std::remove(tokenName.begin(), tokenName.end(), '"'), tokenName.end());
const int delimiterPos = tokenName.rfind(',');
const size_t delimiterPos = tokenName.rfind(',');
if (delimiterPos != tokenName.npos)
{
@@ -1031,6 +1022,7 @@ int Storage::addSourceLocation(int elementNodeId, const ParseLocation& location,
if (location.filePath.empty())
{
LOG_ERROR("no filename set!");
return 0;
}
else
{
@@ -1095,7 +1087,7 @@ std::vector<Id> Storage::getAllChildNodeIds(const Id nodeId) const
return childNodeIds;
}
void Storage::addEdgeAndAllChildrenToGraph(const Id edgeId, std::shared_ptr<Graph> graph) const
void Storage::addEdgeAndAllChildrenToGraph(const Id edgeId, Graph* graph) const
{
StorageEdge storageEdge = m_sqliteStorage.getEdgeById(edgeId);
@@ -1105,15 +1097,14 @@ void Storage::addEdgeAndAllChildrenToGraph(const Id edgeId, std::shared_ptr<Grap
Node* sourceNode = graph->getNodeById(storageEdge.sourceNodeId);
Node* targetNode = graph->getNodeById(storageEdge.targetNodeId);
std::shared_ptr<Edge> edge = std::make_shared<Edge>(edgeId, Edge::intToType(storageEdge.type), sourceNode, targetNode);
graph->addEdge(edge.get());
graph->addEdge(edgeId, Edge::intToType(storageEdge.type), sourceNode, targetNode);
}
void Storage::addNodeAndAllChildrenToGraph(const Id nodeId, std::shared_ptr<Graph> graph) const
void Storage::addNodeAndAllChildrenToGraph(const Id nodeId, Graph* graph) const
{
if (!graph->getNodeById(nodeId))
{
graph->addNode(createNodeForNodeId(nodeId));
addNodeToGraph(nodeId, graph);
}
std::queue<StorageEdge> unprocessedEdges;
@@ -1133,19 +1124,16 @@ void Storage::addNodeAndAllChildrenToGraph(const Id nodeId, std::shared_ptr<Grap
Node* sourceNode = graph->getNodeById(storageEdge.sourceNodeId);
if (!sourceNode)
{
sourceNode = createNodeForNodeId(storageEdge.sourceNodeId);
graph->addNode(sourceNode);
sourceNode = addNodeToGraph(storageEdge.sourceNodeId, graph);
}
Node* targetNode = graph->getNodeById(storageEdge.targetNodeId);
if (!targetNode)
{
targetNode = createNodeForNodeId(storageEdge.targetNodeId);
graph->addNode(targetNode);
targetNode = addNodeToGraph(storageEdge.targetNodeId, graph);
}
std::shared_ptr<Edge> edge = std::make_shared<Edge>(storageEdge.id, Edge::intToType(storageEdge.type), sourceNode, targetNode);
graph->addEdge(edge.get());
graph->addEdge(storageEdge.id, Edge::intToType(storageEdge.type), sourceNode, targetNode);
{
std::vector<StorageEdge> edges = m_sqliteStorage.getEdgesBySourceType(storageEdge.targetNodeId, Edge::EDGE_MEMBER);
@@ -1157,7 +1145,7 @@ void Storage::addNodeAndAllChildrenToGraph(const Id nodeId, std::shared_ptr<Grap
}
}
void Storage::addAggregationEdgesToGraph(const Id nodeId, std::shared_ptr<Graph> graph) const
void Storage::addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const
{
struct EdgeInfo
{
@@ -1245,8 +1233,7 @@ void Storage::addAggregationEdgesToGraph(const Id nodeId, std::shared_ptr<Graph>
Node* sourceNode = graph->getNodeById(nodeId);
if (!sourceNode)
{
sourceNode = createNodeForNodeId(nodeId);
graph->addNode(sourceNode);
sourceNode = addNodeToGraph(nodeId, graph);
}
for (std::map<Id, std::vector<EdgeInfo>>::const_iterator it = connectedParentNodeIds.begin(); it != connectedParentNodeIds.end(); it++)
@@ -1255,8 +1242,7 @@ void Storage::addAggregationEdgesToGraph(const Id nodeId, std::shared_ptr<Graph>
Node* targetNode = graph->getNodeById(aggregationTargetNodeId);
if (!targetNode)
{
targetNode = createNodeForNodeId(aggregationTargetNodeId);
graph->addNode(targetNode);
targetNode = addNodeToGraph(aggregationTargetNodeId, graph);
}
std::shared_ptr<TokenComponentAggregation> componentAggregation = std::make_shared<TokenComponentAggregation>();
@@ -1265,19 +1251,18 @@ void Storage::addAggregationEdgesToGraph(const Id nodeId, std::shared_ptr<Graph>
componentAggregation->addAggregationId(edgeInfo.edgeId, edgeInfo.forward);
}
std::shared_ptr<Edge> edge = std::make_shared<Edge>(0, Edge::EDGE_AGGREGATION, sourceNode, targetNode);
Edge* edge = graph->addEdge(0, Edge::EDGE_AGGREGATION, sourceNode, targetNode);
edge->addComponentAggregation(componentAggregation);
graph->addEdge(edge.get());
}
}
Node* Storage::createNodeForNodeId(const Id nodeId) const
Node* Storage::addNodeToGraph(const Id nodeId, Graph* graph) const
{
StorageNode storageNode = m_sqliteStorage.getNodeById(nodeId);
Node* n = new Node( // TODO: causes memory leaks. refactor graph to operate on shared ptrs.
return graph->addNode(
storageNode.id,
Node::intToType(storageNode.type),
std::make_shared<TokenComponentNameCached>(m_sqliteStorage.getNameHierarchyById(storageNode.nameId))
);
return n;
}
+4 -4
View File
@@ -149,10 +149,10 @@ private:
std::vector<Id> getDirectChildNodeIds(const Id nodeId) const;
std::vector<Id> getAllChildNodeIds(const Id nodeId) const;
void addEdgeAndAllChildrenToGraph(const Id edgeId, std::shared_ptr<Graph> graph) const;
void addNodeAndAllChildrenToGraph(const Id nodeId, std::shared_ptr<Graph> graph) const;
void addAggregationEdgesToGraph(const Id nodeId, std::shared_ptr<Graph> graph) const;
Node* createNodeForNodeId(const Id nodeId) const;
void addEdgeAndAllChildrenToGraph(const Id edgeId, Graph* graph) const;
void addNodeAndAllChildrenToGraph(const Id nodeId, Graph* graph) const;
void addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const;
Node* addNodeToGraph(const Id nodeId, Graph* graph) const;
SearchIndex m_tokenIndex;
SqliteStorage m_sqliteStorage;
+6 -10
View File
@@ -50,17 +50,8 @@ Edge::EdgeType Edge::intToType(int value)
case 0x8000:
return EDGE_AGGREGATION;
}
}
Edge::Edge(EdgeType type, Node* from, Node* to)
: m_type(type)
, m_from(from)
, m_to(to)
{
m_from->addEdge(this);
m_to->addEdge(this);
checkType();
return EDGE_NONE;
}
Edge::Edge(Id id, EdgeType type, Node* from, Node* to)
@@ -189,6 +180,8 @@ std::string Edge::getTypeString(EdgeType type)
{
switch (type)
{
case EDGE_NONE:
return "none";
case EDGE_MEMBER:
return "child";
case EDGE_TYPE_OF:
@@ -265,6 +258,9 @@ bool Edge::checkType() const
switch (m_type)
{
case EDGE_NONE:
break;
case EDGE_MEMBER:
if (!m_from->isType(typeMask | Node::NODE_NAMESPACE | functionMask) ||
(!m_from->isType(Node::NODE_UNDEFINED | Node::NODE_NAMESPACE) && m_to->isType(Node::NODE_NAMESPACE)) ||
+4 -2
View File
@@ -11,12 +11,14 @@ class TokenComponentAggregation;
class TokenComponentAccess;
class TokenComponentDataType;
class Edge: public Token
class Edge
: public Token
{
public:
typedef int EdgeTypeMask;
enum EdgeType : EdgeTypeMask
{
EDGE_NONE = 0x0,
EDGE_MEMBER = 0x1,
EDGE_TYPE_OF = 0x2,
EDGE_RETURN_TYPE_OF = 0x4, // unused: see Storage::addFunctionNode()
@@ -36,10 +38,10 @@ public:
EDGE_AGGREGATION = 0x8000
};
static int typeToInt(EdgeType type);
static EdgeType intToType(int value);
Edge(EdgeType type, Node* from, Node* to);
Edge(Id id, EdgeType type, Node* from, Node* to);
Edge(const Edge& other, Node* from, Node* to);
virtual ~Edge();
+24 -17
View File
@@ -12,24 +12,12 @@ Graph::~Graph()
m_nodes.clear();
}
void Graph::copy(const Graph* other)
{
clear();
add(other);
}
void Graph::clear()
{
m_edges.clear();
m_nodes.clear();
}
void Graph::add(const Graph* other)
{
other->forEachNode(std::bind(&Graph::addNode, this, std::placeholders::_1));
other->forEachEdge(std::bind(&Graph::addEdge, this, std::placeholders::_1));
}
void Graph::forEachNode(std::function<void(Node*)> func) const
{
for (const std::pair<Id, std::shared_ptr<Node>>& node : m_nodes)
@@ -52,17 +40,36 @@ void Graph::forEachToken(std::function<void(Token*)> func) const
forEachEdge(func);
}
void Graph::addNode(Node* node)
Node* Graph::addNode(Id id, Node::NodeType type, std::shared_ptr<TokenComponentName> nameComponent)
{
addNodeAsPlainCopy(node);
Node* n = getNodeById(id);
if (n)
{
return n;
}
std::shared_ptr<Node> node = std::make_shared<Node>(id, type, nameComponent);
m_nodes.emplace(node->getId(), node);
return node.get();
}
void Graph::addEdge(Edge* edge)
Edge* Graph::addEdge(Id id, Edge::EdgeType type, Node* from, Node* to)
{
if (getNodeById(edge->getFrom()->getId()) && getNodeById(edge->getTo()->getId()))
Edge* e = getEdgeById(id);
if (e)
{
addEdgeAsPlainCopy(edge);
return e;
}
if (!getNodeById(from->getId()) || !getNodeById(to->getId()))
{
LOG_ERROR("Can't add edge, without adding the nodes first.");
return nullptr;
}
std::shared_ptr<Edge> edge = std::make_shared<Edge>(id, type, from, to);
m_edges.emplace(edge->getId(), edge);
return edge.get();
}
size_t Graph::getNodeCount() const
+13 -18
View File
@@ -14,24 +14,20 @@ public:
Graph();
virtual ~Graph();
// FilterableGraph implementation // deprecated
virtual void copy(const Graph* other);
virtual void clear();
void clear();
virtual void add(const Graph* other);
void forEachNode(std::function<void(Node*)> func) const;
void forEachEdge(std::function<void(Edge*)> func) const;
void forEachToken(std::function<void(Token*)> func) const;
virtual void forEachNode(std::function<void(Node*)> func) const;
virtual void forEachEdge(std::function<void(Edge*)> func) const;
virtual void forEachToken(std::function<void(Token*)> func) const;
Node* addNode(Id id, Node::NodeType type, std::shared_ptr<TokenComponentName> nameComponent);
Edge* addEdge(Id id, Edge::EdgeType type, Node* from, Node* to);
virtual void addNode(Node* node);
virtual void addEdge(Edge* edge);
size_t getNodeCount() const;
size_t getEdgeCount() const;
virtual size_t getNodeCount() const;
virtual size_t getEdgeCount() const;
virtual Node* getNodeById(Id id) const;
virtual Edge* getEdgeById(Id id) const;
Node* getNodeById(Id id) const;
Edge* getEdgeById(Id id) const;
const std::map<Id, std::shared_ptr<Node>>& getNodes() const;
const std::map<Id, std::shared_ptr<Edge>>& getEdges() const;
@@ -57,15 +53,14 @@ public:
void print(std::ostream& ostream) const;
void printBasic(std::ostream& ostream) const;
protected:
std::map<Id, std::shared_ptr<Node>> m_nodes;
std::map<Id, std::shared_ptr<Edge>> m_edges;
private:
Graph(const Graph&);
void operator=(const Graph&);
void removeEdgeInternal(Edge* edge);
std::map<Id, std::shared_ptr<Node>> m_nodes;
std::map<Id, std::shared_ptr<Edge>> m_edges;
};
std::ostream& operator<<(std::ostream& ostream, const Graph& graph);
+82 -89
View File
@@ -2,7 +2,6 @@
#include <sstream>
#include "utility/file/FileSystem.h"
#include "utility/logging/logging.h"
#include "data/graph/token_component/TokenComponentAbstraction.h"
@@ -12,10 +11,89 @@
#include "data/graph/token_component/TokenComponentSignature.h"
#include "data/graph/token_component/TokenComponentFilePath.h"
Node::Node(NodeType type, std::shared_ptr<TokenComponentName> nameComponent)
: m_type(type)
, m_nameComponent(nameComponent)
std::string Node::getTypeString(NodeType type)
{
switch (type)
{
case NODE_UNDEFINED:
return "undefined";
case NODE_UNDEFINED_FUNCTION:
return "undefined_function";
case NODE_UNDEFINED_VARIABLE:
return "undefined_variable";
case NODE_UNDEFINED_TYPE:
return "undefined_type";
case NODE_CLASS:
return "class";
case NODE_STRUCT:
return "struct";
case NODE_GLOBAL_VARIABLE:
return "global";
case NODE_FIELD:
return "field";
case NODE_FUNCTION:
return "function";
case NODE_METHOD:
return "method";
case NODE_NAMESPACE:
return "namespace";
case NODE_ENUM:
return "enum";
case NODE_ENUM_CONSTANT:
return "enum_constant";
case NODE_TYPEDEF:
return "typedef";
case NODE_TEMPLATE_PARAMETER_TYPE:
return "template_parameter_type";
case NODE_FILE:
return "file";
}
return "";
}
int Node::typeToInt(NodeType type)
{
return type;
}
Node::NodeType Node::intToType(int value)
{
switch (value)
{
case 0x1:
return NODE_UNDEFINED;
case 0x2:
return NODE_UNDEFINED_TYPE;
case 0x4:
return NODE_UNDEFINED_VARIABLE;
case 0x8:
return NODE_UNDEFINED_FUNCTION;
case 0x10:
return NODE_STRUCT;
case 0x20:
return NODE_CLASS;
case 0x40:
return NODE_GLOBAL_VARIABLE;
case 0x80:
return NODE_FIELD;
case 0x100:
return NODE_FUNCTION;
case 0x200:
return NODE_METHOD;
case 0x400:
return NODE_NAMESPACE;
case 0x800:
return NODE_ENUM;
case 0x1000:
return NODE_ENUM_CONSTANT;
case 0x2000:
return NODE_TYPEDEF;
case 0x4000:
return NODE_TEMPLATE_PARAMETER_TYPE;
case 0x8000:
return NODE_FILE;
}
return NODE_UNDEFINED;
}
Node::Node(Id id, NodeType type, std::shared_ptr<TokenComponentName> nameComponent)
@@ -338,91 +416,6 @@ void Node::addComponentFilePath(std::shared_ptr<TokenComponentFilePath> componen
}
}
std::string Node::getTypeString(NodeType type)
{
switch (type)
{
case NODE_UNDEFINED:
return "undefined";
case NODE_UNDEFINED_FUNCTION:
return "undefined_function";
case NODE_UNDEFINED_VARIABLE:
return "undefined_variable";
case NODE_UNDEFINED_TYPE:
return "undefined_type";
case NODE_CLASS:
return "class";
case NODE_STRUCT:
return "struct";
case NODE_GLOBAL_VARIABLE:
return "global";
case NODE_FIELD:
return "field";
case NODE_FUNCTION:
return "function";
case NODE_METHOD:
return "method";
case NODE_NAMESPACE:
return "namespace";
case NODE_ENUM:
return "enum";
case NODE_ENUM_CONSTANT:
return "enum_constant";
case NODE_TYPEDEF:
return "typedef";
case NODE_TEMPLATE_PARAMETER_TYPE:
return "template_parameter_type";
case NODE_FILE:
return "file";
}
return "";
}
int Node::typeToInt(NodeType type)
{
return type;
}
Node::NodeType Node::intToType(int value)
{
switch (value)
{
case 0x1:
return NODE_UNDEFINED;
case 0x2:
return NODE_UNDEFINED_TYPE;
case 0x4:
return NODE_UNDEFINED_VARIABLE;
case 0x8:
return NODE_UNDEFINED_FUNCTION;
case 0x10:
return NODE_STRUCT;
case 0x20:
return NODE_CLASS;
case 0x40:
return NODE_GLOBAL_VARIABLE;
case 0x80:
return NODE_FIELD;
case 0x100:
return NODE_FUNCTION;
case 0x200:
return NODE_METHOD;
case 0x400:
return NODE_NAMESPACE;
case 0x800:
return NODE_ENUM;
case 0x1000:
return NODE_ENUM_CONSTANT;
case 0x2000:
return NODE_TYPEDEF;
case 0x4000:
return NODE_TEMPLATE_PARAMETER_TYPE;
case 0x8000:
return NODE_FILE;
}
return NODE_UNDEFINED;
}
std::string Node::getTypeString() const
{
return getTypeString(m_type);
+2 -2
View File
@@ -16,7 +16,8 @@ class TokenComponentStatic;
class TokenComponentSignature;
class TokenComponentFilePath;
class Node: public Token
class Node
: public Token
{
public:
typedef int NodeTypeMask;
@@ -47,7 +48,6 @@ public:
static int typeToInt(NodeType type);
static NodeType intToType(int value);
Node(NodeType type, std::shared_ptr<TokenComponentName> nameComponent);
Node(Id id, NodeType type, std::shared_ptr<TokenComponentName> nameComponent);
Node(const Node& other);
virtual ~Node();
-12
View File
@@ -3,16 +3,6 @@
#include "data/location/TokenLocation.h"
#include "utility/logging/logging.h"
void Token::resetNextId()
{
s_nextId = 1;
}
Token::Token() // TODO: remove this constructor
: m_id(s_nextId++)
{
}
Token::Token(Id id)
: m_id(id)
{
@@ -64,5 +54,3 @@ void Token::addComponent(std::shared_ptr<TokenComponent> component)
{
m_components.push_back(component);
}
Id Token::s_nextId = 1;
+1 -6
View File
@@ -10,10 +10,7 @@
class Token
{
public:
static void resetNextId();
Token();
Token(Id id);
explicit Token(Id id);
virtual ~Token();
Id getId() const;
@@ -42,8 +39,6 @@ protected:
void copyComponentsFrom(const Token& other);
private:
static Id s_nextId;
void operator=(const Token&);
const Id m_id; // own id