Clang: Improve updating

If project parts are up to date we send them directly to the indexer, so
the indexer can decide we something needs an update.

Change-Id: I7d4f32794c6b3a861cdefb3653a6dfd4e711f619
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2019-05-22 12:26:58 +02:00
parent 912cb9278f
commit b213dee013
27 changed files with 154 additions and 283 deletions

View File

@@ -204,7 +204,6 @@ HEADERS += \
$$PWD/nativefilepath.h \
$$PWD/filepathview.h \
$$PWD/compilermacro.h \
$$PWD/projectpartpchproviderinterface.h \
$$PWD/updategeneratedfilesmessage.h \
$$PWD/removegeneratedfilesmessage.h \
$$PWD/generatedfiles.h \

View File

@@ -25,7 +25,10 @@
#pragma once
#include "projectpartpch.h"
#include "clangsupport_global.h"
#include "projectpartid.h"
#include <utils/smallstringio.h>
namespace ClangBackEnd {
@@ -33,29 +36,26 @@ class PrecompiledHeadersUpdatedMessage
{
public:
PrecompiledHeadersUpdatedMessage() = default;
PrecompiledHeadersUpdatedMessage(ProjectPartPch projectPartPch)
PrecompiledHeadersUpdatedMessage(ProjectPartId projectPartId)
{
projectPartPchs.push_back(projectPartPch);
projectPartIds.push_back(projectPartId);
}
PrecompiledHeadersUpdatedMessage(ProjectPartPchs &&projectPartPchs)
: projectPartPchs(std::move(projectPartPchs))
PrecompiledHeadersUpdatedMessage(ProjectPartIds &&projectPartIds)
: projectPartIds(std::move(projectPartIds))
{}
ProjectPartPchs takeProjectPartPchs() const
{
return std::move(projectPartPchs);
}
ProjectPartIds takeProjectPartIds() const { return std::move(projectPartIds); }
friend QDataStream &operator<<(QDataStream &out, const PrecompiledHeadersUpdatedMessage &message)
{
out << message.projectPartPchs;
out << message.projectPartIds;
return out;
}
friend QDataStream &operator>>(QDataStream &in, PrecompiledHeadersUpdatedMessage &message)
{
in >> message.projectPartPchs;
in >> message.projectPartIds;
return in;
}
@@ -63,16 +63,13 @@ public:
friend bool operator==(const PrecompiledHeadersUpdatedMessage &first,
const PrecompiledHeadersUpdatedMessage &second)
{
return first.projectPartPchs == second.projectPartPchs;
return first.projectPartIds == second.projectPartIds;
}
PrecompiledHeadersUpdatedMessage clone() const
{
return PrecompiledHeadersUpdatedMessage(Utils::clone(projectPartPchs));
}
PrecompiledHeadersUpdatedMessage clone() const { return *this; }
public:
ProjectPartPchs projectPartPchs;
ProjectPartIds projectPartIds;
};
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const PrecompiledHeadersUpdatedMessage &message);

View File

@@ -54,7 +54,7 @@ public:
return first.projectPathId < second.projectPathId;
}
friend QDataStream &operator<<(QDataStream &out, const ProjectPartId &projectPathId)
friend QDataStream &operator<<(QDataStream &out, ProjectPartId projectPathId)
{
out << projectPathId.projectPathId;

View File

@@ -29,8 +29,7 @@ namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const ProjectPartPch &projectPartPch)
{
debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ", "
<< projectPartPch.pchPath << ")";
debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ")";
return debug;
}

View File

@@ -74,8 +74,7 @@ public:
friend bool operator==(const ProjectPartPch &first,
const ProjectPartPch &second)
{
return first.projectPartId == second.projectPartId
&& first.pchPath == second.pchPath;
return first.projectPartId == second.projectPartId && first.pchPath == second.pchPath;
}
ProjectPartPch clone() const

View File

