data: database storage

* replaced storage by a new version that utilizes sqlite for persistence.
* added SqliteStorage to manage direct access to the database.
* added testsuit for sqlite.
* slimmed down the protected interface of the storage.
* changed tests in StorageTestSuit to avoid using protected methods of the storage.
* added functions to begin and commit a transaction to the storage.
* removed GraphFilterTestSuite.
* removed GraphFilterConductorTestSuite.
* added Node and Edge constructor that takes id as parameter
* added constructor for TokenComponentNameCached that accepts NameHierarchy as parameter
* added TokenLocation constructor that takes locationId as parameter.
* created respective construction functions in TokenLocatonLine, -File and -Collection.

fortune cookie message = Recognition will come from unexpected sources.
This commit is contained in:
malte_langkabel
2015-08-25 18:07:02 +02:00
parent d996cf384d
commit e628241b02
63 changed files with 167982 additions and 3582 deletions
+3 -12
View File
@@ -101,12 +101,6 @@ add_files(
data/access/StorageAccessProxy.cpp
data/access/StorageAccessProxy.h
data/graph/filter/GraphFilter.cpp
data/graph/filter/GraphFilter.h
data/graph/filter/GraphFilterConductor.cpp
data/graph/filter/GraphFilterConductor.h
data/graph/filter/GraphFilterImplementations.h
data/graph/token_component/TokenComponent.cpp
data/graph/token_component/TokenComponent.h
data/graph/token_component/TokenComponentAbstraction.cpp
@@ -128,16 +122,10 @@ add_files(
data/graph/Edge.cpp
data/graph/Edge.h
data/graph/FilterableGraph.cpp
data/graph/FilterableGraph.h
data/graph/Graph.cpp
data/graph/Graph.h
data/graph/Node.cpp
data/graph/Node.h
data/graph/StorageGraph.cpp
data/graph/StorageGraph.h
data/graph/SubGraph.cpp
data/graph/SubGraph.h
data/graph/Token.cpp
data/graph/Token.h
@@ -204,10 +192,13 @@ add_files(
data/type/ReferenceModifiedDataType.cpp
data/type/ReferenceModifiedDataType.h
data/SqliteStorage.cpp
data/SqliteStorage.h
data/Storage.cpp
data/Storage.h
data/StorageCache.cpp
data/StorageCache.h
data/StorageTypes.h
settings/ApplicationSettings.cpp
settings/ApplicationSettings.h
@@ -17,31 +17,46 @@ FeatureController::~FeatureController()
void FeatureController::handleMessage(MessageActivateEdge* message)
{
Id edgeId = message->tokenId;
if (!message->isFresh())
if (message->type == Edge::EDGE_AGGREGATION)
{
edgeId = m_storageAccess->getIdForEdgeWithName(message->name);
}
const std::string sourceStartDelimiter = ":";
const std::string sourceEndDelimiter = "->";
if (!edgeId)
{
return;
}
const int sourceStartPosition = message->name.find(sourceStartDelimiter) + sourceStartDelimiter.size();
const int sourceEndPosition = message->name.find(sourceEndDelimiter);
const int targetStartPosition = sourceEndPosition + sourceEndDelimiter.size();
const int targetEndPosition = message->name.size();
if (message->isAggregation())
{
MessageActivateTokens m(m_storageAccess->getTokenIdsForAggregationEdge(edgeId));
const std::string sourceName = message->name.substr(sourceStartPosition, sourceEndPosition - sourceStartPosition);
const std::string targetName = message->name.substr(targetStartPosition, targetEndPosition - targetStartPosition);
const int sourceId = m_storageAccess->getIdForNodeWithName(sourceName);
const int targetId = m_storageAccess->getIdForNodeWithName(targetName);
MessageActivateTokens m(m_storageAccess->getTokenIdsForAggregationEdge(sourceId, targetId));
m.isAggregation = true;
m.undoRedoType = message->undoRedoType;
m.dispatchImmediately();
return;
}
else
{
Id edgeId = message->tokenId;
MessageActivateTokens msg(std::vector<Id>(1, edgeId));
msg.isEdge = true;
msg.undoRedoType = message->undoRedoType;
msg.dispatchImmediately();
if (!message->isFresh())
{
edgeId = m_storageAccess->getIdForEdgeWithName(message->name);
}
if (!edgeId)
{
return;
}
MessageActivateTokens msg(std::vector<Id>(1, edgeId));
msg.isEdge = true;
msg.undoRedoType = message->undoRedoType;
msg.dispatchImmediately();
}
}
void FeatureController::handleMessage(MessageActivateFile* message)
+658
View File
@@ -0,0 +1,658 @@
#include "data/SqliteStorage.h"
#include "data/graph/Node.h"
#include "data/location/TokenLocation.h"
SqliteStorage::SqliteStorage(const std::string& dbFilePath)
{
m_database.open(dbFilePath.c_str());
clear();
}
SqliteStorage::~SqliteStorage()
{
m_database.close();
}
void SqliteStorage::clear()
{
m_database.execDML("PRAGMA foreign_keys=OFF;");
clearTables();
m_database.execDML("PRAGMA foreign_keys=ON;");
setupTables();
}
void SqliteStorage::beginTransaction()
{
m_database.execDML("BEGIN TRANSACTION;");
}
void SqliteStorage::commitTransaction()
{
m_database.execDML("COMMIT TRANSACTION;");
}
void SqliteStorage::rollbackTransaction()
{
m_database.execDML("ROLLBACK TRANSACTION;");
}
Id SqliteStorage::addEdge(int type, Id sourceNodeId, Id targetNodeId)
{
m_database.execDML(
"INSERT INTO element(id) VALUES(NULL);"
);
Id id = m_database.lastRowId();
m_database.execDML((
"INSERT INTO edge(id, type, source_node_id, target_node_id) VALUES("
+ std::to_string(id) + ", " + std::to_string(type) + ", "
+ std::to_string(sourceNodeId) + ", " + std::to_string(targetNodeId) + ");"
).c_str());
return id;
}
Id SqliteStorage::addNode(int type, Id nameId)
{
m_database.execDML(
"INSERT INTO element(id) VALUES(NULL);"
);
Id id = m_database.lastRowId();
m_database.execDML((
"INSERT INTO node(id, type, name_id) VALUES("
+ std::to_string(id) + ", " + std::to_string(type) + ", " + std::to_string(nameId) + ");"
).c_str());
return id;
}
Id SqliteStorage::addFile(Id nameId, const std::string& filePath)
{
Id id = addNode(Node::NODE_FILE, nameId);
m_database.execDML((
"INSERT INTO file(id, path) VALUES("
+ std::to_string(id) + ", '" + filePath + "');"
).c_str());
return id;
}
int SqliteStorage::addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope)
{
m_database.execDML((
"INSERT INTO source_location(id, element_id, file_node_id, start_line, start_column, end_line, end_column, is_scope) "
"VALUES(NULL, " + std::to_string(elementId) + ", " + std::to_string(fileNodeId) + ", "
+ std::to_string(startLine) + ", " + std::to_string(startCol) + ", "
+ std::to_string(endLine) + ", " + std::to_string(endCol) + ", " + std::to_string(isScope) + ");"
).c_str());
return m_database.lastRowId();
}
Id SqliteStorage::addNameHierarchyElement(const std::string& name)
{
m_database.execDML((
"INSERT INTO name_hierarchy_element(id, name, parent_id) "
"VALUES(NULL, '" + name + "', NULL);"
).c_str());
return m_database.lastRowId();
}
Id SqliteStorage::addNameHierarchyElement(const std::string& name, Id parentId)
{
m_database.execDML((
"INSERT INTO name_hierarchy_element(id, name, parent_id) "
"VALUES (NULL, '" + name + "', " + std::to_string(parentId) + ");"
).c_str());
return m_database.lastRowId();
}
void SqliteStorage::removeElement(Id id)
{
m_database.execDML((
"DELETE FROM element WHERE id == " + std::to_string(id) + ";"
).c_str());
}
void SqliteStorage::removeNameHierarchyElement(Id id)
{
m_database.execDML((
"DELETE FROM name_hierarchy_element WHERE id == " + std::to_string(id) + ";"
).c_str());
}
bool SqliteStorage::isEdge(Id elementId) const
{
int count = m_database.execScalar(("SELECT count(*) FROM edge WHERE id = " + std::to_string(elementId) + ";").c_str());
return (count > 0);
}
bool SqliteStorage::isNode(Id elementId) const
{
int count = m_database.execScalar(("SELECT count(*) FROM node WHERE id = " + std::to_string(elementId) + ";").c_str());
return (count > 0);
}
bool SqliteStorage::isFile(Id elementId) const
{
int count = m_database.execScalar(("SELECT count(*) FROM file WHERE id = " + std::to_string(elementId) + ";").c_str());
return (count > 0);
}
StorageEdge SqliteStorage::getEdgeBySourceTargetType(Id sourceId, Id targetId, int type) const
{
StorageEdge edge(
getFirstResult<Id>(
"SELECT id FROM edge WHERE "
"source_node_id == " + std::to_string(sourceId) + " AND "
"target_node_id == " + std::to_string(targetId) + " AND "
"type == " + std::to_string(type) + ";"
),
type, sourceId, targetId
);
return edge;
}
std::vector<StorageEdge> SqliteStorage::getEdgesBySourceId(Id sourceId) const
{
std::vector<StorageEdge> edges;
CppSQLite3Query q = m_database.execQuery((
"SELECT id, type, target_node_id FROM edge WHERE "
"source_node_id == " + std::to_string(sourceId) + ";"
).c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const int type = q.getIntField(1, -1);
const Id targetId = q.getIntField(2, 0);
if (id != 0 && type != -1 && targetId != 0)
{
edges.push_back(StorageEdge(id, type, sourceId, targetId));
}
q.nextRow();
}
return edges;
}
std::vector<StorageEdge> SqliteStorage::getEdgesByTargetId(Id targetId) const
{
std::vector<StorageEdge> edges;
CppSQLite3Query q = m_database.execQuery((
"SELECT id, type, source_node_id FROM edge WHERE "
"target_node_id == " + std::to_string(targetId) + ";"
).c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const int type = q.getIntField(1, -1);
const Id sourceId = q.getIntField(2, 0);
if (id != 0 && type != -1 && targetId != 0)
{
edges.push_back(StorageEdge(id, type, sourceId, targetId));
}
q.nextRow();
}
return edges;
}
std::vector<StorageEdge> SqliteStorage::getEdgesBySourceType(Id sourceId, int type) const
{
std::vector<StorageEdge> edges;
CppSQLite3Query q = m_database.execQuery((
"SELECT id, target_node_id FROM edge WHERE "
"source_node_id == " + std::to_string(sourceId) + " AND "
"type == " + std::to_string(type) + ";"
).c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id targetId = q.getIntField(1, 0);
if (id != 0 && targetId != 0)
{
edges.push_back(StorageEdge(id, type, sourceId, targetId));
}
q.nextRow();
}
return edges;
}
std::vector<StorageEdge> SqliteStorage::getEdgesByTargetType(Id targetId, int type) const
{
std::vector<StorageEdge> edges;
CppSQLite3Query q = m_database.execQuery((
"SELECT id, source_node_id FROM edge WHERE "
"target_node_id == " + std::to_string(targetId) + " AND "
"type == " + std::to_string(type) + ";"
).c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id sourceId = q.getIntField(1, 0);
if (id != 0 && sourceId != 0)
{
edges.push_back(StorageEdge(id, type, sourceId, targetId));
}
q.nextRow();
}
return edges;
}
StorageEdge SqliteStorage::getEdgeById(Id edgeId) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT type, source_node_id, target_node_id FROM edge WHERE "
"id == " + std::to_string(edgeId) + ";"
).c_str());
if (!q.eof())
{
const int type = q.getIntField(0, -1);
const Id sourceId = q.getIntField(1, 0);
const Id targetId = q.getIntField(2, 0);
if (type != -1 && sourceId != 0 && targetId != 0)
{
return StorageEdge(edgeId, type, sourceId, targetId);
}
}
return StorageEdge(0, -1, 0, 0);
}
StorageNode SqliteStorage::getNodeById(Id id) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT type, name_id FROM node WHERE id == " + std::to_string(id) + ";"
).c_str());
if (!q.eof())
{
const int type = q.getIntField(0, -1);
const Id nameId = q.getIntField(1, 0);
if (type != -1 && nameId != 0 )
{
return StorageNode(id, type, nameId);
}
}
return StorageNode(0, -1, 0);
}
StorageNode SqliteStorage::getNodeByNameId(Id nameId) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT id, type FROM node WHERE name_id == " + std::to_string(nameId) + ";"
).c_str());
if (!q.eof())
{
const Id id = q.getIntField(0, 0);
const int type = q.getIntField(1, -1);
if (id != 0 && type != -1)
{
return StorageNode(id, type, nameId);
}
}
return StorageNode(0, -1, 0);
}
StorageNode SqliteStorage::getNodeByName(const std::string& nodeName) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT node.id, node.type, node.name_id FROM node INNER JOIN name_hierarchy_element ON node.name_id = name_hierarchy_element.id WHERE name_hierarchy_element.name = '" + nodeName + "';"
).c_str());
if (!q.eof())
{
const Id id = q.getIntField(0, 0);
const int type = q.getIntField(1, -1);
const Id nameId = q.getIntField(2, 0);
if (id != 0 && type != -1 && nameId != 0)
{
return StorageNode(id, type, nameId);
}
}
return StorageNode(0, -1, 0);
}
StorageFile SqliteStorage::getFileById(const Id id) const
{
return getFirstFile(
"SELECT node.id, node.name_id, file.path FROM node INNER JOIN file ON node.id = file.id "
"WHERE node.id == " + std::to_string(id) + ";"
);
}
StorageFile SqliteStorage::getFileByName(const std::string& fileName) const
{
Id nameId = getNameHierarchyElementIdByName(fileName);
StorageFile storageFile(0, 0, "");
if (nameId != 0)
{
storageFile = getFirstFile(
"SELECT node.id, node.name_id, file.path FROM node INNER JOIN file ON node.id = file.id "
"WHERE node.name_id == " + std::to_string(nameId) + ";"
);
}
return storageFile;
}
void SqliteStorage::setNodeType(int type, Id nodeId)
{
m_database.execDML((
"UPDATE node SET type = " + std::to_string(type) + " WHERE id == " + std::to_string(nodeId) + ";"
).c_str());
}
Id SqliteStorage::getNameHierarchyElementIdByName(const std::string& name) const
{
return getFirstResult<Id>(
"SELECT id FROM name_hierarchy_element WHERE name == '" + name + "';"
);
}
Id SqliteStorage::getNameHierarchyElementIdByName(const std::string& name, Id parentId) const
{
return getFirstResult<Id>(
"SELECT id FROM name_hierarchy_element WHERE name == '" + name + "' AND parent_id == " + std::to_string(parentId) + ";"
);
}
Id SqliteStorage::getNameHierarchyElementIdByNodeId(const Id nodeId) const
{
return getFirstResult<Id>(
"SELECT name_id FROM node WHERE id == " + std::to_string(nodeId) + ";"
);
}
NameHierarchy SqliteStorage::getNameHierarchyById(const Id id) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT name, parent_id FROM name_hierarchy_element WHERE id == " + std::to_string(id) + ";"
).c_str());
const std::string elementName = q.getStringField(0, "");
const Id parentId = q.getIntField(1, 0);
NameHierarchy nameHierarchy = (parentId > 0) ? getNameHierarchyById(parentId) : NameHierarchy();
if (elementName.size() > 0)
{
nameHierarchy.push(std::make_shared<NameElement>(elementName));
}
return nameHierarchy;
}
StorageSourceLocation SqliteStorage::getSourceLocationById(const Id id) const
{
return getFirstSourceLocation(
"SELECT id, element_id, file_node_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE id == " + std::to_string(id) + ";"
);
}
std::vector<StorageSourceLocation> SqliteStorage::getAllSourceLocations() const
{
return getAllSourceLocations(
"SELECT * FROM source_location;"
);
}
std::shared_ptr<TokenLocationFile> SqliteStorage::getTokenLocationsForFile(const FilePath& filePath) const
{
std::shared_ptr<TokenLocationFile> ret = std::make_shared<TokenLocationFile>(filePath);
const Id fileNodeId = getNodeByName(filePath.fileName()).id;
if (fileNodeId == 0) // early out
{
return ret;
}
CppSQLite3Query q = m_database.execQuery((
"SELECT id, element_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE file_node_id == " + std::to_string(fileNodeId) + ";"
).c_str());
while (!q.eof())
{
const Id locationId = q.getIntField(0, 0);
const Id elementId = q.getIntField(1, 0);
const int startLineNumber = q.getIntField(2, -1);
const int startColNumber = q.getIntField(3, -1);
const int endLineNumber = q.getIntField(4, -1);
const int endColNumber = q.getIntField(5, -1);
const int isScope = q.getIntField(6, -1);
if (locationId != 0 && elementId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1)
{
TokenLocation* loc = ret->addTokenLocation(locationId, elementId, startLineNumber, startColNumber, endLineNumber, endColNumber);
loc->setType(isScope ? TokenLocation::LOCATION_SCOPE : TokenLocation::LOCATION_TOKEN);
}
q.nextRow();
}
return ret;
}
std::vector<StorageSourceLocation> SqliteStorage::getTokenLocationsForElementId(const Id elementId) const
{
std::vector<StorageSourceLocation> locations;
CppSQLite3Query q = m_database.execQuery((
"SELECT id, file_node_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE element_id == " + std::to_string(elementId) + ";"
).c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id fileNodeId = q.getIntField(1, 0);
const int startLineNumber = q.getIntField(2, -1);
const int startColNumber = q.getIntField(3, -1);
const int endLineNumber = q.getIntField(4, -1);
const int endColNumber = q.getIntField(5, -1);
const int isScope = q.getIntField(6, -1);
if (id != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1)
{
locations.push_back(StorageSourceLocation(
id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, isScope
));
}
q.nextRow();
}
return locations;
}
Id SqliteStorage::getElementIdByLocationId(Id locationId) const
{
return getFirstResult<Id>(
"SELECT element_id FROM source_location WHERE id == " + std::to_string(locationId) + ";"
);
}
int SqliteStorage::getNodeCount() const
{
return m_database.execScalar("SELECT COUNT(*) from node;");
}
int SqliteStorage::getEdgeCount() const
{
return m_database.execScalar("SELECT COUNT(*) from edge;");
}
int SqliteStorage::getNameHierarchyElementCount() const
{
return m_database.execScalar("SELECT COUNT(*) from name_hierarchy_element;");
}
void SqliteStorage::clearTables()
{
m_database.execDML("DROP TABLE IF EXISTS main.source_location;");
m_database.execDML("DROP TABLE IF EXISTS main.name_hierarchy_element;");
m_database.execDML("DROP TABLE IF EXISTS main.file;");
m_database.execDML("DROP TABLE IF EXISTS main.node;");
m_database.execDML("DROP TABLE IF EXISTS main.edge;");
m_database.execDML("DROP TABLE IF EXISTS main.element;");
}
void SqliteStorage::setupTables()
{
m_database.execDML(
"CREATE TABLE IF NOT EXISTS element("
"id INTEGER, "
"PRIMARY KEY(id));"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS edge("
"id INTEGER NOT NULL, "
"type INTEGER NOT NULL, "
"source_node_id INTEGER NOT NULL, "
"target_node_id INTEGER NOT NULL, "
"PRIMARY KEY(id), "
"FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE, "
"FOREIGN KEY(source_node_id) REFERENCES node(id) ON DELETE CASCADE, "
"FOREIGN KEY(target_node_id) REFERENCES node(id) ON DELETE CASCADE);"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS node("
"id INTEGER NOT NULL, "
"type INTEGER NOT NULL, "
"name_id INTEGER NOT NULL, "
"PRIMARY KEY(id), "
"FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE, "
"FOREIGN KEY(name_id) REFERENCES name_hierarchy_element(id) ON DELETE CASCADE);" // maybe use restrict here
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS file("
"id INTEGER NOT NULL, "
"path TEXT, "
"PRIMARY KEY(id), "
"FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS name_hierarchy_element("
"id INTEGER NOT NULL, "
"name TEXT, "
"parent_id INTEGER, "
"PRIMARY KEY(id)"
"FOREIGN KEY(parent_id) REFERENCES name_hierarchy_element(id) ON DELETE CASCADE);" // maybe use restrict here
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS source_location("
"id INTEGER NOT NULL, "
"element_id INTEGER, "
"file_node_id INTEGER, "
"start_line INTEGER, "
"start_column INTEGER, "
"end_line INTEGER, "
"end_column INTEGER, "
"is_scope INTEGER, "
"PRIMARY KEY(id)"
"FOREIGN KEY(element_id) REFERENCES element(id) ON DELETE CASCADE, "
"FOREIGN KEY(file_node_id) REFERENCES node(id) ON DELETE CASCADE);"
);
}
StorageFile SqliteStorage::getFirstFile(const std::string& query) const
{
CppSQLite3Query q = m_database.execQuery(query.c_str());
if (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id nameId = q.getIntField(1, 0);
const std::string filePath = q.getStringField(2, "");
if (id != 0 && nameId != 0)
{
return StorageFile(id, nameId, filePath);
}
}
return StorageFile(0, 0, "");
}
StorageSourceLocation SqliteStorage::getFirstSourceLocation(const std::string& query) const
{
CppSQLite3Query q = m_database.execQuery(query.c_str());
if (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id elementId = q.getIntField(1, 0);
const Id fileNodeId = q.getIntField(2, 0);
const int startLineNumber = q.getIntField(3, -1);
const int startColNumber = q.getIntField(4, -1);
const int endLineNumber = q.getIntField(5, -1);
const int endColNumber = q.getIntField(6, -1);
const int isScope = q.getIntField(7, -1);
if (id != 0 && elementId != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1)
{
return StorageSourceLocation(
id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, isScope
);
}
}
return StorageSourceLocation(0, 0, 0, -1, -1, -1, -1, -1);
}
std::vector<StorageSourceLocation> SqliteStorage::getAllSourceLocations(const std::string& query) const
{
std::vector<StorageSourceLocation> sourceLocations;
CppSQLite3Query q = m_database.execQuery(query.c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id elementId = q.getIntField(1, 0);
const Id fileNodeId = q.getIntField(2, 0);
const int startLineNumber = q.getIntField(3, -1);
const int startColNumber = q.getIntField(4, -1);
const int endLineNumber = q.getIntField(5, -1);
const int endColNumber = q.getIntField(6, -1);
const int isScope = q.getIntField(7, -1);
if (id != 0 && elementId != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1)
{
sourceLocations.push_back(StorageSourceLocation(
id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, isScope
));
}
q.nextRow();
}
return sourceLocations;
}
+98
View File
@@ -0,0 +1,98 @@
#ifndef SQLITE_STORAGE_H
#define SQLITE_STORAGE_H
#include <memory>
#include <string>
#include <vector>
#include "sqlite/CppSQLite3.h"
#include "utility/file/FilePath.h"
#include "utility/types.h"
#include "data/name/NameHierarchy.h"
#include "data/location/TokenLocationFile.h"
#include "data/location/TokenLocationCollection.h"
#include "data/StorageTypes.h"
class SqliteStorage
{
public:
SqliteStorage(const std::string& dbFilePath);
~SqliteStorage();
void clear();
void beginTransaction();
void commitTransaction();
void rollbackTransaction();
Id addEdge(int type, Id sourceNodeId, Id targetNodeId);
Id addNode(int type, Id nameId);
Id addFile(Id nameId, const std::string& filePath);
int addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope);
Id addNameHierarchyElement(const std::string& name);
Id addNameHierarchyElement(const std::string& name, Id parentId);
void removeElement(Id id);
void removeNameHierarchyElement(Id id);
bool isEdge(Id elementId) const;
bool isNode(Id elementId) const;
bool isFile(Id elementId) const;
StorageEdge getEdgeBySourceTargetType(Id sourceId, Id targetId, int type) const;
std::vector<StorageEdge> getEdgesBySourceId(Id sourceId) const;
std::vector<StorageEdge> getEdgesByTargetId(Id targetId) const;
std::vector<StorageEdge> getEdgesBySourceType(Id sourceId, int type) const;
std::vector<StorageEdge> getEdgesByTargetType(Id targetId, int type) const;
StorageEdge getEdgeById(Id edgeId) const;
StorageNode getNodeById(Id id) const;
StorageNode getNodeByNameId(Id nameId) const;
StorageNode getNodeByName(const std::string& nodeName) const; // hmm... we need to use name hierarchy here...??
StorageFile getFileById(const Id id) const;
StorageFile getFileByName(const std::string& fileName) const;
void setNodeType(int type, Id nodeId);
Id getNameHierarchyElementIdByName(const std::string& name) const;
Id getNameHierarchyElementIdByName(const std::string& name, Id parentId) const;
Id getNameHierarchyElementIdByNodeId(const Id nodeId) const;
NameHierarchy getNameHierarchyById(const Id id) const;
StorageSourceLocation getSourceLocationById(const Id id) const;
std::vector<StorageSourceLocation> getAllSourceLocations() const;
std::shared_ptr<TokenLocationFile> getTokenLocationsForFile(const FilePath& filePath) const;
std::vector<StorageSourceLocation> getTokenLocationsForElementId(const Id elementId) const;
Id getElementIdByLocationId(Id locationId) const;
int getNodeCount() const;
int getEdgeCount() const;
int getNameHierarchyElementCount() const;
private:
void clearTables();
void setupTables();
StorageFile getFirstFile(const std::string& query) const;
StorageSourceLocation getFirstSourceLocation(const std::string& query) const;
std::vector<StorageSourceLocation> getAllSourceLocations(const std::string& query) const;
template <typename ResultType>
ResultType getFirstResult(const std::string& query) const;
mutable CppSQLite3DB m_database;
};
template <typename ResultType>
ResultType SqliteStorage::getFirstResult(const std::string& query) const
{
CppSQLite3Query q = m_database.execQuery(query.c_str());
return q.getIntField(0, 0);
}
#endif // SQLITE_STORAGE_H
+725 -928
View File
File diff suppressed because it is too large Load Diff
+27 -43
View File
@@ -7,12 +7,12 @@
#include "utility/file/FilePath.h"
#include "data/access/StorageAccess.h"
#include "data/graph/StorageGraph.h"
#include "data/graph/token_component/TokenComponentAbstraction.h"
#include "data/graph/token_component/TokenComponentAccess.h"
//#include "data/graph/token_component/TokenComponentAbstraction.h"
//#include "data/graph/token_component/TokenComponentAccess.h"
#include "data/location/TokenLocationCollection.h"
#include "data/parser/ParserClient.h"
#include "data/search/SearchIndex.h"
#include "data/SqliteStorage.h"
class Storage
: public ParserClient
@@ -32,6 +32,9 @@ public:
void logStats() const;
// ParserClient implementation
virtual void prepareParsingFile();
virtual void finishParsingFile();
virtual void onError(const ParseLocation& location, const std::string& message);
virtual size_t getErrorCount() const;
@@ -63,17 +66,14 @@ public:
virtual Id onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy);
virtual Id onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const NameHierarchy& baseNameHierarchy, AccessType access);
const ParseLocation& location, const NameHierarchy& childNameHierarchy,
const NameHierarchy& parentNameHierarchy, AccessType access);
virtual Id onMethodOverrideParsed(
const ParseLocation& location, const ParseFunction& base, const ParseFunction& overrider);
virtual Id onCallParsed(
const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee);
virtual Id onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee);
Id onVariableUsageParsed(
const std::string kind, const ParseLocation& location, const ParseFunction& user,
const NameHierarchy& usedNameHierarchy); // helper
virtual Id onFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy);
virtual Id onGlobalVariableUsageParsed(
@@ -84,14 +84,14 @@ public:
const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy);
virtual Id onEnumConstantUsageParsed(
const ParseLocation& location, const ParseVariable& user, const NameHierarchy& usedNameHierarchy);
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function);
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseVariable& variable);
virtual Id onTypeUsageParsed(const ParseTypeUsage& typeUsage, const ParseFunction& function);
virtual Id onTypeUsageParsed(const ParseTypeUsage& typeUsage, const ParseVariable& variable);
virtual Id onTemplateArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& argumentNameHierarchy,
const NameHierarchy& templateNameHierarchy);
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& type, const NameHierarchy& templateArgumentTypeNameHierarchy);
const ParseTypeUsage& defaultArgumentTypeUsage, const NameHierarchy& templateArgumentTypeNameHierarchy);
virtual Id onTemplateRecordParameterTypeParsed(
const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy,
const NameHierarchy& templateRecordNameHierarchy);
@@ -111,8 +111,8 @@ public:
virtual Id getIdForNodeWithName(const std::string& fullName) const;
virtual Id getIdForEdgeWithName(const std::string& name) const;
virtual std::string getNameForNodeWithId(Id id) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const;
virtual std::string getNameForNodeWithId(Id nodeId) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const;
virtual std::vector<SearchMatch> getAutocompletionMatches(
const std::string& query, const std::string& word) const;
@@ -123,7 +123,7 @@ public:
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id aggregationId) const;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const;
virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const;
virtual TokenLocationCollection getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const;
@@ -136,42 +136,26 @@ public:
virtual std::shared_ptr<TokenLocationFile> getTokenLocationOfParentScope(const TokenLocation* child) const;
protected:
const Graph& getGraph() const;
const TokenLocationCollection& getTokenLocationCollection() const;
const SearchIndex& getSearchIndex() const;
private:
Node* addNodeHierarchy(Node::NodeType type, NameHierarchy nameHierarchy);
Node* addNodeHierarchyWithDistinctSignature(Node::NodeType type, const ParseFunction& function);
Id addNodeHierarchy(Node::NodeType type, NameHierarchy nameHierarchy);
Id addNodeHierarchyWithDistinctSignature(Node::NodeType type, const ParseFunction& function);
Id addNameHierarchyElements(NameHierarchy nameHierarchy);
int addSourceLocation(int elementNodeId, const ParseLocation& location, bool isScope = false);
Id addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type, ParseLocation location);
Node* addFileNode(const FilePath& filePath);
Node* findFileNode(const FilePath& filePath) const;
Id getLastParentNodeId(const Id nodeId) const;
std::vector<Id> getDirectChildNodeIds(const Id nodeId) const;
std::vector<Id> getAllChildNodeIds(const Id nodeId) const;
TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const;
TokenComponentAccess* addAccess(Node* node, ParserClient::AccessType access);
TokenComponentAbstraction::AbstractionType convertAbstractionType(ParserClient::AbstractionType abstraction) const;
TokenComponentAbstraction* addAbstraction(Node* node, ParserClient::AbstractionType abstraction);
Node* addFunctionNode(
Node::NodeType nodeType, const ParseFunction& function,
const ParseLocation& location, const ParseLocation& scopeLocation);
Edge* addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeUsage& typeUsage);
TokenLocation* addTokenLocation(Token* token, const ParseLocation& location, bool isScope = false);
bool getQuerySearchResults(const std::string& query, const std::string& word, SearchResults* results) const;
void addDependingFilePathsAndRemoveFileNodesRecursive(Node* fileNode, std::set<FilePath>* filePaths);
void removeNodeIfUnreferenced(Node* node);
void log(std::string type, std::string str, const ParseLocation& location) const;
StorageGraph m_graph;
TokenLocationCollection m_locationCollection;
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;
SearchIndex m_tokenIndex;
SearchIndex m_filterIndex;
SqliteStorage m_sqliteStorage;
TokenLocationCollection m_errorLocationCollection;
std::vector<std::string> m_errorMessages;
+70
View File
@@ -0,0 +1,70 @@
#ifndef STORAGE_TYPES_H
#define STORAGE_TYPES_H
#include <string>
#include "utility/types.h"
struct StorageEdge
{
StorageEdge(Id id, int type, Id sourceNodeId, Id targetNodeId)
: id(id), type(type), sourceNodeId(sourceNodeId), targetNodeId(targetNodeId)
{}
Id id;
int type;
Id sourceNodeId;
Id targetNodeId;
};
struct StorageNode
{
StorageNode(Id id, int type, Id nameId)
: id(id), type(type), nameId(nameId)
{}
Id id;
int type;
Id nameId;
};
struct StorageFile
{
StorageFile(Id id, Id nameId, const std::string& filePath)
: id(id), nameId(nameId), filePath(filePath)
{}
Id id;
Id nameId;
std::string filePath;
};
struct StorageNameHierarchyElement
{
StorageNameHierarchyElement(Id id, const std::string& name, Id parentId)
: id(id), name(name), parentId(parentId)
{}
Id id;
std::string name;
Id parentId;
};
struct StorageSourceLocation
{
StorageSourceLocation(Id id, Id elementId, Id fileNodeId, int startLine, int startCol, int endLine, int endCol, bool isScope)
: id(id), elementId(elementId), fileNodeId(fileNodeId)
, startLine(startLine), startCol(startCol), endLine(endLine), endCol(endCol), isScope(isScope)
{}
Id id;
Id elementId;
Id fileNodeId;
int startLine;
int startCol;
int endLine;
int endCol;
bool isScope;
};
#endif // STORAGE_TYPES_H
+1 -1
View File
@@ -36,7 +36,7 @@ public:
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const = 0;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id aggregationId) const = 0;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const = 0;
virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const = 0;
virtual TokenLocationCollection getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const = 0;
+2 -2
View File
@@ -132,11 +132,11 @@ Id StorageAccessProxy::getTokenIdForFileNode(const FilePath& filePath) const
return 0;
}
std::vector<Id> StorageAccessProxy::getTokenIdsForAggregationEdge(Id aggregationId) const
std::vector<Id> StorageAccessProxy::getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const
{
if (hasSubject())
{
return m_subject->getTokenIdsForAggregationEdge(aggregationId);
return m_subject->getTokenIdsForAggregationEdge(sourceId, targetId);
}
return std::vector<Id>();
+1 -1
View File
@@ -28,7 +28,7 @@ public:
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id aggregationId) const;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const;
virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const;
virtual TokenLocationCollection getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const;
+56
View File
@@ -8,6 +8,50 @@
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
int Edge::typeToInt(EdgeType type)
{
return type;
}
Edge::EdgeType Edge::intToType(int value)
{
switch (value)
{
case 0x1:
return EDGE_MEMBER;
case 0x2:
return EDGE_TYPE_OF;
case 0x4:
return EDGE_RETURN_TYPE_OF;
case 0x8:
return EDGE_PARAMETER_TYPE_OF;
case 0x10:
return EDGE_TYPE_USAGE;
case 0x20:
return EDGE_USAGE;
case 0x40:
return EDGE_CALL;
case 0x80:
return EDGE_INHERITANCE;
case 0x100:
return EDGE_OVERRIDE;
case 0x200:
return EDGE_TYPEDEF_OF;
case 0x400:
return EDGE_TEMPLATE_PARAMETER_OF;
case 0x800:
return EDGE_TEMPLATE_ARGUMENT_OF;
case 0x1000:
return EDGE_TEMPLATE_DEFAULT_ARGUMENT_OF;
case 0x2000:
return EDGE_TEMPLATE_SPECIALIZATION_OF;
case 0x4000:
return EDGE_INCLUDE;
case 0x8000:
return EDGE_AGGREGATION;
}
}
Edge::Edge(EdgeType type, Node* from, Node* to)
: m_type(type)
, m_from(from)
@@ -19,6 +63,18 @@ Edge::Edge(EdgeType type, Node* from, Node* to)
checkType();
}
Edge::Edge(Id id, EdgeType type, Node* from, Node* to)
: Token(id)
, m_type(type)
, m_from(from)
, m_to(to)
{
m_from->addEdge(this);
m_to->addEdge(this);
checkType();
}
Edge::Edge(const Edge& other, Node* from, Node* to)
: Token(other)
, m_type(other.m_type)
+3
View File
@@ -36,8 +36,11 @@ 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();
-68
View File
@@ -1,68 +0,0 @@
#include "data/graph/FilterableGraph.h"
#include "data/graph/Edge.h"
#include "data/graph/Node.h"
FilterableGraph::FilterableGraph()
{
}
FilterableGraph::~FilterableGraph()
{
}
size_t FilterableGraph::size() const
{
return getNodeCount() + getEdgeCount();
}
Token* FilterableGraph::getTokenById(Id id) const
{
Token* token = getNodeById(id);
if (!token)
{
token = getEdgeById(id);
}
return token;
}
void FilterableGraph::print(std::ostream& ostream) const
{
ostream << "Graph:\n";
ostream << "nodes (" << getNodeCount() << ")\n";
forEachNode(
[&ostream](Node* n)
{
ostream << *n << '\n';
}
);
ostream << "edges (" << getEdgeCount() << ")\n";
forEachEdge(
[&ostream](Edge* e)
{
ostream << *e << '\n';
}
);
}
void FilterableGraph::printBasic(std::ostream& ostream) const
{
ostream << getNodeCount() << " nodes:";
forEachNode(
[&ostream](Node* n)
{
ostream << ' ' << n->getTypeString() << ':' << n->getFullName();
}
);
ostream << '\n';
ostream << getEdgeCount() << " edges:";
forEachEdge(
[&ostream](Edge* e)
{
ostream << ' ' << e->getName();
}
);
ostream << '\n';
}
-45
View File
@@ -1,45 +0,0 @@
#ifndef FILTERABLE_GRAPH_H
#define FILTERABLE_GRAPH_H
#include <functional>
#include <ostream>
#include "utility/types.h"
class Edge;
class Node;
class Token;
class FilterableGraph
{
public:
FilterableGraph();
virtual ~FilterableGraph();
virtual void copy(const FilterableGraph* other) = 0;
virtual void clear() = 0;
virtual void add(const FilterableGraph* other) = 0;
virtual void forEachNode(std::function<void(Node*)> func) const = 0;
virtual void forEachEdge(std::function<void(Edge*)> func) const = 0;
virtual void forEachToken(std::function<void(Token*)> func) const = 0;
virtual void addNode(Node* node) = 0;
virtual void addEdge(Edge* edge) = 0;
virtual size_t getNodeCount() const = 0;
virtual size_t getEdgeCount() const = 0;
virtual Node* getNodeById(Id id) const = 0;
virtual Edge* getEdgeById(Id id) const = 0;
size_t size() const;
Token* getTokenById(Id id) const;
void print(std::ostream& ostream) const;
void printBasic(std::ostream& ostream) const;
};
#endif // FILTERABLE_GRAPH_H
+58 -2
View File
@@ -12,7 +12,7 @@ Graph::~Graph()
m_nodes.clear();
}
void Graph::copy(const FilterableGraph* other)
void Graph::copy(const Graph* other)
{
clear();
add(other);
@@ -24,7 +24,7 @@ void Graph::clear()
m_nodes.clear();
}
void Graph::add(const FilterableGraph* other)
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));
@@ -282,6 +282,62 @@ Edge* Graph::addEdgeAndAllChildrenAsPlainCopy(Edge* edge)
return addEdgeAsPlainCopy(edge);
}
size_t Graph::size() const
{
return getNodeCount() + getEdgeCount();
}
Token* Graph::getTokenById(Id id) const
{
Token* token = getNodeById(id);
if (!token)
{
token = getEdgeById(id);
}
return token;
}
void Graph::print(std::ostream& ostream) const
{
ostream << "Graph:\n";
ostream << "nodes (" << getNodeCount() << ")\n";
forEachNode(
[&ostream](Node* n)
{
ostream << *n << '\n';
}
);
ostream << "edges (" << getEdgeCount() << ")\n";
forEachEdge(
[&ostream](Edge* e)
{
ostream << *e << '\n';
}
);
}
void Graph::printBasic(std::ostream& ostream) const
{
ostream << getNodeCount() << " nodes:";
forEachNode(
[&ostream](Node* n)
{
ostream << ' ' << n->getTypeString() << ':' << n->getFullName();
}
);
ostream << '\n';
ostream << getEdgeCount() << " edges:";
forEachEdge(
[&ostream](Edge* e)
{
ostream << ' ' << e->getName();
}
);
ostream << '\n';
}
void Graph::removeEdgeInternal(Edge* edge)
{
std::map<Id, std::shared_ptr<Edge> >::const_iterator it = m_edges.find(edge->getId());
+10 -5
View File
@@ -6,21 +6,19 @@
#include <deque>
#include "data/graph/Edge.h"
#include "data/graph/FilterableGraph.h"
#include "data/graph/Node.h"
class Graph
: public FilterableGraph
{
public:
Graph();
virtual ~Graph();
// FilterableGraph implementation
virtual void copy(const FilterableGraph* other);
// FilterableGraph implementation // deprecated
virtual void copy(const Graph* other);
virtual void clear();
virtual void add(const FilterableGraph* other);
virtual void add(const Graph* other);
virtual void forEachNode(std::function<void(Node*)> func) const;
virtual void forEachEdge(std::function<void(Edge*)> func) const;
@@ -52,6 +50,13 @@ public:
Node* addNodeAndAllChildrenAsPlainCopy(Node* node);
Edge* addEdgeAndAllChildrenAsPlainCopy(Edge* edge);
size_t size() const;
Token* getTokenById(Id id) const;
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;
+52
View File
@@ -18,6 +18,13 @@ Node::Node(NodeType type, std::shared_ptr<TokenComponentName> nameComponent)
{
}
Node::Node(Id id, NodeType type, std::shared_ptr<TokenComponentName> nameComponent)
: Token(id)
, m_type(type)
, m_nameComponent(nameComponent)
{
}
Node::Node(const Node& other)
: Token(other)
, m_type(other.m_type)
@@ -371,6 +378,51 @@ std::string Node::getTypeString(NodeType type)
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);
+3
View File
@@ -44,8 +44,11 @@ public:
};
static std::string getTypeString(NodeType type);
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();
-217
View File
@@ -1,217 +0,0 @@
#include "data/graph/StorageGraph.h"
#include "data/graph/token_component/TokenComponentAggregation.h"
#include "data/graph/token_component/TokenComponentName.h"
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
StorageGraph::StorageGraph()
{
}
StorageGraph::~StorageGraph()
{
}
Node* StorageGraph::createNodeHierarchy(Node::NodeType type, SearchNode* searchNode)
{
Node* node = getNodeById(searchNode->getFirstTokenId());
if (!node)
{
return insertNodeHierarchy(type, searchNode);
}
if (node->getType() < type)
{
node->setType(type);
}
return node;
}
Node* StorageGraph::createNodeHierarchyWithDistinctSignature(
Node::NodeType type, SearchNode* searchNode, std::shared_ptr<TokenComponentSignature> signature
){
Node* node = getNodeById(searchNode->getFirstTokenId());
if (!node)
{
node = insertNodeHierarchy(type, searchNode);
}
else
{
std::function<bool(Node*)> findSignature =
[signature](Node* n)
{
TokenComponentSignature* sig = n->getComponent<TokenComponentSignature>();
return sig && *sig == *signature.get();
};
Node* parentNode = node->getParentNode();
if (parentNode)
{
node = parentNode->findChildNode(findSignature);
}
else
{
node = findNode(findSignature);
}
if (!node)
{
node = insertNode(type, parentNode, searchNode);
}
else
{
if (node->getType() < type)
{
node->setType(type);
}
return node;
}
}
node->addComponentSignature(signature);
return node;
}
Edge* StorageGraph::createEdge(Edge::EdgeType type, Node* from, Node* to)
{
Edge* edge = from->findEdgeOfType(type,
[from, to](Edge* e)
{
return e->getFrom() == from && e->getTo() == to;
}
);
if (edge)
{
return edge;
}
edge = insertEdge(type, from, to);
if (from->getLastParentNode() != to->getLastParentNode())
{
Id edgeId = edge->getId();
updateAggregationEdges(from->getParentNode(), to, edgeId, 0);
updateAggregationEdges(from, to->getParentNode(), edgeId, 0);
}
return edge;
}
void StorageGraph::removeEdge(Edge* edge)
{
Node* from = edge->getFrom();
Node* to = edge->getTo();
if (from->getLastParentNode() != to->getLastParentNode())
{
Id edgeId = edge->getId();
updateAggregationEdges(from->getParentNode(), to, 0, edgeId);
updateAggregationEdges(from, to->getParentNode(), 0, edgeId);
}
Graph::removeEdge(edge);
}
Node* StorageGraph::insertNodeHierarchy(Node::NodeType type, SearchNode* searchNode)
{
std::deque<SearchNode*> searchNodes = searchNode->getParentsWithoutTokenId();
if (!searchNodes.size())
{
LOG_ERROR("There are no nodes without a set tokenId so this method shouldn't have been called.");
return nullptr;
}
Node* parentNode = nullptr;
SearchNode* parentSearchNode = searchNodes.front()->getParent();
if (parentSearchNode)
{
parentNode = getNodeById(parentSearchNode->getFirstTokenId());
}
while (searchNodes.size() > 0)
{
searchNode = searchNodes.front();
searchNodes.pop_front();
parentNode = insertNode(searchNodes.size() > 0 ? Node::NODE_UNDEFINED : type, parentNode, searchNode);
}
return parentNode;
}
Node* StorageGraph::insertNode(Node::NodeType type, Node* parentNode, SearchNode* searchNode)
{
std::shared_ptr<Node> node =
std::make_shared<Node>(type, std::make_shared<TokenComponentNameReferenced>(searchNode));
m_nodes.emplace(node->getId(), node);
searchNode->addTokenId(node->getId());
if (parentNode)
{
createEdge(Edge::EDGE_MEMBER, parentNode, node.get());
}
return node.get();
}
Edge* StorageGraph::insertEdge(Edge::EdgeType type, Node* from, Node* to)
{
std::shared_ptr<Edge> edgePtr = std::make_shared<Edge>(type, from, to);
m_edges.emplace(edgePtr->getId(), edgePtr);
return edgePtr.get();
}
void StorageGraph::updateAggregationEdges(Node* from, Node* to, Id addEdgeId, Id removeEdgeId)
{
if (!from || !to || from == to)
{
return;
}
const Node::NodeTypeMask mask = Node::NODE_UNDEFINED_TYPE | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM;
const Node::NodeTypeMask varFuncMask =
Node::NODE_UNDEFINED_FUNCTION | Node::NODE_FUNCTION | Node::NODE_UNDEFINED_VARIABLE | Node::NODE_GLOBAL_VARIABLE;
if ((from->isType(mask) && to->isType(mask | varFuncMask)) ||
(from->isType(mask | varFuncMask) && to->isType(mask)))
{
Edge* edge = from->findEdgeOfType(Edge::EDGE_AGGREGATION,
[from, to](Edge* e)
{
const Node* f = e->getFrom();
const Node* t = e->getTo();
return (f == from && t == to) || (f == to && t == from);
}
);
if (!edge && addEdgeId)
{
edge = insertEdge(Edge::EDGE_AGGREGATION, from, to);
edge->addComponentAggregation(std::make_shared<TokenComponentAggregation>());
}
if (addEdgeId)
{
bool forward = (edge->getFrom() == from);
edge->getComponent<TokenComponentAggregation>()->addAggregationId(addEdgeId, forward);
}
if (edge && removeEdgeId)
{
edge->getComponent<TokenComponentAggregation>()->removeAggregationId(removeEdgeId);
}
if (edge && edge->getComponent<TokenComponentAggregation>()->getAggregationCount() == 0)
{
Graph::removeEdge(edge);
}
}
updateAggregationEdges(from->getParentNode(), to, addEdgeId, removeEdgeId);
updateAggregationEdges(from, to->getParentNode(), addEdgeId, removeEdgeId);
}
-29
View File
@@ -1,29 +0,0 @@
#ifndef STORAGE_GRAPH_H
#define STORAGE_GRAPH_H
#include "data/graph/Graph.h"
#include "data/graph/token_component/TokenComponentSignature.h"
#include "data/search/SearchNode.h"
class StorageGraph
: public Graph
{
public:
StorageGraph();
virtual ~StorageGraph();
Node* createNodeHierarchy(Node::NodeType type, SearchNode* searchNode);
Node* createNodeHierarchyWithDistinctSignature(
Node::NodeType type, SearchNode* searchNode, std::shared_ptr<TokenComponentSignature> signature);
Edge* createEdge(Edge::EdgeType type, Node* from, Node* to);
void removeEdge(Edge* edge);
private:
Node* insertNodeHierarchy(Node::NodeType type, SearchNode* searchNode);
Node* insertNode(Node::NodeType type, Node* parentNode, SearchNode* searchNode);
Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to);
void updateAggregationEdges(Node* from, Node* to, Id addEdgeId, Id removeEdgeId);
};
#endif // STORAGE_GRAPH_H
-136
View File
@@ -1,136 +0,0 @@
#include "data/graph/SubGraph.h"
#include "data/graph/Edge.h"
#include "data/graph/Node.h"
SubGraph::SubGraph()
{
}
SubGraph::~SubGraph()
{
}
void SubGraph::copy(const FilterableGraph* other)
{
clear();
add(other);
}
void SubGraph::clear()
{
m_edges.clear();
m_nodes.clear();
}
void SubGraph::add(const FilterableGraph* other)
{
other->forEachNode(std::bind(&SubGraph::addNode, this, std::placeholders::_1));
other->forEachEdge(std::bind(&SubGraph::addEdge, this, std::placeholders::_1));
}
void SubGraph::forEachNode(std::function<void(Node*)> func) const
{
for (const std::pair<Id, Node*>& node : m_nodes)
{
func(node.second);
}
}
void SubGraph::forEachEdge(std::function<void(Edge*)> func) const
{
for (const std::pair<Id, Edge*>& edge : m_edges)
{
func(edge.second);
}
}
void SubGraph::forEachToken(std::function<void(Token*)> func) const
{
forEachNode(func);
forEachEdge(func);
}
void SubGraph::addNode(Node* node)
{
m_nodes.emplace(node->getId(), node);
}
void SubGraph::addEdge(Edge* edge)
{
m_edges.emplace(edge->getId(), edge);
}
size_t SubGraph::getNodeCount() const
{
return m_nodes.size();
}
size_t SubGraph::getEdgeCount() const
{
return m_edges.size();
}
Node* SubGraph::getNodeById(Id id) const
{
std::map<Id, Node*>::const_iterator it = m_nodes.find(id);
if (it != m_nodes.end())
{
return it->second;
}
return nullptr;
}
Edge* SubGraph::getEdgeById(Id id) const
{
std::map<Id, Edge*>::const_iterator it = m_edges.find(id);
if (it != m_edges.end())
{
return it->second;
}
return nullptr;
}
const std::map<Id, Node*>& SubGraph::getNodes() const
{
return m_nodes;
}
const std::map<Id, Edge*>& SubGraph::getEdges() const
{
return m_edges;
}
std::vector<Id> SubGraph::getTokenIds() const
{
std::vector<Id> ids;
for (const std::pair<Id, Node*>& node : m_nodes)
{
ids.push_back(node.first);
}
for (const std::pair<Id, Edge*>& edge : m_edges)
{
ids.push_back(edge.first);
}
return ids;
}
void SubGraph::subtract(const SubGraph& other)
{
for (const std::pair<Id, Node*>& node : other.m_nodes)
{
m_nodes.erase(node.first);
}
for (const std::pair<Id, Edge*>& edge : other.m_edges)
{
m_edges.erase(edge.first);
}
}
std::ostream& operator<<(std::ostream& ostream, const SubGraph& graph)
{
graph.print(ostream);
return ostream;
}
-54
View File
@@ -1,54 +0,0 @@
#ifndef SUB_GRAPH_H
#define SUB_GRAPH_H
#include <functional>
#include <map>
#include <vector>
#include "data/graph/FilterableGraph.h"
class Edge;
class Node;
class Token;
class SubGraph
: public FilterableGraph
{
public:
SubGraph();
virtual ~SubGraph();
// FilterableGraph implementation
virtual void copy(const FilterableGraph* other);
virtual void clear();
virtual void add(const FilterableGraph* other);
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;
virtual void addNode(Node* node);
virtual void addEdge(Edge* edge);
virtual size_t getNodeCount() const;
virtual size_t getEdgeCount() const;
virtual Node* getNodeById(Id id) const;
virtual Edge* getEdgeById(Id id) const;
const std::map<Id, Node*>& getNodes() const;
const std::map<Id, Edge*>& getEdges() const;
std::vector<Id> getTokenIds() const;
void subtract(const SubGraph& other);
private:
std::map<Id, Node*> m_nodes;
std::map<Id, Edge*> m_edges;
};
std::ostream& operator<<(std::ostream& ostream, const SubGraph& graph);
#endif // SUB_GRAPH_H
+6 -1
View File
@@ -8,11 +8,16 @@ void Token::resetNextId()
s_nextId = 1;
}
Token::Token()
Token::Token() // TODO: remove this constructor
: m_id(s_nextId++)
{
}
Token::Token(Id id)
: m_id(id)
{
}
Token::~Token()
{
}
+1
View File
@@ -13,6 +13,7 @@ public:
static void resetNextId();
Token();
Token(Id id);
virtual ~Token();
Id getId() const;
-66
View File
@@ -1,66 +0,0 @@
#include "data/graph/filter/GraphFilter.h"
#include "data/graph/Edge.h"
#include "data/graph/FilterableGraph.h"
#include "utility/logging/logging.h"
GraphFilter::GraphFilter()
: m_outGraph(nullptr)
{
}
GraphFilter::~GraphFilter()
{
}
void GraphFilter::apply(const FilterableGraph* in, FilterableGraph* out)
{
if (!in || !out)
{
LOG_ERROR("GraphFilter not called with correct pointers.");
return;
}
else if (in == out)
{
LOG_ERROR("In and out graphs are the same.");
return;
}
m_outGraph = out;
in->forEachNode(
[this](Node* node)
{
visitNode(node);
}
);
// in->forEachEdge(
// [this](Edge* edge)
// {
// visitEdge(edge);
// }
// );
m_outGraph = nullptr;
}
void GraphFilter::visitNode(Node* node)
{
}
// void GraphFilter::visitEdge(Edge* edge)
// {
// }
void GraphFilter::addNode(Node* node)
{
m_outGraph->addNode(node);
}
void GraphFilter::addEdge(Edge* edge)
{
m_outGraph->addNode(edge->getFrom());
m_outGraph->addNode(edge->getTo());
m_outGraph->addEdge(edge);
}
-27
View File
@@ -1,27 +0,0 @@
#ifndef GRAPH_FILTER_H
#define GRAPH_FILTER_H
class Edge;
class FilterableGraph;
class Node;
class GraphFilter
{
public:
GraphFilter();
virtual ~GraphFilter();
virtual void apply(const FilterableGraph* in, FilterableGraph* out);
protected:
virtual void visitNode(Node* node);
// virtual void visitEdge(Edge* edge);
void addNode(Node* node);
void addEdge(Edge* edge);
private:
FilterableGraph* m_outGraph;
};
#endif // GRAPH_FILTER_H
@@ -1,196 +0,0 @@
#include "data/graph/filter/GraphFilterConductor.h"
#include "data/graph/filter/GraphFilter.h"
#include "data/graph/filter/GraphFilterImplementations.h"
#include "data/graph/SubGraph.h"
#include "data/query/QueryCommand.h"
#include "data/query/QueryNode.h"
#include "data/query/QueryOperator.h"
#include "data/query/QueryToken.h"
#include "data/query/QueryTree.h"
#include "utility/logging/logging.h"
GraphFilterConductor::GraphFilterConductor()
{
}
GraphFilterConductor::~GraphFilterConductor()
{
}
void GraphFilterConductor::filter(const QueryTree* tree, const FilterableGraph* in, FilterableGraph* out)
{
if (tree->isValid())
{
m_inGraph = in;
filterRecursively(tree->getRoot().get(), in, out);
}
}
void GraphFilterConductor::filterRecursively(const QueryNode* node, const FilterableGraph* in, FilterableGraph* out) const
{
if (!node)
{
return;
}
if (node->isOperator())
{
filterOperatorNode(dynamic_cast<const QueryOperator*>(node), in, out);
}
else if (node->isCommand())
{
filterCommandNode(dynamic_cast<const QueryCommand*>(node), in, out);
}
else if (node->isToken())
{
filterTokenNode(dynamic_cast<const QueryToken*>(node), out);
}
}
void GraphFilterConductor::filterOperatorNode(const QueryOperator* node, const FilterableGraph* in, FilterableGraph* out) const
{
switch (node->getType())
{
case QueryOperator::OPERATOR_NOT:
{
SubGraph sub, sub2;
filterRecursively(node->getRight().get(), in, &sub);
sub2.copy(in);
sub2.subtract(sub);
out->add(&sub2);
}
break;
case QueryOperator::OPERATOR_SUB:
case QueryOperator::OPERATOR_AND:
{
SubGraph sub;
filterRecursively(node->getLeft().get(), in, &sub);
filterRecursively(node->getRight().get(), &sub, out);
}
break;
case QueryOperator::OPERATOR_HAS:
{
SubGraph sub, sub2;
filterRecursively(node->getLeft().get(), in, &sub);
GraphFilterCommandMember().apply(&sub, &sub2);
filterRecursively(node->getRight().get(), &sub2, out);
}
break;
case QueryOperator::OPERATOR_OR:
filterRecursively(node->getLeft().get(), in, out);
filterRecursively(node->getRight().get(), in, out);
break;
default:
break;
}
}
void GraphFilterConductor::filterCommandNode(const QueryCommand* node, const FilterableGraph* in, FilterableGraph* out) const
{
switch (node->getType())
{
case QueryCommand::COMMAND_UNDEFINED:
GraphFilterCommandNodeType(
Node::NODE_UNDEFINED | Node::NODE_UNDEFINED_TYPE |
Node::NODE_UNDEFINED_VARIABLE | Node::NODE_UNDEFINED_FUNCTION).apply(in, out);
break;
case QueryCommand::COMMAND_MEMBER:
GraphFilterCommandMember().apply(in, out);
break;
case QueryCommand::COMMAND_PARENT:
GraphFilterCommandParent().apply(in, out);
break;
case QueryCommand::COMMAND_FUNCTION:
GraphFilterCommandNodeType(Node::NODE_FUNCTION).apply(in, out);
break;
case QueryCommand::COMMAND_GLOBAL_VARIABLE:
GraphFilterCommandNodeType(Node::NODE_GLOBAL_VARIABLE).apply(in, out);
break;
case QueryCommand::COMMAND_CLASS:
GraphFilterCommandNodeType(Node::NODE_CLASS).apply(in, out);
break;
case QueryCommand::COMMAND_METHOD:
GraphFilterCommandNodeType(Node::NODE_METHOD).apply(in, out);
break;
case QueryCommand::COMMAND_FIELD:
GraphFilterCommandNodeType(Node::NODE_FIELD).apply(in, out);
break;
case QueryCommand::COMMAND_NAMESPACE:
GraphFilterCommandNodeType(Node::NODE_NAMESPACE).apply(in, out);
break;
case QueryCommand::COMMAND_STRUCT:
GraphFilterCommandNodeType(Node::NODE_STRUCT).apply(in, out);
break;
case QueryCommand::COMMAND_ENUM:
GraphFilterCommandNodeType(Node::NODE_ENUM).apply(in, out);
break;
case QueryCommand::COMMAND_ENUM_CONSTANT:
GraphFilterCommandNodeType(Node::NODE_ENUM_CONSTANT).apply(in, out);
break;
case QueryCommand::COMMAND_TYPEDEF:
GraphFilterCommandNodeType(Node::NODE_TYPEDEF).apply(in, out);
break;
case QueryCommand::COMMAND_CONST:
GraphFilterCommandConst().apply(in, out);
break;
case QueryCommand::COMMAND_STATIC:
GraphFilterCommandStatic().apply(in, out);
break;
case QueryCommand::COMMAND_VIRTUAL:
GraphFilterCommandAbstractionType(TokenComponentAbstraction::ABSTRACTION_VIRTUAL).apply(in, out);
break;
case QueryCommand::COMMAND_PURE_VIRTUAL:
GraphFilterCommandAbstractionType(TokenComponentAbstraction::ABSTRACTION_PURE_VIRTUAL).apply(in, out);
break;
case QueryCommand::COMMAND_PUBLIC:
GraphFilterCommandAccessType(TokenComponentAccess::ACCESS_PUBLIC).apply(in, out);
break;
case QueryCommand::COMMAND_PROTECTED:
GraphFilterCommandAccessType(TokenComponentAccess::ACCESS_PROTECTED).apply(in, out);
break;
case QueryCommand::COMMAND_PRIVATE:
GraphFilterCommandAccessType(TokenComponentAccess::ACCESS_PRIVATE).apply(in, out);
break;
case QueryCommand::COMMAND_CALLER:
GraphFilterCommandCall(true).apply(in, out);
break;
case QueryCommand::COMMAND_CALLEE:
GraphFilterCommandCall(false).apply(in, out);
break;
case QueryCommand::COMMAND_USAGE:
GraphFilterCommandUsage().apply(in, out);
break;
case QueryCommand::COMMAND_SUPER_CLASS:
GraphFilterCommandInheritance(true).apply(in, out);
break;
case QueryCommand::COMMAND_SUB_CLASS:
GraphFilterCommandInheritance(false).apply(in, out);
break;
case QueryCommand::COMMAND_FILE:
GraphFilterCommandNodeType(Node::NODE_FILE).apply(in, out);
break;
default:
LOG_ERROR_STREAM(<< "QueryCommand not supported: " << node->getType());
GraphFilter().apply(in, out);
break;
}
}
void GraphFilterConductor::filterTokenNode(const QueryToken* node, FilterableGraph* out) const
{
GraphFilterToken(node->getTokenName(), node->getTokenIds()).apply(m_inGraph, out);
}
@@ -1,28 +0,0 @@
#ifndef GRAPH_FILTER_CONDUCTOR_H
#define GRAPH_FILTER_CONDUCTOR_H
class FilterableGraph;
class QueryCommand;
class QueryNode;
class QueryOperator;
class QueryToken;
class QueryTree;
class GraphFilterConductor
{
public:
GraphFilterConductor();
~GraphFilterConductor();
void filter(const QueryTree* tree, const FilterableGraph* in, FilterableGraph* out);
private:
void filterRecursively(const QueryNode* node, const FilterableGraph* in, FilterableGraph* out) const;
void filterOperatorNode(const QueryOperator* node, const FilterableGraph* in, FilterableGraph* out) const;
void filterCommandNode(const QueryCommand* node, const FilterableGraph* in, FilterableGraph* out) const;
void filterTokenNode(const QueryToken* node, FilterableGraph* out) const;
const FilterableGraph* m_inGraph;
};
#endif // GRAPH_FILTER_CONDUCTOR_H
@@ -1,303 +0,0 @@
#ifndef GRAPH_FILTER_IMPLEMENTATIONS_H
#define GRAPH_FILTER_IMPLEMENTATIONS_H
#include <set>
#include "data/graph/Edge.h"
#include "data/graph/filter/GraphFilter.h"
#include "data/graph/FilterableGraph.h"
#include "data/graph/Node.h"
#include "data/graph/token_component/TokenComponentAbstraction.h"
#include "data/graph/token_component/TokenComponentAccess.h"
#include "data/graph/token_component/TokenComponentConst.h"
#include "data/graph/token_component/TokenComponentStatic.h"
/*
* empty GraphFilterImplementation for copy-pasting
*
class GraphFilter: public GraphFilter
{
protected:
virtual void visitNode(Node* node)
{
}
};
*/
class GraphFilterCommandMember
: public GraphFilter
{
protected:
virtual void visitNode(Node* node)
{
node->forEachChildNode(
[this](Node* n)
{
addNode(n);
}
);
}
};
class GraphFilterCommandParent
: public GraphFilter
{
protected:
virtual void visitNode(Node* node)
{
Node* parent = node->getParentNode();
if (parent)
{
addNode(parent);
}
}
};
class GraphFilterCommandNodeType
: public GraphFilter
{
public:
GraphFilterCommandNodeType(Node::NodeTypeMask mask)
: m_mask(mask)
{
}
protected:
virtual void visitNode(Node* node)
{
if (node->isType(m_mask))
{
addNode(node);
}
}
private:
const Node::NodeTypeMask m_mask;
};
class GraphFilterCommandConst
: public GraphFilter
{
protected:
virtual void visitNode(Node* node)
{
if (node->getType() == Node::NODE_METHOD && node->getComponent<TokenComponentConst>())
{
addNode(node);
}
// TODO: add const component to field and variable nodes..
}
};
class GraphFilterCommandStatic
: public GraphFilter
{
protected:
virtual void visitNode(Node* node)
{
if (node->getComponent<TokenComponentStatic>())
{
addNode(node);
}
}
};
class GraphFilterCommandAccessType
: public GraphFilter
{
public:
GraphFilterCommandAccessType(TokenComponentAccess::AccessType type)
: m_type(type)
{
}
protected:
virtual void visitNode(Node* node)
{
Edge* edge = node->getMemberEdge();
if (!edge)
{
return;
}
TokenComponentAccess* access = edge->getComponent<TokenComponentAccess>();
if (access && access->getAccess() == m_type)
{
addNode(edge->getTo());
}
}
private:
const TokenComponentAccess::AccessType m_type;
};
class GraphFilterCommandAbstractionType
: public GraphFilter
{
public:
GraphFilterCommandAbstractionType(TokenComponentAbstraction::AbstractionType type)
: m_type(type)
{
}
protected:
virtual void visitNode(Node* node)
{
TokenComponentAbstraction* abstraction = node->getComponent<TokenComponentAbstraction>();
if (abstraction && abstraction->getAbstraction() == m_type)
{
addNode(node);
}
}
private:
const TokenComponentAbstraction::AbstractionType m_type;
};
class GraphFilterCommandCall
: public GraphFilter
{
public:
GraphFilterCommandCall(bool callers)
: m_callers(callers)
{
}
protected:
virtual void visitNode(Node* node)
{
node->forEachEdgeOfType(Edge::EDGE_CALL,
[this, node](Edge* edge)
{
Node* from = edge->getFrom();
Node* to = edge->getTo();
if (m_callers && node == to)
{
addNode(from);
}
else if (!m_callers && node == from)
{
addNode(to);
}
}
);
}
private:
const bool m_callers;
};
class GraphFilterCommandUsage
: public GraphFilter
{
protected:
virtual void visitNode(Node* node)
{
Edge::EdgeTypeMask mask;
mask = Edge::EDGE_TYPE_OF | Edge::EDGE_RETURN_TYPE_OF | Edge::EDGE_PARAMETER_TYPE_OF;
mask = Edge::EDGE_TYPE_USAGE | Edge::EDGE_USAGE | Edge::EDGE_TYPEDEF_OF | mask;
node->forEachEdge(
[this, node, mask](Edge* edge)
{
if (node == edge->getTo() && edge->isType(mask))
{
addNode(edge->getFrom());
}
}
);
}
};
class GraphFilterCommandInheritance
: public GraphFilter
{
public:
GraphFilterCommandInheritance(bool super)
: m_super(super)
{
}
protected:
virtual void visitNode(Node* node)
{
node->forEachEdgeOfType(Edge::EDGE_INHERITANCE,
[this, node](Edge* edge)
{
Node* from = edge->getFrom();
Node* to = edge->getTo();
if (m_super && node == from)
{
addNode(to);
}
else if (!m_super && node == to)
{
addNode(from);
}
}
);
}
private:
const bool m_super;
};
class GraphFilterToken
: public GraphFilter
{
public:
GraphFilterToken(const std::string& tokenName, const std::set<Id>& tokenIds)
: m_tokenName(tokenName)
, m_tokenIds(tokenIds)
{
}
virtual void apply(const FilterableGraph* in, FilterableGraph* out)
{
std::vector<Node*> nodes;
for (Id tokenId : m_tokenIds)
{
Node* node = in->getNodeById(tokenId);
if (node)
{
nodes.push_back(node);
}
else
{
nodes.clear();
break;
}
}
if (nodes.size())
{
for (Node* node : nodes)
{
out->addNode(node);
}
}
else
{
GraphFilter::apply(in, out);
}
}
protected:
virtual void visitNode(Node* node)
{
if (node->getFullName() == m_tokenName)
{
addNode(node);
}
}
private:
const std::string m_tokenName;
const std::set<Id> m_tokenIds;
};
#endif // GRAPH_FILTER_IMPLEMENTATIONS_H
@@ -52,6 +52,14 @@ TokenComponentNameCached::TokenComponentNameCached(const std::vector<std::string
{
}
TokenComponentNameCached::TokenComponentNameCached(const NameHierarchy& nameHierarchy)
{
for (size_t i = 0; i < nameHierarchy.size(); i++)
{
m_nameHierarchy.push_back(nameHierarchy[i]->getFullName());
}
}
TokenComponentNameCached::~TokenComponentNameCached()
{
}
@@ -4,6 +4,7 @@
#include <string>
#include "data/graph/token_component/TokenComponent.h"
#include "data/name/NameHierarchy.h"
#include "data/search/SearchNode.h"
class TokenComponentName
@@ -46,6 +47,7 @@ class TokenComponentNameCached
{
public:
TokenComponentNameCached(const std::vector<std::string>& nameHierarchy);
TokenComponentNameCached(const NameHierarchy& nameHierarchy);
virtual ~TokenComponentNameCached();
virtual std::shared_ptr<TokenComponent> copy() const;
@@ -56,7 +58,7 @@ public:
virtual const SearchNode* getSearchNode() const;
private:
const std::vector<std::string> m_nameHierarchy;
std::vector<std::string> m_nameHierarchy; // TODO: use const NameHierarchy here
};
#endif // TOKEN_COMPONENT_NAME_H
+11
View File
@@ -13,6 +13,17 @@ TokenLocation::TokenLocation(Id tokenId, TokenLocationLine* line, unsigned int c
{
}
TokenLocation::TokenLocation(Id locationId, Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart)
: m_id(locationId)
, m_tokenId(tokenId)
, m_type(LOCATION_TOKEN)
, m_line(line)
, m_columnNumber(columnNumber)
, m_other(nullptr)
, m_isStart(isStart)
{
}
TokenLocation::TokenLocation(TokenLocation *other, TokenLocationLine* line, unsigned int columnNumber, bool isStart)
: m_id(other->m_id)
, m_tokenId(other->m_tokenId)
+1
View File
@@ -22,6 +22,7 @@ public:
};
TokenLocation(Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart);
TokenLocation(Id locationId, Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart);
TokenLocation(TokenLocation* other, TokenLocationLine* line, unsigned int columnNumber, bool isStart);
TokenLocation(const TokenLocation& other, TokenLocationLine* line);
~TokenLocation();
@@ -68,6 +68,30 @@ TokenLocation* TokenLocationCollection::addTokenLocation(
return location;
}
TokenLocation* TokenLocationCollection::addTokenLocation(
Id locationId, Id tokenId, const FilePath& filePath,
unsigned int startLineNumber, unsigned int startColumnNumber,
unsigned int endLineNumber, unsigned int endColumnNumber)
{
if (startLineNumber > endLineNumber || (startLineNumber == endLineNumber && startColumnNumber > endColumnNumber))
{
LOG_ERROR("Can't create TokenLocation with wrong boundaries.");
return nullptr;
}
TokenLocationFile* file = createTokenLocationFile(filePath);
TokenLocation* location =
file->addTokenLocation(locationId, tokenId, startLineNumber, startColumnNumber, endLineNumber, endColumnNumber);
m_locations.emplace(location->getId(), location);
return location;
}
void TokenLocationCollection::removeTokenLocation(TokenLocation* location)
{
if (!findTokenLocationById(location->getId()))
@@ -35,6 +35,10 @@ public:
Id tokenId, const FilePath& filePath,
unsigned int startLineNumber, unsigned int startColumnNumber,
unsigned int endLineNumber, unsigned int endColumnNumber);
TokenLocation* addTokenLocation(
Id locationId, Id tokenId, const FilePath& filePath,
unsigned int startLineNumber, unsigned int startColumnNumber,
unsigned int endLineNumber, unsigned int endColumnNumber);
void removeTokenLocation(TokenLocation* location);
TokenLocation* findTokenLocationById(Id id) const;
@@ -48,6 +48,27 @@ TokenLocation* TokenLocationFile::addTokenLocation(
return start;
}
TokenLocation* TokenLocationFile::addTokenLocation(
Id locationId, Id tokenId,
unsigned int startLineNumber, unsigned int startColumnNumber,
unsigned int endLineNumber, unsigned int endColumnNumber)
{
TokenLocationLine* line = createTokenLocationLine(startLineNumber);
TokenLocation* start = line->addStartTokenLocation(locationId, tokenId, startColumnNumber);
if (startLineNumber != endLineNumber)
{
line = createTokenLocationLine(endLineNumber);
}
line->addEndTokenLocation(start, endColumnNumber);
return start;
}
void TokenLocationFile::removeTokenLocation(TokenLocation* location)
{
TokenLocationLine* line = location->getTokenLocationLine();
@@ -31,6 +31,10 @@ public:
Id tokenId,
unsigned int startLineNumber, unsigned int startColumnNumber,
unsigned int endLineNumber, unsigned int endColumnNumber);
TokenLocation* addTokenLocation(
Id locationId, Id tokenId,
unsigned int startLineNumber, unsigned int startColumnNumber,
unsigned int endLineNumber, unsigned int endColumnNumber);
void removeTokenLocation(TokenLocation* location);
TokenLocationLine* findTokenLocationLineByNumber(unsigned int lineNumber) const;
@@ -54,6 +54,19 @@ TokenLocation* TokenLocationLine::addEndTokenLocation(TokenLocation* start, unsi
return locationPtr.get();
}
TokenLocation* TokenLocationLine::addStartTokenLocation(Id locationId, Id tokenId, unsigned int columnNumber)
{
std::shared_ptr<TokenLocation> locationPtr = std::make_shared<TokenLocation>(locationId, tokenId, this, columnNumber, true);
m_locations.emplace(columnNumber, locationPtr);
return locationPtr.get();
}
void TokenLocationLine::removeTokenLocation(TokenLocation* location)
{
TokenLocationMapType::iterator it = m_locations.find(location->getColumnNumber());
@@ -32,6 +32,7 @@ public:
TokenLocation* addStartTokenLocation(Id tokenId, unsigned int columnNumber);
TokenLocation* addEndTokenLocation(TokenLocation* start, unsigned int columnNumber);
TokenLocation* addStartTokenLocation(Id locationId, Id tokenId, unsigned int columnNumber);
void removeTokenLocation(TokenLocation* location);
TokenLocation* getTokenLocationById(Id id) const;
+3
View File
@@ -50,6 +50,9 @@ public:
ParserClient();
virtual ~ParserClient();
virtual void prepareParsingFile() = 0;
virtual void finishParsingFile() = 0;
virtual void onError(const ParseLocation& location, const std::string& message) = 0;
virtual size_t getErrorCount() const = 0;
+6 -1
View File
@@ -14,7 +14,8 @@ TaskParseCxx::TaskParseCxx(
const Parser::Arguments& arguments,
const std::vector<FilePath>& files
)
: m_parser(client, fileManager)
: m_client(client)
, m_parser(client, fileManager)
, m_arguments(arguments)
, m_files(files)
{
@@ -24,6 +25,8 @@ void TaskParseCxx::enter()
{
m_start = utility::durationStart();
m_client->prepareParsingFile();
m_parser.setupParsing(m_files, m_arguments);
for (const FilePath& path : m_parser.getFileRegister()->getUnparsedSourceFilePaths())
@@ -80,6 +83,8 @@ void TaskParseCxx::exit()
{
FileRegister* fileRegister = m_parser.getFileRegister();
m_client->finishParsingFile();
MessageFinishedParsing(
fileRegister->getParsedFilesCount(),
fileRegister->getFilesCount(),
+1
View File
@@ -27,6 +27,7 @@ public:
virtual void revert();
private:
ParserClient* m_client;
CxxParser m_parser;
const Parser::Arguments m_arguments;
const std::vector<FilePath> m_files;
@@ -107,7 +107,7 @@ std::string CxxDeclNameResolver::getDeclName()
for (int i = 0; i < templateArgumentCount; i++)
{
const clang::TemplateArgument& templateArgument = templateArgumentList.get(i);
if (templateArgument.isDependent()) // TODO: fix case when arg depends on template parameter of outer template class.
if (templateArgument.isDependent()) // IMPORTANT_TODO: fix case when arg depends on template parameter of outer template class, or depends on first template parameter.
{
specializedParameterNamePart += getTemplateParameterString(parameterList->getParam(currentParameterIndex));
currentParameterIndex++;