data: Refactored ParserClient API to return and use Ids instead of NameHierarchies for faster indexing

* Pass NameHierarchy to record new symbol returning an Id
* Cache symbol Ids in Parser implementation
* Reuse symbol Ids as reference when recording related data
* Pass FilePath to record new file returning an Id
* Cache file Ids in CanonicalFilePathCache
* Store file Id in ParseLocation instead of FilePath

fortune cookie message = You know a silent way to impose your will.
This commit is contained in:
Eberhard Graether
2018-10-16 00:54:38 +02:00
parent aab29b241e
commit 4ae052cb9c
169 changed files with 43427 additions and 43502 deletions
-1
View File
@@ -202,7 +202,6 @@ add_files(
data/parser/ParseLocation.h
data/parser/Parser.cpp
data/parser/Parser.h
data/parser/ParserClient.cpp
data/parser/ParserClient.h
data/parser/ParserClientImpl.cpp
data/parser/ParserClientImpl.h
+1 -1
View File
@@ -65,7 +65,7 @@ std::shared_ptr<IntermediateStorage> Indexer<T>::index(std::shared_ptr<IndexerCo
doIndex(castCommand, parserClient, m_indexerStateInfo);
if (parserClient->hasFatalErrors())
if (storage->hasFatalErrors())
{
storage->setAllFilesIncomplete();
}
+6 -6
View File
@@ -1,7 +1,7 @@
#include "ParseLocation.h"
ParseLocation::ParseLocation()
: filePath(L"")
: fileId(0)
, startLineNumber(0)
, startColumnNumber(0)
, endLineNumber(0)
@@ -10,11 +10,11 @@ ParseLocation::ParseLocation()
}
ParseLocation::ParseLocation(
FilePath filePath,
Id fileId,
uint lineNumber,
uint columnNumber
)
: filePath(std::move(filePath.makeCanonical()))
: fileId(fileId)
, startLineNumber(lineNumber)
, startColumnNumber(columnNumber)
, endLineNumber(lineNumber)
@@ -23,11 +23,11 @@ ParseLocation::ParseLocation(
}
ParseLocation::ParseLocation(
FilePath filePath,
Id fileId,
uint startLineNumber, uint startColumnNumber,
uint endLineNumber, uint endColumnNumber
)
: filePath(std::move(filePath.makeCanonical()))
: fileId(fileId)
, startLineNumber(startLineNumber)
, startColumnNumber(startColumnNumber)
, endLineNumber(endLineNumber)
@@ -37,5 +37,5 @@ ParseLocation::ParseLocation(
bool ParseLocation::isValid() const
{
return !filePath.empty();
return fileId;
}
+12 -3
View File
@@ -6,23 +6,32 @@
#include "FilePath.h"
#include "types.h"
enum class ParseLocationType
{
TOKEN,
SCOPE,
SIGNATURE,
QUALIFIER,
LOCAL
};
struct ParseLocation
{
ParseLocation();
ParseLocation(
FilePath filePath,
Id fileId,
uint lineNumber,
uint columnNumber
);
ParseLocation(
FilePath filePath,
Id fileId,
uint startLineNumber, uint startColumnNumber,
uint endLineNumber, uint endColumnNumber
);
bool isValid() const;
FilePath filePath;
Id fileId;
uint startLineNumber;
uint startColumnNumber;
uint endLineNumber;
-119
View File
@@ -1,119 +0,0 @@
#include "ParserClient.h"
#include <sstream>
#include "ParseLocation.h"
std::wstring ParserClient::addAccessPrefix(const std::wstring& str, AccessKind access)
{
switch (access)
{
case ACCESS_PUBLIC:
return L"public " + str;
case ACCESS_PROTECTED:
return L"protected " + str;
case ACCESS_PRIVATE:
return L"private " + str;
case ACCESS_DEFAULT:
return L"default " + str;
default:
break;
}
return str;
}
std::wstring ParserClient::addStaticPrefix(const std::wstring& str, bool isStatic)
{
if (isStatic)
{
return L"static " + str;
}
return str;
}
std::wstring ParserClient::addConstPrefix(const std::wstring& str, bool isConst, bool atFront)
{
if (isConst)
{
return atFront ? L"const " + str : str + L" const";
}
return str;
}
std::wstring ParserClient::addLocationSuffix(const std::wstring& str, const ParseLocation& location)
{
std::wstringstream ss;
ss << str;
ss << L" <" << location.startLineNumber << L":" << location.startColumnNumber << L" ";
ss << location.endLineNumber << L":" << location.endColumnNumber << L">";
return ss.str();
}
std::wstring ParserClient::addLocationSuffix(
const std::wstring& str, const ParseLocation& location, const ParseLocation& scopeLocation
) {
if (!location.isValid())
{
return addLocationSuffix(str, scopeLocation);
}
else if (!scopeLocation.isValid())
{
return addLocationSuffix(str, location);
}
std::wstringstream ss;
ss << str;
ss << L" <" << scopeLocation.startLineNumber << L":" << scopeLocation.startColumnNumber;
ss << L" <" << location.startLineNumber << L":" << location.startColumnNumber << L" ";
ss << location.endLineNumber << L":" << location.endColumnNumber << L"> ";
ss << scopeLocation.endLineNumber << L":" << scopeLocation.endColumnNumber << L">";
return ss.str();
}
std::wstring ParserClient::addLocationSuffix(
const std::wstring& str, const ParseLocation& location, const ParseLocation& scopeLocation, const ParseLocation& signatureLocation
) {
if (!location.isValid())
{
return addLocationSuffix(str, scopeLocation, signatureLocation);
}
if (!scopeLocation.isValid())
{
return addLocationSuffix(str, location, signatureLocation);
}
if (!signatureLocation.isValid())
{
return addLocationSuffix(str, location, scopeLocation);
}
std::wstringstream ss;
ss << str;
ss << L" <" << scopeLocation.startLineNumber << L":" << scopeLocation.startColumnNumber;
ss << L" <" << signatureLocation.startLineNumber << L":" << signatureLocation.startColumnNumber << L" ";
ss << L" <" << location.startLineNumber << L":" << location.startColumnNumber << L" ";
ss << location.endLineNumber << L":" << location.endColumnNumber << L"> ";
ss << signatureLocation.endLineNumber << L":" << signatureLocation.endColumnNumber << L"> ";
ss << scopeLocation.endLineNumber << L":" << scopeLocation.endColumnNumber << L">";
return ss.str();
}
ParserClient::ParserClient()
: m_hasFatalErrors(false)
{
}
void ParserClient::recordError(
const ParseLocation& errorLocation, const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit)
{
doRecordError(errorLocation, message, fatal, indexed, translationUnit);
if (fatal)
{
m_hasFatalErrors = true;
}
}
bool ParserClient::hasFatalErrors() const
{
return m_hasFatalErrors;
}
+12 -54
View File
@@ -2,78 +2,36 @@
#define PARSER_CLIENT_H
#include <string>
#include <vector>
#include "NameHierarchy.h"
#include "AccessKind.h"
#include "DefinitionKind.h"
#include "NameHierarchy.h"
#include "ParseLocation.h"
#include "ReferenceKind.h"
#include "SymbolKind.h"
#include "DefinitionKind.h"
#include "FileInfo.h"
#include "types.h"
struct ParseLocation;
class DataType;
class ParserClient
{
public:
static std::wstring addAccessPrefix(const std::wstring& str, AccessKind access);
static std::wstring addStaticPrefix(const std::wstring& str, bool isStatic);
static std::wstring addConstPrefix(const std::wstring& str, bool isConst, bool atFront);
static std::wstring addLocationSuffix(const std::wstring& str, const ParseLocation& location);
static std::wstring addLocationSuffix(
const std::wstring& str, const ParseLocation& location, const ParseLocation& scopeLocation);
static std::wstring addLocationSuffix(
const std::wstring& str,
const ParseLocation& location,
const ParseLocation& scopeLocation,
const ParseLocation& signatureLocation
);
ParserClient();
virtual ~ParserClient() = default;
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolKind,
AccessKind access, DefinitionKind definitionKind) = 0;
virtual Id recordFile(const FilePath& filePath, bool indexed) = 0;
virtual Id recordSymbolWithLocation(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location,
AccessKind access, DefinitionKind definitionKind) = 0;
virtual Id recordSymbol(const NameHierarchy& symbolName) = 0;
virtual void recordSymbolKind(Id symbolId, SymbolKind symbolKind) = 0;
virtual void recordAccessKind(Id symbolId, AccessKind accessKind) = 0;
virtual void recordDefinitionKind(Id symbolId, DefinitionKind definitionKind) = 0;
virtual Id recordSymbolWithLocationAndScope(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access, DefinitionKind definitionKind) = 0;
virtual Id recordSymbolWithLocationAndScopeAndSignature(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation, const ParseLocation& signatureLocation,
AccessKind access, DefinitionKind definitionKind) = 0;
virtual void recordReference(
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
virtual Id recordReference(ReferenceKind referenceKind, Id referencedSymbolId, Id contextSymbolId,
const ParseLocation& location) = 0;
virtual void recordQualifierLocation(
const NameHierarchy& qualifierName, const ParseLocation& location) = 0;
void recordError(
const ParseLocation& errorLocation, const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit);
virtual void recordLocalSymbol(const std::wstring& name, const ParseLocation& location) = 0;
virtual void recordFile(const FilePath& filePath, bool indexed) = 0;
virtual void recordLocation(Id elementId, const ParseLocation& location, ParseLocationType type) = 0;
virtual void recordComment(const ParseLocation& location) = 0;
bool hasFatalErrors() const;
protected:
virtual void doRecordError(
const ParseLocation& errorLocation, const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit) = 0;
bool m_hasFatalErrors;
virtual void recordError(const FilePath& filePath, uint lineNumber, uint columnNumber, const std::wstring& message,
bool fatal, bool indexed, const FilePath& translationUnit) = 0;
};
#endif // PARSER_CLIENT_H
+59 -73
View File
@@ -3,76 +3,50 @@
#include "Edge.h"
#include "Node.h"
#include "ParseLocation.h"
#include "logging.h"
ParserClientImpl::ParserClientImpl(IntermediateStorage* const storage)
: m_storage(storage)
{
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolKind,
AccessKind access, DefinitionKind definitionKind
)
Id ParserClientImpl::recordFile(const FilePath& filePath, bool indexed)
{
Id fileId = addFileName(filePath);
m_storage->addFile(StorageFile(fileId, filePath.wstr(), indexed, true));
return fileId;
}
Id ParserClientImpl::recordSymbol(const NameHierarchy& symbolName)
{
return addNodeHierarchy(symbolName);
}
void ParserClientImpl::recordSymbolKind(Id symbolId, SymbolKind symbolKind)
{
m_storage->setNodeType(symbolId, NodeType::typeToInt(symbolKindToNodeType(symbolKind).getType()));
}
void ParserClientImpl::recordAccessKind(Id symbolId, AccessKind accessKind)
{
if (accessKind != ACCESS_NONE)
{
m_storage->addComponentAccess(StorageComponentAccess(symbolId, accessKindToInt(accessKind)));
}
}
void ParserClientImpl::recordDefinitionKind(Id symbolId, DefinitionKind definitionKind)
{
Id nodeId = addNodeHierarchy(symbolName, symbolKindToNodeType(symbolKind));
if (definitionKind != DEFINITION_NONE)
{
m_storage->addSymbol(StorageSymbol(nodeId, definitionKindToInt(definitionKind)));
m_storage->addSymbol(StorageSymbol(symbolId, definitionKindToInt(definitionKind)));
}
if (access != ACCESS_NONE)
{
m_storage->addComponentAccess(StorageComponentAccess(nodeId, accessKindToInt(access)));
}
return nodeId;
}
Id ParserClientImpl::recordSymbolWithLocation(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location,
AccessKind access, DefinitionKind definitionKind
)
Id ParserClientImpl::recordReference(ReferenceKind referenceKind, Id referencedSymbolId, Id contextSymbolId, const ParseLocation& location)
{
Id nodeId = recordSymbol(symbolName, symbolKind, access, definitionKind);
addSourceLocation(nodeId, location, LOCATION_TOKEN);
return nodeId;
}
Id ParserClientImpl::recordSymbolWithLocationAndScope(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access, DefinitionKind definitionKind
)
{
Id nodeId = recordSymbolWithLocation(symbolName, symbolKind, location, access, definitionKind);
addSourceLocation(nodeId, scopeLocation, LOCATION_SCOPE);
return nodeId;
}
Id ParserClientImpl::recordSymbolWithLocationAndScopeAndSignature(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation, const ParseLocation& signatureLocation,
AccessKind access, DefinitionKind definitionKind)
{
Id nodeId = recordSymbolWithLocationAndScope(symbolName, symbolKind, location, scopeLocation, access, definitionKind);
addSourceLocation(nodeId, signatureLocation, LOCATION_SIGNATURE);
return nodeId;
}
void ParserClientImpl::recordReference(
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
const ParseLocation& location)
{
Id contextNodeId = addNodeHierarchy(contextName);
Id referencedNodeId = addNodeHierarchy(referencedName);
Id edgeId = addEdge(referenceKindToEdgeType(referenceKind), contextNodeId, referencedNodeId);
Id edgeId = addEdge(referenceKindToEdgeType(referenceKind), contextSymbolId, referencedSymbolId);
addSourceLocation(edgeId, location, LOCATION_TOKEN);
}
void ParserClientImpl::recordQualifierLocation(const NameHierarchy& qualifierName, const ParseLocation& location)
{
Id nodeId = addNodeHierarchy(qualifierName, NodeType::NODE_SYMBOL);
addSourceLocation(nodeId, location, LOCATION_QUALIFIER);
return edgeId;
}
void ParserClientImpl::recordLocalSymbol(const std::wstring& name, const ParseLocation& location)
@@ -81,10 +55,9 @@ void ParserClientImpl::recordLocalSymbol(const std::wstring& name, const ParseLo
addSourceLocation(localSymbolId, location, LOCATION_LOCAL_SYMBOL);
}
void ParserClientImpl::recordFile(const FilePath& filePath, bool indexed)
void ParserClientImpl::recordLocation(Id elementId, const ParseLocation& location, ParseLocationType type)
{
const Id fileId = addFileName(filePath);
m_storage->addFile(StorageFile(fileId, filePath.wstr(), indexed, true));
addSourceLocation(elementId, location, parseLocationTypeToLocationType(type));
}
void ParserClientImpl::recordComment(const ParseLocation& location)
@@ -95,7 +68,7 @@ void ParserClientImpl::recordComment(const ParseLocation& location)
}
m_storage->addSourceLocation(StorageSourceLocationData(
addFileName(location.filePath),
location.fileId,
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
@@ -104,16 +77,17 @@ void ParserClientImpl::recordComment(const ParseLocation& location)
));
}
void ParserClientImpl::doRecordError(
const ParseLocation& location, const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit)
void ParserClientImpl::recordError(
const FilePath& filePath, uint lineNumber, uint columnNumber, const std::wstring& message, bool fatal, bool indexed,
const FilePath& translationUnit)
{
if (location.isValid())
if (!filePath.empty())
{
m_storage->addError(StorageErrorData(
message,
location.filePath.wstr(),
location.startLineNumber,
location.startColumnNumber,
filePath.wstr(),
lineNumber,
columnNumber,
translationUnit.wstr(),
fatal,
indexed
@@ -205,6 +179,24 @@ Edge::EdgeType ParserClientImpl::referenceKindToEdgeType(ReferenceKind reference
return Edge::EDGE_UNDEFINED;
}
LocationType ParserClientImpl::parseLocationTypeToLocationType(ParseLocationType type) const
{
switch (type)
{
case ParseLocationType::TOKEN:
return LOCATION_TOKEN;
case ParseLocationType::SCOPE:
return LOCATION_SCOPE;
case ParseLocationType::SIGNATURE:
return LOCATION_SIGNATURE;
case ParseLocationType::QUALIFIER:
return LOCATION_QUALIFIER;
case ParseLocationType::LOCAL:
return LOCATION_LOCAL_SYMBOL;
}
return LOCATION_TOKEN;
}
Id ParserClientImpl::addNodeHierarchy(const NameHierarchy& nameHierarchy, NodeType nodeType)
{
Id childNodeId = 0;
@@ -267,14 +259,8 @@ void ParserClientImpl::addSourceLocation(Id elementId, const ParseLocation& loca
return;
}
if (location.filePath.empty())
{
LOG_ERROR("no filename set!");
return;
}
Id sourceLocationId = m_storage->addSourceLocation(StorageSourceLocationData(
addFileName(location.filePath),
location.fileId,
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
+11 -29
View File
@@ -15,42 +15,26 @@ class ParserClientImpl
public:
ParserClientImpl(IntermediateStorage* const storage);
Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolKind,
AccessKind access, DefinitionKind definitionKind) override;
Id recordFile(const FilePath& filePath, bool indexed) override;
Id recordSymbolWithLocation(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location,
AccessKind access, DefinitionKind definitionKind) override;
Id recordSymbol(const NameHierarchy& symbolName) override;
void recordSymbolKind(Id symbolId, SymbolKind symbolKind) override;
void recordAccessKind(Id symbolId, AccessKind accessKind) override;
void recordDefinitionKind(Id symbolId, DefinitionKind definitionKind) override;
Id recordSymbolWithLocationAndScope(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access, DefinitionKind definitionKind) override;
Id recordSymbolWithLocationAndScopeAndSignature(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation, const ParseLocation& signatureLocation,
AccessKind access, DefinitionKind definitionKind) override;
void recordReference(
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
const ParseLocation& location) override;
void recordQualifierLocation(
const NameHierarchy& qualifierName, const ParseLocation& location) override;
Id recordReference(ReferenceKind referenceKind, Id referencedSymbolId, Id contextSymbolId, const ParseLocation& location) override;
void recordLocalSymbol(const std::wstring& name, const ParseLocation& location) override;
void recordFile(const FilePath& filePath, bool indexed) override;
void recordLocation(Id elementId, const ParseLocation& location, ParseLocationType type) override;
void recordComment(const ParseLocation& location) override;
private:
void doRecordError(
const ParseLocation& location, const std::wstring& message, bool fatal, bool indexed, const FilePath& sourceFilePath) override;
void recordError(const FilePath& filePath, uint lineNumber, uint columnNumber, const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit) override;
private:
NodeType symbolKindToNodeType(SymbolKind symbolType) const;
Edge::EdgeType referenceKindToEdgeType(ReferenceKind referenceKind) const;
LocationType parseLocationTypeToLocationType(ParseLocationType type) const;
void addAccess(Id nodeId, AccessKind access);
Id addNodeHierarchy(const NameHierarchy& nameHierarchy, NodeType nodeType = NodeType::NODE_SYMBOL);
@@ -58,8 +42,6 @@ private:
Id addEdge(int type, Id sourceId, Id targetId);
void addSourceLocation(Id elementId, const ParseLocation& location, LocationType type);
void addError(const std::wstring& message, bool fatal, bool indexed,
const ParseLocation& location, const FilePath& sourceFilePath);
IntermediateStorage* const m_storage;
std::map<std::wstring, Id> m_fileIdMap;
@@ -10,6 +10,7 @@ IntermediateStorage::IntermediateStorage()
void IntermediateStorage::clear()
{
m_nodesIndex.clear();
m_nodeIdIndex.clear();
m_nodes.clear();
m_filesIndex.clear();
@@ -75,6 +76,19 @@ size_t IntermediateStorage::getSourceLocationCount() const
return m_sourceLocations.size();
}
bool IntermediateStorage::hasFatalErrors() const
{
for (const StorageErrorData& error : m_errors)
{
if (error.fatal)
{
return true;
}
}
return false;
}
void IntermediateStorage::setAllFilesIncomplete()
{
for (StorageFile& file : m_files)
@@ -116,6 +130,7 @@ std::pair<Id, bool> IntermediateStorage::addNode(const StorageNodeData& nodeData
Id nodeId = m_nextId++;
m_nodes.emplace_back(nodeId, nodeData);
m_nodesIndex.emplace(nodeData, m_nodes.size() - 1);
m_nodeIdIndex.emplace(nodeId, m_nodes.size() - 1);
return std::make_pair(nodeId, true);
}
@@ -130,6 +145,15 @@ std::vector<Id> IntermediateStorage::addNodes(const std::vector<StorageNode>& no
return nodeIds;
}
void IntermediateStorage::setNodeType(Id nodeId, int nodeType)
{
auto it = m_nodeIdIndex.find(nodeId);
if (it != m_nodeIdIndex.end() && m_nodes[it->second].type < nodeType)
{
m_nodes[it->second].type = nodeType;
}
}
void IntermediateStorage::addSymbol(const StorageSymbol& symbol)
{
m_symbols.push_back(symbol);
@@ -316,9 +340,11 @@ void IntermediateStorage::setStorageNodes(std::vector<StorageNode> storageNodes)
m_nodes = std::move(storageNodes);
m_nodesIndex.clear();
m_nodeIdIndex.clear();
for (size_t i = 0; i < m_nodes.size(); i++)
{
m_nodesIndex.emplace(m_nodes[i], i);
m_nodeIdIndex.emplace(m_nodes[i].id, i);
}
}
@@ -18,11 +18,13 @@ public:
size_t getByteSize(size_t stringSize) const;
size_t getSourceLocationCount() const;
bool hasFatalErrors() const;
void setAllFilesIncomplete();
void setFilesWithErrorsIncomplete();
std::pair<Id, bool> addNode(const StorageNodeData& nodeData) override;
std::vector<Id> addNodes(const std::vector<StorageNode>& nodes) override;
void setNodeType(Id nodeId, int nodeType);
void addSymbol(const StorageSymbol& symbol) override;
void addSymbols(const std::vector<StorageSymbol>& symbols) override;
void addFile(const StorageFile& file) override;
@@ -65,6 +67,7 @@ private:
std::wstring serialize(const StorageErrorData& errorData) const;
std::map<StorageNodeData, size_t> m_nodesIndex;
std::map<Id, size_t> m_nodeIdIndex;
std::vector<StorageNode> m_nodes;
std::map<StorageFile, size_t> m_filesIndex; // this is used to prevent duplicates (unique)
@@ -26,7 +26,6 @@ class TextAccess;
class Version;
class SourceLocationCollection;
class SourceLocationFile;
struct ParseLocation;
class SqliteIndexStorage
: public SqliteStorage