@@ -1,50 +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 "projectpartpch.h"
#include <utils/optional.h>
namespace ClangBackEnd {
class ProjectPartPchProviderInterface
{
public:
ProjectPartPchProviderInterface() = default;
ProjectPartPchProviderInterface(const ProjectPartPchProviderInterface &) = delete;
ProjectPartPchProviderInterface &operator=(const ProjectPartPchProviderInterface &) = delete;
virtual Utils::optional<ClangBackEnd::ProjectPartPch> projectPartPch(
ClangBackEnd::ProjectPartId projectPartId) const = 0;
virtual const ClangBackEnd::ProjectPartPchs &projectPartPchs() const = 0;
protected:
~ProjectPartPchProviderInterface() = default;
};
} // namespace ClangBackEnd

View File

@@ -43,11 +43,8 @@ void PchManagerClient::alive()
void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message)
{
for (ClangBackEnd::ProjectPartPch &projectPartPch : message.takeProjectPartPchs()) {
const QString pchPath{projectPartPch.pchPath};
addProjectPartPch(std::move(projectPartPch));
precompiledHeaderUpdated(projectPartPch.projectPartId, pchPath, projectPartPch.lastModified);
}
for (ClangBackEnd::ProjectPartId &projectPartId : message.takeProjectPartIds())
precompiledHeaderUpdated(projectPartId);
}
void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message)
@@ -66,10 +63,8 @@ void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message)
void PchManagerClient::precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId)
{
for (auto notifier : m_notifiers) {
removeProjectPartPch(projectPartId);
for (auto notifier : m_notifiers)
notifier->precompiledHeaderRemoved(projectPartId);
}
}
void PchManagerClient::setConnectionClient(PchManagerConnectionClient *connectionClient)
@@ -77,22 +72,6 @@ void PchManagerClient::setConnectionClient(PchManagerConnectionClient *connectio
m_connectionClient = connectionClient;
}
Utils::optional<ClangBackEnd::ProjectPartPch> PchManagerClient::projectPartPch(
ClangBackEnd::ProjectPartId projectPartId) const
{
auto found = std::lower_bound(m_projectPartPchs.cbegin(),
m_projectPartPchs.cend(),
projectPartId,
[] (const auto &projectPartPch, auto projectPartId) {
return projectPartId < projectPartPch.projectPartId;
});
if (found != m_projectPartPchs.end() && found->projectPartId == projectPartId)
return *found;
return Utils::nullopt;
}
void PchManagerClient::attach(PchManagerNotifierInterface *notifier)
{
m_notifiers.push_back(notifier);
@@ -109,47 +88,15 @@ void PchManagerClient::detach(PchManagerNotifierInterface *notifierToBeDeleted)
m_notifiers.erase(newEnd, m_notifiers.end());
}
void PchManagerClient::removeProjectPartPch(ClangBackEnd::ProjectPartId projectPartId)
{
auto found = std::lower_bound(m_projectPartPchs.begin(),
m_projectPartPchs.end(),
projectPartId,
[] (const auto &projectPartPch, auto projectPartId) {
return projectPartId < projectPartPch.projectPartId;
});
if (found != m_projectPartPchs.end() && found->projectPartId == projectPartId) {
*found = std::move(m_projectPartPchs.back());
m_projectPartPchs.pop_back();
}
}
void PchManagerClient::addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch)
{
auto found = std::lower_bound(m_projectPartPchs.begin(),
m_projectPartPchs.end(),
projectPartPch.projectPartId,
[] (const auto &projectPartPch, auto projectPartId) {
return projectPartId < projectPartPch.projectPartId;
});
if (found != m_projectPartPchs.end() && found->projectPartId == projectPartPch.projectPartId)
*found = std::move(projectPartPch);
else
m_projectPartPchs.insert(found, std::move(projectPartPch));
}
const std::vector<PchManagerNotifierInterface *> &PchManagerClient::notifiers() const
{
return m_notifiers;
}
void PchManagerClient::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified)
void PchManagerClient::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId)
{
for (auto notifier : m_notifiers)
notifier->precompiledHeaderUpdated(projectPartId, pchFilePath, lastModified);
notifier->precompiledHeaderUpdated(projectPartId);
}
} // namespace ClangPchManager

