data: parser performance optimization for large projects

* moved inserting everything into the database to the end of parsing a file. this reduces many duplicate queries.
* removed ParserClient interface from Storage.
* errors are updated after parsing a file because we only if there are any duplicate errors after merging the new errors into the database.
* renamed field in db
* added fatal column to error db
This commit is contained in:
malte_langkabel
2016-03-10 18:24:28 +01:00
parent e7c7178057
commit 9a7b818dba
17 changed files with 1254 additions and 1055 deletions
+1 -91
View File
@@ -65,97 +65,7 @@ NetworkProtocolHelper.cpp ERROR: Failed to parse message, invalid type token
NetworkProtocolHelper.cpp ERROR: Failed to parse setActiveToken message, invalid token count
Settings.cpp WARNING: File for Settings not found: data/SettingsTestSuite/wrong_settings.xml
Settings.cpp WARNING: File for Settings not found: data/SettingsTestSuite/wrong_settings.xml
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: typedef: type <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: class: Class <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: struct: Struct <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: global: Global <file.cpp 1:42 1:42>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: field: m_field <file.cpp 1:3 1:3>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: field: Struct::m_field <file.cpp 1:11 1:11>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: function: bool isTrue(char) <file.cpp 1:14 1:14>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: method: void isMethod(bool) <file.cpp 1:9 1:9>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: method: void Class::isMethod(bool) <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: namespace: utility <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: enum: Category <file.cpp 1:17 1:17>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: enum: Class::Category <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: enum constant: VALUE <file.cpp 1:1 1:1>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: class: ClassA <file.cpp 1:0 1:0>
INFO: class: ClassB <file.cpp 1:0 1:0>
INFO: inheritance: ClassB : ClassA <file.cpp 1:5 1:5>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: struct: StructA <file.cpp 1:0 1:0>
INFO: struct: StructB <file.cpp 1:0 1:0>
INFO: inheritance: StructB : StructA <file.cpp 1:5 1:5>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: method: void A::isMethod(bool) <file.cpp 1:9 1:9>
INFO: method: void B::isMethod(bool) <file.cpp 1:7 1:7>
INFO: override: void A::isMethod(bool) -> void B::isMethod(bool) <file.cpp 1:4 1:4>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: function: bool isTrue(char) <file.cpp 1:0 1:0>
INFO: function: void func(bool) <file.cpp 1:0 1:0>
INFO: call: bool isTrue(char) -> void func(bool) <file.cpp 1:9 1:9>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: global: global <file.cpp 1:0 1:0>
INFO: function: bool isTrue(char) <file.cpp 1:0 1:0>
INFO: call: global -> bool isTrue(char) <file.cpp 1:7 1:7>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: function: bool isTrue(char) <file.cpp 1:0 1:0>
INFO: field: Foo::m_field <file.cpp 1:0 1:0>
INFO: field usage: bool isTrue(char) -> Foo::m_field <file.cpp 1:7 1:7>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: function: bool isTrue(char) <file.cpp 1:0 1:0>
INFO: global: global <file.cpp 1:0 1:0>
INFO: global usage: bool isTrue(char) -> global <file.cpp 1:7 1:7>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: function: Struct isTrue(char) <file.cpp 1:0 1:0>
INFO: struct: Struct <file.cpp 1:0 1:0>
INFO: type usage: Struct isTrue(char) -> Struct <file.cpp 1:7 1:7>
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: file: file.h < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.h
INFO: file: file.cpp < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.cpp
INFO: file: file.h < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file file.h
INFO: file: file.cpp < 0:0 0:0>
INFO: include: file.h <file.cpp 1:7 1:7>
INFO: file: file.cpp < 0:0 0:0>
INFO: file: file.h < 0:0 0:0>
TextAccess.cpp ERROR: Could not open file path/to/test.h
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
+15 -8
View File
@@ -5,20 +5,19 @@
#include "clang/Tooling/JSONCompilationDatabase.h"
#include "data/parser/cxx/CxxParser.h"
#include "data/parser/ParserClient.h"
#include "data/Storage.h"
#include "utility/file/FileRegister.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/utility.h"
TaskParseCxx::TaskParseCxx(
ParserClient* client,
Storage* storage,
const FileManager* fileManager,
const Parser::Arguments& arguments,
const std::vector<FilePath>& files
)
: m_client(client)
, m_parser(std::make_shared<CxxParser>(client, fileManager))
: m_storage(storage)
, m_arguments(arguments)
, m_files(files)
, m_isCDB(false)
@@ -27,6 +26,8 @@ TaskParseCxx::TaskParseCxx(
{
m_isCDB = true;
}
m_parserClient = std::make_shared<ParserClientImpl>();
m_parser = std::make_shared<CxxParser>(m_parserClient.get(), fileManager);
}
std::vector<FilePath> TaskParseCxx::getSourceFilesFromCDB(const FilePath& compilationDatabasePath)
@@ -66,7 +67,7 @@ void TaskParseCxx::enter()
m_sourcePaths.push_back(path.absolute());
}
m_client->startParsing();
m_storage->startParsing();
}
Task::TaskState TaskParseCxx::update()
@@ -104,7 +105,10 @@ Task::TaskState TaskParseCxx::update()
MessageStatus(ss.str(), false, true).dispatch();
m_client->startParsingFile(sourcePath);
std::shared_ptr<IntermediateStorage> intermediateStorage = std::make_shared<IntermediateStorage>();
m_parserClient->setStorage(intermediateStorage);
m_parserClient->startParsingFile(sourcePath);
if (m_isCDB)
{
@@ -119,7 +123,10 @@ Task::TaskState TaskParseCxx::update()
m_parser->runTool(std::vector<std::string>(1, sourcePath.str()));
}
m_client->finishParsingFile(sourcePath);
m_parserClient->finishParsingFile(sourcePath);
m_parserClient->resetStorage();
m_storage->injectData(intermediateStorage);
if (isSource)
{
@@ -133,7 +140,7 @@ void TaskParseCxx::exit()
{
MessageStatus("building search index").dispatch();
m_client->finishParsing();
m_storage->finishParsing();
FileRegister* fileRegister = m_parser->getFileRegister();
+4
View File
@@ -129,6 +129,8 @@ add_files(
data/parser/Parser.h
data/parser/ParserClient.cpp
data/parser/ParserClient.h
data/parser/ParserClientImpl.cpp
data/parser/ParserClientImpl.h
data/search/SearchIndex.cpp
data/search/SearchIndex.h
@@ -155,6 +157,8 @@ add_files(
data/ErrorCountInfo.h
data/HierarchyCache.cpp
data/HierarchyCache.h
data/IntermediateStorage.cpp
data/IntermediateStorage.h
data/SqliteStorage.cpp
data/SqliteStorage.h
data/Storage.cpp
@@ -355,11 +355,11 @@ std::vector<CodeSnippetParams> CodeController::getSnippetsForFile(std::shared_pt
{
TokenLocation* endLoc = startLoc->getOtherTokenLocation();
TokenLocation* scopeLoc = scopeLocations->addTokenLocation(
startLoc->getId(),
startLoc->getTokenId(),
startLoc->getLineNumber(),
startLoc->getColumnNumber(),
endLoc->getLineNumber(),
startLoc->getId(),
startLoc->getTokenId(),
startLoc->getLineNumber(),
startLoc->getColumnNumber(),
endLoc->getLineNumber(),
endLoc->getColumnNumber());
scopeLoc->setType(TokenLocation::LOCATION_SCOPE);
}
+390
View File
@@ -0,0 +1,390 @@
#include "data/IntermediateStorage.h"
#include "data/graph/Edge.h"
#include "utility/logging/logging.h"
IntermediateStorage::IntermediateStorage()
: m_nextId(1)
{
}
IntermediateStorage::~IntermediateStorage()
{
}
Id IntermediateStorage::addEdge(int type, Id sourceId, Id targetId)
{
std::shared_ptr<StorageEdge> edge = std::make_shared<StorageEdge>(0, type, sourceId, targetId);
std::string serialized = serialize(*(edge.get()));
std::unordered_map<std::string, Id>::const_iterator it = m_edgeNamesToIds.find(serialized);
if (it != m_edgeNamesToIds.end())
{
return it->second;
}
Id id = m_nextId++;
m_edgeNamesToIds[serialized] = id;
m_edgeIdsToData[id] = edge;
if (type == Edge::EDGE_MEMBER)
{
m_nodeIdsToMemberEdgeIds[targetId] = id;
}
return id;
}
Id IntermediateStorage::addNode(int type, const NameHierarchy& nameHierarchy, bool defined)
{
std::shared_ptr<StorageNode> node = std::make_shared<StorageNode>(0, type, NameHierarchy::serialize(nameHierarchy), defined);
std::string serialized = serialize(*(node.get()));
std::unordered_map<std::string, Id>::const_iterator it = m_nodeNamesToIds.find(serialized);
if (it != m_nodeNamesToIds.end())
{
// refine stored information
if (defined)
{
std::unordered_map<Id, std::shared_ptr<StorageNode>>::const_iterator it2 = m_nodeIdsToData.find(it->second);
std::shared_ptr<StorageNode> storageNode = it2->second;
if (!storageNode->defined && storageNode->type < type)
{
storageNode->type = type;
}
storageNode->defined = true;
}
return it->second;
}
Id id = m_nextId++;
m_nodeNamesToIds[serialized] = id;
m_nodeIdsToData[id] = node;
return id;
}
Id IntermediateStorage::addFile(const std::string& name, const std::string& filePath, const std::string& modificationTime)
{
std::shared_ptr<StorageFile> file = std::make_shared<StorageFile>(0, name, filePath, modificationTime);
std::string serialized = serialize(*(file.get()));
std::unordered_map<std::string, Id>::const_iterator it = m_fileNamesToIds.find(serialized);
if (it != m_fileNamesToIds.end())
{
Id id = it->second;
if (m_fileIdsToData[id]->filePath.size() == 0) // stored information is incomplete.
{
m_fileIdsToData[id] = file; // so we replace it.
}
return id;
}
Id id = m_nextId++;
m_fileNamesToIds[serialized] = id;
m_fileIdsToData[id] = file;
return id;
}
Id IntermediateStorage::addFile(const std::string& filePath)
{
std::shared_ptr<StorageFile> file = std::make_shared<StorageFile>(0, "", filePath, "");
std::string serialized = serialize(*(file.get()));
std::unordered_map<std::string, Id>::const_iterator it = m_fileNamesToIds.find(serialized);
if (it != m_fileNamesToIds.end())
{
return it->second;
}
Id id = m_nextId++;
m_fileNamesToIds[serialized] = id;
m_fileIdsToData[id] = file;
return id;
}
void IntermediateStorage::addSourceLocation(Id elementId, const ParseLocation& location, bool isScope)
{
Id fileNodeId = addFile(location.filePath.str());
m_sourceLocations.push_back(StorageSourceLocation(
0,
elementId,
fileNodeId,
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
location.endColumnNumber,
isScope
));
}
void IntermediateStorage::addComponentAccess(Id nodeId, int type)
{
std::unordered_map<Id, Id>::const_iterator it = m_nodeIdsToMemberEdgeIds.find(nodeId);
if (it != m_nodeIdsToMemberEdgeIds.end())
{
m_componentAccesses.push_back(StorageComponentAccess(it->second, type));
}
else
{
LOG_ERROR_STREAM(<< "Cannot assign access" << type << " to node id " << nodeId << " because it's not a child node.");
}
}
void IntermediateStorage::addCommentLocation(const ParseLocation& location)
{
Id fileNodeId = addFile(location.filePath.str());
m_commentLocations.push_back(StorageCommentLocation(
0,
fileNodeId,
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
location.endColumnNumber
));
}
void IntermediateStorage::addError(const std::string& message, bool fatal, const ParseLocation& location)
{
m_errors.push_back(StorageError(
message,
fatal,
location.filePath.str(),
location.startLineNumber,
location.startColumnNumber
));
}
void IntermediateStorage::transferToStorage(SqliteStorage& storage)
{
storage.beginTransaction();
std::unordered_map<Id, Id> clientIdToStorageId;
for (std::unordered_map<Id, std::shared_ptr<StorageFile>>::const_iterator it = m_fileIdsToData.begin(); it != m_fileIdsToData.end(); it++)
{
if (it->second->name.size() > 0)
{
Id fileNodeId = storage.getFileByPath(it->second->filePath).id;
if (fileNodeId == 0)
{
NameHierarchy nameHierarchy;
nameHierarchy.push(std::make_shared<NameElement>(it->second->name));
fileNodeId = storage.addFile(
NameHierarchy::serialize(nameHierarchy),
it->second->filePath,
it->second->modificationTime
);
}
clientIdToStorageId[it->first] = fileNodeId;
}
}
for (std::unordered_map<Id, std::shared_ptr<StorageNode>>::const_iterator it = m_nodeIdsToData.begin(); it != m_nodeIdsToData.end(); it++)
{
StorageNode clientNode = *(it->second.get());
StorageNode storageNode = storage.getNodeBySerializedName(clientNode.serializedName);
Id storageNodeId = storageNode.id;
if (storageNodeId)
{
if (clientNode.defined)
{
storage.setNodeDefined(true, storageNode.id);
if (!storageNode.defined && storageNode.type < clientNode.type)
{
storage.setNodeType(clientNode.type, storageNode.id);
}
}
}
else
{
storageNodeId = storage.addNode(clientNode.type, clientNode.serializedName, clientNode.defined);
}
clientIdToStorageId[it->first] = storageNodeId;
}
for (std::unordered_map<Id, std::shared_ptr<StorageEdge>>::const_iterator it = m_edgeIdsToData.begin(); it != m_edgeIdsToData.end(); it++)
{
std::unordered_map<Id, Id>::const_iterator it2;
it2 = clientIdToStorageId.find(it->second->sourceNodeId);
if (it2 == clientIdToStorageId.end())
{
continue;
}
Id storageSourceId = it2->second;
it2 = clientIdToStorageId.find(it->second->targetNodeId);
if (it2 == clientIdToStorageId.end())
{
continue;
}
Id storageTargetId = it2->second;
Id edgeId = storage.getEdgeBySourceTargetType(storageSourceId, storageTargetId, it->second->type).id;
if (!edgeId)
{
edgeId = storage.addEdge(it->second->type, storageSourceId, storageTargetId);
}
clientIdToStorageId[it->first] = edgeId;
}
for (size_t i = 0; i < m_sourceLocations.size(); i++)
{
StorageSourceLocation sourceLocation = m_sourceLocations[i];
std::unordered_map<Id, Id>::const_iterator it;
it = clientIdToStorageId.find(sourceLocation.elementId);
if (it == clientIdToStorageId.end())
{
continue;
}
Id storageElementId = it->second;
it = clientIdToStorageId.find(sourceLocation.fileNodeId);
if (it == clientIdToStorageId.end())
{
continue;
}
Id storageFileNodeId = it->second;
storage.addSourceLocation(
storageElementId,
storageFileNodeId,
sourceLocation.startLine,
sourceLocation.startCol,
sourceLocation.endLine,
sourceLocation.endCol,
sourceLocation.isScope
);
}
for (size_t i = 0; i < m_componentAccesses.size(); i++)
{
StorageComponentAccess componentAccess = m_componentAccesses[i];
std::unordered_map<Id, Id>::const_iterator it;
it = clientIdToStorageId.find(componentAccess.memberEdgeId);
if (it == clientIdToStorageId.end())
{
continue;
}
Id storageMemberEdgeId = it->second;
storage.addComponentAccess(storageMemberEdgeId, componentAccess.type);
}
for (size_t i = 0; i < m_commentLocations.size(); i++)
{
StorageCommentLocation commentLocation = m_commentLocations[i];
std::unordered_map<Id, Id>::const_iterator it;
it = clientIdToStorageId.find(commentLocation.fileNodeId);
if (it == clientIdToStorageId.end())
{
continue;
}
Id storageFileNodeId = it->second;
storage.addCommentLocation(
storageFileNodeId,
commentLocation.startLine,
commentLocation.startCol,
commentLocation.endLine,
commentLocation.endCol
);
}
for (size_t i = 0; i < m_errors.size(); i++)
{
StorageError error = m_errors[i];
storage.addError(
error.message,
error.fatal,
error.filePath,
error.lineNumber,
error.columnNumber
);
}
storage.commitTransaction();
}
void IntermediateStorage::forEachFile(std::function<void(const Id /*id*/, const StorageFile& /*data*/)> callback) const
{
for (std::unordered_map<Id, std::shared_ptr<StorageFile>>::const_iterator it = m_fileIdsToData.begin(); it != m_fileIdsToData.end(); it++)
{
callback(it->first, *(it->second.get()));
}
}
void IntermediateStorage::forEachNode(std::function<void(const Id /*id*/, const StorageNode& /*data*/)> callback) const
{
for (std::unordered_map<Id, std::shared_ptr<StorageNode>>::const_iterator it = m_nodeIdsToData.begin(); it != m_nodeIdsToData.end(); it++)
{
callback(it->first, *(it->second.get()));
}
}
void IntermediateStorage::forEachEdge(std::function<void(const Id /*id*/, const StorageEdge& /*data*/)> callback) const
{
for (std::unordered_map<Id, std::shared_ptr<StorageEdge>>::const_iterator it = m_edgeIdsToData.begin(); it != m_edgeIdsToData.end(); it++)
{
callback(it->first, *(it->second.get()));
}
}
void IntermediateStorage::forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const
{
for (std::vector<StorageSourceLocation>::const_iterator it = m_sourceLocations.begin(); it != m_sourceLocations.end(); it++)
{
callback(*it);
}
}
void IntermediateStorage::forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const
{
for (std::vector<StorageComponentAccess>::const_iterator it = m_componentAccesses.begin(); it != m_componentAccesses.end(); it++)
{
callback(*it);
}
}
void IntermediateStorage::forEachCommentLocation(std::function<void(const StorageCommentLocation& /*data*/)> callback) const
{
for (std::vector<StorageCommentLocation>::const_iterator it = m_commentLocations.begin(); it != m_commentLocations.end(); it++)
{
callback(*it);
}
}
void IntermediateStorage::forEachError(std::function<void(const StorageError& /*data*/)> callback) const
{
for (std::vector<StorageError>::const_iterator it = m_errors.begin(); it != m_errors.end(); it++)
{
callback(*it);
}
}
std::string IntermediateStorage::serialize(const StorageEdge& edge)
{
return (
std::to_string(edge.type) +
std::to_string(edge.sourceNodeId) +
std::to_string(edge.targetNodeId)
);
}
std::string IntermediateStorage::serialize(const StorageNode& node)
{
return node.serializedName;
}
std::string IntermediateStorage::serialize(const StorageFile& file)
{
return file.filePath;
}
+63
View File
@@ -0,0 +1,63 @@
#ifndef INTERMEDIATE_STORAGE_H
#define INTERMEDIATE_STORAGE_H
#include <memory>
#include <string>
#include <unordered_map>
#include "utility/types.h"
#include "data/name/NameHierarchy.h"
#include "data/parser/ParseLocation.h"
#include "data/SqliteStorage.h"
#include "data/StorageTypes.h"
class IntermediateStorage
{
public:
IntermediateStorage();
~IntermediateStorage();
Id addEdge(int type, Id sourceId, Id targetId);
Id addNode(int type, const NameHierarchy& nameHierarchy, bool defined);
Id addFile(const std::string& name, const std::string& filePath, const std::string& modificationTime);
Id addFile(const std::string& filePath);
void addSourceLocation(Id elementId, const ParseLocation& location, bool isScope);
void addComponentAccess(Id nodeId , int type);
void addCommentLocation(const ParseLocation& location);
void addError(const std::string& message, bool fatal, const ParseLocation& location);
void transferToStorage(SqliteStorage& storage); // TODO: remove this and use foreach-callbacks instead
void forEachFile(std::function<void(const Id /*id*/, const StorageFile& /*data*/)> callback) const;
void forEachNode(std::function<void(const Id /*id*/, const StorageNode& /*data*/)> callback) const;
void forEachEdge(std::function<void(const Id /*id*/, const StorageEdge& /*data*/)> callback) const;
void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const;
void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const;
void forEachCommentLocation(std::function<void(const StorageCommentLocation& /*data*/)> callback) const;
void forEachError(std::function<void(const StorageError& /*data*/)> callback) const;
private:
std::string serialize(const StorageEdge& edge);
std::string serialize(const StorageNode& node);
std::string serialize(const StorageFile& file);
std::unordered_map<std::string, Id> m_fileNamesToIds; // this is used to prevent duplicates (unique)
std::unordered_map<Id, std::shared_ptr<StorageFile>> m_fileIdsToData;
std::unordered_map<std::string, Id> m_nodeNamesToIds; // this is used to prevent duplicates (unique)
std::unordered_map<Id, std::shared_ptr<StorageNode>> m_nodeIdsToData;
std::unordered_map<std::string, Id> m_edgeNamesToIds; // this is used to prevent duplicates (unique)
std::unordered_map<Id, std::shared_ptr<StorageEdge>> m_edgeIdsToData;
std::vector<StorageSourceLocation> m_sourceLocations;
std::vector<StorageComponentAccess> m_componentAccesses;
std::vector<StorageCommentLocation> m_commentLocations;
std::vector<StorageError> m_errors;
std::unordered_map<Id, Id> m_nodeIdsToMemberEdgeIds;
Id m_nextId;
};
#endif // INTERMEDIATE_STORAGE_H
+33 -25
View File
@@ -110,7 +110,7 @@ Id SqliteStorage::addNode(int type, const std::string& serializedName, bool defi
Id id = m_database.lastRowId();
m_database.execDML((
"INSERT INTO node(id, type, serializedName, defined) VALUES("
"INSERT INTO node(id, type, serialized_name, defined) VALUES("
+ std::to_string(id) + ", " + std::to_string(type) + ", '" + serializedName + "', " + std::to_string(defined) + ");"
).c_str());
@@ -134,8 +134,8 @@ Id SqliteStorage::addFile(const std::string& serializedName, const std::string&
return id;
}
Id SqliteStorage::addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine,
uint endCol, bool isScope)
Id 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) "
@@ -171,12 +171,13 @@ Id SqliteStorage::addCommentLocation(Id fileNodeId, uint startLine, uint startCo
Id SqliteStorage::addError(const std::string& message, bool fatal, const std::string& filePath, uint lineNumber, uint columnNumber)
{
std::string sanitizedMessage = utility::replace((fatal ? "Fatal: " : "") + message, "'", "''");
std::string sanitizedMessage = utility::replace((fatal ? "Fatal: " : "Error: ") + message, "'", "''");
// check for duplicate
CppSQLite3Query q = m_database.execQuery((
"SELECT * FROM error WHERE "
"message == '" + sanitizedMessage + "' AND "
"fatal == " + std::to_string(fatal) + " AND "
"file_path == '" + filePath + "' AND "
"line_number == " + std::to_string(lineNumber) + " AND "
"column_number == " + std::to_string(columnNumber) + ";"
@@ -188,8 +189,8 @@ Id SqliteStorage::addError(const std::string& message, bool fatal, const std::st
}
m_database.execDML((
"INSERT INTO error(message, file_path, line_number, column_number) "
"VALUES ('" + sanitizedMessage + "', '" + filePath + "', " + std::to_string(lineNumber) + ", " + std::to_string(columnNumber) + ");"
"INSERT INTO error(message, fatal, file_path, line_number, column_number) "
"VALUES ('" + sanitizedMessage + "', " + std::to_string(fatal) + ", '" + filePath + "', " + std::to_string(lineNumber) + ", " + std::to_string(columnNumber) + ");"
).c_str());
return m_database.lastRowId();
@@ -410,7 +411,7 @@ StorageNode SqliteStorage::getNodeById(Id id) const
StorageNode SqliteStorage::getNodeBySerializedName(const std::string& serializedName) const
{
std::vector<StorageNode> nodes = getAllNodes("WHERE serializedName == '" + serializedName + "'"); // Todo: use getfirstnode here
std::vector<StorageNode> nodes = getAllNodes("WHERE serialized_name == '" + serializedName + "'"); // Todo: use getfirstnode here
if (nodes.size() > 0)
{
return nodes[0];
@@ -426,7 +427,7 @@ std::vector<StorageNode> SqliteStorage::getNodesByIds(const std::vector<Id>& nod
StorageFile SqliteStorage::getFileById(const Id id) const
{
return getFirstFile(
"SELECT node.id, node.serializedName, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id "
"SELECT node.id, node.serialized_name, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id "
"WHERE node.id == " + std::to_string(id) + ";"
);
}
@@ -434,7 +435,7 @@ StorageFile SqliteStorage::getFileById(const Id id) const
StorageFile SqliteStorage::getFileByPath(const std::string& filePath) const
{
StorageFile storageFile = getFirstFile(
"SELECT node.id, node.serializedName, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id "
"SELECT node.id, node.serialized_name, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id "
"WHERE file.path == '" + filePath + "';"
);
@@ -443,7 +444,7 @@ StorageFile SqliteStorage::getFileByPath(const std::string& filePath) const
std::vector<StorageFile> SqliteStorage::getAllFiles() const
{
return getAllFiles("SELECT file.id, node.serializedName, file.path, file.modification_time FROM file INNER JOIN node ON file.id = node.id;");
return getAllFiles("SELECT file.id, node.serialized_name, file.path, file.modification_time FROM file INNER JOIN node ON file.id = node.id;");
}
std::shared_ptr<TextAccess> SqliteStorage::getFileContentByPath(const std::string& filePath) const
@@ -629,18 +630,19 @@ std::vector<StorageCommentLocation> SqliteStorage::getCommentLocationsInFile(con
std::vector<StorageError> SqliteStorage::getAllErrors() const
{
CppSQLite3Query q = m_database.execQuery(
"SELECT message, file_path, line_number, column_number FROM error;"
);
"SELECT message, fatal, file_path, line_number, column_number FROM error;"
);
std::vector<StorageError> errors;
while (!q.eof())
{
const std::string message = q.getStringField(0, "");
const std::string filePath = q.getStringField(1, "");
const uint lineNumber = q.getIntField(2, 0);
const uint columnNumber = q.getIntField(3, 0);
const bool fatal = q.getIntField(1, 0);
const std::string filePath = q.getStringField(2, "");
const uint lineNumber = q.getIntField(3, 0);
const uint columnNumber = q.getIntField(4, 0);
errors.push_back(StorageError(message, filePath, lineNumber, columnNumber));
errors.push_back(StorageError(message, fatal, filePath, lineNumber, columnNumber));
q.nextRow();
}
@@ -651,18 +653,19 @@ std::vector<StorageError> SqliteStorage::getAllErrors() const
std::vector<StorageError> SqliteStorage::getFatalErrors() const
{
CppSQLite3Query q = m_database.execQuery(
"SELECT message, file_path, line_number, column_number FROM error WHERE message LIKE 'Fatal: %';"
);
"SELECT message, fatal, file_path, line_number, column_number FROM error WHERE fatal == 1;"
);
std::vector<StorageError> errors;
while (!q.eof())
{
const std::string message = q.getStringField(0, "");
const std::string filePath = q.getStringField(1, "");
const uint lineNumber = q.getIntField(2, 0);
const uint columnNumber = q.getIntField(3, 0);
const bool fatal = q.getIntField(1, 0);
const std::string filePath = q.getStringField(2, "");
const uint lineNumber = q.getIntField(3, 0);
const uint columnNumber = q.getIntField(4, 0);
errors.push_back(StorageError(message, filePath, lineNumber, columnNumber));
errors.push_back(StorageError(message, fatal, filePath, lineNumber, columnNumber));
q.nextRow();
}
@@ -736,18 +739,22 @@ void SqliteStorage::setupTables()
"FOREIGN KEY(target_node_id) REFERENCES node(id) ON DELETE CASCADE);"
);
m_database.execDML( // used for checking for duplicates during code analysis // TODO: move to createIndexesForAnalysis() or prepareForAnalysis
"CREATE INDEX IF NOT EXISTS edge_multipart_index ON edge(type, source_node_id, target_node_id);"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS node("
"id INTEGER NOT NULL, "
"type INTEGER NOT NULL, "
"serializedName TEXT, "
"serialized_name TEXT, "
"defined INTEGER NOT NULL, "
"PRIMARY KEY(id), "
"FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE);"
);
m_database.execDML(
"CREATE INDEX IF NOT EXISTS node_serializedName_index ON node(serializedName);"
"CREATE INDEX IF NOT EXISTS node_serialized_name_index ON node(serialized_name);"
);
m_database.execDML(
@@ -801,6 +808,7 @@ void SqliteStorage::setupTables()
"CREATE TABLE IF NOT EXISTS error("
"id INTEGER NOT NULL, "
"message TEXT, "
"fatal INTEGER NOT NULL, "
"file_path TEXT, "
"line_number INTEGER, "
"column_number INTEGER, "
@@ -940,7 +948,7 @@ std::vector<StorageEdge> SqliteStorage::getAllEdges(const std::string& query) co
std::vector<StorageNode> SqliteStorage::getAllNodes(const std::string& query) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT id, type, serializedName, defined FROM node " + query + ";"
"SELECT id, type, serialized_name, defined FROM node " + query + ";"
).c_str());
std::vector<StorageNode> nodes;
+4 -466
View File
@@ -175,30 +175,13 @@ void Storage::finishParsing()
buildHierarchyCache();
}
void Storage::startParsingFile(const FilePath& filePath)
void Storage::injectData(std::shared_ptr<IntermediateStorage> injectedStorage)
{
m_sqliteStorage.beginTransaction();
}
int totalErrorCount = getErrorCount().total;
void Storage::finishParsingFile(const FilePath& filePath)
{
m_sqliteStorage.commitTransaction();
}
injectedStorage->transferToStorage(m_sqliteStorage);
void Storage::onError(const ParseLocation& location, const std::string& message, bool fatal)
{
log(std::string(fatal ? "FATAL " : "") + "ERROR", message, location);
if (!location.isValid())
{
return;
}
size_t totalErrorCount = getErrorCount().total;
m_sqliteStorage.addError(message, fatal, location.filePath.str(), location.startLineNumber, location.startColumnNumber);
if ((int)totalErrorCount != getErrorCount().total)
if (totalErrorCount != getErrorCount().total)
{
MessageShowErrors msg(getErrorCount());
msg.setSendAsTask(false);
@@ -206,394 +189,6 @@ void Storage::onError(const ParseLocation& location, const std::string& message,
}
}
Id Storage::onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access
){
log("typedef", typedefName.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_TYPEDEF, typedefName, true);
addSourceLocation(nodeId, location);
addAccess(nodeId, access);
return nodeId;
}
Id Storage::onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation
){
log("class", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_CLASS, nameHierarchy, scopeLocation.isValid());
addSourceLocation(nodeId, location);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return nodeId;
}
Id Storage::onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation
){
log("struct", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_STRUCT, nameHierarchy, scopeLocation.isValid());
addSourceLocation(nodeId, location);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return nodeId;
}
Id Storage::onGlobalVariableParsed(const ParseLocation& location, const NameHierarchy& variable)
{
log("global", variable.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, variable, true);
addSourceLocation(nodeId, location);
return nodeId;
}
Id Storage::onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access)
{
log("field", field.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_FIELD, field, true);
addSourceLocation(nodeId, location);
addAccess(nodeId, access);
return nodeId;
}
Id Storage::onFunctionParsed(
const ParseLocation& location, const NameHierarchy& function, const ParseLocation& scopeLocation
){
log("function", function.getQualifiedNameWithSignature(), location);
Id nodeId = addNodeHierarchy(Node::NODE_FUNCTION, function, true);
addSourceLocation(nodeId, location);
addSourceLocation(nodeId, scopeLocation, true);
return nodeId;
}
Id Storage::onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation
){
log("method", method.getQualifiedNameWithSignature(), location);
Id nodeId = addNodeHierarchy(Node::NODE_METHOD, method, location.isValid() && scopeLocation.isValid());
addSourceLocation(nodeId, location);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return nodeId;
}
Id Storage::onNamespaceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, const ParseLocation& scopeLocation
){
log("namespace", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_NAMESPACE, nameHierarchy, true);
addSourceLocation(nodeId, location);
addSourceLocation(nodeId, scopeLocation, true);
return nodeId;
}
Id Storage::onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation
){
log("enum", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_ENUM, nameHierarchy, true);
addSourceLocation(nodeId, location);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return nodeId;
}
Id Storage::onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy)
{
log("enum constant", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, nameHierarchy, true);
addSourceLocation(nodeId, location);
return nodeId;
}
Id Storage::onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& childNameHierarchy,
const NameHierarchy& parentNameHierarchy, AccessType access
){
log("inheritance", childNameHierarchy.getQualifiedName() + " : " + parentNameHierarchy.getQualifiedName(), location);
Id childNodeId = addNodeHierarchy(Node::NODE_TYPE, childNameHierarchy, false);
Id parentNodeId = addNodeHierarchy(Node::NODE_TYPE, parentNameHierarchy, false);
Id edgeId = addEdge(childNodeId, parentNodeId, Edge::EDGE_INHERITANCE, location);
return edgeId;
}
Id Storage::onMethodOverrideParsed(
const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider)
{
log("override", overridden.getQualifiedNameWithSignature() + " -> " + overrider.getQualifiedNameWithSignature(), location);
Id baseNodeId = addNodeHierarchy(Node::NODE_FUNCTION, overridden, false);
Id overriderNodeId = addNodeHierarchy(Node::NODE_FUNCTION, overrider, false);
Id edgeId = addEdge(overriderNodeId, baseNodeId, Edge::EDGE_OVERRIDE, location);
return edgeId;
}
Id Storage::onCallParsed(const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee)
{
log("call", caller.getQualifiedNameWithSignature() + " -> " + callee.getQualifiedNameWithSignature(), location);
Id callerNodeId = addNodeHierarchy(Node::NODE_FUNCTION, caller, false);
Id calleeNodeId = addNodeHierarchy(Node::NODE_FUNCTION, callee, false);
Id edgeId = addEdge(callerNodeId, calleeNodeId, Edge::EDGE_CALL, location);
return edgeId;
}
Id Storage::onFieldUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy
){
log("field usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedName(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, false);
Id usedNodeId = addNodeHierarchy(Node::NODE_FIELD, usedNameHierarchy, false);
Id edgeId = addEdge(userNodeId, usedNodeId, Edge::EDGE_USAGE, location);
return edgeId;
}
Id Storage::onGlobalVariableUsageParsed( // or static variable used
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy
){
log("global usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedNameWithSignature(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, false);
Id usedNodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, usedNameHierarchy, false);
Id edgeId = addEdge(userNodeId, usedNodeId, Edge::EDGE_USAGE, location);
return edgeId;
}
Id Storage::onEnumConstantUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy
){
log("enum constant usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedNameWithSignature(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, userNameHierarchy, false);
Id usedNodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, usedNameHierarchy, false);
Id edgeId = addEdge(userNodeId, usedNodeId, Edge::EDGE_USAGE, location);
return edgeId;
}
Id Storage::onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used)
{
log("type usage", user.getQualifiedNameWithSignature() + " -> " + used.getQualifiedName(), location);
if (!location.isValid())
{
return 0;
}
Id functionNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, user, false);
Id typeNodeId = addNodeHierarchy(Node::NODE_TYPE, used, false);
Id edgeId = addEdge(functionNodeId, typeNodeId, Edge::EDGE_TYPE_USAGE, location);
return edgeId;
}
Id Storage::onTemplateArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& argumentTypeNameHierarchy,
const NameHierarchy& templateNameHierarchy)
{
log(
"template argument type",
argumentTypeNameHierarchy.getQualifiedName() + " -> " + templateNameHierarchy.getQualifiedName(),
location
);
Id argumentNodeId = addNodeHierarchy(Node::NODE_TYPE, argumentTypeNameHierarchy, false);
Id templateNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, templateNameHierarchy, false);
addEdge(templateNodeId, argumentNodeId, Edge::EDGE_TEMPLATE_ARGUMENT, location);
return argumentNodeId;
}
Id Storage::onTemplateDefaultArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& defaultArgumentTypeNameHierarchy,
const NameHierarchy& templateParameterNameHierarchy
){
log(
"template default argument",
defaultArgumentTypeNameHierarchy.getQualifiedNameWithSignature() + " -> " + templateParameterNameHierarchy.getQualifiedName(),
location
);
Id defaultArgumentNodeId = addNodeHierarchy(Node::NODE_TYPE, defaultArgumentTypeNameHierarchy, false);
Id parameterNodeId = addNodeHierarchy(Node::NODE_TYPE, templateParameterNameHierarchy, false);
addEdge(parameterNodeId, defaultArgumentNodeId, Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT, location);
return defaultArgumentNodeId;
}
Id Storage::onTemplateParameterTypeParsed(
const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy
){
log("template parameter type", templateParameterTypeNameHierarchy.getQualifiedName(), location);
Id parameterNodeId = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy, true);
addSourceLocation(parameterNodeId, location, false);
addAccess(parameterNodeId, TokenComponentAccess::ACCESS_TEMPLATE);
return parameterNodeId;
}
Id Storage::onTemplateSpecializationParsed(
const ParseLocation& location, const NameHierarchy& specializedNameHierarchy,
const NameHierarchy& specializedFromNameHierarchy
){
log(
"template record specialization",
specializedNameHierarchy.getQualifiedName() + " -> " + specializedFromNameHierarchy.getQualifiedName(),
location
);
Id specializedId = addNodeHierarchy(Node::NODE_TYPE, specializedNameHierarchy, false);
Id recordNodeId = addNodeHierarchy(Node::NODE_TYPE, specializedFromNameHierarchy, false);
Id edgeId = addEdge(specializedId, recordNodeId, Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, location);
return edgeId;
}
Id Storage::onTemplateMemberFunctionSpecializationParsed(
const ParseLocation& location, const NameHierarchy& instantiatedFunction, const NameHierarchy& specializedFunction
){
log(
"template member function specialization",
instantiatedFunction.getQualifiedNameWithSignature() + " -> " + specializedFunction.getQualifiedNameWithSignature(),
location
);
Id instantiatedFunctionNodeId = addNodeHierarchy(Node::NODE_FUNCTION, instantiatedFunction, false);
Id specializedFunctionNodeId = addNodeHierarchy(Node::NODE_FUNCTION, specializedFunction, false);
Id edgeId = addEdge(instantiatedFunctionNodeId, specializedFunctionNodeId, Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION_OF, location);
return edgeId;
}
Id Storage::onTemplateFunctionSpecializationParsed(
const ParseLocation& location, const NameHierarchy specializedFunction, const NameHierarchy templateFunction
){
log("function template specialization", specializedFunction.getQualifiedNameWithSignature(), location);
Id specializedNodeId = addNodeHierarchy(Node::NODE_TYPE, specializedFunction, true);
Id functionNodeId = addNodeHierarchy(Node::NODE_TYPE, templateFunction, false);
Id edgeId = addEdge(specializedNodeId, functionNodeId, Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, location);
return edgeId;
}
Id Storage::onFileParsed(const FileInfo& fileInfo)
{
log("file", fileInfo.path.str(), ParseLocation());
Id fileNodeId = getFileNodeId(fileInfo.path);
if (fileNodeId == 0)
{
NameHierarchy nameHierarchy;
nameHierarchy.push(std::make_shared<NameElement>(fileInfo.path.fileName()));
fileNodeId = m_sqliteStorage.addFile(
NameHierarchy::serialize(nameHierarchy),
fileInfo.path.str(),
utility::timeToString(fileInfo.lastWriteTime)
);
}
return fileNodeId;
}
Id Storage::onFileIncludeParsed(const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo)
{
log("include", includedFileInfo.path.str(), location);
const Id fileNodeId = onFileParsed(fileInfo);
const Id includedFileNodeId = onFileParsed(includedFileInfo);
addEdge(fileNodeId, includedFileNodeId, Edge::EDGE_INCLUDE, location);
return fileNodeId;
}
Id Storage::onMacroDefineParsed(
const ParseLocation& location, const NameHierarchy& macroNameHierarchy, const ParseLocation& scopeLocation
){
log("macro", macroNameHierarchy.getQualifiedName(), location);
Id macroId = addNodeHierarchy(Node::NODE_MACRO, macroNameHierarchy, true);
addSourceLocation(macroId, location);
addSourceLocation(macroId, scopeLocation, true);
Id fileNodeId = getFileNodeId(location.filePath);
addEdge(fileNodeId, macroId, Edge::EDGE_MACRO_USAGE, location);
return macroId;
}
Id Storage::onMacroExpandParsed(const ParseLocation &location, const NameHierarchy& macroNameHierarchy)
{
log("macro use", macroNameHierarchy.getQualifiedName(), location);
Id macroExpandId = addNodeHierarchy(Node::NODE_MACRO, macroNameHierarchy, false);
Id fileNodeId = getFileNodeId(location.filePath);
Id edgeId = addEdge(fileNodeId, macroExpandId, Edge::EDGE_MACRO_USAGE, location);
return edgeId;
}
Id Storage::onCommentParsed(const ParseLocation& location)
{
log("comment", "no name", location);
Id fileNodeId = m_sqliteStorage.getFileByPath(location.filePath.str()).id;
Id commentId = m_sqliteStorage.addCommentLocation(
fileNodeId,
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
location.endColumnNumber
);
return commentId;
}
Id Storage::getIdForNodeWithNameHierarchy(const NameHierarchy& nameHierarchy) const
{
return m_sqliteStorage.getNodeBySerializedName(NameHierarchy::serialize(nameHierarchy)).id;
@@ -1449,54 +1044,6 @@ void Storage::addEdgesToGraph(const std::vector<Id> edgeIds, Graph* graph) const
}
}
TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const
{
switch (access)
{
case ACCESS_PUBLIC:
return TokenComponentAccess::ACCESS_PUBLIC;
case ACCESS_PROTECTED:
return TokenComponentAccess::ACCESS_PROTECTED;
case ACCESS_PRIVATE:
return TokenComponentAccess::ACCESS_PRIVATE;
case ACCESS_NONE:
return TokenComponentAccess::ACCESS_NONE;
}
}
void Storage::addAccess(Id nodeId, TokenComponentAccess::AccessType access)
{
if (access == TokenComponentAccess::ACCESS_NONE)
{
return;
}
std::vector<StorageEdge> memberEdges = m_sqliteStorage.getEdgesByTargetType(nodeId, Edge::EDGE_MEMBER);
if (memberEdges.size() != 1)
{
LOG_ERROR_STREAM(<< "Cannot assign access" << access << " to node id " << nodeId << " because it's no child.");
return;
}
m_sqliteStorage.addComponentAccess(memberEdges[0].id, access);
}
void Storage::addAccess(Id nodeId, ParserClient::AccessType access)
{
addAccess(nodeId, convertAccessType(access));
}
TokenComponentAccess::AccessType Storage::getAccess(Id nodeId) const
{
std::vector<StorageEdge> memberEdges = m_sqliteStorage.getEdgesByTargetType(nodeId, Edge::EDGE_MEMBER);
if (memberEdges.size() == 1)
{
return TokenComponentAccess::intToType(m_sqliteStorage.getComponentAccessByMemberEdgeId(memberEdges[0].id).type);
}
return TokenComponentAccess::ACCESS_NONE;
}
void Storage::addComponentAccessToGraph(Graph* graph) const
{
std::vector<Id> memberEdgeIds;
@@ -1542,12 +1089,3 @@ void Storage::buildHierarchyCache()
m_hierarchyCache.createConnection(edge.id, edge.sourceNodeId, edge.targetNodeId, isVisible);
}
}
void Storage::log(std::string type, std::string str, const ParseLocation& location) const
{
LOG_INFO_STREAM_BARE(
<< type << ": " << str << " <" << location.filePath.str() << " "
<< location.startLineNumber << ":" << location.startColumnNumber << " "
<< location.endLineNumber << ":" << location.endColumnNumber << ">"
);
}
+7 -80
View File
@@ -14,9 +14,9 @@
#include "data/search/SearchIndex.h"
#include "data/SqliteStorage.h"
class Storage
: public ParserClient
, public StorageAccess
#include "data/parser/ParserClientImpl.h"
class Storage: public StorageAccess
{
public:
Storage(const FilePath& dbPath);
@@ -39,79 +39,10 @@ public:
void logStats() const;
// ParserClient implementation
virtual void startParsing();
virtual void finishParsing();
void startParsing();
void finishParsing();
virtual void startParsingFile(const FilePath& filePath);
virtual void finishParsingFile(const FilePath& filePath);
virtual void onError(const ParseLocation& location, const std::string& message, bool fatal);
virtual ErrorCountInfo getErrorCount() const;
virtual Id onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access);
virtual Id onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation);
virtual Id onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation);
virtual Id onGlobalVariableParsed(const ParseLocation& location, const NameHierarchy& variable);
virtual Id onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access);
virtual Id onFunctionParsed(
const ParseLocation& location, const NameHierarchy& function, const ParseLocation& scopeLocation);
virtual Id onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation);
virtual Id onNamespaceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, const ParseLocation& scopeLocation);
virtual Id onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation);
virtual Id onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy);
virtual Id onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& childNameHierarchy,
const NameHierarchy& parentNameHierarchy, AccessType access);
virtual Id onMethodOverrideParsed(
const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider);
virtual Id onCallParsed(
const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee);
virtual Id onFieldUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy);
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy);
virtual Id onEnumConstantUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy);
virtual Id onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used);
virtual Id onTemplateArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& argumentTypeNameHierarchy,
const NameHierarchy& templateNameHierarchy);
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& defaultArgumentTypeNameHierarchy,
const NameHierarchy& templateParameterNameHierarchy);
virtual Id onTemplateParameterTypeParsed(
const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy);
virtual Id onTemplateSpecializationParsed(
const ParseLocation& location, const NameHierarchy& specializedNameHierarchy,
const NameHierarchy& specializedFromNameHierarchy);
virtual Id onTemplateMemberFunctionSpecializationParsed(
const ParseLocation& location, const NameHierarchy& instantiatedFunction, const NameHierarchy& specializedFunction);
virtual Id onTemplateFunctionSpecializationParsed(
const ParseLocation& location, const NameHierarchy specializedFunction, const NameHierarchy templateFunction);
virtual Id onFileParsed(const FileInfo& fileInfo);
virtual Id onFileIncludeParsed(
const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo);
virtual Id onMacroDefineParsed(
const ParseLocation& location, const NameHierarchy& macroNameHierarchy, const ParseLocation& scopeLocation);
virtual Id onMacroExpandParsed(const ParseLocation& location, const NameHierarchy& macroNameHierarchy);
virtual Id onCommentParsed(const ParseLocation& location);
void injectData(std::shared_ptr<IntermediateStorage> injectedStorage);
// StorageAccess implementation
virtual Id getIdForNodeWithNameHierarchy(const NameHierarchy& nameHierarchy) const;
@@ -152,6 +83,7 @@ public:
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const;
virtual TimePoint getFileModificationTime(const FilePath& filePath) const;
virtual ErrorCountInfo getErrorCount() const;
virtual StorageStats getStorageStats() const;
private:
@@ -174,11 +106,6 @@ private:
void addNodesToGraph(const std::vector<Id> nodeIds, Graph* graph) const;
void addEdgesToGraph(const std::vector<Id> edgeIds, Graph* graph) const;
TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const;
void addAccess(Id nodeId, TokenComponentAccess::AccessType access);
void addAccess(Id nodeId, ParserClient::AccessType access);
TokenComponentAccess::AccessType getAccess(Id nodeId) const;
void addComponentAccessToGraph(Graph* graph) const;
void buildSearchIndex();
+3 -1
View File
@@ -105,14 +105,16 @@ struct StorageCommentLocation
struct StorageError
{
StorageError(const std::string& message, const std::string& filePath, uint lineNumber, uint columnNumber)
StorageError(const std::string& message, bool fatal, const std::string& filePath, uint lineNumber, uint columnNumber)
: message(message)
, fatal(fatal)
, filePath(filePath)
, lineNumber(lineNumber)
, columnNumber(columnNumber)
{}
std::string message;
bool fatal;
std::string filePath;
uint lineNumber;
uint columnNumber;
+580
View File
@@ -0,0 +1,580 @@
#include "data/parser/ParserClientImpl.h"
#include "data/parser/ParseLocation.h"
#include "data/graph/Node.h"
#include "data/graph/Edge.h"
#include "utility/logging/logging.h"
#include "utility/utility.h"
ParserClientImpl::ParserClientImpl()
{
}
ParserClientImpl::~ParserClientImpl()
{
}
void ParserClientImpl::setStorage(std::shared_ptr<IntermediateStorage> storage)
{
m_storage = storage;
}
void ParserClientImpl::resetStorage()
{
m_storage.reset();
}
void ParserClientImpl::startParsing()
{
}
void ParserClientImpl::finishParsing()
{
}
void ParserClientImpl::startParsingFile(const FilePath& filePath)
{
}
void ParserClientImpl::finishParsingFile(const FilePath& filePath)
{
}
void ParserClientImpl::onError(const ParseLocation& location, const std::string& message, bool fatal)
{
log(std::string(fatal ? "FATAL: " : "ERROR: "), message, location);
if (!location.isValid())
{
return;
}
addError(message, fatal, location);
}
Id ParserClientImpl::onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access)
{
log("typedef", typedefName.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_TYPEDEF, typedefName, true);
addSourceLocation(nodeId, location, false);
addAccess(nodeId, access);
return 0;
}
Id ParserClientImpl::onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation)
{
log("class", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_CLASS, nameHierarchy, scopeLocation.isValid());
addSourceLocation(nodeId, location, false);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return 0;
}
Id ParserClientImpl::onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation)
{
log("struct", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_STRUCT, nameHierarchy, scopeLocation.isValid());
addSourceLocation(nodeId, location, false);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return 0;
}
Id ParserClientImpl::onGlobalVariableParsed(const ParseLocation& location, const NameHierarchy& variable)
{
log("global", variable.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, variable, true);
addSourceLocation(nodeId, location, false);
return 0;
}
Id ParserClientImpl::onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access)
{
log("field", field.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_FIELD, field, true);
addSourceLocation(nodeId, location, false);
addAccess(nodeId, access);
return 0;
}
Id ParserClientImpl::onFunctionParsed(
const ParseLocation& location, const NameHierarchy& function, const ParseLocation& scopeLocation)
{
log("function", function.getQualifiedNameWithSignature(), location);
Id nodeId = addNodeHierarchy(Node::NODE_FUNCTION, function, true);
addSourceLocation(nodeId, location, false);
addSourceLocation(nodeId, scopeLocation, true);
return 0;
}
Id ParserClientImpl::onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation)
{
log("method", method.getQualifiedNameWithSignature(), location);
Id nodeId = addNodeHierarchy(Node::NODE_METHOD, method, location.isValid() && scopeLocation.isValid());
addSourceLocation(nodeId, location, false);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return 0;
}
Id ParserClientImpl::onNamespaceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, const ParseLocation& scopeLocation)
{
log("namespace", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_NAMESPACE, nameHierarchy, true);
addSourceLocation(nodeId, location, false);
addSourceLocation(nodeId, scopeLocation, true);
return 0;
}
Id ParserClientImpl::onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation)
{
log("enum", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_ENUM, nameHierarchy, true);
addSourceLocation(nodeId, location, false);
addSourceLocation(nodeId, scopeLocation, true);
addAccess(nodeId, access);
return 0;
}
Id ParserClientImpl::onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy)
{
log("enum constant", nameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, nameHierarchy, true);
addSourceLocation(nodeId, location, false);
return 0;
}
Id ParserClientImpl::onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& childNameHierarchy,
const NameHierarchy& parentNameHierarchy, AccessType access)
{
log("inheritance", childNameHierarchy.getQualifiedName() + " : " + parentNameHierarchy.getQualifiedName(), location);
Id childNodeId = addNodeHierarchy(Node::NODE_TYPE, childNameHierarchy, false);
Id parentNodeId = addNodeHierarchy(Node::NODE_TYPE, parentNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_INHERITANCE, childNodeId, parentNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onMethodOverrideParsed(
const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider)
{
log("override", overridden.getQualifiedNameWithSignature() + " -> " + overrider.getQualifiedNameWithSignature(), location);
Id overriddenNodeId = addNodeHierarchy(Node::NODE_FUNCTION, overridden, false);
Id overriderNodeId = addNodeHierarchy(Node::NODE_FUNCTION, overrider, false);
Id edgeId = addEdge(Edge::EDGE_OVERRIDE, overriderNodeId, overriddenNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onCallParsed(const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee)
{
log("call", caller.getQualifiedNameWithSignature() + " -> " + callee.getQualifiedNameWithSignature(), location);
Id callerNodeId = addNodeHierarchy(Node::NODE_FUNCTION, caller, false);
Id calleeNodeId = addNodeHierarchy(Node::NODE_FUNCTION, callee, false);
Id edgeId = addEdge(Edge::EDGE_CALL, callerNodeId, calleeNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onFieldUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy)
{
log("field usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedName(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, false);
Id usedNodeId = addNodeHierarchy(Node::NODE_FIELD, usedNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onGlobalVariableUsageParsed( // or static variable used
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy)
{
log("global usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedNameWithSignature(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, false);
Id usedNodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, usedNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onEnumConstantUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy)
{
log("enum constant usage", userNameHierarchy.getQualifiedNameWithSignature() + " -> " + usedNameHierarchy.getQualifiedNameWithSignature(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, userNameHierarchy, false);
Id usedNodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, usedNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used)
{
log("type usage", user.getQualifiedNameWithSignature() + " -> " + used.getQualifiedName(), location);
if (!location.isValid())
{
return 0;
}
Id functionNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, user, false);
Id typeNodeId = addNodeHierarchy(Node::NODE_TYPE, used, false);
Id edgeId = addEdge(Edge::EDGE_TYPE_USAGE, functionNodeId, typeNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onTemplateArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& argumentTypeNameHierarchy,
const NameHierarchy& templateNameHierarchy)
{
log(
"template argument type",
argumentTypeNameHierarchy.getQualifiedName() + " -> " + templateNameHierarchy.getQualifiedName(),
location
);
Id argumentNodeId = addNodeHierarchy(Node::NODE_TYPE, argumentTypeNameHierarchy, false);
Id templateNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, templateNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_TEMPLATE_ARGUMENT, templateNodeId, argumentNodeId);
addSourceLocation(edgeId, location, false);
return argumentNodeId;
}
Id ParserClientImpl::onTemplateDefaultArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& defaultArgumentTypeNameHierarchy,
const NameHierarchy& templateParameterNameHierarchy)
{
log(
"template default argument",
defaultArgumentTypeNameHierarchy.getQualifiedNameWithSignature() + " -> " + templateParameterNameHierarchy.getQualifiedName(),
location
);
Id defaultArgumentNodeId = addNodeHierarchy(Node::NODE_TYPE, defaultArgumentTypeNameHierarchy, false);
Id parameterNodeId = addNodeHierarchy(Node::NODE_TYPE, templateParameterNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT, parameterNodeId, defaultArgumentNodeId);
addSourceLocation(edgeId, location, false);
return defaultArgumentNodeId;
}
Id ParserClientImpl::onTemplateParameterTypeParsed( // TODO: move this up to where nodes are created
const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy)
{
log("template parameter type", templateParameterTypeNameHierarchy.getQualifiedName(), location);
Id nodeId = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy, true);
addSourceLocation(nodeId, location, false);
addAccess(nodeId, TokenComponentAccess::ACCESS_TEMPLATE);
return 0;
}
Id ParserClientImpl::onTemplateSpecializationParsed(
const ParseLocation& location, const NameHierarchy& specializedNameHierarchy,
const NameHierarchy& specializedFromNameHierarchy)
{
log(
"template record specialization",
specializedNameHierarchy.getQualifiedName() + " -> " + specializedFromNameHierarchy.getQualifiedName(),
location
);
Id specializedId = addNodeHierarchy(Node::NODE_TYPE, specializedNameHierarchy, false);
Id recordNodeId = addNodeHierarchy(Node::NODE_TYPE, specializedFromNameHierarchy, false);
Id edgeId = addEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, specializedId, recordNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onTemplateMemberFunctionSpecializationParsed(
const ParseLocation& location, const NameHierarchy& instantiatedFunction, const NameHierarchy& specializedFunction)
{
log(
"template member function specialization",
instantiatedFunction.getQualifiedNameWithSignature() + " -> " + specializedFunction.getQualifiedNameWithSignature(),
location
);
Id instantiatedFunctionNodeId = addNodeHierarchy(Node::NODE_FUNCTION, instantiatedFunction, false);
Id specializedFunctionNodeId = addNodeHierarchy(Node::NODE_FUNCTION, specializedFunction, false);
Id edgeId = addEdge(Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION_OF, instantiatedFunctionNodeId, specializedFunctionNodeId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onFileParsed(const FileInfo& fileInfo) // TODO: move up to nodes
{
log("file", fileInfo.path.str(), ParseLocation());
addFile(fileInfo.path.fileName(), fileInfo.path.str(), utility::timeToString(fileInfo.lastWriteTime));
return 0;
}
Id ParserClientImpl::onFileIncludeParsed(const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo)
{
log("include", includedFileInfo.path.str(), location);
Id fileNodeId = addFile(fileInfo.path.fileName(), fileInfo.path.str(), utility::timeToString(fileInfo.lastWriteTime));
Id includedFileNodeId = addFile(includedFileInfo.path.fileName(), includedFileInfo.path.str(), utility::timeToString(includedFileInfo.lastWriteTime));
Id edgeId = addEdge(Edge::EDGE_INCLUDE, fileNodeId, includedFileNodeId);
addSourceLocation(edgeId, location, false);
return fileNodeId;
}
Id ParserClientImpl::onMacroDefineParsed(
const ParseLocation& location, const NameHierarchy& macroNameHierarchy, const ParseLocation& scopeLocation)
{
log("macro", macroNameHierarchy.getQualifiedName(), location);
Id macroId = addNodeHierarchy(Node::NODE_MACRO, macroNameHierarchy, true);
addSourceLocation(macroId, location, false);
addSourceLocation(macroId, scopeLocation, true);
//Id fileNodeId = getFileNodeId(location.filePath); // do we need this???
//addEdge(Edge::EDGE_MACRO_USAGE, fileNodeId, macroId, , location);
return macroId;
}
Id ParserClientImpl::onMacroExpandParsed(const ParseLocation &location, const NameHierarchy& macroNameHierarchy)
{
log("macro use", macroNameHierarchy.getQualifiedName(), location);
Id macroExpandId = addNodeHierarchy(Node::NODE_MACRO, macroNameHierarchy, false);
Id fileNodeId = addFile(location.filePath.str());
Id edgeId = addEdge(Edge::EDGE_MACRO_USAGE, fileNodeId, macroExpandId);
addSourceLocation(edgeId, location, false);
return edgeId;
}
Id ParserClientImpl::onCommentParsed(const ParseLocation& location) // TODO: move up to nodes
{
log("comment", "no name", location);
Id fileNodeId = addFile(location.filePath.str());
addCommentLocation(location);
return 0;
}
TokenComponentAccess::AccessType ParserClientImpl::convertAccessType(ParserClient::AccessType access) const
{
switch (access)
{
case ACCESS_PUBLIC:
return TokenComponentAccess::ACCESS_PUBLIC;
case ACCESS_PROTECTED:
return TokenComponentAccess::ACCESS_PROTECTED;
case ACCESS_PRIVATE:
return TokenComponentAccess::ACCESS_PRIVATE;
case ACCESS_NONE:
return TokenComponentAccess::ACCESS_NONE;
}
}
void ParserClientImpl::addAccess(Id nodeId, ParserClient::AccessType access)
{
addAccess(nodeId, convertAccessType(access));
}
void ParserClientImpl::addAccess(Id nodeId, TokenComponentAccess::AccessType access)
{
if (access == TokenComponentAccess::ACCESS_NONE)
{
return;
}
addComponentAccess(nodeId, access);
}
Id ParserClientImpl::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool defined)
{
if (nameHierarchy.size() == 0)
{
return 0;
}
Id parentNodeId = 0;
bool nodeMayExist = true;
NameHierarchy currentNameHierarchy;
for (size_t i = 0; i < nameHierarchy.size(); i++)
{
currentNameHierarchy.push(nameHierarchy[i]);
const bool isLastElement = (i == nameHierarchy.size() - 1);
Node::NodeType type = (isLastElement ? nodeType : Node::NODE_UNDEFINED);
Id nodeId = addNode(type, currentNameHierarchy, isLastElement && defined);
// Todo: performance optimization: check if node exists. dont add edge if it existed before...
if (parentNodeId != 0)
{
addEdge(Edge::EDGE_MEMBER, parentNodeId, nodeId);
}
parentNodeId = nodeId;
}
return parentNodeId;
}
Id ParserClientImpl::addFile(const std::string& name, const std::string& filePath, const std::string& modificationTime)
{
if (!m_storage)
{
return 0;
}
return m_storage->addFile(name, filePath, modificationTime);
}
Id ParserClientImpl::addFile(const std::string& filePath)
{
if (!m_storage)
{
return 0;
}
return m_storage->addFile(filePath);
}
Id ParserClientImpl::addNode(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool defined)
{
if (!m_storage)
{
return 0;
}
return m_storage->addNode(Node::typeToInt(nodeType), nameHierarchy, defined);
}
Id ParserClientImpl::addEdge(int type, Id sourceId, Id targetId)
{
if (!m_storage)
{
return 0;
}
if (!sourceId || !targetId)
{
return 0;
}
return m_storage->addEdge(type, sourceId, targetId);
}
void ParserClientImpl::addSourceLocation(Id elementId, const ParseLocation& location, bool isScope)
{
if (!m_storage)
{
return;
}
if (!location.isValid())
{
return;
}
if (location.filePath.empty())
{
LOG_ERROR("no filename set!");
return;
}
m_storage->addSourceLocation(elementId, location, isScope);
}
void ParserClientImpl::addComponentAccess(Id nodeId , int type)
{
if (!m_storage)
{
return;
}
m_storage->addComponentAccess(nodeId, type);
}
void ParserClientImpl::addCommentLocation(const ParseLocation& location)
{
if (!m_storage)
{
return;
}
m_storage->addCommentLocation(location);
}
void ParserClientImpl::addError(const std::string& message, bool fatal, const ParseLocation& location)
{
if (!m_storage)
{
return;
}
m_storage->addError(message, fatal, location);
}
void ParserClientImpl::log(std::string type, std::string str, const ParseLocation& location) const
{
LOG_INFO_STREAM_BARE(
<< type << ": " << str << " <" << location.filePath.str() << " "
<< location.startLineNumber << ":" << location.startColumnNumber << " "
<< location.endLineNumber << ":" << location.endColumnNumber << ">"
);
}
+111
View File
@@ -0,0 +1,111 @@
#ifndef PARSER_CLIENT_IMPL_H
#define PARSER_CLIENT_IMPL_H
#include "data/parser/ParserClient.h"
#include "data/IntermediateStorage.h"
#include "data/graph/token_component/TokenComponentAccess.h"
#include "data/graph/Node.h"
#include "data/SqliteStorage.h"
class ParserClientImpl: public ParserClient
{
public:
ParserClientImpl();
virtual ~ParserClientImpl();
void setStorage(std::shared_ptr<IntermediateStorage> storage);
void resetStorage();
virtual void startParsing();
virtual void finishParsing();
virtual void startParsingFile(const FilePath& filePath);
virtual void finishParsingFile(const FilePath& filePath);
virtual void onError(const ParseLocation& location, const std::string& message, bool fatal);
virtual Id onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access);
virtual Id onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation);
virtual Id onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation);
virtual Id onGlobalVariableParsed(const ParseLocation& location, const NameHierarchy& variable);
virtual Id onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access);
virtual Id onFunctionParsed(
const ParseLocation& location, const NameHierarchy& function, const ParseLocation& scopeLocation);
virtual Id onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation);
virtual Id onNamespaceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const ParseLocation& scopeLocation);
virtual Id onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& scopeLocation);
virtual Id onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy);
virtual Id onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const NameHierarchy& baseNameHierarchy, AccessType access);
virtual Id onMethodOverrideParsed(
const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider);
virtual Id onCallParsed(
const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee);
virtual Id onFieldUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy);
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy);
virtual Id onEnumConstantUsageParsed(
const ParseLocation& location, const NameHierarchy& userNameHierarchy, const NameHierarchy& usedNameHierarchy);
virtual Id onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used);
virtual Id onTemplateArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& argumentTypeNameHierarchy,
const NameHierarchy& templateNameHierarchy);
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseLocation& location, const NameHierarchy& defaultArgumentTypeNameHierarchy,
const NameHierarchy& templateArgumentTypeNameHierarchy);
virtual Id onTemplateParameterTypeParsed(
const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy);
virtual Id onTemplateSpecializationParsed(
const ParseLocation& location, const NameHierarchy& specializedNameHierarchy,
const NameHierarchy& specializedFromNameHierarchy);
virtual Id onTemplateMemberFunctionSpecializationParsed(
const ParseLocation& location, const NameHierarchy& instantiatedFunction, const NameHierarchy& specializedFunction);
virtual Id onFileParsed(const FileInfo& fileInfo);
virtual Id onFileIncludeParsed(
const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo);
virtual Id onMacroDefineParsed(
const ParseLocation& location, const NameHierarchy& macroNameHierarchy, const ParseLocation& scopeLocation);
virtual Id onMacroExpandParsed(
const ParseLocation& location, const NameHierarchy& macroNameHierarchy);
virtual Id onCommentParsed(const ParseLocation& location);
private:
TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const;
void addAccess(Id nodeId, ParserClient::AccessType access);
void addAccess(Id nodeId, TokenComponentAccess::AccessType access);
Id ParserClientImpl::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool defined);
Id addFile(const std::string& name, const std::string& filePath, const std::string& modificationTime);
Id addFile(const std::string& filePath);
Id addNode(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool defined);
Id addEdge(int type, Id sourceId, Id targetId);
void addSourceLocation(Id elementId, const ParseLocation& location, bool isScope);
void addComponentAccess(Id nodeId , int type);
void addCommentLocation(const ParseLocation& location);
void addError(const std::string& message, bool fatal, const ParseLocation& location);
void log(std::string type, std::string str, const ParseLocation& location) const;
std::shared_ptr<IntermediateStorage> m_storage;
};
#endif // PARSER_CLIENT_IMPL_H
+5 -3
View File
@@ -5,10 +5,11 @@
#include <deque>
#include "data/parser/Parser.h"
#include "data/parser/ParserClientImpl.h"
#include "utility/scheduling/Task.h"
#include "utility/TimePoint.h"
class ParserClient;
class Storage;
class FileManager;
class CxxParser;
@@ -25,7 +26,7 @@ class TaskParseCxx
{
public:
TaskParseCxx(
ParserClient* client,
Storage* storage,
const FileManager* fileManager,
const Parser::Arguments& arguments,
const std::vector<FilePath>& files
@@ -41,8 +42,9 @@ public:
virtual void revert();
private:
ParserClient* m_client;
Storage* m_storage;
std::shared_ptr<CxxParser> m_parser;
std::shared_ptr<ParserClientImpl> m_parserClient;
const Parser::Arguments m_arguments;
const std::vector<FilePath> m_files;
+1 -1
View File
@@ -1 +1 @@
#define DEPLOY
// #define DEPLOY
+27 -357
View File
@@ -19,118 +19,54 @@ public:
m_filePath = "file.cpp";
}
void test_storage_saves_typedef()
void test_storage_saves_file()
{
TestStorage storage;
Id id = storage.onTypedefParsed(validLocation(1), createNameHierarchy("type"), ParserClient::ACCESS_NONE);
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "type");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_TYPEDEF);
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
Id id = intermetiateStorage->addFile("test.h", "path/to/test.h", "someTime");
storage.injectData(intermetiateStorage);
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "test.h");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_FILE);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_class()
void test_storage_saves_node()
{
NameHierarchy a = createNameHierarchy("type");
TestStorage storage;
Id id = storage.onClassParsed(validLocation(1), createNameHierarchy("Class"), ParserClient::ACCESS_NONE, validLocation(2));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "Class");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_CLASS);
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
Id id = intermetiateStorage->addNode(Node::typeToInt(Node::NODE_TYPEDEF), a, true);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
TS_ASSERT_EQUALS(tlc->getTokenLocations().find(2)->second->getType(), TokenLocation::LOCATION_SCOPE);
storage.injectData(intermetiateStorage);
Id storedId = storage.getIdForNodeWithNameHierarchy(a);
TS_ASSERT(storedId != 0);
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(storedId), Node::NODE_TYPEDEF);
}
void test_storage_saves_struct()
{
TestStorage storage;
Id id = storage.onStructParsed(validLocation(1), createNameHierarchy("Struct"), ParserClient::ACCESS_NONE, validLocation(2));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "Struct");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_STRUCT);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
TS_ASSERT_EQUALS(tlc->getTokenLocations().find(2)->second->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_global_variable()
{
TestStorage storage;
Id id = storage.onGlobalVariableParsed(validLocation(42), createNameHierarchy("Global"));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "Global");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_GLOBAL_VARIABLE);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_field()
{
TestStorage storage;
Id id = storage.onFieldParsed(
validLocation(3), createNameHierarchy("m_field"), ParserClient::ACCESS_NONE);
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "m_field");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_FIELD);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_field_as_member()
{
NameHierarchy a = createNameHierarchy("Struct::m_field");
NameHierarchy b = createNameHierarchy("Struct");
NameHierarchy a = createNameHierarchy("Struct");
NameHierarchy b = createNameHierarchy("Struct::m_field");
TestStorage storage;
Id id = storage.onFieldParsed(
validLocation(11), a, ParserClient::ACCESS_PUBLIC
);
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "Struct::m_field");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_FIELD);
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
Id aId = intermetiateStorage->addNode(Node::typeToInt(Node::NODE_STRUCT), a, true);
Id bId = intermetiateStorage->addNode(Node::typeToInt(Node::NODE_FIELD), b, true);
intermetiateStorage->addEdge(Edge::typeToInt(Edge::EDGE_MEMBER), aId, bId);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_MEMBER, b, a) != 0);
storage.injectData(intermetiateStorage);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
TS_ASSERT(storage.getIdForEdge(Edge::EDGE_MEMBER, a, b) != 0);
}
void test_storage_saves_function()
{
TestStorage storage;
Id id = storage.onFunctionParsed(
validLocation(14), createFunctionNameHierarchy("bool", "isTrue", "(char)"), validLocation(41)
);
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "bool isTrue(char)");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_FUNCTION);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
}
void test_storage_saves_method()
{
TestStorage storage;
Id id = storage.onMethodParsed(
validLocation(9),
createFunctionNameHierarchy("void", "isMethod", "(bool)"),
ParserClient::ACCESS_NONE,
ParserClient::ABSTRACTION_NONE,
validLocation(4)
);
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "void isMethod(bool)");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_METHOD);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
}
void test_storage_saves_method_static()
{
@@ -150,247 +86,6 @@ public:
//TS_ASSERT(node->getComponent<TokenComponentStatic>());
}
void test_storage_saves_method_as_member()
{
NameHierarchy a = createFunctionNameHierarchy("void", "Class::isMethod", "(bool)");
TestStorage storage;
storage.onMethodParsed(
validLocation(1),
a,
ParserClient::ACCESS_PROTECTED,
ParserClient::ABSTRACTION_VIRTUAL,
validLocation(4)
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_MEMBER, createNameHierarchy("Class"), a) != 0);
}
void test_storage_saves_namespace()
{
TestStorage storage;
Id id = storage.onNamespaceParsed(validLocation(1), createNameHierarchy("utility"), validLocation(2));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "utility");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_NAMESPACE);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
TS_ASSERT_EQUALS(tlc->getTokenLocations().find(2)->second->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_enum()
{
TestStorage storage;
Id id = storage.onEnumParsed(validLocation(17), createNameHierarchy("Category"), ParserClient::ACCESS_NONE, validLocation(23));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "Category");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_ENUM);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
TS_ASSERT_EQUALS(tlc->getTokenLocations().find(2)->second->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_enum_as_member()
{
NameHierarchy a = createNameHierarchy("Class::Category");
TestStorage storage;
storage.onEnumParsed(
validLocation(1), a,
ParserClient::ACCESS_PRIVATE, validLocation(2)
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_MEMBER, createNameHierarchy("Class"), a) != 0);
}
void test_storage_saves_enum_constant()
{
TestStorage storage;
Id id = storage.onEnumConstantParsed(validLocation(1), createNameHierarchy("VALUE"));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "VALUE");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_ENUM_CONSTANT);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_class_inheritance()
{
TestStorage storage;
storage.onClassParsed(validLocation(), createNameHierarchy("ClassA"), ParserClient::ACCESS_NONE, validLocation());
storage.onClassParsed(validLocation(), createNameHierarchy("ClassB"), ParserClient::ACCESS_NONE, validLocation());
Id id =
storage.onInheritanceParsed(validLocation(5), createNameHierarchy("ClassB"),
createNameHierarchy("ClassA"), ParserClient::ACCESS_PUBLIC
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_INHERITANCE, createNameHierarchy("ClassB"), createNameHierarchy("ClassA")) != 0);
//TS_ASSERT(edge->getComponent<TokenComponentAccess>());
//TS_ASSERT_EQUALS(edge->getComponent<TokenComponentAccess>()->getAccess(), TokenComponentAccess::ACCESS_PUBLIC);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_struct_inheritance()
{
TestStorage storage;
storage.onStructParsed(validLocation(), createNameHierarchy("StructA"), ParserClient::ACCESS_NONE, validLocation());
storage.onStructParsed(validLocation(), createNameHierarchy("StructB"), ParserClient::ACCESS_NONE, validLocation());
Id id =
storage.onInheritanceParsed(validLocation(5), createNameHierarchy("StructB"),
createNameHierarchy("StructA"), ParserClient::ACCESS_PUBLIC
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_INHERITANCE, createNameHierarchy("StructB"), createNameHierarchy("StructA")) != 0);
//TS_ASSERT(edge->getComponent<TokenComponentAccess>());
//TS_ASSERT_EQUALS(edge->getComponent<TokenComponentAccess>()->getAccess(), TokenComponentAccess::ACCESS_PUBLIC);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_method_override()
{
TestStorage storage;
NameHierarchy a = createFunctionNameHierarchy("void", "A::isMethod", "(bool)");
NameHierarchy b = createFunctionNameHierarchy("void", "B::isMethod", "(bool)");
storage.onMethodParsed(
validLocation(9),
a,
ParserClient::ACCESS_PRIVATE,
ParserClient::ABSTRACTION_VIRTUAL,
validLocation(4));
storage.onMethodParsed(
validLocation(7),
b,
ParserClient::ACCESS_PRIVATE,
ParserClient::ABSTRACTION_NONE,
validLocation(3));
storage.onMethodOverrideParsed(validLocation(4), a, b);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_OVERRIDE, b, a) != 0);
}
void test_storage_saves_call()
{
TestStorage storage;
NameHierarchy a = createFunctionNameHierarchy("bool", "isTrue", "(char)");
NameHierarchy b = createFunctionNameHierarchy("void", "func", "(bool)");
storage.onFunctionParsed(
validLocation(), a, validLocation()
);
storage.onFunctionParsed(
validLocation(), b, validLocation()
);
Id id = storage.onCallParsed(
validLocation(9),
a,
b
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_CALL, a, b) != 0);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_call_in_global_variable_declaration()
{
TestStorage storage;
storage.onGlobalVariableParsed(validLocation(), createNameHierarchy("global"));
NameHierarchy a = createFunctionNameHierarchy("bool", "isTrue", "(char)");
storage.onFunctionParsed(
validLocation(), a, validLocation()
);
Id id = storage.onCallParsed(
validLocation(7),
createNameHierarchy("global"),
a
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_CALL, createNameHierarchy("global"), a) != 0);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_field_usage()
{
NameHierarchy a = createFunctionNameHierarchy("bool", "isTrue", "(char)");
TestStorage storage;
storage.onFunctionParsed(
validLocation(), a, validLocation()
);
storage.onFieldParsed(
validLocation(), createNameHierarchy("Foo::m_field"), ParserClient::ACCESS_PRIVATE
);
Id id = storage.onFieldUsageParsed(
validLocation(7),
a,
createNameHierarchy("Foo::m_field")
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_USAGE, a, createNameHierarchy("Foo::m_field")) != 0);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_global_variable_usage()
{
NameHierarchy a = createFunctionNameHierarchy("bool", "isTrue", "(char)");
TestStorage storage;
storage.onFunctionParsed(
validLocation(), a, validLocation()
);
storage.onGlobalVariableParsed(validLocation(), createNameHierarchy("global"));
Id id = storage.onGlobalVariableUsageParsed(
validLocation(7),
a,
createNameHierarchy("global")
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_USAGE, a, createNameHierarchy("global")) != 0);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_saves_type_usage()
{
NameHierarchy a = createFunctionNameHierarchy("Struct", "isTrue", "(char)");
TestStorage storage;
storage.onFunctionParsed(
validLocation(), a, validLocation()
);
storage.onStructParsed(
validLocation(), createNameHierarchy("Struct"), ParserClient::ACCESS_NONE, validLocation());
Id id = storage.onTypeUsageParsed(
validLocation(7), a, createNameHierarchy("Struct")
);
TS_ASSERT(storage.getEdgeId(Edge::EDGE_TYPE_USAGE, a, createNameHierarchy("Struct")) != 0);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_clears_single_file_data_of_single_file_storage()
{
/*TestStorage storage;
@@ -508,30 +203,6 @@ public:
//TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 0);
}
void test_storage_saves_file_nodes()
{
TestStorage storage;
Id id = storage.onFileParsed(FileInfo("file.h"));
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeWithId(id).getQualifiedNameWithSignature(), "file.h");
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_FILE);
}
void test_storage_saves_include_edge()
{
TestStorage storage;
storage.onFileParsed(FileInfo("file.h"));
storage.onFileParsed(FileInfo("file.cpp"));
Id id = storage.onFileIncludeParsed(validLocation(7), FileInfo("file.cpp"), FileInfo("file.h"));
TS_ASSERT(storage.getEdgeId(Edge::EDGE_INCLUDE, createNameHierarchy("file.cpp"), createNameHierarchy("file.h")) != 0);
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 1);
}
void test_storage_finds_and_removes_depending_file_nodes()
{
//TestStorage storage;
@@ -568,7 +239,6 @@ private:
: Storage("data/test.sqlite")
{
clear();
onFileParsed(FileInfo("file.cpp"));
}
std::shared_ptr<TokenLocationCollection> getLocationCollectionForTokenId(Id id) const
-13
View File
@@ -1,19 +1,6 @@
#include "TestStorage.h"
#include "utility/text/TextAccess.h"
#include "data/parser/cxx/CxxParser.h"
#include "TestFileManager.h"
TestStorage::TestStorage()
: Storage("data/test.sqlite")
{
}
void TestStorage::parseCxxCode(std::string code)
{
clear();
TestFileManager fm;
CxxParser parser(this, &fm);
parser.parseFile("input.cc", TextAccess::createFromString(code), Parser::Arguments());
}
+5 -5
View File
@@ -1,15 +1,15 @@
#include "data/parser/cxx/TaskParseCxx.h"
#include "data/parser/ParserClient.h"
#include "data/Storage.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
TaskParseCxx::TaskParseCxx(
ParserClient* client,
Storage* storage,
const FileManager* fileManager,
const Parser::Arguments& arguments,
const std::vector<FilePath>& files
)
: m_client(client)
: m_storage(storage)
, m_arguments(arguments)
{
}
@@ -21,7 +21,7 @@ std::vector<FilePath> TaskParseCxx::getSourceFilesFromCDB(const FilePath& compil
void TaskParseCxx::enter()
{
m_client->startParsing();
m_storage->startParsing();
}
Task::TaskState TaskParseCxx::update()
@@ -31,7 +31,7 @@ Task::TaskState TaskParseCxx::update()
void TaskParseCxx::exit()
{
m_client->finishParsing();
m_storage->finishParsing();
MessageFinishedParsing(0, 0, 0).dispatch();
}