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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 << ">"
|
||||
);
|
||||
}
|
||||
@@ -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,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 @@
|
||||
#define DEPLOY
|
||||
// #define DEPLOY
|
||||
|
||||
+27
-357
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user