View File

@@ -28,7 +28,7 @@
#include "clangpchmanager_global.h"
#include <pchmanagerclientinterface.h>
#include <projectpartpchproviderinterface.h>
#include <projectpartid.h>
#include <vector>
@@ -37,8 +37,7 @@ class PchManagerConnectionClient;
class ProgressManagerInterface;
class PchManagerNotifierInterface;
class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchManagerClientInterface,
public ClangBackEnd::ProjectPartPchProviderInterface
class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchManagerClientInterface
{
friend class PchManagerNotifierInterface;
public:
@@ -56,27 +55,13 @@ public:
void setConnectionClient(PchManagerConnectionClient *connectionClient);
Utils::optional<ClangBackEnd::ProjectPartPch> projectPartPch(
ClangBackEnd::ProjectPartId projectPartId) const override;
const ClangBackEnd::ProjectPartPchs &projectPartPchs() const override
{
return m_projectPartPchs;
}
unittest_public : const std::vector<PchManagerNotifierInterface *> &notifiers() const;
void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified);
void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId);
void attach(PchManagerNotifierInterface *notifier);
void detach(PchManagerNotifierInterface *notifier);
void addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch);
void removeProjectPartPch(ClangBackEnd::ProjectPartId projectPartId);
private:
ClangBackEnd::ProjectPartPchs m_projectPartPchs;
std::vector<PchManagerNotifierInterface*> m_notifiers;
PchManagerConnectionClient *m_connectionClient=nullptr;
ProgressManagerInterface &m_pchCreationProgressManager;

View File

@@ -42,10 +42,7 @@ public:
PchManagerNotifierInterface(const PchManagerNotifierInterface &) = delete;
PchManagerNotifierInterface &operator=(const PchManagerNotifierInterface &) = delete;
virtual void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified)
= 0;
virtual void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId) = 0;
virtual void precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId) = 0;
PchManagerClient &m_pchManagerClient;

View File

@@ -30,9 +30,7 @@
namespace ClangRefactoring {
void RefactoringProjectUpdater::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &,
long long)
void RefactoringProjectUpdater::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId)
{
const QString projectPartName = fetchProjectPartName(projectPartId);

View File

@@ -47,9 +47,7 @@ public:
{
}
void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified) override;
void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId) override;
void precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId) override;
private:

View File

@@ -180,7 +180,7 @@ void PchCreator::doInMainThreadAfterFinished()
m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified,
m_projectPartPch.projectPartId);
m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}});
m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch});
m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch.projectPartId});
}
}

View File

@@ -34,6 +34,7 @@
#include <updategeneratedfilesmessage.h>
#include <updateprojectpartsmessage.h>
#include <utils/algorithm.h>
#include <utils/smallstring.h>
#include <QApplication>
@@ -57,18 +58,29 @@ void PchManagerServer::end()
QCoreApplication::exit();
}
namespace {
ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectParts)
{
return Utils::transform<ProjectPartIds>(projectParts, [](const auto &projectPart) {
return projectPart.projectPartId;
});
}
} // namespace
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
{
m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
ProjectPartContainers newProjectParts = m_projectPartsManager.update(message.takeProjectsParts());
auto upToDateProjectParts = m_projectPartsManager.update(message.takeProjectsParts());
if (m_generatedFiles.isValid()) {
m_pchTaskGenerator.addProjectParts(std::move(newProjectParts),
m_pchTaskGenerator.addProjectParts(std::move(upToDateProjectParts.notUpToDate),
std::move(message.toolChainArguments));
} else {
m_projectPartsManager.updateDeferred(newProjectParts);
m_projectPartsManager.updateDeferred(upToDateProjectParts.notUpToDate);
}
client()->precompiledHeadersUpdated(toProjectPartIds(upToDateProjectParts.upToDate));
}
void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)

View File

