Files
Sourcetrail/src/lib/data/parser/ParserClientImpl.cpp
T
Eberhard Graether 9a36d48d1e src: Improved project loading performance
* faster hierarchy cache building
* cache symbol definition kinds
* don't request files when caches can be used
* save SearchEdge by starting character in SearchNode to avoid iteration when adding to SearchIndex
* fixed disabled state of some search buttons
2017-07-15 15:21:08 +02:00

337 lines
8.0 KiB
C++

#include "data/parser/ParserClientImpl.h"
#include "data/graph/Edge.h"
#include "data/graph/Node.h"
#include "data/location/LocationType.h"
#include "data/parser/ParseLocation.h"
#include "utility/logging/logging.h"
ParserClientImpl::ParserClientImpl()
{
}
ParserClientImpl::~ParserClientImpl()
{
}
void ParserClientImpl::setStorage(std::shared_ptr<IntermediateStorage> storage)
{
m_storage = storage;
}
void ParserClientImpl::resetStorage()
{
m_storage.reset();
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolKind,
AccessKind access, DefinitionKind definitionKind
)
{
Id nodeId = addNodeHierarchy(symbolName, symbolKindToNodeType(symbolKind));
addSymbol(nodeId, definitionKind);
addAccess(nodeId, access);
return nodeId;
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location,
AccessKind access, DefinitionKind definitionKind
)
{
Id nodeId = recordSymbol(symbolName, symbolKind, access, definitionKind);
addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN));
return nodeId;
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolKind,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access, DefinitionKind definitionKind
)
{
Id nodeId = recordSymbol(symbolName, symbolKind, location, access, definitionKind);
addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE));
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);
addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN));
}
void ParserClientImpl::onError(const ParseLocation& location, const std::string& message, bool fatal, bool indexed)
{
if (location.isValid())
{
addError(message, fatal, indexed, location);
}
}
void ParserClientImpl::onLocalSymbolParsed(const std::string& name, const ParseLocation& location)
{
const Id localSymbolId = addLocalSymbol(name);
addSourceLocation(localSymbolId, location, locationTypeToInt(LOCATION_LOCAL_SYMBOL));
}
void ParserClientImpl::onFileParsed(const FileInfo& fileInfo)
{
const Id nodeId = addNodeHierarchy(NameHierarchy(fileInfo.path.str(), NAME_DELIMITER_FILE), Node::NODE_FILE);
addFile(nodeId, fileInfo.path, fileInfo.lastWriteTime.toString());
}
void ParserClientImpl::onCommentParsed(const ParseLocation& location)
{
addCommentLocation(location);
}
Node::NodeType ParserClientImpl::symbolKindToNodeType(SymbolKind symbolKind) const
{
switch (symbolKind)
{
case SYMBOL_BUILTIN_TYPE:
return Node::NODE_BUILTIN_TYPE;
case SYMBOL_CLASS:
return Node::NODE_CLASS;
case SYMBOL_ENUM:
return Node::NODE_ENUM;
case SYMBOL_ENUM_CONSTANT:
return Node::NODE_ENUM_CONSTANT;
case SYMBOL_FIELD:
return Node::NODE_FIELD;
case SYMBOL_FUNCTION:
return Node::NODE_FUNCTION;
case SYMBOL_GLOBAL_VARIABLE:
return Node::NODE_GLOBAL_VARIABLE;
case SYMBOL_INTERFACE:
return Node::NODE_INTERFACE;
case SYMBOL_MACRO:
return Node::NODE_MACRO;
case SYMBOL_METHOD:
return Node::NODE_METHOD;
case SYMBOL_NAMESPACE:
return Node::NODE_NAMESPACE;
case SYMBOL_PACKAGE:
return Node::NODE_PACKAGE;
case SYMBOL_STRUCT:
return Node::NODE_STRUCT;
case SYMBOL_TEMPLATE_PARAMETER:
return Node::NODE_TEMPLATE_PARAMETER_TYPE;
case SYMBOL_TYPEDEF:
return Node::NODE_TYPEDEF;
case SYMBOL_TYPE_PARAMETER:
return Node::NODE_TYPE_PARAMETER;
case SYMBOL_UNION:
return Node::NODE_TYPE;
default:
break;
}
return Node::NODE_NON_INDEXED;
}
Edge::EdgeType ParserClientImpl::referenceKindToEdgeType(ReferenceKind referenceKind) const
{
switch (referenceKind)
{
case REFERENCE_TYPE_USAGE:
return Edge::EDGE_TYPE_USAGE;
case REFERENCE_USAGE:
return Edge::EDGE_USAGE;
case REFERENCE_CALL:
return Edge::EDGE_CALL;
case REFERENCE_INHERITANCE:
return Edge::EDGE_INHERITANCE;
case REFERENCE_OVERRIDE:
return Edge::EDGE_OVERRIDE;
case REFERENCE_TEMPLATE_ARGUMENT:
return Edge::EDGE_TEMPLATE_ARGUMENT;
case REFERENCE_TYPE_ARGUMENT:
return Edge::EDGE_TYPE_ARGUMENT;
case REFERENCE_TEMPLATE_DEFAULT_ARGUMENT:
return Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT;
case REFERENCE_TEMPLATE_SPECIALIZATION:
return Edge::EDGE_TEMPLATE_SPECIALIZATION;
case REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION:
return Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION;
case REFERENCE_INCLUDE:
return Edge::EDGE_INCLUDE;
case REFERENCE_IMPORT:
return Edge::EDGE_IMPORT;
case REFERENCE_MACRO_USAGE:
return Edge::EDGE_MACRO_USAGE;
default:
break;
}
return Edge::EDGE_UNDEFINED;
}
void ParserClientImpl::addAccess(Id nodeId, AccessKind access)
{
if (access != ACCESS_NONE)
{
addComponentAccess(nodeId, accessKindToInt(access));
}
}
Id ParserClientImpl::addNodeHierarchy(NameHierarchy nameHierarchy, Node::NodeType nodeType)
{
if (nameHierarchy.size() == 0)
{
return 0;
}
Id parentNodeId = 0;
NameHierarchy currentNameHierarchy(nameHierarchy.getDelimiter());
for (size_t i = 0; i < nameHierarchy.size(); i++)
{
currentNameHierarchy.push(nameHierarchy[i]);
const bool currentIsLastElement = (i == nameHierarchy.size() - 1);
const Node::NodeType currentType = (currentIsLastElement ? nodeType : Node::NODE_NON_INDEXED); // TODO: rename to unknown!
Id nodeId = addNode(currentType, currentNameHierarchy);
if (parentNodeId != 0)
{
addEdge(Edge::EDGE_MEMBER, parentNodeId, nodeId);
}
parentNodeId = nodeId;
}
return parentNodeId;
}
Id ParserClientImpl::addNode(Node::NodeType nodeType, NameHierarchy nameHierarchy)
{
if (!m_storage)
{
return 0;
}
return m_storage->addNode(Node::typeToInt(nodeType), NameHierarchy::serialize(nameHierarchy));
}
void ParserClientImpl::addFile(Id id, const FilePath& filePath, const std::string& modificationTime)
{
if (!m_storage)
{
return;
}
m_storage->addFile(id, filePath.str(), modificationTime, true);
}
void ParserClientImpl::addSymbol(Id id, DefinitionKind definitionKind)
{
if (!m_storage)
{
return;
}
if (definitionKind != DEFINITION_NONE)
{
m_storage->addSymbol(id, definitionKindToInt(definitionKind));
}
}
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);
}
Id ParserClientImpl::addLocalSymbol(const std::string& name)
{
if (!m_storage)
{
return 0;
}
return m_storage->addLocalSymbol(name);
}
void ParserClientImpl::addSourceLocation(Id elementId, const ParseLocation& location, int type)
{
if (!m_storage)
{
return;
}
if (!location.isValid())
{
return;
}
if (location.filePath.empty())
{
LOG_ERROR("no filename set!");
return;
}
Id sourceLocationId = m_storage->addSourceLocation(
addNodeHierarchy(NameHierarchy(location.filePath.str(), NAME_DELIMITER_FILE), Node::NODE_FILE),
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
location.endColumnNumber,
type
);
m_storage->addOccurrence(
elementId,
sourceLocationId
);
}
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(
addNodeHierarchy(NameHierarchy(location.filePath.str(), NAME_DELIMITER_FILE), Node::NODE_FILE),
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
location.endColumnNumber
);
}
void ParserClientImpl::addError(const std::string& message, bool fatal, bool indexed, const ParseLocation& location)
{
if (!m_storage)
{
return;
}
m_storage->addError(message, location.filePath, location.startLineNumber, location.startColumnNumber, fatal, indexed);
}