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:
Marco Bubke
2019-03-13 15:09:30 +01:00
parent 7249427749
commit 6effa1822b
111 changed files with 2657 additions and 1803 deletions

View File

@@ -31,6 +31,7 @@
#include "qtcreatorprojectupdater.h"
#include <filepathcaching.h>
#include <projectpartsstorage.h>
#include <refactoringdatabaseinitializer.h>
#include <sqlitedatabase.h>
@@ -79,11 +80,13 @@ public:
"Creating Dependencies");
Core::ProgressManager::addTask(promise.future(), title, "dependency creation", nullptr);
}};
ClangBackEnd::ProjectPartsStorage<Sqlite::Database> projectPartsStorage{database};
PchManagerClient pchManagerClient{pchCreationProgressManager, dependencyCreationProgressManager};
PchManagerConnectionClient connectionClient{&pchManagerClient};
QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(),
pchManagerClient,
filePathCache};
filePathCache,
projectPartsStorage};
};
std::unique_ptr<ClangPchManagerPluginData> ClangPchManagerPlugin::d;

View File

@@ -44,10 +44,9 @@ void PchManagerClient::alive()
void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message)
{
for (ClangBackEnd::ProjectPartPch &projectPartPch : message.takeProjectPartPchs()) {
const QString projectPartId{projectPartPch.projectPartId};
const QString pchPath{projectPartPch.pchPath};
addProjectPartPch(std::move(projectPartPch));
precompiledHeaderUpdated(projectPartId, pchPath, projectPartPch.lastModified);
precompiledHeaderUpdated(projectPartPch.projectPartId, pchPath, projectPartPch.lastModified);
}
}
@@ -65,11 +64,10 @@ void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message)
}
}
void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)
void PchManagerClient::precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId)
{
for (auto notifier : m_notifiers) {
Utils::SmallString id(projectPartId);
removeProjectPartPch(id);
removeProjectPartPch(projectPartId);
notifier->precompiledHeaderRemoved(projectPartId);
}
}
@@ -79,7 +77,8 @@ void PchManagerClient::setConnectionClient(PchManagerConnectionClient *connectio
m_connectionClient = connectionClient;
}
Utils::optional<ClangBackEnd::ProjectPartPch> PchManagerClient::projectPartPch(Utils::SmallStringView projectPartId) const
Utils::optional<ClangBackEnd::ProjectPartPch> PchManagerClient::projectPartPch(
ClangBackEnd::ProjectPartId projectPartId) const
{
auto found = std::lower_bound(m_projectPartPchs.cbegin(),
m_projectPartPchs.cend(),
@@ -110,7 +109,7 @@ void PchManagerClient::detach(PchManagerNotifierInterface *notifierToBeDeleted)
m_notifiers.erase(newEnd, m_notifiers.end());
}
void PchManagerClient::removeProjectPartPch(Utils::SmallStringView projectPartId)
void PchManagerClient::removeProjectPartPch(ClangBackEnd::ProjectPartId projectPartId)
{
auto found = std::lower_bound(m_projectPartPchs.begin(),
m_projectPartPchs.end(),
@@ -145,7 +144,7 @@ const std::vector<PchManagerNotifierInterface *> &PchManagerClient::notifiers()
return m_notifiers;
}
void PchManagerClient::precompiledHeaderUpdated(const QString &projectPartId,
void PchManagerClient::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified)
{

View File

@@ -52,21 +52,20 @@ public:
void precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) override;
void progress(ClangBackEnd::ProgressMessage &&message) override;
void precompiledHeaderRemoved(const QString &projectPartId);
void precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId);
void setConnectionClient(PchManagerConnectionClient *connectionClient);
Utils::optional<ClangBackEnd::ProjectPartPch> projectPartPch(
Utils::SmallStringView projectPartId) const override;
ClangBackEnd::ProjectPartId projectPartId) const override;
const ClangBackEnd::ProjectPartPchs &projectPartPchs() const override
{
return m_projectPartPchs;
}
unittest_public:
const std::vector<PchManagerNotifierInterface*> &notifiers() const;
void precompiledHeaderUpdated(const QString &projectPartId,
unittest_public : const std::vector<PchManagerNotifierInterface *> &notifiers() const;
void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified);
@@ -74,7 +73,7 @@ unittest_public:
void detach(PchManagerNotifierInterface *notifier);
void addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch);
void removeProjectPartPch(Utils::SmallStringView projectPartId);
void removeProjectPartPch(ClangBackEnd::ProjectPartId projectPartId);
private:
ClangBackEnd::ProjectPartPchs m_projectPartPchs;