@@ -44,34 +44,35 @@ ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectsParts)
return ids;
}
ProjectPartContainers ProjectPartsManager::update(ProjectPartContainers &&projectsParts)
ProjectPartsManager::UpToDataProjectParts ProjectPartsManager::update(ProjectPartContainers &&projectsParts)
{
auto updatedProjectParts = filterNewProjectParts(std::move(projectsParts), m_projectParts);
auto notUpToDateProjectParts = filterProjectParts(projectsParts, m_projectParts);
if (updatedProjectParts.empty())
return {};
if (notUpToDateProjectParts.empty())
return {std::move(projectsParts), {}};
auto persistentProjectParts = m_projectPartsStorage.fetchProjectParts(
toProjectPartIds(updatedProjectParts));
toProjectPartIds(notUpToDateProjectParts));
if (persistentProjectParts.size() > 0) {
mergeProjectParts(persistentProjectParts);
updatedProjectParts = filterNewProjectParts(std::move(updatedProjectParts),
persistentProjectParts);
notUpToDateProjectParts = filterProjectParts(notUpToDateProjectParts, persistentProjectParts);
if (updatedProjectParts.empty())
if (notUpToDateProjectParts.empty())
return {};
}
m_projectPartsStorage.updateProjectParts(updatedProjectParts);
m_projectPartsStorage.resetIndexingTimeStamps(updatedProjectParts);
m_projectPartsStorage.updateProjectParts(notUpToDateProjectParts);
m_projectPartsStorage.resetIndexingTimeStamps(notUpToDateProjectParts);
m_precompiledHeaderStorage.deleteProjectPrecompiledHeaders(
toProjectPartIds(updatedProjectParts));
toProjectPartIds(notUpToDateProjectParts));
mergeProjectParts(updatedProjectParts);
mergeProjectParts(notUpToDateProjectParts);
return updatedProjectParts;
auto upToDateProjectParts = filterProjectParts(projectsParts, notUpToDateProjectParts);
return {upToDateProjectParts, notUpToDateProjectParts};
}
void ProjectPartsManager::remove(const ProjectPartIds &projectPartIds)
@@ -176,8 +177,8 @@ ProjectPartContainers ProjectPartsManager::deferredUpdates()
return deferredProjectParts;
}
ProjectPartContainers ProjectPartsManager::filterNewProjectParts(
ProjectPartContainers &&projectsParts, const ProjectPartContainers &oldProjectParts)
ProjectPartContainers ProjectPartsManager::filterProjectParts(
const ProjectPartContainers &projectsParts, const ProjectPartContainers &oldProjectParts)
{
ProjectPartContainers updatedProjectPartContainers;
updatedProjectPartContainers.reserve(projectsParts.size());

View File

@@ -36,6 +36,7 @@
namespace ClangBackEnd {
inline namespace Pch {
class ProjectPartsManager final : public ProjectPartsManagerInterface
{
public:
@@ -45,14 +46,14 @@ public:
, m_precompiledHeaderStorage(precompiledHeaderStorage)
{}
ProjectPartContainers update(ProjectPartContainers &&projectsParts) override;
UpToDataProjectParts update(ProjectPartContainers &&projectsParts) override;
void remove(const ProjectPartIds &projectPartIds) override;
ProjectPartContainers projects(const ProjectPartIds &projectPartIds) const override;
void updateDeferred(const ProjectPartContainers &projectsParts) override;
ProjectPartContainers deferredUpdates() override;
static ProjectPartContainers filterNewProjectParts(ProjectPartContainers &&newProjectsParts,
const ProjectPartContainers &oldProjectParts);
static ProjectPartContainers filterProjectParts(const ProjectPartContainers &newProjectsParts,
const ProjectPartContainers &oldProjectParts);
void mergeProjectParts(const ProjectPartContainers &projectsParts);
const ProjectPartContainers &projectParts() const;

View File

@@ -32,11 +32,18 @@ namespace ClangBackEnd {
class ProjectPartsManagerInterface
{
public:
class UpToDataProjectParts
{
public:
ProjectPartContainers upToDate;
ProjectPartContainers notUpToDate;
};
ProjectPartsManagerInterface() = default;
ProjectPartsManagerInterface(const ProjectPartsManagerInterface &) = delete;
ProjectPartsManagerInterface &operator=(const ProjectPartsManagerInterface &) = delete;
virtual ProjectPartContainers update(ProjectPartContainers &&projectsParts) = 0;
virtual UpToDataProjectParts update(ProjectPartContainers &&projectsParts) = 0;
virtual void remove(const ProjectPartIds &projectPartIds) = 0;
virtual ProjectPartContainers projects(const ProjectPartIds &projectPartIds) const = 0;
virtual void updateDeferred(const ProjectPartContainers &projectsParts) = 0;

View File

@@ -32,6 +32,8 @@
#include <llvm/ADT/ArrayRef.h>
#include <iostream>
namespace ClangBackEnd {
namespace {
@@ -136,9 +138,10 @@ bool IndexDataConsumer::handleDeclOccurence(
if (!namedDeclaration->getIdentifier())
return true;
if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles))
if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles)) {
namedDeclaration->getDeclName().dump();
return true;
}
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());

View File

@@ -43,6 +43,10 @@ public:
Target *activeTarget() const { return {}; }
QVariant namedSettings(const QString &name) const { return settings.at(name); }
void setNamedSettings(const QString &name, const QVariant &value) { settings[name] = value; }
Utils::FileName rootProjectDirectoryPath;
mutable std::map<QString, QVariant> settings;
};
} // namespace ProjectExplorer

View File

@@ -51,7 +51,7 @@
#include <precompiledheadersupdatedmessage.h>
#include <projectpartartefact.h>
#include <projectpartentry.h>
#include <projectpartid.h>
#include <projectpartpch.h>
#include <sourcedependency.h>
#include <sourcelocationentry.h>
#include <sourcelocationscontainer.h>
@@ -719,18 +719,14 @@ std::ostream &operator<<(std::ostream &out, const NativeFilePath &filePath)
std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessage &message)
{
out << "("
<< message.projectPartPchs
<< ")";
out << "(" << message.projectPartIds << ")";
return out;
}
std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch)
{
out << "("
<< projectPartPch.projectPartId << ", "
<< projectPartPch.pchPath << ", "
out << "(" << projectPartPch.projectPartId << ", " << projectPartPch.pchPath << ", "
<< projectPartPch.lastModified << ")";
return out;

View File

@@ -36,9 +36,6 @@ public:
: ClangPchManager::PchManagerNotifierInterface(pchManagerClient)
{}
MOCK_METHOD3(precompiledHeaderUpdated,
void(ClangBackEnd::ProjectPartId projectPartId,
const QString &pchFilePath,
long long lastModified));
MOCK_METHOD1(precompiledHeaderUpdated, void(ClangBackEnd::ProjectPartId projectPartId));
MOCK_METHOD1(precompiledHeaderRemoved, void(ClangBackEnd::ProjectPartId projectPartId));
};

