forked from qt-creator/qt-creator
Clang: Improve project part updating
The project part ids are now already created very early in the database. This removes some checks because we can assume that an id already exists. The project part are now completely persistent, so we can read them from the database and compare them with new generated from a new creator session. This should help to not recreate the same PCH again and again. Task-number: QTCREATORBUG-21151 Change-Id: Iced818ff9f7431eaed3e37978087cc0a43b9afda Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -17,8 +17,6 @@ HEADERS += \
|
||||
$$PWD/usedmacro.h \
|
||||
$$PWD/sourcedependency.h \
|
||||
$$PWD/filestatus.h \
|
||||
$$PWD/projectpartartefactexception.h \
|
||||
$$PWD/projectpartartefact.h \
|
||||
$$PWD/filestatuscache.h \
|
||||
$$PWD/indexdataconsumer.h \
|
||||
$$PWD/sourcesmanager.h \
|
||||
@@ -68,5 +66,4 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
$$PWD/sourcerangefilter.cpp \
|
||||
$$PWD/symbolindexer.cpp \
|
||||
$$PWD/projectpartartefact.cpp \
|
||||
$$PWD/filestatuscache.cpp
|
||||
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
if (usr) {
|
||||
m_symbolEntries.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(globalId),
|
||||
std::forward_as_tuple(std::move(usr.value()),
|
||||
std::forward_as_tuple(std::move(*usr),
|
||||
macroName,
|
||||
SymbolKind::Macro));
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ bool IndexDataConsumer::handleDeclOccurence(
|
||||
auto kindAndTags = symbolKindAndTags(declaration);
|
||||
m_symbolEntries.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(globalId),
|
||||
std::forward_as_tuple(std::move(usr.value()),
|
||||
std::forward_as_tuple(std::move(*usr),
|
||||
symbolName(namedDeclaration),
|
||||
kindAndTags.first,
|
||||
kindAndTags.second));
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "projectpartartefact.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
|
||||
|
||||
Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringView jsonText)
|
||||
{
|
||||
if (jsonText.isEmpty())
|
||||
return {};
|
||||
|
||||
QJsonDocument document = createJsonDocument(jsonText, "Compiler arguments parsing error");
|
||||
|
||||
return Utils::transform<Utils::SmallStringVector>(document.array(), [] (const QJsonValue &value) {
|
||||
return Utils::SmallString{value.toString()};
|
||||
});
|
||||
}
|
||||
|
||||
CompilerMacros ProjectPartArtefact::createCompilerMacrosFromDocument(const QJsonDocument &document)
|
||||
{
|
||||
QJsonArray array = document.array();
|
||||
CompilerMacros macros;
|
||||
macros.reserve(array.size());
|
||||
|
||||
for (const QJsonValueRef entry : array) {
|
||||
const QJsonArray entryArray = entry.toArray();
|
||||
macros.emplace_back(
|
||||
entryArray[0].toString(), entryArray[1].toString(), entryArray[2].toInt());
|
||||
}
|
||||
|
||||
std::sort(macros.begin(), macros.end());
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
IncludeSearchPaths ProjectPartArtefact::createIncludeSearchPathsFromDocument(const QJsonDocument &document)
|
||||
{
|
||||
QJsonArray array = document.array();
|
||||
IncludeSearchPaths paths;
|
||||
paths.reserve(array.size());
|
||||
|
||||
for (const QJsonValueRef entry : array) {
|
||||
const QJsonArray entryArray = entry.toArray();
|
||||
paths.emplace_back(entryArray[0].toString(), entryArray[1].toInt(), entryArray[2].toInt());
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
CompilerMacros ProjectPartArtefact::toCompilerMacros(Utils::SmallStringView jsonText)
|
||||
{
|
||||
if (jsonText.isEmpty())
|
||||
return {};
|
||||
|
||||
QJsonDocument document = createJsonDocument(jsonText, "Compiler macros parsing error");
|
||||
|
||||
return createCompilerMacrosFromDocument(document);
|
||||
}
|
||||
|
||||
QJsonDocument ProjectPartArtefact::createJsonDocument(Utils::SmallStringView jsonText,
|
||||
const char *whatError)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument document = QJsonDocument::fromJson(QByteArray::fromRawData(jsonText.data(),
|
||||
jsonText.size()),
|
||||
&error);
|
||||
checkError(whatError, error);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
IncludeSearchPaths ProjectPartArtefact::toIncludeSearchPaths(Utils::SmallStringView jsonText)
|
||||
{
|
||||
|
||||
if (jsonText.isEmpty())
|
||||
return {};
|
||||
|
||||
QJsonDocument document = createJsonDocument(jsonText, "Include search paths parsing error");
|
||||
|
||||
return createIncludeSearchPathsFromDocument(document);
|
||||
}
|
||||
|
||||
void ProjectPartArtefact::checkError(const char *whatError, const QJsonParseError &error)
|
||||
{
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
throw ProjectPartArtefactParseError(whatError,
|
||||
error.errorString());
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second)
|
||||
{
|
||||
return first.toolChainArguments == second.toolChainArguments
|
||||
&& first.compilerMacros == second.compilerMacros
|
||||
&& first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
|
||||
&& first.projectIncludeSearchPaths == second.projectIncludeSearchPaths;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -1,101 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "projectpartartefactexception.h"
|
||||
|
||||
#include <utils/cpplanguage_details.h>
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
#include <compilermacro.h>
|
||||
#include <includesearchpath.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QJsonDocument)
|
||||
QT_FORWARD_DECLARE_STRUCT(QJsonParseError)
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ProjectPartArtefact
|
||||
{
|
||||
public:
|
||||
ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
|
||||
Utils::SmallStringView compilerMacrosText,
|
||||
Utils::SmallStringView systemIncludeSearchPathsText,
|
||||
Utils::SmallStringView projectIncludeSearchPathsText,
|
||||
int projectPartId,
|
||||
int language,
|
||||
int languageVersion,
|
||||
int languageExtension)
|
||||
: toolChainArguments(toStringVector(compilerArgumentsText))
|
||||
, compilerMacros(toCompilerMacros(compilerMacrosText))
|
||||
, systemIncludeSearchPaths(toIncludeSearchPaths(systemIncludeSearchPathsText))
|
||||
, projectIncludeSearchPaths(toIncludeSearchPaths(projectIncludeSearchPathsText))
|
||||
, projectPartId(projectPartId)
|
||||
, language(static_cast<Utils::Language>(language))
|
||||
, languageVersion(static_cast<Utils::LanguageVersion>(languageVersion))
|
||||
, languageExtension(static_cast<Utils::LanguageExtension>(languageExtension))
|
||||
{}
|
||||
|
||||
ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
|
||||
Utils::SmallStringView compilerMacrosText,
|
||||
Utils::SmallStringView systemIncludeSearchPathsText,
|
||||
Utils::SmallStringView projectIncludeSearchPathsText,
|
||||
int projectPartId,
|
||||
Utils::Language language,
|
||||
Utils::LanguageVersion languageVersion,
|
||||
Utils::LanguageExtension languageExtension)
|
||||
: toolChainArguments(toStringVector(compilerArgumentsText))
|
||||
, compilerMacros(toCompilerMacros(compilerMacrosText))
|
||||
, systemIncludeSearchPaths(toIncludeSearchPaths(systemIncludeSearchPathsText))
|
||||
, projectIncludeSearchPaths(toIncludeSearchPaths(projectIncludeSearchPathsText))
|
||||
, projectPartId(projectPartId)
|
||||
, language(language)
|
||||
, languageVersion(languageVersion)
|
||||
, languageExtension(languageExtension)
|
||||
{}
|
||||
|
||||
static Utils::SmallStringVector toStringVector(Utils::SmallStringView jsonText);
|
||||
static CompilerMacros createCompilerMacrosFromDocument(const QJsonDocument &document);
|
||||
static IncludeSearchPaths createIncludeSearchPathsFromDocument(const QJsonDocument &document);
|
||||
static CompilerMacros toCompilerMacros(Utils::SmallStringView jsonText);
|
||||
static QJsonDocument createJsonDocument(Utils::SmallStringView jsonText, const char *whatError);
|
||||
static IncludeSearchPaths toIncludeSearchPaths(Utils::SmallStringView jsonText);
|
||||
static void checkError(const char *whatError, const QJsonParseError &error);
|
||||
friend bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second);
|
||||
|
||||
public:
|
||||
Utils::SmallStringVector toolChainArguments;
|
||||
CompilerMacros compilerMacros;
|
||||
IncludeSearchPaths systemIncludeSearchPaths;
|
||||
IncludeSearchPaths projectIncludeSearchPaths;
|
||||
int projectPartId = -1;
|
||||
Utils::Language language = Utils::Language::Cxx;
|
||||
Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
|
||||
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
|
||||
};
|
||||
|
||||
using ProjectPartArtefacts = std::vector<ProjectPartArtefact>;
|
||||
} // namespace ClangBackEnd
|
||||
@@ -1,40 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <sqliteexception.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ProjectPartArtefactParseError : public Sqlite::Exception
|
||||
{
|
||||
public:
|
||||
ProjectPartArtefactParseError(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&errorMessage)
|
||||
: Exception(whatErrorHasHappen, std::move(errorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -65,7 +65,8 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
|
||||
ClangPathWatcherInterface &pathWatcher,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
FileStatusCache &fileStatusCache,
|
||||
Sqlite::TransactionInterface &transactionInterface)
|
||||
Sqlite::TransactionInterface &transactionInterface,
|
||||
ProjectPartsStorageInterface &projectPartsStorage)
|
||||
: m_symbolIndexerTaskQueue(symbolIndexerTaskQueue)
|
||||
, m_symbolStorage(symbolStorage)
|
||||
, m_buildDependencyStorage(buildDependenciesStorage)
|
||||
@@ -74,6 +75,7 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
|
||||
, m_filePathCache(filePathCache)
|
||||
, m_fileStatusCache(fileStatusCache)
|
||||
, m_transactionInterface(transactionInterface)
|
||||
, m_projectPartsStorage(projectPartsStorage)
|
||||
{
|
||||
pathWatcher.setNotifier(this);
|
||||
}
|
||||
@@ -86,26 +88,13 @@ void SymbolIndexer::updateProjectParts(ProjectPartContainers &&projectParts)
|
||||
|
||||
void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
||||
{
|
||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||
const auto optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(projectPart.projectPartId);
|
||||
int projectPartId = m_symbolStorage.insertOrUpdateProjectPart(
|
||||
projectPart.projectPartId,
|
||||
projectPart.toolChainArguments,
|
||||
projectPart.compilerMacros,
|
||||
projectPart.systemIncludeSearchPaths,
|
||||
projectPart.projectIncludeSearchPaths,
|
||||
projectPart.language,
|
||||
projectPart.languageVersion,
|
||||
projectPart.languageExtension);
|
||||
if (optionalArtefact)
|
||||
projectPartId = optionalArtefact->projectPartId;
|
||||
Sqlite::DeferredTransaction transaction{m_transactionInterface};
|
||||
|
||||
ProjectPartId projectPartId = projectPart.projectPartId;
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch
|
||||
= m_precompiledHeaderStorage.fetchPrecompiledHeader(projectPartId);
|
||||
|
||||
FilePathIds sourcePathIds = updatableFilePathIds(projectPart, optionalArtefact);
|
||||
transaction.commit();
|
||||
if (sourcePathIds.empty())
|
||||
return;
|
||||
|
||||
using Builder = CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector>;
|
||||
Builder commandLineBuilder{projectPart,
|
||||
@@ -113,9 +102,8 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
||||
InputFileType::Source,
|
||||
{},
|
||||
{},
|
||||
optionalProjectPartPch
|
||||
? FilePathView{optionalProjectPartPch.value().pchPath}
|
||||
: FilePathView{}};
|
||||
optionalProjectPartPch ? FilePathView{optionalProjectPartPch->pchPath}
|
||||
: FilePathView{}};
|
||||
|
||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
||||
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
||||
@@ -132,14 +120,6 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
||||
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
|
||||
m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
|
||||
m_buildDependencyStorage.insertOrUpdateFileStatuses(symbolsCollector.fileStatuses());
|
||||
|
||||
m_buildDependencyStorage.insertOrUpdateSourceDependencies(
|
||||
symbolsCollector.sourceDependencies());
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
};
|
||||
@@ -151,9 +131,7 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
||||
m_symbolIndexerTaskQueue.processEntries();
|
||||
}
|
||||
|
||||
void SymbolIndexer::pathsWithIdsChanged(const Utils::SmallStringVector &)
|
||||
{
|
||||
}
|
||||
void SymbolIndexer::pathsWithIdsChanged(const ProjectPartIds &) {}
|
||||
|
||||
void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds)
|
||||
{
|
||||
@@ -173,8 +151,8 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
m_fileStatusCache.update(filePathId);
|
||||
|
||||
Sqlite::DeferredTransaction transaction{m_transactionInterface};
|
||||
const Utils::optional<ProjectPartArtefact> optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(
|
||||
filePathId);
|
||||
const Utils::optional<ProjectPartArtefact>
|
||||
optionalArtefact = m_projectPartsStorage.fetchProjectPartArtefact(filePathId);
|
||||
if (!optionalArtefact)
|
||||
return;
|
||||
|
||||
@@ -182,9 +160,9 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
= m_precompiledHeaderStorage.fetchPrecompiledHeader(optionalArtefact->projectPartId);
|
||||
transaction.commit();
|
||||
|
||||
const ProjectPartArtefact &artefact = optionalArtefact.value();
|
||||
const ProjectPartArtefact &artefact = *optionalArtefact;
|
||||
|
||||
auto pchPath = optionalProjectPartPch ? optionalProjectPartPch.value().pchPath : FilePath{};
|
||||
auto pchPath = optionalProjectPartPch ? optionalProjectPartPch->pchPath : FilePath{};
|
||||
|
||||
CommandLineBuilder<ProjectPartArtefact, Utils::SmallStringVector>
|
||||
builder{artefact, artefact.toolChainArguments, InputFileType::Source, {}, {}, pchPath};
|
||||
@@ -201,13 +179,6 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
|
||||
m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
|
||||
m_buildDependencyStorage.insertOrUpdateFileStatuses(symbolsCollector.fileStatuses());
|
||||
|
||||
m_buildDependencyStorage.insertOrUpdateSourceDependencies(
|
||||
symbolsCollector.sourceDependencies());
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
#include "builddependenciesstorageinterface.h"
|
||||
#include "clangpathwatcher.h"
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
#include <precompiledheaderstorageinterface.h>
|
||||
#include <projectpartcontainer.h>
|
||||
#include <filecontainerv2.h>
|
||||
#include <projectpartsstorageinterface.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -49,12 +50,13 @@ public:
|
||||
ClangPathWatcherInterface &pathWatcher,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
FileStatusCache &fileStatusCache,
|
||||
Sqlite::TransactionInterface &transactionInterface);
|
||||
Sqlite::TransactionInterface &transactionInterface,
|
||||
ProjectPartsStorageInterface &projectPartsStorage);
|
||||
|
||||
void updateProjectParts(ProjectPartContainers &&projectParts);
|
||||
void updateProjectPart(ProjectPartContainer &&projectPart);
|
||||
|
||||
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
|
||||
void pathsWithIdsChanged(const ProjectPartIds &ids) override;
|
||||
void pathsChanged(const FilePathIds &filePathIds) override;
|
||||
void updateChangedPath(FilePathId filePath,
|
||||
std::vector<SymbolIndexerTask> &symbolIndexerTask);
|
||||
@@ -78,6 +80,7 @@ private:
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
FileStatusCache &m_fileStatusCache;
|
||||
Sqlite::TransactionInterface &m_transactionInterface;
|
||||
ProjectPartsStorageInterface &m_projectPartsStorage;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <filepathid.h>
|
||||
#include <projectpartid.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
@@ -43,12 +44,10 @@ class SymbolIndexerTask
|
||||
public:
|
||||
using Callable = std::function<void(SymbolsCollectorInterface &symbolsCollector)>;
|
||||
|
||||
SymbolIndexerTask(FilePathId filePathId,
|
||||
int projectPartId,
|
||||
Callable &&callable)
|
||||
: callable(std::move(callable)),
|
||||
filePathId(filePathId),
|
||||
projectPartId(projectPartId)
|
||||
SymbolIndexerTask(FilePathId filePathId, ProjectPartId projectPartId, Callable &&callable)
|
||||
: callable(std::move(callable))
|
||||
, filePathId(filePathId)
|
||||
, projectPartId(projectPartId)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -78,7 +77,7 @@ public:
|
||||
public:
|
||||
Callable callable;
|
||||
FilePathId filePathId;
|
||||
int projectPartId;
|
||||
ProjectPartId projectPartId;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <builddependenciesstorage.h>
|
||||
#include <precompiledheaderstorage.h>
|
||||
#include <projectpartsstorage.h>
|
||||
|
||||
#include <refactoringdatabaseinitializer.h>
|
||||
#include <filepathcachingfwd.h>
|
||||
@@ -84,7 +85,8 @@ public:
|
||||
ProgressCounter::SetProgressCallback &&setProgressCallback)
|
||||
: m_filePathCache(filePathCache)
|
||||
, m_buildDependencyStorage(database)
|
||||
, m_recompiledHeaderStorage(database)
|
||||
, m_precompiledHeaderStorage(database)
|
||||
, m_projectPartsStorage(database)
|
||||
, m_symbolStorage(database)
|
||||
, m_collectorManger(generatedFiles, database)
|
||||
, m_progressCounter(std::move(setProgressCallback))
|
||||
@@ -121,7 +123,8 @@ private:
|
||||
using SymbolIndexerTaskScheduler = TaskScheduler<SymbolsCollectorManager, SymbolIndexerTask::Callable>;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
BuildDependenciesStorage m_buildDependencyStorage;
|
||||
PrecompiledHeaderStorage<Sqlite::Database> m_recompiledHeaderStorage;
|
||||
PrecompiledHeaderStorage<Sqlite::Database> m_precompiledHeaderStorage;
|
||||
ProjectPartsStorage<Sqlite::Database> m_projectPartsStorage;
|
||||
SymbolStorage m_symbolStorage;
|
||||
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
|
||||
FileStatusCache m_fileStatusCache{m_filePathCache};
|
||||
@@ -130,11 +133,12 @@ private:
|
||||
SymbolIndexer m_indexer{m_indexerQueue,
|
||||
m_symbolStorage,
|
||||
m_buildDependencyStorage,
|
||||
m_recompiledHeaderStorage,
|
||||
m_precompiledHeaderStorage,
|
||||
m_sourceWatcher,
|
||||
m_filePathCache,
|
||||
m_fileStatusCache,
|
||||
m_symbolStorage.m_database};
|
||||
m_symbolStorage.database,
|
||||
m_projectPartsStorage};
|
||||
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter};
|
||||
SymbolIndexerTaskScheduler m_indexerScheduler;
|
||||
};
|
||||
|
||||
@@ -50,10 +50,10 @@ class SymbolStorage final : public SymbolStorageInterface
|
||||
|
||||
public:
|
||||
SymbolStorage(Database &database)
|
||||
: m_transaction(database),
|
||||
m_database(database)
|
||||
: transaction(database)
|
||||
, database(database)
|
||||
{
|
||||
m_transaction.commit();
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||
@@ -70,91 +70,9 @@ public:
|
||||
deleteNewLocationsTable();
|
||||
}
|
||||
|
||||
int insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &toolChainArguments,
|
||||
const CompilerMacros &compilerMacros,
|
||||
const IncludeSearchPaths &systemIncludeSearchPaths,
|
||||
const IncludeSearchPaths &projectIncludeSearchPaths,
|
||||
Utils::Language language,
|
||||
Utils::LanguageVersion languageVersion,
|
||||
Utils::LanguageExtension languageExtension) override
|
||||
{
|
||||
Utils::SmallString toolChainArgumentsAsJson = toJson(toolChainArguments);
|
||||
Utils::SmallString compilerMacrosAsJson = toJson(compilerMacros);
|
||||
Utils::SmallString systemIncludeSearchPathsAsJason = toJson(systemIncludeSearchPaths);
|
||||
Utils::SmallString projectIncludeSearchPathsAsJason = toJson(projectIncludeSearchPaths);
|
||||
|
||||
m_insertOrUpdateProjectPartStatement.write(projectPartName,
|
||||
toolChainArgumentsAsJson,
|
||||
compilerMacrosAsJson,
|
||||
systemIncludeSearchPathsAsJason,
|
||||
projectIncludeSearchPathsAsJason,
|
||||
static_cast<int>(language),
|
||||
static_cast<int>(languageVersion),
|
||||
static_cast<int>(languageExtension));
|
||||
|
||||
auto projectPartId = m_getProjectPartIdStatement.template value<int>(projectPartName);
|
||||
|
||||
return projectPartId.value();
|
||||
}
|
||||
|
||||
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const override
|
||||
{
|
||||
ReadStatement &statement = m_getProjectPartArtefactsBySourceId;
|
||||
|
||||
return statement.template value<ProjectPartArtefact, 8>(sourceId.filePathId);
|
||||
}
|
||||
|
||||
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const override
|
||||
{
|
||||
ReadStatement &statement = m_getProjectPartArtefactsByProjectPartName;
|
||||
|
||||
return statement.template value<ProjectPartArtefact, 8>(projectPartName);
|
||||
}
|
||||
|
||||
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
|
||||
{
|
||||
QJsonDocument document;
|
||||
QJsonArray array;
|
||||
|
||||
std::transform(strings.begin(), strings.end(), std::back_inserter(array), [] (const auto &string) {
|
||||
return QJsonValue(string.data());
|
||||
});
|
||||
|
||||
document.setArray(array);
|
||||
|
||||
return document.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
static Utils::SmallString toJson(const CompilerMacros &compilerMacros)
|
||||
{
|
||||
QJsonDocument document;
|
||||
QJsonArray array;
|
||||
|
||||
for (const CompilerMacro ¯o : compilerMacros)
|
||||
array.push_back(QJsonArray{{QString(macro.key), QString(macro.value), macro.index}});
|
||||
|
||||
document.setArray(array);
|
||||
|
||||
return document.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
static Utils::SmallString toJson(const IncludeSearchPaths &includeSearchPaths)
|
||||
{
|
||||
QJsonDocument document;
|
||||
QJsonArray array;
|
||||
|
||||
for (const IncludeSearchPath &path : includeSearchPaths)
|
||||
array.push_back(QJsonArray{{path.path.data(), path.index, int(path.type)}});
|
||||
|
||||
document.setArray(array);
|
||||
|
||||
return document.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries)
|
||||
{
|
||||
WriteStatement &statement = m_insertSymbolsToNewSymbolsStatement;
|
||||
WriteStatement &statement = insertSymbolsToNewSymbolsStatement;
|
||||
|
||||
for (const auto &symbolEntry : symbolEntries) {
|
||||
statement.write(symbolEntry.first,
|
||||
@@ -166,7 +84,7 @@ public:
|
||||
|
||||
void fillTemporaryLocationsTable(const SourceLocationEntries &sourceLocations)
|
||||
{
|
||||
WriteStatement &statement = m_insertLocationsToNewLocationsStatement;
|
||||
WriteStatement &statement = insertLocationsToNewLocationsStatement;
|
||||
|
||||
for (const auto &locationEntry : sourceLocations) {
|
||||
statement.write(locationEntry.symbolId,
|
||||
@@ -177,40 +95,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void addNewSymbolsToSymbols()
|
||||
{
|
||||
m_addNewSymbolsToSymbolsStatement.execute();
|
||||
}
|
||||
void addNewSymbolsToSymbols() { addNewSymbolsToSymbolsStatement.execute(); }
|
||||
|
||||
void syncNewSymbolsFromSymbols()
|
||||
{
|
||||
m_syncNewSymbolsFromSymbolsStatement.execute();
|
||||
}
|
||||
void syncNewSymbolsFromSymbols() { syncNewSymbolsFromSymbolsStatement.execute(); }
|
||||
|
||||
void syncSymbolsIntoNewLocations()
|
||||
{
|
||||
m_syncSymbolsIntoNewLocationsStatement.execute();
|
||||
}
|
||||
void syncSymbolsIntoNewLocations() { syncSymbolsIntoNewLocationsStatement.execute(); }
|
||||
|
||||
void deleteAllLocationsFromUpdatedFiles()
|
||||
{
|
||||
m_deleteAllLocationsFromUpdatedFilesStatement.execute();
|
||||
deleteAllLocationsFromUpdatedFilesStatement.execute();
|
||||
}
|
||||
|
||||
void insertNewLocationsInLocations()
|
||||
{
|
||||
m_insertNewLocationsInLocationsStatement.execute();
|
||||
}
|
||||
void insertNewLocationsInLocations() { insertNewLocationsInLocationsStatement.execute(); }
|
||||
|
||||
void deleteNewSymbolsTable()
|
||||
{
|
||||
m_deleteNewSymbolsTableStatement.execute();
|
||||
}
|
||||
void deleteNewSymbolsTable() { deleteNewSymbolsTableStatement.execute(); }
|
||||
|
||||
void deleteNewLocationsTable()
|
||||
{
|
||||
m_deleteNewLocationsTableStatement.execute();
|
||||
}
|
||||
void deleteNewLocationsTable() { deleteNewLocationsTableStatement.execute(); }
|
||||
|
||||
SourceLocationEntries sourceLocations() const
|
||||
{
|
||||
@@ -230,7 +130,7 @@ public:
|
||||
table.addIndex({usrColumn, symbolNameColumn});
|
||||
table.addIndex({symbolIdColumn});
|
||||
|
||||
table.initialize(m_database);
|
||||
table.initialize(database);
|
||||
|
||||
return table;
|
||||
}
|
||||
@@ -248,85 +148,49 @@ public:
|
||||
table.addColumn("locationKind", Sqlite::ColumnType::Integer);
|
||||
table.addUniqueIndex({sourceIdColumn, lineColumn, columnColumn});
|
||||
|
||||
table.initialize(m_database);
|
||||
table.initialize(database);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
public:
|
||||
Sqlite::ImmediateNonThrowingDestructorTransaction m_transaction;
|
||||
Database &m_database;
|
||||
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
|
||||
Database &database;
|
||||
Sqlite::Table newSymbolsTablet{createNewSymbolsTable()};
|
||||
Sqlite::Table newLocationsTable{createNewLocationsTable()};
|
||||
WriteStatement m_insertSymbolsToNewSymbolsStatement{
|
||||
WriteStatement insertSymbolsToNewSymbolsStatement{
|
||||
"INSERT INTO newSymbols(temporarySymbolId, usr, symbolName, symbolKind) VALUES(?,?,?,?)",
|
||||
m_database};
|
||||
WriteStatement m_insertLocationsToNewLocationsStatement{
|
||||
"INSERT OR IGNORE INTO newLocations(temporarySymbolId, line, column, sourceId, locationKind) VALUES(?,?,?,?,?)",
|
||||
m_database
|
||||
};
|
||||
ReadStatement m_selectNewSourceIdsStatement{
|
||||
"SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_addNewSymbolsToSymbolsStatement{
|
||||
database};
|
||||
WriteStatement insertLocationsToNewLocationsStatement{
|
||||
"INSERT OR IGNORE INTO newLocations(temporarySymbolId, line, column, sourceId, "
|
||||
"locationKind) VALUES(?,?,?,?,?)",
|
||||
database};
|
||||
ReadStatement selectNewSourceIdsStatement{
|
||||
"SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources "
|
||||
"WHERE newLocations.sourceId == sources.sourceId)",
|
||||
database};
|
||||
WriteStatement addNewSymbolsToSymbolsStatement{
|
||||
"INSERT INTO symbols(usr, symbolName, symbolKind) "
|
||||
"SELECT usr, symbolName, symbolKind FROM newSymbols WHERE NOT EXISTS "
|
||||
"(SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_syncNewSymbolsFromSymbolsStatement{
|
||||
"UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_syncSymbolsIntoNewLocationsStatement{
|
||||
"UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_deleteAllLocationsFromUpdatedFilesStatement{
|
||||
database};
|
||||
WriteStatement syncNewSymbolsFromSymbolsStatement{
|
||||
"UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = "
|
||||
"symbols.usr)",
|
||||
database};
|
||||
WriteStatement syncSymbolsIntoNewLocationsStatement{
|
||||
"UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE "
|
||||
"newSymbols.temporarySymbolId = newLocations.temporarySymbolId)",
|
||||
database};
|
||||
WriteStatement deleteAllLocationsFromUpdatedFilesStatement{
|
||||
"DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_insertNewLocationsInLocationsStatement{
|
||||
"INSERT INTO locations(symbolId, line, column, sourceId, locationKind) SELECT symbolId, line, column, sourceId, locationKind FROM newLocations",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_deleteNewSymbolsTableStatement{
|
||||
"DELETE FROM newSymbols",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_deleteNewLocationsTableStatement{
|
||||
"DELETE FROM newLocations",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_insertOrUpdateProjectPartStatement{
|
||||
"INSERT INTO projectParts(projectPartName, toolChainArguments, compilerMacros, "
|
||||
"systemIncludeSearchPaths, projectIncludeSearchPaths, language, languageVersion, "
|
||||
"languageExtension) VALUES (?001,?002,?003,?004,?005,?006,?007,?008) ON "
|
||||
"CONFLICT(projectPartName) DO UPDATE SET toolChainArguments=?002, compilerMacros=?003, "
|
||||
"systemIncludeSearchPaths=?004, projectIncludeSearchPaths=?005, language=?006, "
|
||||
"languageVersion=?007, languageExtension=?008",
|
||||
m_database};
|
||||
mutable ReadStatement m_getProjectPartIdStatement{
|
||||
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
|
||||
m_database
|
||||
};
|
||||
|
||||
mutable ReadStatement m_getCompileArgumentsForFileIdStatement{
|
||||
"SELECT toolChainArguments FROM projectParts WHERE projectPartId = (SELECT projectPartId "
|
||||
"FROM projectPartsSources WHERE sourceId = ?)",
|
||||
m_database};
|
||||
mutable ReadStatement m_getProjectPartArtefactsBySourceId{
|
||||
"SELECT toolChainArguments, compilerMacros, systemIncludeSearchPaths, "
|
||||
"projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension "
|
||||
"FROM projectParts WHERE projectPartId = (SELECT "
|
||||
"projectPartId FROM projectPartsSources WHERE sourceId = ?)",
|
||||
m_database};
|
||||
mutable ReadStatement m_getProjectPartArtefactsByProjectPartName{
|
||||
"SELECT toolChainArguments, compilerMacros, systemIncludeSearchPaths, "
|
||||
"projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension "
|
||||
"FROM projectParts WHERE projectPartName = ?",
|
||||
m_database};
|
||||
database};
|
||||
WriteStatement insertNewLocationsInLocationsStatement{
|
||||
"INSERT INTO locations(symbolId, line, column, sourceId, locationKind) SELECT symbolId, "
|
||||
"line, column, sourceId, locationKind FROM newLocations",
|
||||
database};
|
||||
WriteStatement deleteNewSymbolsTableStatement{"DELETE FROM newSymbols", database};
|
||||
WriteStatement deleteNewLocationsTableStatement{"DELETE FROM newLocations", database};
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -25,19 +25,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "filestatus.h"
|
||||
#include "projectpartentry.h"
|
||||
#include "projectpartartefact.h"
|
||||
#include "sourcelocationentry.h"
|
||||
#include "sourcedependency.h"
|
||||
#include "symbolentry.h"
|
||||
#include "usedmacro.h"
|
||||
|
||||
#include <includesearchpath.h>
|
||||
|
||||
#include <sqlitetransaction.h>
|
||||
|
||||
#include <compilermacro.h>
|
||||
#include <sqlitetransaction.h>
|
||||
|
||||
#include <utils/cpplanguage_details.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -51,20 +45,6 @@ public:
|
||||
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||
const SourceLocationEntries &sourceLocations)
|
||||
= 0;
|
||||
virtual int insertOrUpdateProjectPart(
|
||||
Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArguments,
|
||||
const CompilerMacros &compilerMacros,
|
||||
const ClangBackEnd::IncludeSearchPaths &systemIncludeSearchPaths,
|
||||
const ClangBackEnd::IncludeSearchPaths &projectIncludeSearchPaths,
|
||||
Utils::Language language,
|
||||
Utils::LanguageVersion languageVersion,
|
||||
Utils::LanguageExtension languageExtension)
|
||||
= 0;
|
||||
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
|
||||
FilePathId sourceId) const = 0;
|
||||
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
|
||||
Utils::SmallStringView projectPartName) const = 0;
|
||||
|
||||
protected:
|
||||
~SymbolStorageInterface() = default;
|
||||
|
||||
Reference in New Issue
Block a user