logic: Store locations of errors in source_location table of DB

This commit is contained in:
mlangkabel
2018-11-30 16:02:10 +01:00
parent 34691a0555
commit a51799c279
23 changed files with 290 additions and 193 deletions
+46 -1
View File
@@ -3,6 +3,51 @@
#include "StorageError.h"
typedef StorageError ErrorInfo;
struct ErrorInfo
{
ErrorInfo()
: id(0)
, message(L"")
, filePath(L"")
, lineNumber(-1)
, columnNumber(-1)
, translationUnit(L"")
, fatal(0)
, indexed(0)
{}
ErrorInfo(
Id id,
std::wstring message,
std::wstring filePath,
uint lineNumber,
uint columnNumber,
std::wstring translationUnit,
bool fatal,
bool indexed
)
: id(id)
, message(std::move(message))
, filePath(std::move(filePath))
, lineNumber(lineNumber)
, columnNumber(columnNumber)
, translationUnit(std::move(translationUnit))
, fatal(fatal)
, indexed(indexed)
{}
Id id;
std::wstring message;
std::wstring filePath;
uint lineNumber;
uint columnNumber;
std::wstring translationUnit;
bool fatal;
bool indexed;
};
#endif // ERROR_INFO_H
+14 -10
View File
@@ -1,17 +1,18 @@
#include "TaskBuildIndex.h"
#include "AppPath.h"
#include "Blackboard.h"
#include "DialogView.h"
#include "FileLogger.h"
#include "InterprocessIndexer.h"
#include "MessageIndexingStatus.h"
#include "MessageStatus.h"
#include "Blackboard.h"
#include "ParserClientImpl.h"
#include "StorageProvider.h"
#include "TimeStamp.h"
#include "UserPaths.h"
#include "utilityApp.h"
#include "DialogView.h"
#include "InterprocessIndexer.h"
#include "StorageProvider.h"
#if _WIN32
const std::wstring TaskBuildIndex::s_processName(L"sourcetrail_indexer.exe");
@@ -131,19 +132,22 @@ void TaskBuildIndex::doExit(std::shared_ptr<Blackboard> blackboard)
}
std::vector<FilePath> crashedFiles = m_interprocessIndexingStatusManager.getCrashedSourceFilePaths();
if (crashedFiles.size())
if (!crashedFiles.empty())
{
std::shared_ptr<IntermediateStorage> is = std::make_shared<IntermediateStorage>();
std::shared_ptr<IntermediateStorage> storage = std::make_shared<IntermediateStorage>();
std::shared_ptr<ParserClientImpl> parserClient = std::make_shared<ParserClientImpl>(storage.get());
for (const FilePath& path : crashedFiles)
{
is->addError(StorageErrorData(
Id fileId = parserClient->recordFile(path.getCanonical(), false);
parserClient->recordError(
L"The translation unit threw an exception during indexing. Please check if the source file "
"conforms to the specified language standard and all necessary options are defined within your project "
"setup.", path.wstr(), 1, 1, path.wstr(), true, true
));
"setup.", true, true, path, ParseLocation(fileId, 1, 1)
);
LOG_INFO(L"crashed translation unit: " + path.wstr());
}
m_storageProvider->insert(is);
m_storageProvider->insert(storage);
}
blackboard->set<bool>("indexer_threads_stopped", true);
@@ -199,9 +199,9 @@ void SharedIntermediateStorage::setStorageComponentAccesses(const std::set<Stora
}
}
std::vector<StorageErrorData> SharedIntermediateStorage::getStorageErrors() const
std::vector<StorageError> SharedIntermediateStorage::getStorageErrors() const
{
std::vector<StorageErrorData> result;
std::vector<StorageError> result;
result.reserve(m_storageErrors.size());
for (unsigned int i = 0; i < m_storageErrors.size(); i++)
@@ -212,7 +212,7 @@ std::vector<StorageErrorData> SharedIntermediateStorage::getStorageErrors() cons
return result;
}
void SharedIntermediateStorage::setStorageErrors(const std::vector<StorageErrorData>& errors)
void SharedIntermediateStorage::setStorageErrors(const std::vector<StorageError>& errors)
{
m_storageErrors.clear();
@@ -37,8 +37,8 @@ public:
std::set<StorageComponentAccess> getStorageComponentAccesses() const;
void setStorageComponentAccesses(const std::set<StorageComponentAccess>& storageComponentAccesses);
std::vector<StorageErrorData> getStorageErrors() const;
void setStorageErrors(const std::vector<StorageErrorData>& errors);
std::vector<StorageError> getStorageErrors() const;
void setStorageErrors(const std::vector<StorageError>& errors);
Id getNextId() const;
void setNextId(const Id nextId);
@@ -52,7 +52,7 @@ private:
SharedMemory::Vector<SharedStorageEdge> m_storageEdges;
SharedMemory::Vector<SharedStorageLocalSymbol> m_storageLocalSymbols;
SharedMemory::Vector<SharedStorageSourceLocation> m_storageSourceLocations;
SharedMemory::Vector<SharedStorageErrorData> m_storageErrors;
SharedMemory::Vector<SharedStorageError> m_storageErrors;
SharedMemory::Allocator* m_allocator;
@@ -112,58 +112,46 @@ inline StorageLocalSymbol fromShared(const SharedStorageLocalSymbol& symbol)
}
struct SharedStorageErrorData
struct SharedStorageError
{
SharedStorageErrorData(
SharedStorageError(
Id id,
const std::string& message,
const std::string& filePath,
uint lineNumber,
uint columnNumber,
const std::string& sourceFilePath,
const std::string& translationUnit,
bool fatal,
bool indexed,
SharedMemory::Allocator* allocator
)
: message(message.c_str(), allocator)
, filePath(filePath.c_str(), allocator)
, lineNumber(lineNumber)
, columnNumber(columnNumber)
, translationUnit(sourceFilePath.c_str(), allocator)
: id(id)
, message(message.c_str(), allocator)
, translationUnit(translationUnit.c_str(), allocator)
, fatal(fatal)
, indexed(indexed)
{}
Id id;
SharedMemory::String message;
SharedMemory::String filePath;
uint lineNumber;
uint columnNumber;
SharedMemory::String translationUnit;
bool fatal;
bool indexed;
};
inline SharedStorageErrorData toShared(const StorageErrorData& error, SharedMemory::Allocator* allocator)
inline SharedStorageError toShared(const StorageError& error, SharedMemory::Allocator* allocator)
{
return SharedStorageErrorData(
return SharedStorageError(
error.id,
utility::encodeToUtf8(error.message),
utility::encodeToUtf8(error.filePath),
error.lineNumber,
error.columnNumber,
utility::encodeToUtf8(error.translationUnit),
error.fatal,
error.indexed, allocator
);
}
inline StorageErrorData fromShared(const SharedStorageErrorData& error)
inline StorageError fromShared(const SharedStorageError& error)
{
return StorageErrorData(
return StorageError(
error.id,
utility::decodeFromUtf8(error.message.c_str()),
utility::decodeFromUtf8(error.filePath.c_str()),
error.lineNumber,
error.columnNumber,
utility::decodeFromUtf8(error.translationUnit.c_str()),
error.fatal,
error.indexed
@@ -211,6 +211,28 @@ std::shared_ptr<SourceLocationFile> SourceLocationFile::getFilteredByType(Locati
return ret;
}
std::shared_ptr<SourceLocationFile> SourceLocationFile::getFilteredByTypes(const std::vector<LocationType>& types) const
{
size_t typeMask = 0;
for (LocationType type : types)
{
typeMask |= 1 << type;
}
std::shared_ptr<SourceLocationFile> ret =
std::make_shared<SourceLocationFile>(getFilePath(), false, isComplete(), isIndexed());
for (const std::shared_ptr<SourceLocation>& location : m_locations)
{
if ((1 << location->getType()) & typeMask)
{
ret->addSourceLocationCopy(location.get());
}
}
return ret;
}
std::wostream& operator<<(std::wostream& ostream, const SourceLocationFile& file)
{
ostream << L"file \"" << file.getFilePath().wstr() << L"\"";
@@ -58,6 +58,7 @@ public:
std::shared_ptr<SourceLocationFile> getFilteredByLines(size_t firstLineNumber, size_t lastLineNumber) const;
std::shared_ptr<SourceLocationFile> getFilteredByType(LocationType type) const;
std::shared_ptr<SourceLocationFile> getFilteredByTypes(const std::vector<LocationType>& types) const;
private:
const FilePath m_filePath;
+1 -2
View File
@@ -30,8 +30,7 @@ public:
virtual void recordLocation(Id elementId, const ParseLocation& location, ParseLocationType type) = 0;
virtual void recordComment(const ParseLocation& location) = 0;
virtual void recordError(const FilePath& filePath, uint lineNumber, uint columnNumber, const std::wstring& message,
bool fatal, bool indexed, const FilePath& translationUnit) = 0;
virtual void recordError(const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit, const ParseLocation& location) = 0;
};
#endif // PARSER_CLIENT_H
+6 -7
View File
@@ -78,20 +78,19 @@ void ParserClientImpl::recordComment(const ParseLocation& location)
}
void ParserClientImpl::recordError(
const FilePath& filePath, uint lineNumber, uint columnNumber, const std::wstring& message, bool fatal, bool indexed,
const FilePath& translationUnit)
const std::wstring& message, bool fatal, bool indexed,
const FilePath& translationUnit, const ParseLocation& location)
{
if (!filePath.empty())
if (location.fileId != 0)
{
m_storage->addError(StorageErrorData(
Id errorId = m_storage->addError(StorageErrorData(
message,
filePath.wstr(),
lineNumber,
columnNumber,
translationUnit.wstr(),
fatal,
indexed
));
addSourceLocation(errorId, location, LOCATION_ERROR);
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ public:
void recordLocation(Id elementId, const ParseLocation& location, ParseLocationType type) override;
void recordComment(const ParseLocation& location) override;
void recordError(const FilePath& filePath, uint lineNumber, uint columnNumber, const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit) override;
void recordError(const std::wstring& message, bool fatal, bool indexed, const FilePath& translationUnit, const ParseLocation& location) override;
private:
NodeType symbolKindToNodeType(SymbolKind symbolType) const;
+26 -12
View File
@@ -1,5 +1,6 @@
#include "IntermediateStorage.h"
#include "LocationType.h"
#include "utility.h"
IntermediateStorage::IntermediateStorage()
@@ -46,8 +47,8 @@ size_t IntermediateStorage::getByteSize(size_t stringSize) const
for (const StorageErrorData& storageError: getErrors())
{
byteSize += sizeof(StorageErrorData);
byteSize += stringSize + storageError.filePath.size();
byteSize += stringSize + storageError.message.size();
byteSize += stringSize + storageError.translationUnit.size();
}
for (const StorageNode& storageNode: getStorageNodes())
@@ -99,15 +100,18 @@ void IntermediateStorage::setAllFilesIncomplete()
void IntermediateStorage::setFilesWithErrorsIncomplete()
{
std::set<std::wstring> errorFileNames;
for (const StorageErrorData& error : m_errors)
std::set<Id> errorFileIds;
for (const StorageSourceLocation& location : m_sourceLocations)
{
errorFileNames.insert(error.filePath);
if (location.type == locationTypeToInt(LOCATION_ERROR))
{
errorFileIds.insert(location.fileNodeId);
}
}
for (StorageFile& file : m_files)
{
if (errorFileNames.find(file.filePath) != errorFileNames.end())
if (errorFileIds.find(file.id) != errorFileIds.end())
{
file.complete = false;
}
@@ -281,13 +285,18 @@ void IntermediateStorage::addComponentAccesses(const std::vector<StorageComponen
m_componentAccesses.insert(componentAccesses.begin(), componentAccesses.end());
}
void IntermediateStorage::addError(const StorageErrorData& errorData)
Id IntermediateStorage::addError(const StorageErrorData& errorData)
{
if (m_errorsIndex.find(errorData) == m_errorsIndex.end())
auto it = m_errorsIndex.find(errorData);
if (it != m_errorsIndex.end())
{
m_errors.emplace_back(errorData);
m_errorsIndex.emplace(errorData);
return m_errors[it->second].id;
}
Id errorId = m_nextId++;
m_errors.emplace_back(errorId, errorData);
m_errorsIndex.emplace(errorData, m_errors.size() - 1);
return errorId;
}
const std::vector<StorageNode>& IntermediateStorage::getStorageNodes() const
@@ -330,7 +339,7 @@ const std::set<StorageComponentAccess>& IntermediateStorage::getComponentAccesse
return m_componentAccesses;
}
const std::vector<StorageErrorData>& IntermediateStorage::getErrors() const
const std::vector<StorageError>& IntermediateStorage::getErrors() const
{
return m_errors;
}
@@ -395,10 +404,15 @@ void IntermediateStorage::setComponentAccesses(std::set<StorageComponentAccess>
m_componentAccesses = std::move(componentAccesses);
}
void IntermediateStorage::setErrors(std::vector<StorageErrorData> errors)
void IntermediateStorage::setErrors(std::vector<StorageError> errors)
{
m_errors = std::move(errors);
m_errorsIndex = utility::toSet(m_errors);
m_errorsIndex.clear();
for (size_t i = 0; i < m_errors.size(); i++)
{
m_errorsIndex.emplace(m_errors[i], i);
}
}
Id IntermediateStorage::getNextId() const
+5 -7
View File
@@ -38,7 +38,7 @@ public:
void addOccurrences(const std::vector<StorageOccurrence>& occurrences) override;
void addComponentAccess(const StorageComponentAccess& componentAccess) override;
void addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses) override;
void addError(const StorageErrorData& errorData) override;
Id addError(const StorageErrorData& errorData) override;
const std::vector<StorageNode>& getStorageNodes() const override;
const std::vector<StorageFile>& getStorageFiles() const override;
@@ -48,7 +48,7 @@ public:
const std::set<StorageSourceLocation>& getStorageSourceLocations() const override;
const std::set<StorageOccurrence>& getStorageOccurrences() const override;
const std::set<StorageComponentAccess>& getComponentAccesses() const override;
const std::vector<StorageErrorData>& getErrors() const override;
const std::vector<StorageError>& getErrors() const override;
void setStorageNodes(std::vector<StorageNode> storageNodes);
void setStorageFiles(std::vector<StorageFile> storageFiles);
@@ -58,14 +58,12 @@ public:
void setStorageSourceLocations(std::set<StorageSourceLocation> storageSourceLocations);
void setStorageOccurrences(std::set<StorageOccurrence> storageOccurrences);
void setComponentAccesses(std::set<StorageComponentAccess> componentAccesses);
void setErrors(std::vector<StorageErrorData> errors);
void setErrors(std::vector<StorageError> errors);
Id getNextId() const;
void setNextId(const Id nextId);
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;
@@ -86,8 +84,8 @@ private:
std::set<StorageComponentAccess> m_componentAccesses;
std::set<StorageErrorData> m_errorsIndex; // this is used to prevent duplicates (unique)
std::vector<StorageErrorData> m_errors;
std::map<StorageErrorData, size_t> m_errorsIndex; // this is used to prevent duplicates (unique)
std::vector<StorageError> m_errors;
Id m_nextId;
};
+22 -13
View File
@@ -138,9 +138,9 @@ void PersistentStorage::addComponentAccesses(const std::vector<StorageComponentA
m_sqliteIndexStorage.addComponentAccesses(componentAccesses);
}
void PersistentStorage::addError(const StorageErrorData& data)
Id PersistentStorage::addError(const StorageErrorData& data)
{
m_sqliteIndexStorage.addError(data);
return m_sqliteIndexStorage.addError(data).id;
}
const std::vector<StorageNode>& PersistentStorage::getStorageNodes() const
@@ -183,9 +183,9 @@ const std::set<StorageComponentAccess>& PersistentStorage::getComponentAccesses(
return m_storageData.accesses = utility::toSet(m_sqliteIndexStorage.getAll<StorageComponentAccess>());
}
const std::vector<StorageErrorData>& PersistentStorage::getErrors() const
const std::vector<StorageError>& PersistentStorage::getErrors() const
{
std::vector<StorageErrorData> errors;
std::vector<StorageError> errors;
for (const StorageError& error : m_sqliteIndexStorage.getAll<StorageError>())
{
errors.emplace_back(error);
@@ -204,7 +204,7 @@ void PersistentStorage::finishInjection()
{
m_sqliteIndexStorage.commitTransaction();
std::vector<ErrorInfo> errors = m_sqliteIndexStorage.getAll<StorageError>();
std::vector<ErrorInfo> errors = m_sqliteIndexStorage.getAllErrorInfos();
if (m_preInjectionErrorCount < errors.size())
{
ErrorCountInfo errorCount(errors);
@@ -333,7 +333,6 @@ void PersistentStorage::clearFileElements(const std::vector<FilePath>& filePaths
m_sqliteIndexStorage.beginTransaction();
m_sqliteIndexStorage.removeElementsWithLocationInFiles(fileNodeIds, updateStatusCallback);
m_sqliteIndexStorage.removeElements(fileNodeIds);
m_sqliteIndexStorage.removeErrorsInFiles(filePaths);
m_sqliteIndexStorage.commitTransaction();
updateStatusCallback(100);
}
@@ -1344,7 +1343,7 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getSourceLocationsF
for (const StorageSourceLocation& sourceLocation: m_sqliteIndexStorage.getAllByIds<StorageSourceLocation>(locationIds))
{
const LocationType type = intToLocationType(sourceLocation.type);
if (type == LOCATION_QUALIFIER || type == LOCATION_SIGNATURE)
if (type != LOCATION_TOKEN && type != LOCATION_SCOPE && type != LOCATION_QUALIFIER && type != LOCATION_LOCAL_SYMBOL)
{
continue;
}
@@ -1407,6 +1406,12 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getSourceLocationsF
elementIds.push_back(occurrence.elementId);
}
const LocationType type = intToLocationType(location.type);
if (type != LOCATION_TOKEN && type != LOCATION_SCOPE && type != LOCATION_QUALIFIER && type != LOCATION_LOCAL_SYMBOL)
{
continue;
}
collection->addSourceLocation(
intToLocationType(location.type),
location.id,
@@ -1428,7 +1433,9 @@ std::shared_ptr<SourceLocationFile> PersistentStorage::getSourceLocationsForFile
{
TRACE();
return m_sqliteIndexStorage.getSourceLocationsForFile(filePath);
return m_sqliteIndexStorage.getSourceLocationsForFile(filePath)->getFilteredByTypes({
LOCATION_TOKEN, LOCATION_SCOPE, LOCATION_QUALIFIER, LOCATION_LOCAL_SYMBOL
});
}
std::shared_ptr<SourceLocationFile> PersistentStorage::getSourceLocationsForLinesInFile(
@@ -1438,7 +1445,9 @@ std::shared_ptr<SourceLocationFile> PersistentStorage::getSourceLocationsForLine
TRACE();
return m_sqliteIndexStorage.getSourceLocationsForLinesInFile(
filePath, startLine, endLine)->getFilteredByLines(startLine, endLine);
filePath, startLine, endLine)->getFilteredByLines(startLine, endLine)->getFilteredByTypes({
LOCATION_TOKEN, LOCATION_SCOPE, LOCATION_QUALIFIER, LOCATION_LOCAL_SYMBOL
});
}
std::shared_ptr<SourceLocationFile> PersistentStorage::getSourceLocationsOfTypeInFile(
@@ -1515,14 +1524,14 @@ StorageStats PersistentStorage::getStorageStats() const
ErrorCountInfo PersistentStorage::getErrorCount() const
{
return ErrorCountInfo(m_sqliteIndexStorage.getAll<StorageError>());
return ErrorCountInfo(m_sqliteIndexStorage.getAllErrorInfos());
}
std::vector<ErrorInfo> PersistentStorage::getErrorsLimited(const ErrorFilter& filter) const
{
std::vector<ErrorInfo> errors;
for (const ErrorInfo& error : m_sqliteIndexStorage.getAll<StorageError>())
for (const ErrorInfo& error : m_sqliteIndexStorage.getAllErrorInfos())
{
if (filter.filter(error))
{
@@ -1562,8 +1571,8 @@ std::vector<ErrorInfo> PersistentStorage::getErrorsForFileLimited(const ErrorFil
std::vector<ErrorInfo> res;
std::vector<StorageError> errors = m_sqliteIndexStorage.getAll<StorageError>();
for (const StorageError& error : errors)
std::vector<ErrorInfo> errors = m_sqliteIndexStorage.getAllErrorInfos();
for (const ErrorInfo& error : errors)
{
if (filter.filter(error) && fileIds.find(getFileNodeId(FilePath(error.filePath))) != fileIds.end())
{
+3 -3
View File
@@ -34,7 +34,7 @@ public:
void addOccurrences(const std::vector<StorageOccurrence>& occurrences) override;
void addComponentAccess(const StorageComponentAccess& componentAccess) override;
void addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses) override;
void addError(const StorageErrorData& data) override;
Id addError(const StorageErrorData& data) override;
const std::vector<StorageNode>& getStorageNodes() const override;
const std::vector<StorageFile>& getStorageFiles() const override;
@@ -44,7 +44,7 @@ public:
const std::set<StorageSourceLocation>& getStorageSourceLocations() const override;
const std::set<StorageOccurrence>& getStorageOccurrences() const override;
const std::set<StorageComponentAccess>& getComponentAccesses() const override;
const std::vector<StorageErrorData>& getErrors() const override;
const std::vector<StorageError>& getErrors() const override;
void startInjection() override;
void finishInjection() override;
@@ -164,7 +164,7 @@ private:
std::set<StorageSourceLocation> locations;
std::set<StorageOccurrence> occurrences;
std::set<StorageComponentAccess> accesses;
std::vector<StorageErrorData> errors;
std::vector<StorageError> errors;
} m_storageData;
Id getFileNodeId(const FilePath& filePath) const;
+3 -2
View File
@@ -20,9 +20,10 @@ void Storage::inject(Storage* injected)
{
// TRACE("inject errors");
for (const StorageErrorData& error : injected->getErrors())
for (const StorageError& error : injected->getErrors())
{
addError(error);
Id errorId = addError(error);
injectedIdToOwnElementId.emplace(error.id, errorId);
}
}
+2 -2
View File
@@ -38,7 +38,7 @@ public:
virtual void addOccurrences(const std::vector<StorageOccurrence>& occurrences) = 0;
virtual void addComponentAccess(const StorageComponentAccess& componentAccess) = 0;
virtual void addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses) = 0;
virtual void addError(const StorageErrorData& data) = 0;
virtual Id addError(const StorageErrorData& data) = 0;
virtual const std::vector<StorageNode>& getStorageNodes() const = 0;
virtual const std::vector<StorageFile>& getStorageFiles() const = 0;
@@ -48,7 +48,7 @@ public:
virtual const std::set<StorageSourceLocation>& getStorageSourceLocations() const = 0;
virtual const std::set<StorageOccurrence>& getStorageOccurrences() const = 0;
virtual const std::set<StorageComponentAccess>& getComponentAccesses() const = 0;
virtual const std::vector<StorageErrorData>& getErrors() const = 0;
virtual const std::vector<StorageError>& getErrors() const = 0;
void inject(Storage* injected);
@@ -4,14 +4,14 @@
#include <unordered_map>
#include "FileSystem.h"
#include "LocationType.h"
#include "logging.h"
#include "TextAccess.h"
#include "utilityString.h"
#include "SourceLocationCollection.h"
#include "SourceLocationFile.h"
#include "utilityString.h"
const size_t SqliteIndexStorage::s_storageVersion = 20;
const size_t SqliteIndexStorage::s_storageVersion = 21;
namespace
{
@@ -426,9 +426,6 @@ StorageError SqliteIndexStorage::addError(const StorageErrorData& data)
{
m_checkErrorExistsStmt.bind(1, utility::encodeToUtf8(sanitizedMessage).c_str());
m_checkErrorExistsStmt.bind(2, int(data.fatal));
m_checkErrorExistsStmt.bind(3, utility::encodeToUtf8(data.filePath).c_str());
m_checkErrorExistsStmt.bind(4, int(data.lineNumber));
m_checkErrorExistsStmt.bind(5, int(data.columnNumber));
CppSQLite3Query checkQuery = executeQuery(m_checkErrorExistsStmt);
if (!checkQuery.eof() && checkQuery.numFields() > 0)
@@ -440,13 +437,14 @@ StorageError SqliteIndexStorage::addError(const StorageErrorData& data)
if (id == 0)
{
m_insertErrorStmt.bind(1, utility::encodeToUtf8(sanitizedMessage).c_str());
m_insertErrorStmt.bind(2, data.fatal);
m_insertErrorStmt.bind(3, data.indexed);
m_insertErrorStmt.bind(4, utility::encodeToUtf8(data.filePath).c_str());
m_insertErrorStmt.bind(5, int(data.lineNumber));
m_insertErrorStmt.bind(6, int(data.columnNumber));
m_insertErrorStmt.bind(7, utility::encodeToUtf8(data.translationUnit).c_str());
executeStatement(m_insertElementStmt);
id = m_database.lastRowId();
m_insertErrorStmt.bind(1, int(id));
m_insertErrorStmt.bind(2, utility::encodeToUtf8(sanitizedMessage).c_str());
m_insertErrorStmt.bind(3, data.fatal);
m_insertErrorStmt.bind(4, data.indexed);
m_insertErrorStmt.bind(5, utility::encodeToUtf8(data.translationUnit).c_str());
const bool success = executeStatement(m_insertErrorStmt);
if (success)
@@ -624,13 +622,6 @@ void SqliteIndexStorage::removeAllErrors()
);
}
void SqliteIndexStorage::removeErrorsInFiles(const std::vector<FilePath>& filePaths)
{
executeStatement(
"DELETE FROM error WHERE file_path IN ('" + utility::join(utility::toStrings(filePaths), "', '") + "');"
);
}
bool SqliteIndexStorage::isEdge(Id elementId) const
{
int count = executeStatementScalar("SELECT count(*) FROM edge WHERE id = " + std::to_string(elementId) + ";", 0);
@@ -816,7 +807,7 @@ void SqliteIndexStorage::setFileIndexed(Id fileId, bool indexed)
void SqliteIndexStorage::setFileCompleteIfNoError(Id fileId, const std::wstring& filePath, bool complete)
{
bool fileHasErrors = doGetFirst<StorageError>("WHERE file_path == '" + utility::encodeToUtf8(filePath) + "'").id;
bool fileHasErrors = doGetFirst<StorageSourceLocation>("WHERE file_node_id == " + std::to_string(fileId) + " AND type == " + std::to_string(locationTypeToInt(LOCATION_ERROR))).id;
if (fileHasErrors != complete)
{
executeStatement(
@@ -970,6 +961,58 @@ std::vector<StorageComponentAccess> SqliteIndexStorage::getComponentAccessesByNo
return doGetAll<StorageComponentAccess>("WHERE node_id IN (" + utility::join(utility::toStrings(nodeIds), ',') + ")");
}
std::vector<ErrorInfo> SqliteIndexStorage::getAllErrorInfos() const
{
std::vector<ErrorInfo> errorInfos;
CppSQLite3Query q = executeQuery(
"SELECT error.id, error.message, error.fatal, error.indexed, error.translation_unit, file.path, source_location.start_line, source_location.start_column "
"FROM occurrence "
"INNER JOIN error ON (error.id = occurrence.element_id) "
"INNER JOIN source_location ON (source_location.id = occurrence.source_location_id) "
"INNER JOIN file ON (file.id = source_location.file_node_id);"
);
std::map<Id, size_t> errorIdCount;
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const std::string message = q.getStringField(1, "");
const bool fatal = q.getIntField(2, 0);
const bool indexed = q.getIntField(3, 0);
const std::string translationUnit = q.getStringField(4, "");
const std::string filePath = q.getStringField(5, "");
const int lineNumber = q.getIntField(6, -1);
const int columnNumber = q.getIntField(7, -1);
if (id != 0)
{
// There can be multiple errors with the same id, so a count is added to the id
Id errorId = id * 10000;
auto it = errorIdCount.find(id);
if (it != errorIdCount.end())
{
errorId += it->second;
it->second = it->second + 1;
}
else
{
errorIdCount.emplace(id, 1);
}
errorInfos.push_back(ErrorInfo(
errorId, utility::decodeFromUtf8(message), utility::decodeFromUtf8(filePath),
lineNumber, columnNumber, utility::decodeFromUtf8(translationUnit), fatal, indexed
));
}
q.nextRow();
}
return errorInfos;
}
int SqliteIndexStorage::getNodeCount() const
{
return executeStatementScalar("SELECT COUNT(*) FROM node;", 0);
@@ -1002,7 +1045,7 @@ int SqliteIndexStorage::getSourceLocationCount() const
int SqliteIndexStorage::getErrorCount() const
{
return executeStatementScalar("SELECT COUNT(*) FROM error;", 0);
return executeStatementScalar("SELECT COUNT(*) FROM error INNER JOIN occurrence ON (error.id = occurrence.element_id);", 0);
}
std::vector<std::pair<int, SqliteDatabaseIndex>> SqliteIndexStorage::getIndices() const
@@ -1026,7 +1069,7 @@ std::vector<std::pair<int, SqliteDatabaseIndex>> SqliteIndexStorage::getIndices(
));
indices.push_back(std::make_pair(
STORAGE_MODE_WRITE,
SqliteDatabaseIndex("error_all_data_index", "error(message, fatal, file_path, line_number, column_number)")
SqliteDatabaseIndex("error_all_data_index", "error(message, fatal)")
));
indices.push_back(std::make_pair(
STORAGE_MODE_WRITE,
@@ -1170,11 +1213,9 @@ void SqliteIndexStorage::setupTables()
"message TEXT, "
"fatal INTEGER NOT NULL, "
"indexed INTEGER NOT NULL, "
"file_path TEXT, "
"line_number INTEGER, "
"column_number INTEGER, "
"translation_unit TEXT, "
"PRIMARY KEY(id));"
"PRIMARY KEY(id), "
"FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE);"
);
}
catch (CppSQLite3Exception& e)
@@ -1279,15 +1320,12 @@ void SqliteIndexStorage::setupPrecompiledStatements()
m_checkErrorExistsStmt = m_database.compileStatement(
"SELECT id FROM error WHERE "
"message = ? AND "
"fatal == ? AND "
"file_path == ? AND "
"line_number == ? AND "
"column_number == ? "
"fatal == ? "
"LIMIT 1;"
);
m_insertErrorStmt = m_database.compileStatement(
"INSERT INTO error(message, fatal, indexed, file_path, line_number, column_number, translation_unit) "
"VALUES(?, ?, ?, ?, ?, ?, ?);"
"INSERT INTO error(id, message, fatal, indexed, translation_unit) "
"VALUES(?, ?, ?, ?, ?);"
);
}
catch (CppSQLite3Exception& e)
@@ -1483,27 +1521,23 @@ template <>
void SqliteIndexStorage::forEach<StorageError>(const std::string& query, std::function<void(StorageError&&)> func) const
{
CppSQLite3Query q = executeQuery(
"SELECT message, fatal, indexed, file_path, line_number, column_number, translation_unit FROM error " + query + ";"
"SELECT id, message, fatal, indexed, translation_unit FROM error " + query + ";"
);
Id id = 1;
while (!q.eof())
{
const std::string message = q.getStringField(0, "");
const bool fatal = q.getIntField(1, 0);
const bool indexed = q.getIntField(2, 0);
const std::string filePath = q.getStringField(3, "");
const int lineNumber = q.getIntField(4, -1);
const int columnNumber = q.getIntField(5, -1);
const std::string translationUnit = q.getStringField(6, "");
const Id id = q.getIntField(0, 0);
const std::string message = q.getStringField(1, "");
const bool fatal = q.getIntField(2, 0);
const bool indexed = q.getIntField(3, 0);
const std::string translationUnit = q.getStringField(4, "");
if (lineNumber != -1 && columnNumber != -1)
if (id != 0)
{
func(StorageError(
id, utility::decodeFromUtf8(message), utility::decodeFromUtf8(filePath), lineNumber, columnNumber,
id, utility::decodeFromUtf8(message),
utility::decodeFromUtf8(translationUnit), fatal, indexed
));
id++;
}
q.nextRow();
@@ -5,7 +5,9 @@
#include <string>
#include <vector>
#include "ErrorInfo.h"
#include "LocationType.h"
#include "LowMemoryStringMap.h"
#include "SqliteDatabaseIndex.h"
#include "SqliteStorage.h"
#include "StorageComponentAccess.h"
@@ -17,7 +19,6 @@
#include "StorageOccurrence.h"
#include "StorageSourceLocation.h"
#include "StorageSymbol.h"
#include "LowMemoryStringMap.h"
#include "types.h"
#include "utility.h"
#include "utilityString.h"
@@ -69,7 +70,6 @@ public:
void removeElementsWithLocationInFiles(const std::vector<Id>& fileIds, std::function<void(int)> updateStatusCallback);
void removeAllErrors();
void removeErrorsInFiles(const std::vector<FilePath>& filePaths);
bool isEdge(Id elementId) const;
bool isNode(Id elementId) const;
@@ -119,6 +119,8 @@ public:
StorageComponentAccess getComponentAccessByNodeId(Id memberEdgeId) const;
std::vector<StorageComponentAccess> getComponentAccessesByNodeIds(const std::vector<Id>& memberEdgeIds) const;
std::vector<ErrorInfo> getAllErrorInfos() const;
template <typename ResultType>
std::vector<ResultType> getAll() const
{
+6 -25
View File
@@ -10,27 +10,19 @@ struct StorageErrorData
{
StorageErrorData()
: message(L"")
, filePath(L"")
, lineNumber(-1)
, columnNumber(-1)
, translationUnit(L"")
, fatal(0)
, indexed(0)
{}
StorageErrorData(
std::wstring message,
std::wstring filePath,
uint lineNumber,
uint columnNumber,
std::wstring translationUnit,
bool fatal,
bool indexed
)
: message(std::move(message))
, filePath(std::move(filePath))
, lineNumber(lineNumber)
, columnNumber(columnNumber)
, translationUnit(std::move(translationUnit))
, fatal(fatal)
, indexed(indexed)
@@ -42,26 +34,21 @@ struct StorageErrorData
{
return message < other.message;
}
else if (filePath != other.filePath)
else if (translationUnit != other.translationUnit)
{
return filePath < other.filePath;
return translationUnit < other.translationUnit;
}
else if (lineNumber != other.lineNumber)
else if (fatal != other.fatal)
{
return lineNumber < other.lineNumber;
return fatal < other.fatal;
}
else
{
return columnNumber < other.columnNumber;
return indexed < other.indexed;
}
}
std::wstring message;
std::wstring filePath;
uint lineNumber;
uint columnNumber;
std::wstring translationUnit;
bool fatal;
bool indexed;
@@ -82,18 +69,12 @@ struct StorageError: public StorageErrorData
StorageError(
Id id,
std::wstring message,
std::wstring filePath,
uint lineNumber,
uint columnNumber,
std::wstring translationUnit,
bool fatal,
bool indexed
)
: StorageErrorData(
std::move(message),
std::move(filePath),
lineNumber,
columnNumber,
std::move(translationUnit),
fatal,
indexed
@@ -63,6 +63,7 @@ void CxxDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level lev
return;
}
Id fileId = 0;
FilePath filePath;
uint lineNumber = 0;
uint columnNumber = 0;
@@ -76,13 +77,14 @@ void CxxDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level lev
loc = info.getLocation();
}
clang::FileID fileId = sourceManager.getFileID(loc);
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
clang::FileID clangFileId = sourceManager.getFileID(loc);
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(clangFileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
ParseLocation location = utility::getParseLocation(loc, sourceManager, nullptr, m_canonicalFilePathCache);
filePath = m_canonicalFilePathCache->getCanonicalFilePath(location.fileId);
fileId = location.fileId;
filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileId);
lineNumber = location.startLineNumber;
columnNumber = location.startColumnNumber;
}
@@ -92,6 +94,7 @@ void CxxDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level lev
if (fileEntry != nullptr && fileEntry->isValid())
{
filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
fileId = m_client->recordFile(filePath, false /*keeps the "indexed" state if the file already exists*/);
lineNumber = 1;
columnNumber = 1;
}
@@ -100,20 +103,19 @@ void CxxDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level lev
else
{
filePath = m_sourceFilePath;
fileId = m_client->recordFile(filePath, false /*keeps the "indexed" state if the file already exists*/);
lineNumber = 1;
columnNumber = 1;
}
if (!filePath.empty())
if (fileId != 0)
{
m_client->recordError(
filePath,
lineNumber,
columnNumber,
utility::decodeFromUtf8(message),
level == clang::DiagnosticsEngine::Fatal,
m_canonicalFilePathCache->getFileRegister()->hasFilePath(filePath),
m_sourceFilePath
m_sourceFilePath,
ParseLocation(fileId, lineNumber, columnNumber)
);
}
}
-5
View File
@@ -375,11 +375,6 @@ void QtCodeField::createAnnotations(std::shared_ptr<SourceLocationFile> location
locationFile->forEachSourceLocation(
[&](const SourceLocation* location)
{
if (location->getType() == LOCATION_SIGNATURE || location->getType() == LOCATION_COMMENT)
{
return;
}
if (location->getLocationId() && locationIds.find(location->getLocationId()) != locationIds.end())
{
return;
+2 -4
View File
@@ -264,13 +264,11 @@ void JavaParser::doRecordError(
bool indexed = jIndexed;
m_client->recordError(
m_currentFilePath,
beginLine,
beginColumn,
utility::decodeFromUtf8(m_javaEnvironment->toStdString(jMessage)),
fatal,
indexed,
FilePath()
FilePath(),
ParseLocation(m_currentFileId, beginLine, beginColumn)
);
}
+17 -12
View File
@@ -44,6 +44,7 @@ public:
std::multimap<Id, StorageSourceLocation> signatureLocationMap;
std::multimap<Id, StorageSourceLocation> localSymbolLocationMap;
std::multimap<Id, StorageSourceLocation> qualifierLocationMap;
std::multimap<Id, StorageSourceLocation> errorLocationMap;
std::vector<StorageSourceLocation> commentLocations;
for (const StorageSourceLocation& location : getStorageSourceLocations())
{
@@ -53,7 +54,7 @@ public:
elementIds.emplace_back(it->second);
}
if (!elementIds.size())
if (elementIds.empty())
{
elementIds.emplace_back(0);
}
@@ -92,6 +93,12 @@ public:
signatureLocationMap.emplace(elementId, location);
}
break;
case LOCATION_ERROR:
if (elementId)
{
errorLocationMap.emplace(elementId, location);
}
break;
case LOCATION_COMMENT:
commentLocations.emplace_back(location);
break;
@@ -262,18 +269,16 @@ public:
addLine(L"COMMENT: comment" + addFileName(locStr, filePathMap[location.fileNodeId]));
}
for (const StorageErrorData& error : getErrors())
for (const StorageError& error : getErrors())
{
std::wstring locStr = addLocationStr(
L"",
StorageSourceLocation(
0, 0, error.lineNumber, error.columnNumber, error.lineNumber, error.columnNumber,
locationTypeToInt(LOCATION_ERROR)
)
);
errors.emplace_back(error.message + locStr);
addLine(L"ERROR: " + error.message + addFileName(locStr, FilePath(error.filePath)));
for (auto errorLocationIt = errorLocationMap.find(error.id);
errorLocationIt != errorLocationMap.end() && errorLocationIt->first == error.id;
errorLocationIt++)
{
std::wstring locStr = addLocationStr(L"", errorLocationIt->second);
errors.emplace_back(error.message + locStr);
addLine(L"ERROR: " + error.message + addFileName(locStr, filePathMap[errorLocationIt->second.fileNodeId]));
}
}
}