View File

@@ -33,7 +33,7 @@ class MockProjectPartsManager : public ClangBackEnd::ProjectPartsManagerInterfac
{
public:
MOCK_METHOD1(update,
ClangBackEnd::ProjectPartContainers(
ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts(
const ClangBackEnd::ProjectPartContainers &projectsParts));
MOCK_METHOD1(remove, void(const ClangBackEnd::ProjectPartIds &projectPartIds));
MOCK_CONST_METHOD1(
@@ -42,7 +42,8 @@ public:
MOCK_METHOD1(updateDeferred, void(const ClangBackEnd::ProjectPartContainers &projectsParts));
MOCK_METHOD0(deferredUpdates, ClangBackEnd::ProjectPartContainers());
ClangBackEnd::ProjectPartContainers update(ClangBackEnd::ProjectPartContainers &&projectsParts) override
ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts update(
ClangBackEnd::ProjectPartContainers &&projectsParts) override
{
return update(projectsParts);
}

View File

@@ -203,8 +203,8 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
EXPECT_CALL(mockPchManagerClient,
precompiledHeadersUpdated(
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartPchs,
ElementsAre(Eq(creator.projectPartPch())))));
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
creator.doInMainThreadAfterFinished();
}

View File

@@ -65,11 +65,9 @@ protected:
filePathCache,
mockProjectPartsStorage};
ClangBackEnd::ProjectPartId projectPartId{1};
ClangBackEnd::FilePath pchFilePath{"/path/to/pch"};
PrecompiledHeadersUpdatedMessage message{{{projectPartId, pchFilePath.clone(), 1}}};
PrecompiledHeadersUpdatedMessage message{{projectPartId}};
ClangBackEnd::ProjectPartId projectPartId2{2};
ClangBackEnd::FilePath pchFilePath2{"/path/to/pch2"};
PrecompiledHeadersUpdatedMessage message2{{{projectPartId2, pchFilePath2.clone(), 1}}};
PrecompiledHeadersUpdatedMessage message2{{projectPartId2}};
};
TEST_F(PchManagerClient, NotifierAttached)
@@ -93,8 +91,7 @@ TEST_F(PchManagerClient, NotifierDetached)
TEST_F(PchManagerClient, Update)
{
EXPECT_CALL(mockPchManagerNotifier,
precompiledHeaderUpdated(projectPartId, pchFilePath.toQString(), Eq(1)));
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderUpdated(projectPartId));
client.precompiledHeadersUpdated(message.clone());
}
@@ -106,58 +103,6 @@ TEST_F(PchManagerClient, Remove)
projectUpdater.removeProjectParts({projectPartId, projectPartId});
}
TEST_F(PchManagerClient, GetNoProjectPartPchForWrongProjectPartId)
{
auto optional = client.projectPartPch(23);
ASSERT_FALSE(optional);
}
TEST_F(PchManagerClient, GetProjectPartPchForProjectPartId)
{
client.precompiledHeadersUpdated(std::move(message));
auto optional = client.projectPartPch(projectPartId);
ASSERT_TRUE(optional);
}
TEST_F(PchManagerClient, ProjectPartPchRemoved)
{
client.precompiledHeadersUpdated(std::move(message));
client.precompiledHeaderRemoved(projectPartId);
ASSERT_FALSE(client.projectPartPch(projectPartId));
}
TEST_F(PchManagerClient, ProjectPartPchHasNoDublicateEntries)
{
client.precompiledHeadersUpdated(message.clone());
client.precompiledHeadersUpdated(message2.clone());
client.precompiledHeadersUpdated(message.clone());
ASSERT_THAT(client.projectPartPchs(), SizeIs(2));
}
TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdLastModified)
{
client.precompiledHeadersUpdated(std::move(message));
ASSERT_THAT(client.projectPartPch(projectPartId)->lastModified, 1);
}
TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdIsUpdated)
{
client.precompiledHeadersUpdated(message.clone());
PrecompiledHeadersUpdatedMessage updateMessage{{{projectPartId, pchFilePath.clone(), 42}}};
client.precompiledHeadersUpdated(updateMessage.clone());
ASSERT_THAT(client.projectPartPch(projectPartId)->lastModified, 42);
}
TEST_F(PchManagerClient, SetPchCreationProgress)
{
EXPECT_CALL(mockPchCreationProgressManager, setProgress(10, 20));

View File

@@ -148,7 +148,7 @@ TEST_F(PchManagerClientServerInProcess, SendRemoveGeneratedFilesMessage)
TEST_F(PchManagerClientServerInProcess, SendPrecompiledHeaderUpdatedMessage)
{
PrecompiledHeadersUpdatedMessage message{{{1, "/path/to/pch", 1}}};
PrecompiledHeadersUpdatedMessage message{1};
EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(message));

View File

@@ -48,6 +48,7 @@ using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::V2::FileContainers;
using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::ProjectPartContainers;
using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts;
class PchManagerServer : public ::testing::Test
{
@@ -55,7 +56,8 @@ class PchManagerServer : public ::testing::Test
{
server.setClient(&mockPchManagerClient);
ON_CALL(mockProjectPartsManager, update(projectParts)).WillByDefault(Return(projectParts));
ON_CALL(mockProjectPartsManager, update(projectParts))
.WillByDefault(Return(UpToDataProjectParts{{}, projectParts}));
ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(true));
}
@@ -107,7 +109,8 @@ protected:
Utils::LanguageVersion::C11,
Utils::LanguageExtension::All};
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
std::vector<ProjectPartContainer> projectParts2{projectPart2};
std::vector<ProjectPartContainer> projectParts1{projectPart1};
std::vector<ProjectPartContainer> projectParts2{projectPart2};
FileContainer generatedFile{{"/path/to/", "file"}, "content", {}};
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{
Utils::clone(projectParts), {"toolChainArgument"}};
@@ -120,7 +123,7 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts))
.WillOnce(Return(projectParts2));
.WillOnce(Return(UpToDataProjectParts{{}, projectParts2}));
EXPECT_CALL(
mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
@@ -219,7 +222,7 @@ TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1)))
.WillOnce(Return(ProjectPartContainers{projectPart1}));
.WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}}));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
EXPECT_CALL(mockProjectPartsManager, updateDeferred(ElementsAre(projectPart1)));
@@ -233,7 +236,7 @@ TEST_F(PchManagerServer, GeneratePchIfGeneratedFilesAreValid)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1)))
.WillOnce(Return(ProjectPartContainers{projectPart1}));
.WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}}));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _));
EXPECT_CALL(mockProjectPartsManager, updateDeferred(_)).Times(0);
@@ -276,4 +279,19 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreStillInvalidSoNoPchsGener
server.updateGeneratedFiles(updateGeneratedFilesMessage.clone());
}
TEST_F(PchManagerServer, SentUpToDateProjectPartIdsToClient)
{
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts))
.WillOnce(Return(UpToDataProjectParts{projectParts1, projectParts2}));
EXPECT_CALL(mockPchTaskGenerator,
addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
EXPECT_CALL(mockPchManagerClient,
precompiledHeadersUpdated(
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
ElementsAre(Eq(projectPart1.projectPartId)))));
server.updateProjectParts(updateProjectPartsMessage.clone());
}
} // namespace