View File

@@ -27,6 +27,8 @@
#include "clangpchmanager_global.h"
#include <projectpartid.h>
QT_FORWARD_DECLARE_CLASS(QString)
namespace ClangPchManager {
@@ -40,10 +42,11 @@ public:
PchManagerNotifierInterface(const PchManagerNotifierInterface &) = delete;
PchManagerNotifierInterface &operator=(const PchManagerNotifierInterface &) = delete;
virtual void precompiledHeaderUpdated(const QString &projectPartId,
virtual void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified) = 0;
virtual void precompiledHeaderRemoved(const QString &projectPartId) = 0;
long long lastModified)
= 0;
virtual void precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId) = 0;
PchManagerClient &m_pchManagerClient;

View File

@@ -29,20 +29,22 @@
namespace ClangPchManager {
PchManagerProjectUpdater::PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
PchManagerClient &client,
ClangBackEnd::FilePathCachingInterface &filePathCache)
: ProjectUpdater(server, filePathCache),
m_client(client)
{
}
void PchManagerProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
void PchManagerProjectUpdater::removeProjectParts(const ClangBackEnd::ProjectPartIds &projectPartIds)
{
ProjectUpdater::removeProjectParts(projectPartIds);
for (const QString &projectPartiId : projectPartIds)
m_client.precompiledHeaderRemoved(projectPartiId);
for (ClangBackEnd::ProjectPartId projectPartId : projectPartIds)
m_client.precompiledHeaderRemoved(projectPartId);
}
void PchManagerProjectUpdater::removeProjectParts(const QStringList &projectPartNames)
{
ClangBackEnd::ProjectPartIds projectPartIds = toProjectPartIds(projectPartNames);
ProjectUpdater::removeProjectParts(projectPartIds);
for (ClangBackEnd::ProjectPartId projectPartId : projectPartIds)
m_client.precompiledHeaderRemoved(projectPartId);
}
} // namespace ClangPchManager

View File

@@ -34,9 +34,14 @@ class PchManagerProjectUpdater : public ProjectUpdater
public:
PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
PchManagerClient &client,
ClangBackEnd::FilePathCachingInterface &filePathCache);
ClangBackEnd::FilePathCachingInterface &filePathCache,
ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
: ProjectUpdater(server, filePathCache, projectPartsStorage)
, m_client(client)
{}
void removeProjectParts(const QStringList &projectPartIds);
void removeProjectParts(const ClangBackEnd::ProjectPartIds &projectPartIds);
void removeProjectParts(const QStringList &projectPartNames);
private:
PchManagerClient &m_client;

View File