View File

@@ -36,6 +36,7 @@ namespace {
using ClangBackEnd::FilePathId;
using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::ProjectPartContainers;
using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts;
class ProjectPartsManager : public testing::Test
{
@@ -111,16 +112,20 @@ protected:
TEST_F(ProjectPartsManager, GetNoProjectPartsForAddingEmptyProjectParts)
{
auto updatedProjectParts = manager.update({});
auto projectParts = manager.update({});
ASSERT_THAT(updatedProjectParts, IsEmpty());
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
Field(&UpToDataProjectParts::notUpToDate, IsEmpty())));
}
TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPart)
{
auto updatedProjectParts = manager.update({projectPartContainer1});
auto projectParts = manager.update({projectPartContainer1});
ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1));
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1))));
}
TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlreadyInTheDatabase)
@@ -128,9 +133,11 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlr
ON_CALL(mockProjectPartsStorage, fetchProjectParts(_))
.WillByDefault(Return(ProjectPartContainers{projectPartContainer1}));
auto updatedProjectParts = manager.update({projectPartContainer1, projectPartContainer2});
auto projectParts = manager.update({projectPartContainer1, projectPartContainer2});
ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer2));
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)),
Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer2))));
}
TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPartAlreadyInTheDatabase)
@@ -138,9 +145,12 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPa
ON_CALL(mockProjectPartsStorage, fetchProjectParts(_))
.WillByDefault(Return(ProjectPartContainers{projectPartContainer1}));
auto updatedProjectParts = manager.update({updatedProjectPartContainer1, projectPartContainer2});
auto projectParts = manager.update({updatedProjectPartContainer1, projectPartContainer2});
ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1, projectPartContainer2));
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
Field(&UpToDataProjectParts::notUpToDate,
ElementsAre(updatedProjectPartContainer1, projectPartContainer2))));
}
TEST_F(ProjectPartsManager, ProjectPartAdded)
@@ -184,9 +194,11 @@ TEST_F(ProjectPartsManager, DoNotUpdateNotNewProjectPart)
{
manager.update({projectPartContainer1});
auto updatedProjectParts = manager.update({projectPartContainer1});
auto projectParts = manager.update({projectPartContainer1});
ASSERT_THAT(updatedProjectParts, IsEmpty());
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)),
Field(&UpToDataProjectParts::notUpToDate, IsEmpty())));
}
TEST_F(ProjectPartsManager, NoDuplicateProjectPartAfterUpdatingWithNotNewProjectPart)
@@ -216,8 +228,8 @@ TEST_F(ProjectPartsManager, MergeProjectMultipleTimesParts)
TEST_F(ProjectPartsManager, GetNewProjectParts)
{
auto newProjectParts = manager.filterNewProjectParts({projectPartContainer1, projectPartContainer2},
{projectPartContainer2});
auto newProjectParts = manager.filterProjectParts({projectPartContainer1, projectPartContainer2},
{projectPartContainer2});
ASSERT_THAT(newProjectParts, ElementsAre(projectPartContainer1));
}
@@ -226,9 +238,12 @@ TEST_F(ProjectPartsManager, GetUpdatedProjectPart)
{
manager.update({projectPartContainer1, projectPartContainer2});
auto updatedProjectParts = manager.update({updatedProjectPartContainer1});
auto projectParts = manager.update({updatedProjectPartContainer1});
ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1));
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
Field(&UpToDataProjectParts::notUpToDate,
ElementsAre(updatedProjectPartContainer1))));
}
TEST_F(ProjectPartsManager, ProjectPartIsReplacedWithUpdatedProjectPart)
@@ -280,14 +295,14 @@ TEST_F(ProjectPartsManager, UpdateDeferred)
TEST_F(ProjectPartsManager, NotUpdateDeferred)
{
auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2});
manager.update({projectPartContainer1, projectPartContainer2});
ASSERT_THAT(manager.deferredUpdates(), IsEmpty());
}
TEST_F(ProjectPartsManager, UpdateDeferredCleansDeferredUpdates)
{
auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2});
manager.update({projectPartContainer1, projectPartContainer2});
manager.updateDeferred({projectPartContainer1});
manager.deferredUpdates();
@@ -386,9 +401,11 @@ TEST_F(ProjectPartsManager,
ON_CALL(mockProjectPartsStorage, fetchProjectParts(_))
.WillByDefault(Return(ProjectPartContainers{projectPartContainerWithoutPrecompiledHeader1}));
auto updatedProjectParts = manager.update({projectPartContainer1});
auto projectParts = manager.update({projectPartContainer1});
ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1));
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1))));
}
TEST_F(ProjectPartsManager, ProjectPartAddedWithProjectPartAlreadyInTheDatabaseButWithoutEntries)

View File

@@ -101,7 +101,7 @@ TEST_F(RefactoringProjectUpdater, DontUpdateProjectPartIfNoProjectPartExistsForI
EXPECT_CALL(mockCppModelManager, projectPartForId(Eq(QString("project1"))));
EXPECT_CALL(mockRefactoringServer, updateProjectParts(_)).Times(0);
pchManagerClient.precompiledHeadersUpdated({{{3, "/path/to/pch", 12}}});
pchManagerClient.precompiledHeadersUpdated({3});
}
TEST_F(RefactoringProjectUpdater, UpdateProjectPart)
@@ -118,7 +118,7 @@ TEST_F(RefactoringProjectUpdater, UpdateProjectPart)
updateProjectParts(Field(&UpdateProjectPartsMessage::projectsParts,
ElementsAre(IsProjectPartContainer(3)))));
pchManagerClient.precompiledHeadersUpdated({{{3, "/path/to/pch", 12}}});
pchManagerClient.precompiledHeadersUpdated({3});
}
TEST_F(RefactoringProjectUpdater, RemoveProjectPart)