@@ -61,13 +61,6 @@ public:
ClangBackEnd::FilePathIds sources;
};
ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
ClangBackEnd::FilePathCachingInterface &filePathCache)
: m_server(server),
m_filePathCache(filePathCache)
{
}
void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
Utils::SmallStringVector &&toolChainArguments)
{
@@ -75,9 +68,9 @@ void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart
toProjectPartContainers(projectParts), std::move(toolChainArguments)});
}
void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
void ProjectUpdater::removeProjectParts(ClangBackEnd::ProjectPartIds projectPartIds)
{
Utils::SmallStringVector sortedIds(projectPartIds);
auto sortedIds{projectPartIds};
std::sort(sortedIds.begin(), sortedIds.end());
m_server.removeProjectParts(ClangBackEnd::RemoveProjectPartsMessage{std::move(sortedIds)});
@@ -278,7 +271,12 @@ ClangBackEnd::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
return ClangBackEnd::ProjectPartContainer(projectPart->id(),
const QByteArray projectPartName = projectPart->id().toUtf8();
ClangBackEnd::ProjectPartId projectPartId = m_projectPartsStorage.fetchProjectPartId(
projectPartName);
return ClangBackEnd::ProjectPartContainer(projectPartId,
Utils::SmallStringVector(arguments),
createCompilerMacros(projectPart->projectMacros),
std::move(includeSearchPaths.system),
@@ -296,9 +294,6 @@ ClangBackEnd::ProjectPartContainers ProjectUpdater::toProjectPartContainers(
{
using namespace std::placeholders;
std::vector<ClangBackEnd::ProjectPartContainer> projectPartContainers;
projectPartContainers.reserve(projectParts.size());
projectParts.erase(std::remove_if(projectParts.begin(),
projectParts.end(),
[](const CppTools::ProjectPart *projectPart) {
@@ -306,6 +301,9 @@ ClangBackEnd::ProjectPartContainers ProjectUpdater::toProjectPartContainers(
}),
projectParts.end());
std::vector<ClangBackEnd::ProjectPartContainer> projectPartContainers;
projectPartContainers.reserve(projectParts.size());
std::transform(projectParts.begin(),
projectParts.end(),
std::back_inserter(projectPartContainers),
@@ -336,4 +334,26 @@ ClangBackEnd::FilePaths ProjectUpdater::createExcludedPaths(
return excludedPaths;
}
QString ProjectUpdater::fetchProjectPartName(ClangBackEnd::ProjectPartId projectPartId) const
{
return m_projectPartsStorage.fetchProjectPartName(projectPartId).toQString();
}
ClangBackEnd::ProjectPartIds ProjectUpdater::toProjectPartIds(
const QStringList &projectPartNames) const
{
ClangBackEnd::ProjectPartIds projectPartIds;
projectPartIds.reserve(projectPartIds.size());
std::transform(projectPartNames.begin(),
projectPartNames.end(),
std::back_inserter(projectPartIds),
[&](const QString &projectPartName) {
return m_projectPartsStorage.fetchProjectPartId(
Utils::SmallString{projectPartName});
});
return projectPartIds;
}
} // namespace ClangPchManager

View File

@@ -33,6 +33,7 @@
#include <generatedfiles.h>
#include <includesearchpath.h>
#include <projectpartcontainer.h>
#include <projectpartsstorageinterface.h>
#include <projectexplorer/headerpath.h>
@@ -69,11 +70,16 @@ public:
};
ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
ClangBackEnd::FilePathCachingInterface &filePathCache);
ClangBackEnd::FilePathCachingInterface &filePathCache,
ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
: m_server(server)
, m_filePathCache(filePathCache)
, m_projectPartsStorage(projectPartsStorage)
{}
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
Utils::SmallStringVector &&toolChainArguments);
void removeProjectParts(const QStringList &projectPartIds);
void removeProjectParts(ClangBackEnd::ProjectPartIds projectPartIds);
void updateGeneratedFiles(ClangBackEnd::V2::FileContainers &&generatedFiles);
void removeGeneratedFiles(ClangBackEnd::FilePaths &&filePaths);
@@ -88,6 +94,7 @@ public:
CppTools::ProjectPart *projectPart) const;
ClangBackEnd::ProjectPartContainers toProjectPartContainers(
std::vector<CppTools::ProjectPart *> projectParts) const;
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
const CppTools::ProjectFile &projectFile) const;
static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
@@ -98,11 +105,16 @@ public:
static ClangBackEnd::FilePaths createExcludedPaths(
const ClangBackEnd::V2::FileContainers &generatedFiles);
QString fetchProjectPartName(ClangBackEnd::ProjectPartId projectPartId) const;
ClangBackEnd::ProjectPartIds toProjectPartIds(const QStringList &projectPartNames) const;
private:
ClangBackEnd::GeneratedFiles m_generatedFiles;
ClangBackEnd::FilePaths m_excludedPaths;
ClangBackEnd::ProjectManagementServerInterface &m_server;
ClangBackEnd::FilePathCachingInterface &m_filePathCache;
ClangBackEnd::ProjectPartsStorageInterface &m_projectPartsStorage;
};
} // namespace ClangPchManager

View File

@@ -55,11 +55,12 @@ class QtCreatorProjectUpdater : public ProjectUpdaterType,
public ProjectExplorer::ExtraCompilerFactoryObserver
{
public:
template <typename ClientType>
template<typename ClientType>
QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
ClientType &client,
ClangBackEnd::FilePathCachingInterface &filePathCache)
: ProjectUpdaterType(server, client, filePathCache)
ClangBackEnd::FilePathCachingInterface &filePathCache,
ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
: ProjectUpdaterType(server, client, filePathCache, projectPartsStorage)
{
connectToCppModelManager();
}
@@ -78,7 +79,7 @@ public:
}
void projectPartsRemoved(const QStringList &projectPartIds)
{
{
ProjectUpdaterType::removeProjectParts(projectPartIds);
}