aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2018-09-11 17:02:45 +0200
committerMarco Bubke <marco.bubke@qt.io>2018-09-24 14:33:05 +0000
commit4e6d09d8e1e9ba776ee20000d5a39b46ce2c25af (patch)
tree423e880fb98d221db033127d51917942854c7b92
parenta334650953880e29219e28bda89b4136875f3dc2 (diff)
Clang: Reuse thread based pipeline for pch creation
The pch creation so far used signal and slots but there was no explicit pipeline. This patch is introducing the same architecture like the refactoring plugin. It is filtering out older project parts from the pipeline. Change-Id: Iaa6bd2ca1272231b97ebe1f5f7b2ce8e43bc590c Task-number: QTCREATORBUG-21111 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager-source.pri6
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.cpp4
-rw-r--r--src/plugins/clangpchmanager/pchmanagerclient.cpp19
-rw-r--r--src/plugins/clangpchmanager/pchmanagerclient.h7
-rw-r--r--src/plugins/clangpchmanager/projectupdater.cpp5
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp83
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri18
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludesaction.h6
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h11
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/includecollector.cpp2
-rw-r--r--src/tools/clangpchmanagerbackend/source/includecollector.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp324
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.h77
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h8
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchgenerator.h165
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchgeneratornotifierinterface.h53
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp21
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.h8
-rw-r--r--src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h (renamed from src/plugins/clangpchmanager/precompiledheaderstorage.h)2
-rw-r--r--src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h (renamed from src/plugins/clangpchmanager/precompiledheaderstorageinterface.h)4
-rw-r--r--src/tools/clangpchmanagerbackend/source/processorinterface.h47
-rw-r--r--src/tools/clangpchmanagerbackend/source/processormanager.h (renamed from src/tools/clangrefactoringbackend/source/symbolscollectormanager.h)49
-rw-r--r--src/tools/clangpchmanagerbackend/source/processormanagerinterface.h (renamed from src/tools/clangrefactoringbackend/source/symbolscollectormanagerinterface.h)18
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp126
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartqueue.h (renamed from src/tools/clangrefactoringbackend/source/symbolindexertaskschedulerinterface.h)44
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h43
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectparts.cpp14
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectparts.h1
-rw-r--r--src/tools/clangpchmanagerbackend/source/queueinterface.h (renamed from src/tools/clangpchmanagerbackend/source/pchgeneratorinterface.h)19
-rw-r--r--src/tools/clangpchmanagerbackend/source/taskscheduler.h189
-rw-r--r--src/tools/clangpchmanagerbackend/source/taskschedulerinterface.h49
-rw-r--r--src/tools/clangrefactoringbackend/clangrefactoringbackend.pro1
-rw-r--r--src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri8
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp46
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertask.h5
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp71
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h46
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h9
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.cpp146
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.h91
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.h34
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.cpp4
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.h2
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h17
-rw-r--r--tests/unit/unittest/data/includecollector_faulty.cpp1
-rw-r--r--tests/unit/unittest/data/includecollector_faulty.h8
-rw-r--r--tests/unit/unittest/google-using-declarations.h3
-rw-r--r--tests/unit/unittest/googletest.h5
-rw-r--r--tests/unit/unittest/gtest-creator-printing.cpp3
-rw-r--r--tests/unit/unittest/mockpchcreator.h24
-rw-r--r--tests/unit/unittest/mockprecompiledheaderstorage.h2
-rw-r--r--tests/unit/unittest/mockprocessor.h79
-rw-r--r--tests/unit/unittest/mockprocessormanager.h (renamed from tests/unit/unittest/mockpchgeneratornotifier.h)14
-rw-r--r--tests/unit/unittest/mockprojectpartqueue.h46
-rw-r--r--tests/unit/unittest/mockqueue.h (renamed from tests/unit/unittest/mocksymbolscollectormanager.h)9
-rw-r--r--tests/unit/unittest/mocksymbolindexertaskqueue.h2
-rw-r--r--tests/unit/unittest/mocksymbolscollector.h3
-rw-r--r--tests/unit/unittest/mocktaskscheduler.h (renamed from tests/unit/unittest/mocksymbolindexertaskscheduler.h)12
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp229
-rw-r--r--tests/unit/unittest/pchgenerator-test.cpp219
-rw-r--r--tests/unit/unittest/pchmanagerclient-test.cpp19
-rw-r--r--tests/unit/unittest/pchmanagerserver-test.cpp97
-rw-r--r--tests/unit/unittest/precompiledheaderstorage-test.cpp4
-rw-r--r--tests/unit/unittest/processormanager-test.cpp112
-rw-r--r--tests/unit/unittest/projectpartqueue-test.cpp169
-rw-r--r--tests/unit/unittest/projectparts-test.cpp18
-rw-r--r--tests/unit/unittest/projectupdater-test.cpp10
-rw-r--r--tests/unit/unittest/refactoringprojectupdater-test.cpp4
-rw-r--r--tests/unit/unittest/symbolindexer-test.cpp30
-rw-r--r--tests/unit/unittest/symbolindexertaskqueue-test.cpp28
-rw-r--r--tests/unit/unittest/symbolscollectormanager-test.cpp98
-rw-r--r--tests/unit/unittest/taskscheduler-test.cpp (renamed from tests/unit/unittest/symbolindexertaskscheduler-test.cpp)87
-rw-r--r--tests/unit/unittest/unittest.pro18
74 files changed, 1496 insertions, 1767 deletions
diff --git a/src/plugins/clangpchmanager/clangpchmanager-source.pri b/src/plugins/clangpchmanager/clangpchmanager-source.pri
index 98010437c0..27e35dc740 100644
--- a/src/plugins/clangpchmanager/clangpchmanager-source.pri
+++ b/src/plugins/clangpchmanager/clangpchmanager-source.pri
@@ -12,10 +12,7 @@ HEADERS += \
$$PWD/pchmanagerconnectionclient.h \
$$PWD/clangpchmanager_global.h \
$$PWD/projectupdater.h \
- $$PWD/pchmanagerprojectupdater.h \
- $$PWD/precompiledheaderstorage.h \
- $$PWD/precompiledheaderstorageinterface.h
-
+ $$PWD/pchmanagerprojectupdater.h
SOURCES += \
$$PWD/pchmanagerclient.cpp \
@@ -23,4 +20,3 @@ SOURCES += \
$$PWD/pchmanagerconnectionclient.cpp \
$$PWD/projectupdater.cpp \
$$PWD/pchmanagerprojectupdater.cpp
-
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
index 5817db9034..098faf50b3 100644
--- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
@@ -27,7 +27,6 @@
#include "pchmanagerconnectionclient.h"
#include "pchmanagerclient.h"
-#include "precompiledheaderstorage.h"
#include "qtcreatorprojectupdater.h"
#include <filepathcaching.h>
@@ -62,8 +61,7 @@ public:
Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
- PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
- PchManagerClient pchManagerClient{preCompiledHeaderStorage};
+ PchManagerClient pchManagerClient;
PchManagerConnectionClient connectionClient{&pchManagerClient};
QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(),
pchManagerClient,
diff --git a/src/plugins/clangpchmanager/pchmanagerclient.cpp b/src/plugins/clangpchmanager/pchmanagerclient.cpp
index e5321865ce..81af53308e 100644
--- a/src/plugins/clangpchmanager/pchmanagerclient.cpp
+++ b/src/plugins/clangpchmanager/pchmanagerclient.cpp
@@ -34,11 +34,6 @@
namespace ClangPchManager {
-PchManagerClient::PchManagerClient(PrecompiledHeaderStorageInterface &precompiledHeaderStorage)
- : m_precompiledHeaderStorage(precompiledHeaderStorage)
-{
-}
-
void PchManagerClient::alive()
{
if (m_connectionClient)
@@ -50,7 +45,6 @@ void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeader
for (ClangBackEnd::ProjectPartPch &projectPartPch : message.takeProjectPartPchs()) {
const QString projectPartId{projectPartPch.projectPartId};
const QString pchPath{projectPartPch.pchPath};
- addPchToDatabase(projectPartPch);
addProjectPartPch(std::move(projectPartPch));
precompiledHeaderUpdated(projectPartId, pchPath, projectPartPch.lastModified);
}
@@ -60,7 +54,6 @@ void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)
{
for (auto notifier : m_notifiers) {
Utils::SmallString id(projectPartId);
- removePchFromDatabase(id);
removeProjectPartPch(id);
notifier->precompiledHeaderRemoved(projectPartId);
}
@@ -117,18 +110,6 @@ void PchManagerClient::removeProjectPartPch(Utils::SmallStringView projectPartId
}
}
-void PchManagerClient::addPchToDatabase(const ClangBackEnd::ProjectPartPch &projectPartPch)
-{
- m_precompiledHeaderStorage.insertPrecompiledHeader(projectPartPch.projectPartId,
- projectPartPch.pchPath,
- projectPartPch.lastModified);
-}
-
-void PchManagerClient::removePchFromDatabase(const Utils::SmallStringView &projectPartId)
-{
- m_precompiledHeaderStorage.deletePrecompiledHeader(projectPartId);
-}
-
void PchManagerClient::addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch)
{
auto found = std::lower_bound(m_projectPartPchs.begin(),
diff --git a/src/plugins/clangpchmanager/pchmanagerclient.h b/src/plugins/clangpchmanager/pchmanagerclient.h
index e9b80ebe51..92c44465f2 100644
--- a/src/plugins/clangpchmanager/pchmanagerclient.h
+++ b/src/plugins/clangpchmanager/pchmanagerclient.h
@@ -26,7 +26,6 @@
#pragma once
#include "clangpchmanager_global.h"
-#include "precompiledheaderstorageinterface.h"
#include <pchmanagerclientinterface.h>
#include <projectpartpchproviderinterface.h>
@@ -43,7 +42,7 @@ class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchMa
{
friend class PchManagerNotifierInterface;
public:
- PchManagerClient(PrecompiledHeaderStorageInterface &precompiledHeaderStorage);
+ PchManagerClient() = default;
void alive() override;
void precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) override;
@@ -71,14 +70,10 @@ unittest_public:
void addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch);
void removeProjectPartPch(Utils::SmallStringView projectPartId);
- void addPchToDatabase(const ClangBackEnd::ProjectPartPch &projectPartPch);
- void removePchFromDatabase(const Utils::SmallStringView &projectPartId);
-
private:
ClangBackEnd::ProjectPartPchs m_projectPartPchs;
std::vector<PchManagerNotifierInterface*> m_notifiers;
PchManagerConnectionClient *m_connectionClient=nullptr;
- PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage;
};
} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
index 81d140d3f7..a3fbb6cb62 100644
--- a/src/plugins/clangpchmanager/projectupdater.cpp
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -72,9 +72,10 @@ void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart
void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
{
- ClangBackEnd::RemoveProjectPartsMessage message{Utils::SmallStringVector(projectPartIds)};
+ Utils::SmallStringVector sortedIds(projectPartIds);
+ std::sort(sortedIds.begin(), sortedIds.end());
- m_server.removeProjectParts(std::move(message));
+ m_server.removeProjectParts(ClangBackEnd::RemoveProjectPartsMessage{std::move(sortedIds)});
}
void ProjectUpdater::updateGeneratedFiles(ClangBackEnd::V2::FileContainers &&generatedFiles)
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
index d751ab0bd4..d510427081 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -28,13 +28,16 @@
#include <environment.h>
#include <generatedfiles.h>
#include <pchcreator.h>
-#include <pchgenerator.h>
#include <pchmanagerserver.h>
#include <pchmanagerclientproxy.h>
+#include <precompiledheaderstorage.h>
+#include <processormanager.h>
#include <projectparts.h>
+#include <projectpartqueue.h>
#include <filepathcaching.h>
#include <refactoringdatabaseinitializer.h>
#include <sqlitedatabase.h>
+#include <taskscheduler.h>
#include <QCommandLineParser>
#include <QCoreApplication>
@@ -53,9 +56,9 @@ using ClangBackEnd::ClangPathWatcher;
using ClangBackEnd::ConnectionServer;
using ClangBackEnd::GeneratedFiles;
using ClangBackEnd::PchCreator;
-using ClangBackEnd::PchGenerator;
using ClangBackEnd::PchManagerClientProxy;
using ClangBackEnd::PchManagerServer;
+using ClangBackEnd::PrecompiledHeaderStorage;
using ClangBackEnd::ProjectParts;
using ClangBackEnd::FilePathCache;
@@ -121,6 +124,61 @@ QStringList processArguments(QCoreApplication &application)
return parser.positionalArguments();
}
+class PchCreatorManager final : public ClangBackEnd::ProcessorManager<ClangBackEnd::PchCreator>
+{
+public:
+ using Processor = ClangBackEnd::PchCreator;
+ PchCreatorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
+ ClangBackEnd::Environment &environment,
+ Sqlite::Database &database,
+ PchManagerServer &pchManagerServer,
+ ClangBackEnd::ClangPathWatcherInterface &fileSystemWatcher)
+ : ProcessorManager(generatedFiles),
+ m_environment(environment),
+ m_database(database),
+ m_pchManagerServer(pchManagerServer),
+ m_fileSystemWatcher(fileSystemWatcher)
+ {}
+
+protected:
+ std::unique_ptr<ClangBackEnd::PchCreator> createProcessor() const override
+ {
+ return std::make_unique<PchCreator>(m_environment,
+ m_database,
+ *m_pchManagerServer.client(),
+ m_fileSystemWatcher);
+ }
+
+private:
+ ClangBackEnd::Environment &m_environment;
+ Sqlite::Database &m_database;
+ ClangBackEnd::PchManagerServer &m_pchManagerServer;
+ ClangBackEnd::ClangPathWatcherInterface &m_fileSystemWatcher;
+};
+
+struct Data // because we have a cycle dependency
+{
+ using TaskScheduler = ClangBackEnd::TaskScheduler<PchCreatorManager, ClangBackEnd::ProjectPartQueue::Task>;
+
+ Data(const QString &databasePath,
+ const QString &pchsPath)
+ : database{Utils::PathString{databasePath}, 100000ms},
+ environment{pchsPath}
+ {}
+ Sqlite::Database database;
+ ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
+ ClangBackEnd::FilePathCaching filePathCache{database};
+ ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher{filePathCache};
+ ApplicationEnvironment environment;
+ ProjectParts projectParts;
+ GeneratedFiles generatedFiles;
+ PchCreatorManager pchCreatorManager{generatedFiles, environment, database, clangPchManagerServer, includeWatcher};
+ PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
+ TaskScheduler taskScheduler{pchCreatorManager, projectPartQueue, std::thread::hardware_concurrency()};
+ ClangBackEnd::ProjectPartQueue projectPartQueue{taskScheduler, preCompiledHeaderStorage, database};
+ PchManagerServer clangPchManagerServer{includeWatcher, projectPartQueue, projectParts, generatedFiles};
+};
+
int main(int argc, char *argv[])
{
try {
@@ -138,25 +196,12 @@ int main(int argc, char *argv[])
const QString databasePath = arguments[1];
const QString pchsPath = arguments[2];
- Sqlite::Database database{Utils::PathString{databasePath}, 100000ms};
- ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
- ClangBackEnd::FilePathCaching filePathCache{database};
- ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache);
- ApplicationEnvironment environment{pchsPath};
- PchGenerator<QProcess> pchGenerator(environment);
- GeneratedFiles generatedFiles;
- PchCreator pchCreator(environment, filePathCache, generatedFiles);
- pchCreator.setGenerator(&pchGenerator);
- ProjectParts projectParts;
- PchManagerServer clangPchManagerServer(includeWatcher,
- pchCreator,
- projectParts,
- generatedFiles);
- includeWatcher.setNotifier(&clangPchManagerServer);
- pchGenerator.setNotifier(&clangPchManagerServer);
+ Data data{databasePath, pchsPath};
+
+ data.includeWatcher.setNotifier(&data.clangPchManagerServer);
ConnectionServer<PchManagerServer, PchManagerClientProxy> connectionServer;
- connectionServer.setServer(&clangPchManagerServer);
+ connectionServer.setServer(&data.clangPchManagerServer);
connectionServer.start(connectionName);
return application.exec();
diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
index 9556f50cd1..c6cf965992 100644
--- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
+++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
@@ -2,7 +2,8 @@ INCLUDEPATH += $$PWD
SOURCES += \
$$PWD/pchmanagerserver.cpp \
- $$PWD/projectparts.cpp
+ $$PWD/projectparts.cpp \
+ $$PWD/projectpartqueue.cpp
HEADERS += \
$$PWD/pchmanagerserver.h \
@@ -12,9 +13,15 @@ HEADERS += \
$$PWD/projectparts.h \
$$PWD/pchcreatorinterface.h \
$$PWD/projectpartsinterface.h \
- $$PWD/pchgenerator.h \
- $$PWD/pchgeneratornotifierinterface.h \
- $$PWD/pchgeneratorinterface.h
+ $$PWD/projectpartqueue.h \
+ $$PWD/queueinterface.h \
+ $$PWD/projectpartqueueinterface.h \
+ $$PWD/processormanagerinterface.h \
+ $$PWD/processorinterface.h \
+ $$PWD/taskscheduler.h \
+ $$PWD/taskschedulerinterface.h \
+ $$PWD/precompiledheaderstorage.h \
+ $$PWD/precompiledheaderstorageinterface.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \
@@ -26,5 +33,6 @@ HEADERS += \
$$PWD/collectincludestoolaction.h \
$$PWD/collectincludesaction.h \
$$PWD/collectincludespreprocessorcallbacks.h \
- $$PWD/pchcreator.h
+ $$PWD/pchcreator.h \
+ $$PWD/processormanager.h
}
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
index 923cf5bfc0..d55559b41e 100644
--- a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
+++ b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
@@ -41,7 +41,7 @@ class CollectIncludesAction final : public clang::PreprocessOnlyAction
public:
CollectIncludesAction(FilePathIds &includeIds,
FilePathIds &topIncludeIds,
- FilePathCachingInterface &filePathCache,
+ const FilePathCachingInterface &filePathCache,
std::vector<uint> &excludedIncludeUID,
std::vector<uint> &alreadyIncludedFileUIDs)
: m_includeIds(includeIds),
@@ -56,12 +56,10 @@ public:
{
if (clang::PreprocessOnlyAction::BeginSourceFileAction(compilerInstance)) {
auto &preprocessor = compilerInstance.getPreprocessor();
- auto &headerSearch = preprocessor.getHeaderSearchInfo();
preprocessor.SetSuppressIncludeNotFoundError(true);
auto macroPreprocessorCallbacks = new CollectIncludesPreprocessorCallbacks(
- headerSearch,
m_includeIds,
m_topIncludeIds,
m_filePathCache,
@@ -85,7 +83,7 @@ public:
private:
FilePathIds &m_includeIds;
FilePathIds &m_topIncludeIds;
- FilePathCachingInterface &m_filePathCache;
+ const FilePathCachingInterface &m_filePathCache;
std::vector<uint> &m_excludedIncludeUID;
std::vector<uint> &m_alreadyIncludedFileUIDs;
};
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
index 645d87e91d..2a6d0a54d8 100644
--- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
+++ b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
@@ -48,15 +48,13 @@ namespace ClangBackEnd {
class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks
{
public:
- CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch,
- FilePathIds &includeIds,
+ CollectIncludesPreprocessorCallbacks(FilePathIds &includeIds,
FilePathIds &topIncludeIds,
- FilePathCachingInterface &filePathCache,
+ const FilePathCachingInterface &filePathCache,
const std::vector<uint> &excludedIncludeUID,
std::vector<uint> &alreadyIncludedFileUIDs,
clang::SourceManager &sourceManager)
- : m_headerSearch(headerSearch),
- m_includeIds(includeIds),
+ : m_includeIds(includeIds),
m_topIncludeIds(topIncludeIds),
m_filePathCache(filePathCache),
m_excludedIncludeUID(excludedIncludeUID),
@@ -159,10 +157,9 @@ public:
}
private:
- clang::HeaderSearch &m_headerSearch;
FilePathIds &m_includeIds;
FilePathIds &m_topIncludeIds;
- FilePathCachingInterface &m_filePathCache;
+ const FilePathCachingInterface &m_filePathCache;
const std::vector<uint> &m_excludedIncludeUID;
std::vector<uint> &m_alreadyIncludedFileUIDs;
clang::SourceManager &m_sourceManager;
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
index e5c30829fa..a9c6e9717e 100644
--- a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
+++ b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
@@ -39,7 +39,7 @@ class CollectIncludesToolAction final : public clang::tooling::FrontendActionFac
public:
CollectIncludesToolAction(FilePathIds &includeIds,
FilePathIds &topIncludeIds,
- FilePathCachingInterface &filePathCache,
+ const FilePathCachingInterface &filePathCache,
const Utils::PathStringVector &excludedIncludes)
: m_includeIds(includeIds),
m_topIncludeIds(topIncludeIds),
@@ -93,7 +93,7 @@ private:
std::vector<uint> m_excludedIncludeUIDs;
FilePathIds &m_includeIds;
FilePathIds &m_topIncludeIds;
- FilePathCachingInterface &m_filePathCache;
+ const FilePathCachingInterface &m_filePathCache;
const Utils::PathStringVector &m_excludedIncludes;
};
diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp
index 3c93de82b2..6be1533353 100644
--- a/src/tools/clangpchmanagerbackend/source/includecollector.cpp
+++ b/src/tools/clangpchmanagerbackend/source/includecollector.cpp
@@ -33,7 +33,7 @@
namespace ClangBackEnd {
-IncludeCollector::IncludeCollector(FilePathCachingInterface &filePathCache)
+IncludeCollector::IncludeCollector(const FilePathCachingInterface &filePathCache)
: m_filePathCache(filePathCache)
{
}
diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/includecollector.h
index fc3c1a5991..30dd89d470 100644
--- a/src/tools/clangpchmanagerbackend/source/includecollector.h
+++ b/src/tools/clangpchmanagerbackend/source/includecollector.h
@@ -34,7 +34,7 @@ namespace ClangBackEnd {
class IncludeCollector : public ClangTool
{
public:
- IncludeCollector(FilePathCachingInterface &filePathCache);
+ IncludeCollector(const FilePathCachingInterface &filePathCache);
void collectIncludes();
@@ -48,7 +48,7 @@ private:
FilePathIds m_includeIds;
FilePathIds m_topIncludeIds;
Utils::SmallStringVector m_directories;
- FilePathCachingInterface &m_filePathCache;
+ const FilePathCachingInterface &m_filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
index fb7ccaae53..e02f563efe 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -29,39 +29,21 @@
#include "includecollector.h"
#include "pchnotcreatederror.h"
+#include <clangpathwatcherinterface.h>
#include <filepathcachinginterface.h>
#include <generatedfiles.h>
+#include <pchmanagerclientinterface.h>
+#include <precompiledheadersupdatedmessage.h>
#include <projectpartpch.h>
#include <QCryptographicHash>
#include <QDateTime>
#include <QFile>
+#include <QProcess>
#include <QTemporaryFile>
namespace ClangBackEnd {
-PchCreator::PchCreator(Environment &environment,
- FilePathCachingInterface &filePathCache,
- const GeneratedFiles &generatedFiles)
- : m_generatedFiles(generatedFiles),
- m_environment(environment),
- m_filePathCache(filePathCache)
-{
-}
-
-PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
- Environment &environment,
- FilePathCachingInterface &filePathCache,
- PchGeneratorInterface *pchGenerator,
- const GeneratedFiles &generatedFiles)
- : m_projectParts(std::move(projectsParts)),
- m_generatedFiles(generatedFiles),
- m_environment(environment),
- m_filePathCache(filePathCache),
- m_pchGenerator(pchGenerator)
-{
-}
-
namespace {
template <typename Source,
typename Target>
@@ -76,16 +58,6 @@ void append(Target &target, const Source &source)
target.push_back(ValueType(std::move(entry)));
}
-template <typename Source,
- typename Target>
-void append(Target &target, Source &source)
-{
- target.reserve(target.size() + source.size());
-
- for (auto &&entry : source)
- target.emplace_back(entry);
-}
-
void appendFilePathId(Utils::PathStringVector &target,
const ClangBackEnd::FilePathIds &source,
const ClangBackEnd::FilePathCachingInterface &filePathCache)
@@ -94,51 +66,6 @@ void appendFilePathId(Utils::PathStringVector &target,
target.emplace_back(filePathCache.filePath(id).path());
}
-template <typename GetterFunction>
-std::size_t globalCount(const V2::ProjectPartContainers &projectsParts,
- GetterFunction getterFunction)
-{
- auto sizeFunction = [&] (std::size_t size, const V2::ProjectPartContainer &projectContainer) {
- return size + getterFunction(projectContainer).size();
- };
-
- return std::accumulate(projectsParts.begin(),
- projectsParts.end(),
- std::size_t(0),
- sizeFunction);
-}
-
-template <typename Container,
- typename GetterFunction>
-void generateGlobal(Container &entries,
- const V2::ProjectPartContainers &projectsParts,
- GetterFunction getterFunction)
-{
- entries.reserve(entries.capacity() + globalCount(projectsParts, getterFunction));
-
- for (const V2::ProjectPartContainer &projectPart : projectsParts) {
- auto &&projectPartPaths = getterFunction(projectPart);
-
- append(entries, projectPartPaths);
- };
-}
-
-template <typename Container,
- typename GetterFunction>
-Utils::PathStringVector generateGlobal(
- const V2::ProjectPartContainers &projectsParts,
- GetterFunction getterFunction,
- std::size_t prereserve = 0)
-{
- Container entries;
- entries.reserve(prereserve);
-
- generateGlobal(entries, projectsParts, getterFunction);
-
- return entries;
-}
-
-
Utils::PathStringVector generatedFilePaths(const V2::FileContainers &generaredFiles)
{
Utils::PathStringVector generaredFilePaths;
@@ -152,114 +79,6 @@ Utils::PathStringVector generatedFilePaths(const V2::FileContainers &generaredFi
}
-Utils::PathStringVector PchCreator::generateGlobalHeaderPaths() const
-{
- auto includeFunction = [&] (const V2::ProjectPartContainer &projectPart) {
- return m_filePathCache.filePaths(projectPart.headerPathIds);
- };
-
- Utils::PathStringVector headerPaths = generateGlobal<Utils::PathStringVector>(m_projectParts,
- includeFunction,
- m_generatedFiles.fileContainers().size());
-
- Utils::PathStringVector generatedPath = generatedFilePaths(m_generatedFiles.fileContainers());
-
- headerPaths.insert(headerPaths.end(),
- std::make_move_iterator(generatedPath.begin()),
- std::make_move_iterator(generatedPath.end()));
-
- return headerPaths;
-}
-
-Utils::PathStringVector PchCreator::generateGlobalSourcePaths() const
-{
- auto sourceFunction = [&] (const V2::ProjectPartContainer &projectPart) {
- return m_filePathCache.filePaths(projectPart.sourcePathIds);
- };
-
- return generateGlobal<Utils::PathStringVector>(m_projectParts, sourceFunction);
-}
-
-Utils::PathStringVector PchCreator::generateGlobalHeaderAndSourcePaths() const
-{
- const auto &sourcePaths = generateGlobalSourcePaths();
- auto includePaths = generateGlobalHeaderPaths();
-
- append(includePaths, sourcePaths);
-
- return includePaths;
-}
-
-Utils::SmallStringVector PchCreator::generateGlobalArguments() const
-{
- Utils::SmallStringVector arguments;
-
- auto argumentFunction = [] (const V2::ProjectPartContainer &projectPart)
- -> const Utils::SmallStringVector & {
- return projectPart.arguments;
- };
-
- generateGlobal(arguments, m_projectParts, argumentFunction);
-
- return arguments;
-}
-
-Utils::SmallStringVector PchCreator::generateGlobalCommandLine() const
-{
- Utils::SmallStringVector commandLine;
- commandLine.emplace_back(m_environment.clangCompilerPath());
-
- auto argumentFunction = [] (const V2::ProjectPartContainer &projectPart)
- -> const Utils::SmallStringVector & {
- return projectPart.arguments;
- };
-
- generateGlobal(commandLine, m_projectParts, argumentFunction);
-
- return commandLine;
-}
-
-Utils::SmallStringVector PchCreator::generateGlobalPchCompilerArguments() const
-{
- Utils::SmallStringVector arguments;
- arguments.reserve(5);
-
- arguments.emplace_back("-x");
- arguments.emplace_back("c++-header");
- arguments.emplace_back("-Xclang");
- arguments.emplace_back("-emit-pch");
- arguments.emplace_back("-o");
- arguments.emplace_back(generateGlobalPchFilePath());
- arguments.emplace_back(generateGlobalPchHeaderFilePath());
-
- return arguments;
-}
-
-Utils::SmallStringVector PchCreator::generateGlobalClangCompilerArguments() const
-{
- auto compilerArguments = generateGlobalArguments();
- const auto pchArguments = generateGlobalPchCompilerArguments();
-
- append(compilerArguments, pchArguments);
-
- return compilerArguments;
-}
-
-FilePathIds PchCreator::generateGlobalPchIncludeIds() const
-{
- IncludeCollector collector(m_filePathCache);
-
- collector.setExcludedIncludes(generateGlobalSourcePaths());
-
- collector.addFiles(generateGlobalHeaderAndSourcePaths(), generateGlobalCommandLine());
-
- collector.addUnsavedFiles(m_generatedFiles.fileContainers());
-
- collector.collectIncludes();
-
- return collector.takeIncludeIds();
-}
-
namespace {
std::size_t contentSize(const FilePaths &includes)
@@ -286,28 +105,19 @@ Utils::SmallString PchCreator::generatePchIncludeFileContent(const FilePathIds &
return fileContent;
}
-Utils::SmallString PchCreator::generateGlobalPchHeaderFileContent() const
-{
- return generatePchIncludeFileContent(generateGlobalPchIncludeIds());
-}
-std::unique_ptr<QFile> PchCreator::generateGlobalPchHeaderFile()
+bool PchCreator::generatePch(Utils::SmallStringVector &&compilerArguments)
{
- return generateFileWithContent(generateGlobalPchHeaderFilePath(),
- generateGlobalPchHeaderFileContent());
-}
+ QProcess process;
-void PchCreator::generatePch(Utils::SmallStringVector &&compilerArguments,
- ProjectPartPch &&projectPartPch)
-{
- m_pchGenerator->startTask(std::move(compilerArguments), std::move(projectPartPch));
-}
+ process.setProcessChannelMode(QProcess::ForwardedChannels);
+ process.setArguments(QStringList(compilerArguments));
+ process.setProgram(QString(m_environment.clangCompilerPath()));
-void PchCreator::generateGlobalPch()
-{
- generateGlobalPchHeaderFile();
+ process.start();
+ process.waitForFinished(300000);
- generatePch(generateGlobalClangCompilerArguments(), ProjectPartPch());
+ return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
QStringList PchCreator::convertToQStringList(const Utils::SmallStringVector &compilerArguments)
@@ -324,52 +134,13 @@ namespace {
void hashProjectPart(QCryptographicHash &hash, const V2::ProjectPartContainer &projectPart)
{
const auto &projectPartId = projectPart.projectPartId;
- hash.addData(projectPartId.data(), projectPartId.size());
+ hash.addData(projectPartId.data(), int(projectPartId.size()));
for (const auto &argument : projectPart.arguments)
- hash.addData(argument.data(), argument.size());
+ hash.addData(argument.data(), int(argument.size()));
}
}
-QByteArray PchCreator::globalProjectHash() const
-{
- QCryptographicHash hash(QCryptographicHash::Sha1);
-
- for (const auto &projectPart : m_projectParts)
- hashProjectPart(hash, projectPart);
-
- auto result = hash.result();
-
- return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
-}
-
-Utils::SmallString PchCreator::generateGlobalPchFilePathWithoutExtension() const
-{
- QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
- fileName += '/';
- fileName += globalProjectHash();
-
- return Utils::SmallString::fromQByteArray(fileName);
-}
-
-Utils::SmallString PchCreator::generateGlobalPchHeaderFilePath() const
-{
- Utils::SmallString filePath = generateGlobalPchFilePathWithoutExtension();
-
- filePath += ".h";
-
- return filePath;
-}
-
-Utils::SmallString PchCreator::generateGlobalPchFilePath() const
-{
- Utils::SmallString filePath = generateGlobalPchFilePathWithoutExtension();
-
- filePath += ".pch";
-
- return filePath;
-}
-
Utils::SmallStringVector PchCreator::generateProjectPartCommandLine(
const V2::ProjectPartContainer &projectPart) const
{
@@ -399,7 +170,7 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaders(
const V2::ProjectPartContainer &projectPart) const
{
Utils::PathStringVector headerPaths;
- headerPaths.reserve(projectPart.headerPathIds.size() + m_generatedFiles.fileContainers().size());
+ headerPaths.reserve(projectPart.headerPathIds.size() + m_unsavedFiles.size());
std::transform(projectPart.headerPathIds.begin(),
projectPart.headerPathIds.end(),
@@ -408,7 +179,7 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaders(
return m_filePathCache.filePath(filePathId);
});
- Utils::PathStringVector generatedPath = generatedFilePaths(m_generatedFiles.fileContainers());
+ Utils::PathStringVector generatedPath = generatedFilePaths(m_unsavedFiles);
std::copy(std::make_move_iterator(generatedPath.begin()),
std::make_move_iterator(generatedPath.end()),
@@ -484,7 +255,7 @@ std::pair<FilePathIds,FilePathIds> PchCreator::generateProjectPartPchIncludes(
{},
arguments);
- collector.addUnsavedFiles(m_generatedFiles.fileContainers());
+ collector.addUnsavedFiles(m_unsavedFiles);
collector.collectIncludes();
@@ -549,35 +320,68 @@ IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &proje
auto pchFilePath = generateProjectPartPchFilePath(projectPart);
generateFileWithContent(pchIncludeFilePath, content);
- generatePch(generateProjectPartClangCompilerArguments(projectPart),
- {projectPart.projectPartId.clone(), std::move(pchFilePath), lastModified});
+ bool success = generatePch(generateProjectPartClangCompilerArguments(projectPart));
+
+ m_projectPartPch.projectPartId = projectPart.projectPartId;
+
+ if (success) {
+ m_projectPartPch.pchPath = std::move(pchFilePath);
+ m_projectPartPch.lastModified = lastModified;
+ }
return {projectPart.projectPartId.clone(), std::move(allExternalIncludes)};
}
-void PchCreator::generatePchs()
+void PchCreator::generatePch(const V2::ProjectPartContainer &projectPart)
{
- for (const V2::ProjectPartContainer &projectPart : m_projectParts) {
- auto includePaths = generateProjectPartPch(projectPart);
- m_projectsIncludeIds.push_back(std::move(includePaths));
- }
+ m_projectIncludeIds = generateProjectPartPch(projectPart);
+}
+
+IdPaths PchCreator::takeProjectIncludes()
+{
+ return std::move(m_projectIncludeIds);
+}
+
+const ProjectPartPch &PchCreator::projectPartPch()
+{
+ return m_projectPartPch;
+}
+
+void PchCreator::setUnsavedFiles(const V2::FileContainers &fileContainers)
+{
+ m_unsavedFiles = fileContainers;
}
-void PchCreator::generatePchs(V2::ProjectPartContainers &&projectsParts)
+void PchCreator::setIsUsed(bool isUsed)
{
- m_projectParts = std::move(projectsParts);
+ m_isUsed = isUsed;
+}
+
+bool PchCreator::isUsed() const
+{
+ return m_isUsed;
+}
- generatePchs();
+void PchCreator::clear()
+{
+ m_projectPartPch = ProjectPartPch{};
+ m_projectIncludeIds = IdPaths{};
+}
+
+void PchCreator::doInMainThreadAfterFinished()
+{
+ m_pchManagerClient.precompiledHeadersUpdated(ProjectPartPchs{m_projectPartPch});
+ m_fileSystemWatcher.updateIdPaths({takeProjectIncludes()});
}
-std::vector<IdPaths> PchCreator::takeProjectsIncludes()
+const IdPaths &PchCreator::projectIncludes() const
{
- return std::move(m_projectsIncludeIds);
+ return m_projectIncludeIds;
}
-void PchCreator::setGenerator(PchGeneratorInterface *pchGenerator)
+const FilePathCaching &PchCreator::filePathCache()
{
- m_pchGenerator = pchGenerator;
+ return m_filePathCache;
}
std::unique_ptr<QFile> PchCreator::generateFileWithContent(
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h
index 65425296b6..b3e0dcde56 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h
@@ -27,10 +27,9 @@
#include "pchcreatorinterface.h"
-#include "pchgeneratorinterface.h"
#include "idpaths.h"
-#include <filepathcachingfwd.h>
+#include <filepathcaching.h>
#include <projectpartpch.h>
#include <projectpartcontainerv2.h>
@@ -44,50 +43,40 @@ namespace ClangBackEnd {
class Environment;
class GeneratedFiles;
+class PchManagerClientInterface;
+class ClangPathWatcherInterface;
class PchCreator final : public PchCreatorInterface
{
public:
PchCreator(Environment &environment,
- FilePathCachingInterface &filePathCache,
- const GeneratedFiles &generatedFiles);
- PchCreator(V2::ProjectPartContainers &&projectsParts,
- Environment &environment,
- FilePathCachingInterface &filePathCache,
- PchGeneratorInterface *pchGenerator,
- const GeneratedFiles &generatedFiles);
-
- void generatePchs(V2::ProjectPartContainers &&projectsParts) override;
- std::vector<IdPaths> takeProjectsIncludes() override;
-
- void setGenerator(PchGeneratorInterface *pchGenerator);
-
-unittest_public:
- Utils::PathStringVector generateGlobalHeaderPaths() const;
- Utils::PathStringVector generateGlobalSourcePaths() const;
- Utils::PathStringVector generateGlobalHeaderAndSourcePaths() const;
- Utils::SmallStringVector generateGlobalArguments() const;
- Utils::SmallStringVector generateGlobalCommandLine() const;
- Utils::SmallStringVector generateGlobalPchCompilerArguments() const;
- Utils::SmallStringVector generateGlobalClangCompilerArguments() const;
-
- FilePathIds generateGlobalPchIncludeIds() const;
+ Sqlite::Database &database,
+ PchManagerClientInterface &pchManagerClient,
+ ClangPathWatcherInterface &fileSystemWatcher)
+ : m_filePathCache(database),
+ m_environment(environment),
+ m_pchManagerClient(pchManagerClient),
+ m_fileSystemWatcher(fileSystemWatcher)
+ {
+ }
+
+ void generatePch(const V2::ProjectPartContainer &projectsPart) override;
+ IdPaths takeProjectIncludes() override;
+ const ProjectPartPch &projectPartPch() override;
+ void setUnsavedFiles(const V2::FileContainers &fileContainers) override;
+ void setIsUsed(bool isUsed) override;
+ bool isUsed() const override;
+ void clear() override;
+ void doInMainThreadAfterFinished() override;
+
+ const IdPaths &projectIncludes() const;
+ const FilePathCaching &filePathCache();
Utils::SmallString generatePchIncludeFileContent(const FilePathIds &includeIds) const;
- Utils::SmallString generateGlobalPchHeaderFileContent() const;
- std::unique_ptr<QFile> generateGlobalPchHeaderFile();
- void generatePch(Utils::SmallStringVector &&commandLineArguments,
- ProjectPartPch &&projectPartPch);
- void generateGlobalPch();
-
- Utils::SmallString globalPchContent() const;
+ bool generatePch(Utils::SmallStringVector &&commandLineArguments);
static QStringList convertToQStringList(const Utils::SmallStringVector &convertToQStringList);
- Utils::SmallString generateGlobalPchFilePathWithoutExtension() const;
- Utils::SmallString generateGlobalPchHeaderFilePath() const;
- Utils::SmallString generateGlobalPchFilePath() const;
-
Utils::SmallStringVector generateProjectPartCommandLine(
const V2::ProjectPartContainer &projectPart) const;
Utils::SmallString generateProjectPartPchFilePathWithoutExtension(
@@ -116,20 +105,18 @@ unittest_public:
const Utils::SmallString &filePath,
const Utils::SmallString &content);
- void generatePchs();
-
private:
static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart);
- QByteArray globalProjectHash() const;
private:
- V2::ProjectPartContainers m_projectParts;
- std::vector<ProjectPartPch> m_projectPartPchs;
- std::vector<IdPaths> m_projectsIncludeIds;
- const GeneratedFiles &m_generatedFiles;
+ ProjectPartPch m_projectPartPch;
+ IdPaths m_projectIncludeIds;
+ FilePathCaching m_filePathCache;
+ V2::FileContainers m_unsavedFiles;
Environment &m_environment;
- FilePathCachingInterface &m_filePathCache;
- PchGeneratorInterface *m_pchGenerator = nullptr;
+ PchManagerClientInterface &m_pchManagerClient;
+ ClangPathWatcherInterface &m_fileSystemWatcher;
+ bool m_isUsed = false;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
index dd33176519..c3098577f7 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
@@ -27,21 +27,23 @@
#include "idpaths.h"
#include "projectpartpch.h"
+#include "processorinterface.h"
#include <filecontainerv2.h>
#include <projectpartcontainerv2.h>
namespace ClangBackEnd {
-class PchCreatorInterface
+class PchCreatorInterface : public ProcessorInterface
{
public:
PchCreatorInterface() = default;
PchCreatorInterface(const PchCreatorInterface &) = delete;
PchCreatorInterface &operator=(const PchCreatorInterface &) = delete;
- virtual void generatePchs(V2::ProjectPartContainers &&projectsParts) = 0;
- virtual std::vector<IdPaths> takeProjectsIncludes() = 0;
+ virtual void generatePch(const V2::ProjectPartContainer &projectsPart) = 0;
+ virtual IdPaths takeProjectIncludes() = 0;
+ virtual const ProjectPartPch &projectPartPch() = 0;
protected:
~PchCreatorInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/pchgenerator.h b/src/tools/clangpchmanagerbackend/source/pchgenerator.h
deleted file mode 100644
index 144f21bffa..0000000000
--- a/src/tools/clangpchmanagerbackend/source/pchgenerator.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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 "environment.h"
-#include "pchgeneratorinterface.h"
-#include "pchgeneratornotifierinterface.h"
-
-#include <projectpartpch.h>
-
-#include <QProcess>
-
-#include <queue>
-
-namespace ClangBackEnd {
-
-template <typename Process>
-class PchGenerator final : public PchGeneratorInterface
-{
-public:
- PchGenerator(Environment &environment,
- PchGeneratorNotifierInterface *notifier=nullptr)
- : m_environment(environment),
- m_notifier(notifier)
- {
- }
-
- ~PchGenerator()
- {
- cleanupAllProcesses();
- }
-
- void startTask(Utils::SmallStringVector &&compilerArguments, ProjectPartPch &&projectPartPch) override
- {
- addTask(std::move(compilerArguments), std::move(projectPartPch));
- }
-
- void setNotifier(PchGeneratorNotifierInterface *notifier)
- {
- m_notifier = notifier;
- }
-
-unittest_public:
- Process *addTask(Utils::SmallStringVector &&compilerArguments, ProjectPartPch &&projectPartPch)
- {
- auto process = std::make_unique<Process>();
- Process *processPointer = process.get();
-
- process->setProcessChannelMode(QProcess::ForwardedChannels);
- process->setArguments(QStringList(compilerArguments));
- process->setProgram(QString(m_environment.clangCompilerPath()));
-
- connectProcess(processPointer, std::move(projectPartPch));
-
- if (!deferProcess())
- startProcess(std::move(process));
- else
- m_deferredProcesses.push(std::move(process));
-
- return processPointer;
- }
-
- void connectProcess(Process *process, ProjectPartPch &&projectPartPch)
- {
- auto finishedCallback = [=,projectPartPch=std::move(projectPartPch)] (int exitCode, QProcess::ExitStatus exitStatus) {
- deleteProcess(process);
- activateNextDeferredProcess();
- m_notifier->taskFinished(generateTaskFinishStatus(exitCode, exitStatus), projectPartPch);
- };
-
- QObject::connect(process,
- static_cast<void (Process::*)(int, QProcess::ExitStatus)>(&Process::finished),
- std::move(finishedCallback));
- }
-
- void startProcess(std::unique_ptr<Process> &&process)
- {
- process->start();
- m_runningProcesses.push_back(std::move(process));
- }
-
- const std::vector<std::unique_ptr<Process>> &runningProcesses() const
- {
- return m_runningProcesses;
- }
-
- const std::queue<std::unique_ptr<Process>> &deferredProcesses() const
- {
- return m_deferredProcesses;
- }
-
- void deleteProcess(Process *process)
- {
- auto found = std::find_if(m_runningProcesses.begin(),
- m_runningProcesses.end(),
- [=] (const std::unique_ptr<Process> &entry) {
- return entry.get() == process;
- });
-
- if (found != m_runningProcesses.end()) {
- std::unique_ptr<Process> avoidDoubleDeletedProcess = std::move(*found);
- m_runningProcesses.erase(found);
- }
- }
-
- void cleanupAllProcesses()
- {
- std::vector<std::unique_ptr<Process>> runningProcesses = std::move(m_runningProcesses);
- std::queue<std::unique_ptr<Process>> deferredProcesses = std::move(m_deferredProcesses);
- }
-
- static TaskFinishStatus generateTaskFinishStatus(int exitCode, QProcess::ExitStatus exitStatus)
- {
- if (exitCode != 0 || exitStatus != QProcess::NormalExit)
- return TaskFinishStatus::Unsuccessfully;
- else
- return TaskFinishStatus::Successfully;
- }
-
- bool deferProcess() const
- {
- return m_environment.hardwareConcurrency() <= m_runningProcesses.size();
- }
-
- void activateNextDeferredProcess()
- {
- if (!m_deferredProcesses.empty()) {
- std::unique_ptr<Process> process = std::move(m_deferredProcesses.front());
- m_deferredProcesses.pop();
-
- startProcess(std::move(process));
- }
- }
-
-private:
- std::vector<std::unique_ptr<Process>> m_runningProcesses;
- std::queue<std::unique_ptr<Process>> m_deferredProcesses;
- Environment &m_environment;
- PchGeneratorNotifierInterface *m_notifier=nullptr;
-};
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchgeneratornotifierinterface.h b/src/tools/clangpchmanagerbackend/source/pchgeneratornotifierinterface.h
deleted file mode 100644
index 32f47c9f5c..0000000000
--- a/src/tools/clangpchmanagerbackend/source/pchgeneratornotifierinterface.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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 <iosfwd>
-
-namespace ClangBackEnd {
-
-class ProjectPartPch;
-
-enum class TaskFinishStatus
-{
- Successfully,
- Unsuccessfully
-};
-
-class PchGeneratorNotifierInterface
-{
-public:
- PchGeneratorNotifierInterface() = default;
- PchGeneratorNotifierInterface(const PchGeneratorNotifierInterface &) = delete;
- PchGeneratorNotifierInterface &operator=(const PchGeneratorNotifierInterface &) = delete;
-
- virtual void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) = 0;
-
-protected:
- ~PchGeneratorNotifierInterface() = default;
-};
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
index e165365d30..7ce2e553a2 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
@@ -27,6 +27,7 @@
#include <pchmanagerclientinterface.h>
#include <precompiledheadersupdatedmessage.h>
+#include <projectpartqueue.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
#include <updategeneratedfilesmessage.h>
@@ -39,11 +40,11 @@
namespace ClangBackEnd {
PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
- PchCreatorInterface &pchCreator,
+ ProjectPartQueueInterface &projectPartQueue,
ProjectPartsInterface &projectParts,
GeneratedFilesInterface &generatedFiles)
: m_fileSystemWatcher(fileSystemWatcher),
- m_pchCreator(pchCreator),
+ m_projectPartQueue(projectPartQueue),
m_projectParts(projectParts),
m_generatedFiles(generatedFiles)
{
@@ -58,9 +59,7 @@ void PchManagerServer::end()
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
{
- m_pchCreator.generatePchs(m_projectParts.update(message.takeProjectsParts()));
-
- m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
+ m_projectPartQueue.addProjectParts(m_projectParts.update(message.takeProjectsParts()));
}
void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
@@ -68,6 +67,8 @@ void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
m_fileSystemWatcher.removeIds(message.projectsPartIds);
m_projectParts.remove(message.projectsPartIds);
+
+ m_projectPartQueue.removeProjectParts(message.projectsPartIds);
}
void PchManagerServer::updateGeneratedFiles(UpdateGeneratedFilesMessage &&message)
@@ -82,19 +83,11 @@ void PchManagerServer::removeGeneratedFiles(RemoveGeneratedFilesMessage &&messag
void PchManagerServer::pathsWithIdsChanged(const Utils::SmallStringVector &ids)
{
- m_pchCreator.generatePchs(m_projectParts.projects(ids));
-
- m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
+ m_projectPartQueue.addProjectParts(m_projectParts.projects(ids));
}
void PchManagerServer::pathsChanged(const FilePathIds &/*filePathIds*/)
{
}
-void PchManagerServer::taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch)
-{
- if (status == TaskFinishStatus::Successfully)
- client()->precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage({projectPartPch.clone()}));
-}
-
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
index 717ba03359..66b6c85e99 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
@@ -28,7 +28,6 @@
#include "clangpathwatcherinterface.h"
#include "clangpathwatchernotifier.h"
#include "pchcreatorinterface.h"
-#include "pchgeneratornotifierinterface.h"
#include "pchmanagerserverinterface.h"
#include "projectpartsinterface.h"
@@ -38,16 +37,16 @@
namespace ClangBackEnd {
class SourceRangesAndDiagnosticsForQueryMessage;
+class ProjectPartQueueInterface;
class PchManagerServer : public PchManagerServerInterface,
public ClangPathWatcherNotifier,
- public PchGeneratorNotifierInterface,
public IpcClientProvider<PchManagerClientInterface>
{
public:
PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
- PchCreatorInterface &pchCreator,
+ ProjectPartQueueInterface &projectPartQueue,
ProjectPartsInterface &projectParts,
GeneratedFilesInterface &generatedFiles);
@@ -59,11 +58,10 @@ public:
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
void pathsChanged(const FilePathIds &filePathIds) override;
- void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override;
private:
ClangPathWatcherInterface &m_fileSystemWatcher;
- PchCreatorInterface &m_pchCreator;
+ ProjectPartQueueInterface &m_projectPartQueue;
ProjectPartsInterface &m_projectParts;
GeneratedFilesInterface &m_generatedFiles;
};
diff --git a/src/plugins/clangpchmanager/precompiledheaderstorage.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
index 4ad57e980a..94c454231e 100644
--- a/src/plugins/clangpchmanager/precompiledheaderstorage.h
+++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
@@ -32,7 +32,7 @@
#include <utils/smallstringview.h>
-namespace ClangPchManager {
+namespace ClangBackEnd {
template<typename Database=Sqlite::Database>
class PrecompiledHeaderStorage final : public PrecompiledHeaderStorageInterface
diff --git a/src/plugins/clangpchmanager/precompiledheaderstorageinterface.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
index 1c834acbd3..9ff6e1efe2 100644
--- a/src/plugins/clangpchmanager/precompiledheaderstorageinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
@@ -27,7 +27,7 @@
#include <utils/smallstringview.h>
-namespace ClangPchManager {
+namespace ClangBackEnd {
class PrecompiledHeaderStorageInterface
{
@@ -47,4 +47,4 @@ protected:
~PrecompiledHeaderStorageInterface() = default;
};
-} // namespace ClangPchManager
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/processorinterface.h b/src/tools/clangpchmanagerbackend/source/processorinterface.h
new file mode 100644
index 0000000000..444c6c6ddb
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/processorinterface.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <filecontainerv2.h>
+
+namespace ClangBackEnd {
+
+class ProcessorInterface
+{
+public:
+ ProcessorInterface() = default;
+ virtual ~ProcessorInterface() = default;
+ ProcessorInterface(const ProcessorInterface &) = delete;
+ ProcessorInterface &operator=(const ProcessorInterface &) = delete;
+
+ virtual void setUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
+ virtual bool isUsed() const = 0;
+ virtual void setIsUsed(bool isUsed) = 0;
+ virtual void clear() = 0;
+ virtual void doInMainThreadAfterFinished() = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectormanager.h b/src/tools/clangpchmanagerbackend/source/processormanager.h
index d5a020904f..be20c5d87f 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollectormanager.h
+++ b/src/tools/clangpchmanagerbackend/source/processormanager.h
@@ -25,8 +25,8 @@
#pragma once
-#include "symbolscollectormanagerinterface.h"
-#include "symbolscollectorinterface.h"
+
+#include "processormanagerinterface.h"
#include "generatedfiles.h"
#include <memory>
@@ -38,51 +38,54 @@ class Database;
namespace ClangBackEnd {
class GeneratedFiles;
-class SymbolsCollector;
-template<typename SymbolsCollector>
-class SymbolsCollectorManager final : public SymbolsCollectorManagerInterface
+
+template <typename ProcessorType>
+class ProcessorManager : public ProcessorManagerInterface
{
public:
- SymbolsCollectorManager(Sqlite::Database &database,
- const GeneratedFiles &generatedFiles)
- : m_database(database),
- m_generatedFiles(generatedFiles)
+ using Processor = ProcessorType;
+ ProcessorManager(const GeneratedFiles &generatedFiles)
+ : m_generatedFiles(generatedFiles)
{}
- SymbolsCollector &unusedSymbolsCollector() override
+ Processor &unusedProcessor() override
{
- auto split = std::partition(m_collectors.begin(),
- m_collectors.end(),
+ auto split = std::partition(m_processors.begin(),
+ m_processors.end(),
[] (const auto &collector) {
return collector->isUsed();
});
- auto freeCollectors = std::distance(split, m_collectors.end());
+ auto freeCollectors = std::distance(split, m_processors.end());
if (freeCollectors > 0)
return initializedCollector(*split->get());
- m_collectors.emplace_back(std::make_unique<SymbolsCollector>(m_database));
+ m_processors.push_back(createProcessor());
- return initializedCollector(*m_collectors.back().get());
+ return initializedCollector(*m_processors.back().get());
}
- const std::vector<std::unique_ptr<SymbolsCollector>> &collectors() const
+ const std::vector<std::unique_ptr<Processor>> &processors() const
{
- return m_collectors;
+ return m_processors;
}
+protected:
+ ~ProcessorManager() = default;
+ virtual std::unique_ptr<Processor> createProcessor() const = 0;
+
private:
- SymbolsCollector &initializedCollector(SymbolsCollector &collector)
+ Processor &initializedCollector(Processor &creator)
{
- collector.setIsUsed(true);
- collector.setUnsavedFiles(m_generatedFiles.fileContainers());
- return collector;
+ creator.setIsUsed(true);
+ creator.setUnsavedFiles(m_generatedFiles.fileContainers());
+ return creator;
}
+
private:
- std::vector<std::unique_ptr<SymbolsCollector>> m_collectors;
- Sqlite::Database &m_database;
+ std::vector<std::unique_ptr<Processor>> m_processors;
const GeneratedFiles &m_generatedFiles;
};
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectormanagerinterface.h b/src/tools/clangpchmanagerbackend/source/processormanagerinterface.h
index b0cb3a0332..13d02fbc94 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollectormanagerinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/processormanagerinterface.h
@@ -25,25 +25,23 @@
#pragma once
-#include <filecontainerv2.h>
+#include <processorinterface.h>
-#include <vector>
+#include <filecontainerv2.h>
namespace ClangBackEnd {
-class SymbolsCollectorInterface;
-
-class SymbolsCollectorManagerInterface
+class ProcessorManagerInterface
{
public:
- SymbolsCollectorManagerInterface() = default;
- SymbolsCollectorManagerInterface(const SymbolsCollectorManagerInterface &) = delete;
- SymbolsCollectorManagerInterface &operator=(const SymbolsCollectorManagerInterface &) = delete;
+ ProcessorManagerInterface() = default;
+ ProcessorManagerInterface(const ProcessorManagerInterface &) = delete;
+ ProcessorManagerInterface &operator=(const ProcessorManagerInterface &) = delete;
- virtual SymbolsCollectorInterface &unusedSymbolsCollector() = 0;
+ virtual ProcessorInterface &unusedProcessor() = 0;
protected:
- ~SymbolsCollectorManagerInterface() = default;
+ ~ProcessorManagerInterface() = default;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp b/src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp
new file mode 100644
index 0000000000..e61913ac04
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "projectpartqueue.h"
+
+#include <pchcreatorinterface.h>
+#include <precompiledheaderstorageinterface.h>
+#include <sqlitetransaction.h>
+
+namespace ClangBackEnd {
+
+void ProjectPartQueue::addProjectParts(V2::ProjectPartContainers &&projectParts)
+{
+ auto compare = [](const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
+ return first.projectPartId < second.projectPartId;
+ };
+
+ V2::ProjectPartContainers mergedProjectParts;
+ mergedProjectParts.reserve(m_projectParts.size() + projectParts.size());
+ std::set_union(std::make_move_iterator(projectParts.begin()),
+ std::make_move_iterator(projectParts.end()),
+ std::make_move_iterator(m_projectParts.begin()),
+ std::make_move_iterator(m_projectParts.end()),
+ std::back_inserter(mergedProjectParts),
+ compare);
+
+ m_projectParts = std::move(mergedProjectParts);
+}
+
+class CompareDifference
+{
+public:
+ bool operator()(const V2::ProjectPartContainer &first, const Utils::SmallString &second)
+ {
+ return first.projectPartId < second;
+ }
+
+ bool operator()(const Utils::SmallString &first, const V2::ProjectPartContainer &second)
+ {
+ return first < second.projectPartId;
+ }
+};
+
+void ProjectPartQueue::removeProjectParts(const Utils::SmallStringVector &projectsPartIds)
+{
+ V2::ProjectPartContainers notToBeRemovedProjectParts;
+ notToBeRemovedProjectParts.reserve(m_projectParts.size());
+ std::set_difference(std::make_move_iterator(m_projectParts.begin()),
+ std::make_move_iterator(m_projectParts.end()),
+ projectsPartIds.begin(),
+ projectsPartIds.end(),
+ std::back_inserter(notToBeRemovedProjectParts),
+ CompareDifference{});
+
+ m_projectParts = std::move(notToBeRemovedProjectParts);
+}
+
+void ProjectPartQueue::processEntries()
+{
+ uint taskCount = m_taskScheduler.freeSlots();
+
+ auto newEnd = std::prev(m_projectParts.end(), std::min<int>(int(taskCount), int(m_projectParts.size())));
+ m_taskScheduler.addTasks(
+ createPchTasks({std::make_move_iterator(newEnd),
+ std::make_move_iterator(m_projectParts.end())}));
+ m_projectParts.erase(newEnd, m_projectParts.end());
+}
+
+const V2::ProjectPartContainers &ProjectPartQueue::projectParts() const
+{
+ return m_projectParts;
+}
+
+std::vector<ProjectPartQueue::Task> ProjectPartQueue::createPchTasks(
+ V2::ProjectPartContainers &&projectParts) const
+{
+ std::vector<Task> tasks;
+ tasks.reserve(projectParts.size());
+
+ auto convert = [this] (auto &&projectPart) {
+ return [projectPart=std::move(projectPart), this] (PchCreatorInterface &pchCreator) {
+ pchCreator.generatePch(projectPart);
+ const auto &projectPartPch = pchCreator.projectPartPch();
+ Sqlite::ImmediateTransaction transaction(m_transactionsInterface);
+ if (projectPartPch.pchPath.empty()) {
+ m_precompiledHeaderStorage.deletePrecompiledHeader(projectPartPch.projectPartId);
+ } else {
+ m_precompiledHeaderStorage.insertPrecompiledHeader(projectPartPch.projectPartId,
+ projectPartPch.pchPath,
+ projectPartPch.lastModified);
+ }
+ transaction.commit();
+ };
+ };
+
+ std::transform(std::make_move_iterator(projectParts.begin()),
+ std::make_move_iterator(projectParts.end()),
+ std::back_inserter(tasks),
+ convert);
+
+ return tasks;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskschedulerinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartqueue.h
index c71454df3d..55b490fc64 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskschedulerinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/projectpartqueue.h
@@ -25,8 +25,8 @@
#pragma once
-#include <functional>
-#include <vector>
+#include "projectpartqueueinterface.h"
+#include "taskschedulerinterface.h"
namespace Sqlite {
class TransactionInterface;
@@ -34,27 +34,37 @@ class TransactionInterface;
namespace ClangBackEnd {
-class SymbolsCollectorInterface;
-class SymbolStorageInterface;
+class PrecompiledHeaderStorageInterface;
+class PchTaskSchedulerInterface;
+class PchCreatorInterface;
-using uint = unsigned int;
-
-class SymbolIndexerTaskSchedulerInterface
+class ProjectPartQueue final : public ProjectPartQueueInterface
{
public:
- using Task = std::function<void(SymbolsCollectorInterface &symbolsCollector,
- SymbolStorageInterface &symbolStorage,
- Sqlite::TransactionInterface &transaction)>;
+ using Task = std::function<void (PchCreatorInterface&)>;
+
+ ProjectPartQueue(TaskSchedulerInterface<Task> &taskScheduler,
+ PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
+ Sqlite::TransactionInterface &transactionsInterface)
+ : m_taskScheduler(taskScheduler),
+ m_precompiledHeaderStorage(precompiledHeaderStorage),
+ m_transactionsInterface(transactionsInterface)
+ {}
+
+ void addProjectParts(V2::ProjectPartContainers &&projectParts);
+ void removeProjectParts(const Utils::SmallStringVector &projectsPartIds);
+
+ void processEntries();
- SymbolIndexerTaskSchedulerInterface() = default;
- SymbolIndexerTaskSchedulerInterface(const SymbolIndexerTaskSchedulerInterface &) = delete;
- SymbolIndexerTaskSchedulerInterface &operator=(const SymbolIndexerTaskSchedulerInterface &) = delete;
+ const V2::ProjectPartContainers &projectParts() const;
- virtual void addTasks(std::vector<Task> &&tasks) = 0;
- virtual uint freeSlots() = 0;
+ std::vector<Task> createPchTasks(V2::ProjectPartContainers &&projectParts) const;
-protected:
- ~SymbolIndexerTaskSchedulerInterface() = default;
+private:
+ V2::ProjectPartContainers m_projectParts;
+ TaskSchedulerInterface<Task> &m_taskScheduler;
+ PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage;
+ Sqlite::TransactionInterface &m_transactionsInterface;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h
new file mode 100644
index 0000000000..0b705fe312
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "queueinterface.h"
+
+#include <projectpartcontainerv2.h>
+
+namespace ClangBackEnd {
+
+class ProjectPartQueueInterface : public QueueInterface
+{
+public:
+ virtual void addProjectParts(V2::ProjectPartContainers &&projectParts) = 0;
+ virtual void removeProjectParts(const Utils::SmallStringVector &projectsPartIds) = 0;
+
+protected:
+ ~ProjectPartQueueInterface() = default;
+};
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.cpp b/src/tools/clangpchmanagerbackend/source/projectparts.cpp
index b1689f036d..6be06380bf 100644
--- a/src/tools/clangpchmanagerbackend/source/projectparts.cpp
+++ b/src/tools/clangpchmanagerbackend/source/projectparts.cpp
@@ -35,9 +35,7 @@ inline namespace Pch {
V2::ProjectPartContainers ProjectParts::update(V2::ProjectPartContainers &&projectsParts)
{
- auto uniqueProjectParts = ProjectParts::uniqueProjectParts(std::move(projectsParts));
-
- auto updatedProjectPartContainers = newProjectParts(std::move(uniqueProjectParts));
+ auto updatedProjectPartContainers = newProjectParts(std::move(projectsParts));
mergeProjectParts(updatedProjectPartContainers);
@@ -68,16 +66,6 @@ V2::ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector
return projectPartsWithIds;
}
-V2::ProjectPartContainers ProjectParts::uniqueProjectParts(V2::ProjectPartContainers &&projectsParts)
-{
- std::sort(projectsParts.begin(), projectsParts.end());
- auto newEnd = std::unique(projectsParts.begin(), projectsParts.end());
-
- projectsParts.erase(newEnd, projectsParts.end());
-
- return std::move(projectsParts);
-}
-
V2::ProjectPartContainers ProjectParts::newProjectParts(V2::ProjectPartContainers &&projectsParts) const
{
V2::ProjectPartContainers updatedProjectPartContainers;
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.h b/src/tools/clangpchmanagerbackend/source/projectparts.h
index 67c8bc0256..c0d9c61e7f 100644
--- a/src/tools/clangpchmanagerbackend/source/projectparts.h
+++ b/src/tools/clangpchmanagerbackend/source/projectparts.h
@@ -43,7 +43,6 @@ public:
V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const override;
unittest_public:
- static V2::ProjectPartContainers uniqueProjectParts(V2::ProjectPartContainers &&projectsParts);
V2::ProjectPartContainers newProjectParts(V2::ProjectPartContainers &&projectsParts) const;
void mergeProjectParts(const V2::ProjectPartContainers &projectsParts);
const V2::ProjectPartContainers &projectParts() const;
diff --git a/src/tools/clangpchmanagerbackend/source/pchgeneratorinterface.h b/src/tools/clangpchmanagerbackend/source/queueinterface.h
index c25eb248b2..d8ec0c69ed 100644
--- a/src/tools/clangpchmanagerbackend/source/pchgeneratorinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/queueinterface.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -29,21 +29,16 @@
namespace ClangBackEnd {
-class ProjectPartPch;
-
-class PchGeneratorInterface
+class QueueInterface
{
public:
- PchGeneratorInterface() = default;
- PchGeneratorInterface(const PchGeneratorInterface &) = delete;
- PchGeneratorInterface &operator=(const PchGeneratorInterface &) = delete;
+ QueueInterface() = default;
+ QueueInterface(const QueueInterface &) = delete;
+ QueueInterface &operator=(const QueueInterface &) = delete;
- virtual void startTask(Utils::SmallStringVector &&compilerArguments,
- ProjectPartPch &&projectPartPch) = 0;
+ virtual void processEntries() = 0;
protected:
- ~PchGeneratorInterface() = default;
+ ~QueueInterface() = default;
};
-
} // namespace ClangBackEnd
-
diff --git a/src/tools/clangpchmanagerbackend/source/taskscheduler.h b/src/tools/clangpchmanagerbackend/source/taskscheduler.h
new file mode 100644
index 0000000000..35c3c51984
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/taskscheduler.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "taskschedulerinterface.h"
+#include "symbolindexertask.h"
+#include "queueinterface.h"
+
+#include <processormanagerinterface.h>
+#include <symbolindexertaskqueueinterface.h>
+#include <symbolscollectorinterface.h>
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QMetaObject>
+#include <QThread>
+
+#include <algorithm>
+#include <functional>
+#include <future>
+#include <thread>
+#include <vector>
+
+namespace Sqlite {
+class TransactionInterface;
+};
+
+namespace ClangBackEnd {
+
+class FilePathCachingInterface;
+class ProcessorManagerInterface;
+class QueueInterface;
+class SymbolStorageInterface;
+
+template <typename ProcessorManager,
+ typename Task>
+class TaskScheduler : public TaskSchedulerInterface<Task>
+{
+public:
+ using ProcessorInterface = typename ProcessorManager::Processor;
+ using Future = std::future<ProcessorInterface&>;
+
+ TaskScheduler(ProcessorManager &symbolsCollectorManager,
+ QueueInterface &queue,
+ uint hardwareConcurrency,
+ std::launch launchPolicy = std::launch::async)
+ : m_processorManager(symbolsCollectorManager),
+ m_queue(queue),
+ m_hardwareConcurrency(hardwareConcurrency),
+ m_launchPolicy(launchPolicy)
+ {}
+
+ void addTasks(std::vector<Task> &&tasks)
+ {
+ for (auto &task : tasks) {
+ auto callWrapper = [&, task=std::move(task)] (auto processor)
+ -> ProcessorInterface& {
+ task(processor.get());
+ executeInLoop([&] {
+ m_queue.processEntries();
+ });
+
+ return processor;
+ };
+ m_futures.emplace_back(std::async(m_launchPolicy,
+ std::move(callWrapper),
+ std::ref(m_processorManager.unusedProcessor())));
+ }
+ }
+
+ const std::vector<Future> &futures() const
+ {
+ return m_futures;
+ }
+
+ uint freeSlots()
+ {
+ removeFinishedFutures();
+
+ if (m_isDisabled)
+ return 0;
+
+ return uint(std::max(int(m_hardwareConcurrency) - int(m_futures.size()), 0));
+ }
+
+ void syncTasks()
+ {
+ for (auto &future : m_futures)
+ future.wait();
+ }
+
+ void disable()
+ {
+ m_isDisabled = true;
+ }
+
+private:
+ void removeFinishedFutures()
+ {
+ auto notReady = [] (Future &future) {
+ return future.wait_for(std::chrono::duration<int>::zero()) != std::future_status::ready;
+ };
+
+ auto split = std::partition(m_futures.begin(), m_futures.end(), notReady);
+
+ std::for_each(split, m_futures.end(), [] (Future &future) {
+ ProcessorInterface &processor = future.get();
+ processor.doInMainThreadAfterFinished();
+ processor.setIsUsed(false);
+ processor.clear();
+ });
+
+ m_futures.erase(split, m_futures.end());
+ }
+
+ #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
+ template <typename CallableType>
+ class CallableEvent : public QEvent {
+ public:
+ using Callable = std::decay_t<CallableType>;
+ CallableEvent(Callable &&callable)
+ : QEvent(QEvent::None),
+ callable(std::move(callable))
+ {}
+ CallableEvent(const Callable &callable)
+ : QEvent(QEvent::None),
+ callable(callable)
+ {}
+
+ ~CallableEvent()
+ {
+ callable();
+ }
+ public:
+ Callable callable;
+ };
+
+ template <typename Callable>
+ void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) {
+ if (QThread *thread = qobject_cast<QThread*>(object))
+ object = QAbstractEventDispatcher::instance(thread);
+
+ QCoreApplication::postEvent(object,
+ new CallableEvent<Callable>(std::forward<Callable>(callable)),
+ Qt::HighEventPriority);
+ }
+ #else
+ template <typename Callable>
+ void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) {
+ if (QThread *thread = qobject_cast<QThread*>(object))
+ object = QAbstractEventDispatcher::instance(thread);
+
+ QMetaObject::invokeMethod(object, std::forward<Callable>(callable));
+ }
+ #endif
+
+private:
+ std::vector<Future> m_futures;
+ ProcessorManager &m_processorManager;
+ QueueInterface &m_queue;
+ uint m_hardwareConcurrency;
+ std::launch m_launchPolicy;
+ bool m_isDisabled = false;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/taskschedulerinterface.h b/src/tools/clangpchmanagerbackend/source/taskschedulerinterface.h
new file mode 100644
index 0000000000..a79a3ed8d2
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/taskschedulerinterface.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <vector>
+
+namespace ClangBackEnd {
+
+using uint = unsigned int;
+
+template <typename Task>
+class TaskSchedulerInterface
+{
+public:
+ TaskSchedulerInterface() = default;
+ TaskSchedulerInterface(const TaskSchedulerInterface &) = delete;
+ TaskSchedulerInterface &operator=(const TaskSchedulerInterface &) = delete;
+
+ virtual void addTasks(std::vector<Task> &&tasks) = 0;
+ virtual uint freeSlots() = 0;
+
+protected:
+ ~TaskSchedulerInterface() = default;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro b/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro
index 072d254728..ea66a43b61 100644
--- a/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro
+++ b/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro
@@ -17,6 +17,7 @@ QT -= gui
LIBS += $$LIBTOOLING_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH
+INCLUDEPATH += ../clangpchmanagerbackend/source
QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index d15e0f625d..26fa44aa68 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -24,11 +24,7 @@ HEADERS += \
$$PWD/indexdataconsumer.h \
$$PWD/sourcesmanager.h \
$$PWD/symbolindexertaskqueue.h \
- $$PWD/symbolindexertaskscheduler.h \
- $$PWD/symbolscollectormanagerinterface.h \
$$PWD/symbolindexertaskqueueinterface.h \
- $$PWD/symbolindexertaskschedulerinterface.h \
- $$PWD/symbolscollectormanager.h \
$$PWD/symbolindexertask.h
!isEmpty(LIBTOOLING_LIBS) {
@@ -74,6 +70,4 @@ SOURCES += \
$$PWD/sourcerangefilter.cpp \
$$PWD/symbolindexer.cpp \
$$PWD/projectpartartefact.cpp \
- $$PWD/filestatuscache.cpp \
- $$PWD/symbolindexertaskqueue.cpp \
- $$PWD/symbolindexertaskscheduler.cpp
+ $$PWD/filestatuscache.cpp
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index 5c9f0cbccc..272e89fa89 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -101,27 +101,25 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
std::vector<SymbolIndexerTask> symbolIndexerTask;
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
- auto indexing = [projectPartId, arguments, sourcePathId]
- (SymbolsCollectorInterface &symbolsCollector,
- SymbolStorageInterface &symbolStorage,
- Sqlite::TransactionInterface &transactionInterface) {
+ auto indexing = [projectPartId, arguments, sourcePathId, this]
+ (SymbolsCollectorInterface &symbolsCollector) {
symbolsCollector.setFile(sourcePathId, arguments);
symbolsCollector.collectSymbols();
- Sqlite::ImmediateTransaction transaction{transactionInterface};
+ Sqlite::ImmediateTransaction transaction{m_transactionInterface};
- symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
- symbolsCollector.sourceLocations());
+ m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
+ symbolsCollector.sourceLocations());
- symbolStorage.updateProjectPartSources(projectPartId,
- symbolsCollector.sourceFiles());
+ m_symbolStorage.updateProjectPartSources(projectPartId,
+ symbolsCollector.sourceFiles());
- symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
+ m_symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
- symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
+ m_symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
- symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
+ m_symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
transaction.commit();
};
@@ -130,7 +128,7 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
}
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
- m_symbolIndexerTaskQueue.processTasks();
+ m_symbolIndexerTaskQueue.processEntries();
}
void SymbolIndexer::pathsWithIdsChanged(const Utils::SmallStringVector &)
@@ -146,7 +144,7 @@ void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds)
updateChangedPath(filePathId, symbolIndexerTask);
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
- m_symbolIndexerTaskQueue.processTasks();
+ m_symbolIndexerTaskQueue.processEntries();
}
void SymbolIndexer::updateChangedPath(FilePathId filePathId,
@@ -169,26 +167,24 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
const Utils::SmallStringVector arguments = compilerArguments(artefact.compilerArguments,
optionalProjectPartPch);
- auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId]
- (SymbolsCollectorInterface &symbolsCollector,
- SymbolStorageInterface &symbolStorage,
- Sqlite::TransactionInterface &transactionInterface) {
+ auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId, this]
+ (SymbolsCollectorInterface &symbolsCollector) {
symbolsCollector.setFile(filePathId, arguments);
symbolsCollector.collectSymbols();
- Sqlite::ImmediateTransaction transaction{transactionInterface};
+ Sqlite::ImmediateTransaction transaction{m_transactionInterface};
- symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
- symbolsCollector.sourceLocations());
+ m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
+ symbolsCollector.sourceLocations());
- symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
+ m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
- symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
+ m_symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
- symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
+ m_symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
- symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
+ m_symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
transaction.commit();
};
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertask.h b/src/tools/clangrefactoringbackend/source/symbolindexertask.h
index 3b18681e07..de3303815d 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexertask.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexertask.h
@@ -35,16 +35,13 @@ class TransactionInterface;
namespace ClangBackEnd {
-class SymbolIndexerTaskSchedulerInterface;
class SymbolsCollectorInterface;
class SymbolStorageInterface;
class SymbolIndexerTask
{
public:
- using Callable = std::function<void(SymbolsCollectorInterface &symbolsCollector,
- SymbolStorageInterface &symbolStorage,
- Sqlite::TransactionInterface &transaction)>;
+ using Callable = std::function<void(SymbolsCollectorInterface &symbolsCollector)>;
SymbolIndexerTask(FilePathId filePathId,
int projectPartId,
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp
deleted file mode 100644
index bb891467a6..0000000000
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 "symbolindexertaskqueue.h"
-
-#include <symbolindexertaskschedulerinterface.h>
-
-#include <utils/algorithm.h>
-
-namespace ClangBackEnd {
-
-void SymbolIndexerTaskQueue::addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
-{
- auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
- first.callable = std::move(second.callable);
-
- return std::move(first);
- };
-
- m_tasks = Utils::setUnionMerge<std::vector<SymbolIndexerTask>>(tasks, m_tasks, merge);
-}
-
-void SymbolIndexerTaskQueue::removeTasks(const std::vector<int> &projectPartIds)
-{
- auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
- return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
- };
-
- auto newEnd = std::remove_if(m_tasks.begin(), m_tasks.end(), shouldBeRemoved);
-
- m_tasks.erase(newEnd, m_tasks.end());
-}
-
-const std::vector<SymbolIndexerTask> &SymbolIndexerTaskQueue::tasks() const
-{
- return m_tasks;
-}
-
-void SymbolIndexerTaskQueue::processTasks()
-{
- int taskCount = m_symbolIndexerScheduler.freeSlots();
-
- auto newEnd = std::prev(m_tasks.end(), std::min<int>(taskCount, int(m_tasks.size())));
- m_symbolIndexerScheduler.addTasks({std::make_move_iterator(newEnd),
- std::make_move_iterator(m_tasks.end())});
- m_tasks.erase(newEnd, m_tasks.end());
-}
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h
index 6a627e8865..3dc54998d0 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h
@@ -29,7 +29,9 @@
#include "symbolindexertask.h"
#include <filepathid.h>
+#include <taskschedulerinterface.h>
+#include <utils/algorithm.h>
#include <utils/smallstringvector.h>
#include <functional>
@@ -41,29 +43,59 @@ class TransactionInterface;
namespace ClangBackEnd {
-class SymbolIndexerTaskSchedulerInterface;
class SymbolsCollectorInterface;
class SymbolStorageInterface;
class SymbolIndexerTaskQueue final : public SymbolIndexerTaskQueueInterface
{
public:
- SymbolIndexerTaskQueue(SymbolIndexerTaskSchedulerInterface &symbolIndexerTaskScheduler)
+ using Task = SymbolIndexerTask::Callable;
+
+ SymbolIndexerTaskQueue(TaskSchedulerInterface<Task> &symbolIndexerTaskScheduler)
: m_symbolIndexerScheduler(symbolIndexerTaskScheduler)
{}
- void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks);
- void removeTasks(const std::vector<int> &projectPartIds);
+ void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
+ {
+ auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
+ first.callable = std::move(second.callable);
+
+ return std::move(first);
+ };
+
+ m_tasks = Utils::setUnionMerge<std::vector<SymbolIndexerTask>>(tasks, m_tasks, merge);
+ }
+ void removeTasks(const std::vector<int> &projectPartIds)
+ {
+ auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
+ return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
+ };
+
+ auto newEnd = std::remove_if(m_tasks.begin(), m_tasks.end(), shouldBeRemoved);
+
+ m_tasks.erase(newEnd, m_tasks.end());
+ }
+
+ const std::vector<SymbolIndexerTask> &tasks() const
+ {
+ return m_tasks;
+ }
- const std::vector<SymbolIndexerTask> &tasks() const;
+ void processEntries()
+ {
+ uint taskCount = m_symbolIndexerScheduler.freeSlots();
- void processTasks();
+ auto newEnd = std::prev(m_tasks.end(), std::min<int>(int(taskCount), int(m_tasks.size())));
+ m_symbolIndexerScheduler.addTasks({std::make_move_iterator(newEnd),
+ std::make_move_iterator(m_tasks.end())});
+ m_tasks.erase(newEnd, m_tasks.end());
+ }
void syncTasks();
private:
std::vector<Utils::SmallString> m_projectPartIds;
std::vector<SymbolIndexerTask> m_tasks;
- SymbolIndexerTaskSchedulerInterface &m_symbolIndexerScheduler;
+ TaskSchedulerInterface<Task> &m_symbolIndexerScheduler;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h
index 9e96a79e6c..dfcc78bd23 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h
@@ -25,24 +25,21 @@
#pragma once
+#include <queueinterface.h>
+
#include <utils/smallstringvector.h>
namespace ClangBackEnd {
class SymbolIndexerTask;
-class SymbolIndexerTaskQueueInterface
+class SymbolIndexerTaskQueueInterface : public QueueInterface
{
public:
- SymbolIndexerTaskQueueInterface() = default;
- SymbolIndexerTaskQueueInterface(const SymbolIndexerTaskQueueInterface &) = delete;
- SymbolIndexerTaskQueueInterface &operator=(const SymbolIndexerTaskQueueInterface &) = delete;
-
virtual void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) = 0
/* [[expects: std::is_sorted(tasks)]] */;
virtual void removeTasks(const std::vector<int> &projectPartIds) = 0
/* [[expects: std::is_sorted(projectPartIds)]] */;
- virtual void processTasks() = 0;
protected:
~SymbolIndexerTaskQueueInterface() = default;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.cpp b/src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.cpp
deleted file mode 100644
index e9f5cbe285..0000000000
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 "symbolindexertaskscheduler.h"
-
-#include <symbolindexertaskqueueinterface.h>
-#include <symbolscollectormanagerinterface.h>
-#include <symbolscollectorinterface.h>
-
-#include <QAbstractEventDispatcher>
-#include <QCoreApplication>
-#include <QMetaObject>
-#include <QThread>
-
-#include <algorithm>
-#include <thread>
-
-namespace ClangBackEnd {
-namespace {
-#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
-template <typename CallableType>
-class CallableEvent : public QEvent {
-public:
- using Callable = std::decay_t<CallableType>;
- CallableEvent(Callable &&callable)
- : QEvent(QEvent::None),
- callable(std::move(callable))
- {}
- CallableEvent(const Callable &callable)
- : QEvent(QEvent::None),
- callable(callable)
- {}
-
- ~CallableEvent()
- {
- callable();
- }
-public:
- Callable callable;
-};
-
-template <typename Callable>
-void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) {
- if (QThread *thread = qobject_cast<QThread*>(object))
- object = QAbstractEventDispatcher::instance(thread);
-
- QCoreApplication::postEvent(object,
- new CallableEvent<Callable>(std::forward<Callable>(callable)),
- Qt::HighEventPriority);
-}
-#else
-template <typename Callable>
-void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) {
- if (QThread *thread = qobject_cast<QThread*>(object))
- object = QAbstractEventDispatcher::instance(thread);
-
- QMetaObject::invokeMethod(object, std::forward<Callable>(callable));
-}
-#endif
-}
-
-void SymbolIndexerTaskScheduler::addTasks(std::vector<Task> &&tasks)
-{
- for (auto &task : tasks) {
- auto callWrapper = [&, task=std::move(task)] (
- std::reference_wrapper<SymbolsCollectorInterface> symbolsCollector)
- -> SymbolsCollectorInterface& {
- task(symbolsCollector.get(), m_symbolStorage, m_transactionInterface);
- executeInLoop([&] {
- m_symbolIndexerTaskQueue.processTasks();
- });
-
- return symbolsCollector;
- };
- m_futures.emplace_back(std::async(m_launchPolicy,
- std::move(callWrapper),
- std::ref(m_symbolsCollectorManager.unusedSymbolsCollector())));
- }
-}
-
-const std::vector<SymbolIndexerTaskScheduler::Future> &SymbolIndexerTaskScheduler::futures() const
-{
- return m_futures;
-}
-
-uint SymbolIndexerTaskScheduler::freeSlots()
-{
- removeFinishedFutures();
-
- if (m_isDisabled)
- return 0;
-
- return uint(std::max(int(m_hardware_concurrency) - int(m_futures.size()), 0));
-}
-
-void SymbolIndexerTaskScheduler::syncTasks()
-{
- for (auto &future : m_futures)
- future.wait();
-}
-
-void SymbolIndexerTaskScheduler::disable()
-{
- m_isDisabled = true;
-}
-
-void SymbolIndexerTaskScheduler::removeFinishedFutures()
-{
- auto notReady = [] (Future &future) {
- return future.wait_for(std::chrono::duration<int>::zero()) != std::future_status::ready;
- };
-
- auto split = std::partition(m_futures.begin(), m_futures.end(), notReady);
-
- std::for_each(split, m_futures.end(), [] (Future &future) {
- SymbolsCollectorInterface &symbolCollector = future.get();
- symbolCollector.setIsUsed(false);
- symbolCollector.clear();
- });
-
- m_futures.erase(split, m_futures.end());
-}
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.h
deleted file mode 100644
index 6182376dab..0000000000
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskscheduler.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 "symbolindexertaskschedulerinterface.h"
-#include "symbolindexertask.h"
-
-#include <functional>
-#include <future>
-#include <vector>
-
-namespace Sqlite {
-class TransactionInterface;
-};
-
-namespace ClangBackEnd {
-
-class FilePathCachingInterface;
-class SymbolsCollectorInterface;
-class SymbolsCollectorManagerInterface;
-class SymbolIndexerTaskQueueInterface;
-class SymbolStorageInterface;
-
-class SymbolIndexerTaskScheduler final : public SymbolIndexerTaskSchedulerInterface
-{
-public:
- using Task = SymbolIndexerTask::Callable;
- using Future = std::future<SymbolsCollectorInterface&>;
-
- SymbolIndexerTaskScheduler(SymbolsCollectorManagerInterface &symbolsCollectorManager,
- SymbolStorageInterface &symbolStorage,
- Sqlite::TransactionInterface &transactionInterface,
- SymbolIndexerTaskQueueInterface &symbolIndexerTaskQueue,
- uint hardware_concurrency,
- std::launch launchPolicy = std::launch::async)
- : m_symbolsCollectorManager(symbolsCollectorManager),
- m_symbolStorage(symbolStorage),
- m_transactionInterface(transactionInterface),
- m_symbolIndexerTaskQueue(symbolIndexerTaskQueue),
- m_hardware_concurrency(hardware_concurrency),
- m_launchPolicy(launchPolicy)
- {}
-
- void addTasks(std::vector<Task> &&tasks);
-
- const std::vector<Future> &futures() const;
-
- uint freeSlots();
-
- void syncTasks();
-
- void disable();
-
-private:
- void removeFinishedFutures();
-
-private:
- std::vector<Future> m_futures;
- SymbolsCollectorManagerInterface &m_symbolsCollectorManager;
- SymbolStorageInterface &m_symbolStorage;
- Sqlite::TransactionInterface &m_transactionInterface;
- SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue;
- uint m_hardware_concurrency;
- std::launch m_launchPolicy;
- bool m_isDisabled = false;
-};
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
index 8f7821bddb..918edb626a 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexing.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -30,9 +30,9 @@
#include "storagesqlitestatementfactory.h"
#include "symbolindexer.h"
#include "symbolscollector.h"
-#include "symbolscollectormanager.h"
+#include "processormanager.h"
#include "symbolindexertaskqueue.h"
-#include "symbolindexertaskscheduler.h"
+#include "taskscheduler.h"
#include "symbolstorage.h"
#include <refactoringdatabaseinitializer.h>
@@ -48,19 +48,40 @@
namespace ClangBackEnd {
+class SymbolsCollectorManager;
+
+class SymbolsCollectorManager final : public ClangBackEnd::ProcessorManager<SymbolsCollector>
+{
+public:
+ using Processor = SymbolsCollector;
+ SymbolsCollectorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
+ Sqlite::Database &database)
+ : ProcessorManager(generatedFiles),
+ m_database(database)
+ {}
+
+protected:
+ std::unique_ptr<SymbolsCollector> createProcessor() const
+ {
+ return std::make_unique<SymbolsCollector>(m_database);
+ }
+
+private:
+ Sqlite::Database &m_database;
+};
+
class SymbolIndexing final : public SymbolIndexingInterface
{
public:
using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<Sqlite::Database>;
using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
-
SymbolIndexing(Sqlite::Database &database,
FilePathCachingInterface &filePathCache,
const GeneratedFiles &generatedFiles)
: m_filePathCache(filePathCache),
m_statementFactory(database),
- m_collectorManger(database, generatedFiles),
- m_indexerScheduler(m_collectorManger, m_symbolStorage, database, m_indexerQueue, std::thread::hardware_concurrency())
+ m_collectorManger(generatedFiles, database),
+ m_indexerScheduler(m_collectorManger, m_indexerQueue, std::thread::hardware_concurrency())
{
}
@@ -86,12 +107,13 @@ public:
void updateProjectParts(V2::ProjectPartContainers &&projectParts) override;
private:
+ using SymbolIndexerTaskScheduler = TaskScheduler<SymbolsCollectorManager, SymbolIndexerTask::Callable>;
FilePathCachingInterface &m_filePathCache;
StatementFactory m_statementFactory;
Storage m_symbolStorage{m_statementFactory};
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
FileStatusCache m_fileStatusCache{m_filePathCache};
- SymbolsCollectorManager<SymbolsCollector> m_collectorManger;
+ SymbolsCollectorManager m_collectorManger;
SymbolIndexerTaskScheduler m_indexerScheduler;
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler};
SymbolIndexer m_indexer{m_indexerQueue,
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
index 53e0bbba6e..afa01de2e9 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
@@ -129,6 +129,10 @@ void SymbolsCollector::collectSymbols()
&m_collectMacrosSourceFileCallbacks).get());
}
+void SymbolsCollector::doInMainThreadAfterFinished()
+{
+}
+
const SymbolEntries &SymbolsCollector::symbols() const
{
return m_symbolEntries;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h
index 70213555d6..beb610d190 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h
@@ -54,6 +54,8 @@ public:
void collectSymbols() override;
+ void doInMainThreadAfterFinished() override;
+
const SymbolEntries &symbols() const override;
const SourceLocationEntries &sourceLocations() const override;
const FilePathIds &sourceFiles() const override;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
index 540866630f..0b7e00509d 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
@@ -31,7 +31,7 @@
#include "sourcelocationentry.h"
#include "usedmacro.h"
-#include <filecontainerv2.h>
+#include <processorinterface.h>
#include <utils/smallstringvector.h>
@@ -40,20 +40,10 @@
namespace ClangBackEnd {
-class SymbolsCollectorInterface
+class SymbolsCollectorInterface : public ProcessorInterface
{
public:
- SymbolsCollectorInterface() = default;
- virtual ~SymbolsCollectorInterface() = default;
- SymbolsCollectorInterface(const SymbolsCollectorInterface &) = delete;
- SymbolsCollectorInterface &operator=(const SymbolsCollectorInterface &) = delete;
-
virtual void setFile(FilePathId filePathId, const Utils::SmallStringVector &arguments) = 0;
-
- virtual void setUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
-
- virtual void clear() = 0;
-
virtual void collectSymbols() = 0;
virtual const SymbolEntries &symbols() const = 0;
@@ -62,9 +52,6 @@ public:
virtual const UsedMacros &usedMacros() const = 0;
virtual const FileStatuses &fileStatuses() const = 0;
virtual const SourceDependencies &sourceDependencies() const = 0;
-
- virtual bool isUsed() const = 0;
- virtual void setIsUsed(bool isUsed) = 0;
};
} // namespace ClangBackEnd
diff --git a/tests/unit/unittest/data/includecollector_faulty.cpp b/tests/unit/unittest/data/includecollector_faulty.cpp
new file mode 100644
index 0000000000..a25ff9062c
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_faulty.cpp
@@ -0,0 +1 @@
+#include "includecollector_faulty.h"
diff --git a/tests/unit/unittest/data/includecollector_faulty.h b/tests/unit/unittest/data/includecollector_faulty.h
new file mode 100644
index 0000000000..4a0601f95b
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_faulty.h
@@ -0,0 +1,8 @@
+#pragma once
+
+IDENTIFICATION DIVISION.
+PROGRAM-ID. HELLO-WORLD.
+* simple hello world program
+PROCEDURE DIVISION.
+ DISPLAY 'Hello world!'.
+ STOP RUN.
diff --git a/tests/unit/unittest/google-using-declarations.h b/tests/unit/unittest/google-using-declarations.h
index e7fe88065b..4f88488b4e 100644
--- a/tests/unit/unittest/google-using-declarations.h
+++ b/tests/unit/unittest/google-using-declarations.h
@@ -27,6 +27,7 @@
#include <gmock/gmock.h>
+
using testing::_;
using testing::A;
using testing::AllOf;
@@ -34,6 +35,8 @@ using testing::An;
using testing::AnyNumber;
using testing::AnyOf;
using testing::Assign;
+using testing::ByMove;
+using testing::ByRef;
using testing::Contains;
using testing::ElementsAre;
using testing::Field;
diff --git a/tests/unit/unittest/googletest.h b/tests/unit/unittest/googletest.h
index 6b01852fe2..e5d221d6a8 100644
--- a/tests/unit/unittest/googletest.h
+++ b/tests/unit/unittest/googletest.h
@@ -25,10 +25,15 @@
#pragma once
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include <gtest/gtest-printers.h>
+
#include "compare-operators.h"
#include "conditionally-disabled-tests.h"
diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp
index c2ce8a9cbc..ea59cc5942 100644
--- a/tests/unit/unittest/gtest-creator-printing.cpp
+++ b/tests/unit/unittest/gtest-creator-printing.cpp
@@ -621,7 +621,8 @@ std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch
{
out << "("
<< projectPartPch.projectPartId << ", "
- << projectPartPch.pchPath << ")";
+ << projectPartPch.pchPath << ", "
+ << projectPartPch.lastModified << ")";
return out;
}
diff --git a/tests/unit/unittest/mockpchcreator.h b/tests/unit/unittest/mockpchcreator.h
index 91ef19402b..4d1fd24707 100644
--- a/tests/unit/unittest/mockpchcreator.h
+++ b/tests/unit/unittest/mockpchcreator.h
@@ -35,13 +35,21 @@
class MockPchCreator : public ClangBackEnd::PchCreatorInterface
{
public:
- MOCK_METHOD1(generatePchs,
- void(const ClangBackEnd::V2::ProjectPartContainers &projectParts));
- MOCK_METHOD0(takeProjectsIncludes,
- std::vector<ClangBackEnd::IdPaths>());
+ MOCK_METHOD1(generatePch,
+ void(const ClangBackEnd::V2::ProjectPartContainer &projectPart));
+ MOCK_METHOD0(takeProjectIncludes,
+ ClangBackEnd::IdPaths());
+ MOCK_METHOD0(projectPartPch,
+ const ClangBackEnd::ProjectPartPch &());
+ MOCK_METHOD1(setUnsavedFiles,
+ void (const ClangBackEnd::V2::FileContainers &fileContainers));
+ MOCK_METHOD0(clear,
+ void());
+ MOCK_METHOD0(doInMainThreadAfterFinished,
+ void());
+ MOCK_CONST_METHOD0(isUsed,
+ bool());
+ MOCK_METHOD1(setIsUsed,
+ void(bool));
- void generatePchs(std::vector<ClangBackEnd::V2::ProjectPartContainer> &&projectParts) override
- {
- generatePchs(projectParts);
- }
};
diff --git a/tests/unit/unittest/mockprecompiledheaderstorage.h b/tests/unit/unittest/mockprecompiledheaderstorage.h
index 60ba352584..11493a5560 100644
--- a/tests/unit/unittest/mockprecompiledheaderstorage.h
+++ b/tests/unit/unittest/mockprecompiledheaderstorage.h
@@ -29,7 +29,7 @@
#include <precompiledheaderstorageinterface.h>
-class MockPrecompiledHeaderStorage : public ClangPchManager::PrecompiledHeaderStorageInterface
+class MockPrecompiledHeaderStorage : public ClangBackEnd::PrecompiledHeaderStorageInterface
{
public:
MOCK_METHOD3(insertPrecompiledHeader,
diff --git a/tests/unit/unittest/mockprocessor.h b/tests/unit/unittest/mockprocessor.h
new file mode 100644
index 0000000000..040d537ed4
--- /dev/null
+++ b/tests/unit/unittest/mockprocessor.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 "googletest.h"
+
+#include <processorinterface.h>
+
+namespace Sqlite {
+class Database;
+}
+
+class MockProcessor : public ClangBackEnd::ProcessorInterface
+{
+public:
+ MockProcessor()
+ {
+ ON_CALL(*this, setIsUsed(_)).WillByDefault(Invoke(this, &MockProcessor::setIsUsed2));
+ ON_CALL(*this, isUsed()).WillByDefault(Invoke(this, &MockProcessor::isUsed2));
+ ON_CALL(*this, setUnsavedFiles(_)).WillByDefault(Invoke(this, &MockProcessor::setHasUnsavedFiles));
+ }
+
+ MOCK_METHOD1(setUnsavedFiles,
+ void(const ClangBackEnd::V2::FileContainers &unsavedFiles));
+
+ MOCK_METHOD0(clear,
+ void());
+
+ MOCK_CONST_METHOD0(isUsed,
+ bool());
+
+ MOCK_METHOD1(setIsUsed,
+ void(bool));
+
+ MOCK_METHOD0(doInMainThreadAfterFinished,
+ void());
+
+ void setIsUsed2(bool isUsed)
+ {
+ used = isUsed;
+ }
+
+ bool isUsed2() const
+ {
+ return used;
+ }
+
+ void setHasUnsavedFiles(const ClangBackEnd::V2::FileContainers &unsavedFiles)
+ {
+ hasUnsavedFiles = true;
+ }
+
+public:
+ bool used = false;
+ bool hasUnsavedFiles = false;
+};
diff --git a/tests/unit/unittest/mockpchgeneratornotifier.h b/tests/unit/unittest/mockprocessormanager.h
index fe5b8b2af4..3252aada19 100644
--- a/tests/unit/unittest/mockpchgeneratornotifier.h
+++ b/tests/unit/unittest/mockprocessormanager.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,16 +23,14 @@
**
****************************************************************************/
-#pragma once
-
#include "googletest.h"
-#include <pchgeneratornotifierinterface.h>
+#include <processormanagerinterface.h>
-class MockPchGeneratorNotifier : public ClangBackEnd::PchGeneratorNotifierInterface
+class MockProcessorManager : public ClangBackEnd::ProcessorManagerInterface
{
public:
- MOCK_METHOD2(taskFinished,
- void (ClangBackEnd::TaskFinishStatus status,
- const ClangBackEnd::ProjectPartPch &projectPartPch));
+ using Processor = ClangBackEnd::ProcessorInterface;
+
+ MOCK_METHOD0(unusedProcessor, ClangBackEnd::ProcessorInterface &());
};
diff --git a/tests/unit/unittest/mockprojectpartqueue.h b/tests/unit/unittest/mockprojectpartqueue.h
new file mode 100644
index 0000000000..8d1ec1f66c
--- /dev/null
+++ b/tests/unit/unittest/mockprojectpartqueue.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "googletest.h"
+
+#include <projectpartqueueinterface.h>
+
+class MockProjectPartQueue : public ClangBackEnd::ProjectPartQueueInterface
+{
+public:
+ MOCK_METHOD1(addProjectParts,
+ void (const ClangBackEnd::V2::ProjectPartContainers &projectParts));
+ MOCK_METHOD1(removeProjectParts,
+ void (const Utils::SmallStringVector &projectsPartIds));
+
+ MOCK_METHOD0(processEntries, void ());
+
+ void addProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts) override
+ {
+ addProjectParts(projectParts);
+ }
+};
diff --git a/tests/unit/unittest/mocksymbolscollectormanager.h b/tests/unit/unittest/mockqueue.h
index aedd196c60..74c3513914 100644
--- a/tests/unit/unittest/mocksymbolscollectormanager.h
+++ b/tests/unit/unittest/mockqueue.h
@@ -27,12 +27,11 @@
#include "googletest.h"
-#include <symbolscollectormanagerinterface.h>
+#include <queueinterface.h>
-class MockSymbolsCollectorManager : public ClangBackEnd::SymbolsCollectorManagerInterface
+class MockQueue : public ClangBackEnd::QueueInterface
{
public:
- MOCK_METHOD0(unusedSymbolsCollector,
- ClangBackEnd::SymbolsCollectorInterface & ());
-
+ MOCK_METHOD0(processEntries, void());
};
+
diff --git a/tests/unit/unittest/mocksymbolindexertaskqueue.h b/tests/unit/unittest/mocksymbolindexertaskqueue.h
index 52be4cb942..7fb0d3f0bd 100644
--- a/tests/unit/unittest/mocksymbolindexertaskqueue.h
+++ b/tests/unit/unittest/mocksymbolindexertaskqueue.h
@@ -36,5 +36,5 @@ public:
void (std::vector<ClangBackEnd::SymbolIndexerTask> &&tasks));
MOCK_METHOD1(removeTasks,
void (const std::vector<int> &projectPartIds));
- MOCK_METHOD0(processTasks, void());
+ MOCK_METHOD0(processEntries, void());
};
diff --git a/tests/unit/unittest/mocksymbolscollector.h b/tests/unit/unittest/mocksymbolscollector.h
index 1bced44da9..b41a4bcd4a 100644
--- a/tests/unit/unittest/mocksymbolscollector.h
+++ b/tests/unit/unittest/mocksymbolscollector.h
@@ -60,6 +60,9 @@ public:
MOCK_METHOD0(clear,
void());
+ MOCK_METHOD0(doInMainThreadAfterFinished,
+ void());
+
MOCK_CONST_METHOD0(symbols,
const ClangBackEnd::SymbolEntries &());
diff --git a/tests/unit/unittest/mocksymbolindexertaskscheduler.h b/tests/unit/unittest/mocktaskscheduler.h
index c3b70ca93c..647e8aefc0 100644
--- a/tests/unit/unittest/mocksymbolindexertaskscheduler.h
+++ b/tests/unit/unittest/mocktaskscheduler.h
@@ -27,17 +27,19 @@
#include "googletest.h"
-#include <symbolindexertaskschedulerinterface.h>
+#include <taskschedulerinterface.h>
+#include <symbolindexertask.h>
-class MockSymbolIndexerTaskScheduler : public ClangBackEnd::SymbolIndexerTaskSchedulerInterface
+template <typename Task>
+class MockTaskScheduler : public ClangBackEnd::TaskSchedulerInterface<Task>
{
public:
- MOCK_METHOD1(addTasks,
- void (const std::vector<ClangBackEnd::SymbolIndexerTaskSchedulerInterface::Task> &));
+ MOCK_METHOD1_T(addTasks,
+ void (const std::vector<Task> &));
MOCK_METHOD0(freeSlots,
uint ());
- void addTasks(std::vector<ClangBackEnd::SymbolIndexerTaskSchedulerInterface::Task> &&tasks) override
+ void addTasks(std::vector<Task> &&tasks)
{
addTasks(tasks);
}
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
index 44bbcc7e1c..cd35d7fcae 100644
--- a/tests/unit/unittest/pchcreator-test.cpp
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -27,14 +27,15 @@
#include "fakeprocess.h"
-#include "mockpchgeneratornotifier.h"
+#include "mockclangpathwatcher.h"
+#include "mockpchmanagerclient.h"
#include "testenvironment.h"
#include <refactoringdatabaseinitializer.h>
#include <filepathcaching.h>
#include <generatedfiles.h>
#include <pchcreator.h>
-#include <pchgenerator.h>
+#include <precompiledheadersupdatedmessage.h>
#include <sqlitedatabase.h>
@@ -62,25 +63,28 @@ class PchCreator: public ::testing::Test
protected:
void SetUp()
{
- generatedFiles.update({generatedFile});
+ creator.setUnsavedFiles({generatedFile});
}
ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path)
{
- return filePathCache.filePathId(path);
+ return creator.filePathCache().filePathId(path);
}
protected:
- GeneratedFiles generatedFiles;
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
- ClangBackEnd::FilePathCaching filePathCache{database};
FilePath main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
FilePath main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
FilePath header1Path = TESTDATA_DIR "/includecollector_header1.h";
FilePath header2Path = TESTDATA_DIR "/includecollector_header2.h";
Utils::SmallStringView generatedFileName = "includecollector_generated_file.h";
FilePath generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h";
+ TestEnvironment environment;
+ FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}};
+ NiceMock<MockPchManagerClient> mockPchManagerClient;
+ NiceMock<MockClangPathWatcher> mockClangPathWatcher;
+ ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient, mockClangPathWatcher};
ProjectPartContainer projectPart1{"project1",
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
{{"DEFINE", "1"}},
@@ -93,90 +97,10 @@ protected:
{"/includes"},
{id(header2Path)},
{id(main2Path)}};
- TestEnvironment environment;
- FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}};
- NiceMock<MockPchGeneratorNotifier> mockPchGeneratorNotifier;
- ClangBackEnd::PchGenerator<FakeProcess> generator{environment, &mockPchGeneratorNotifier};
- ClangBackEnd::PchCreator creator{{projectPart1.clone(),projectPart2.clone()},
- environment,
- filePathCache,
- &generator,
- generatedFiles};
};
using PchCreatorSlowTest = PchCreator;
using PchCreatorVerySlowTest = PchCreator;
-TEST_F(PchCreator, CreateGlobalHeaderPaths)
-{
- auto filePaths = creator.generateGlobalHeaderPaths();
-
- ASSERT_THAT(filePaths,
- UnorderedElementsAre(header1Path, header2Path, generatedFilePath));
-}
-
-TEST_F(PchCreator, CreateGlobalSourcePaths)
-{
- auto filePaths = creator.generateGlobalSourcePaths();
-
- ASSERT_THAT(filePaths,
- UnorderedElementsAre(main1Path, main2Path));
-}
-
-TEST_F(PchCreator, CreateGlobalHeaderAndSourcePaths)
-{
- auto filePaths = creator.generateGlobalHeaderAndSourcePaths();
-
- ASSERT_THAT(filePaths,
- UnorderedElementsAre(main1Path, main2Path, header1Path, header2Path, generatedFilePath));
-}
-
-TEST_F(PchCreator, CreateGlobalArguments)
-{
- auto arguments = creator.generateGlobalArguments();
-
- ASSERT_THAT(arguments, ElementsAre("-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header", "-I", TESTDATA_DIR, "-x" , "c++-header", "-Wno-pragma-once-outside-header"));
-}
-
-TEST_F(PchCreator, CreateGlobalCommandLine)
-{
- auto arguments = creator.generateGlobalCommandLine();
-
- ASSERT_THAT(arguments, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header", "-I", TESTDATA_DIR, "-x" , "c++-header", "-Wno-pragma-once-outside-header"));
-}
-
-TEST_F(PchCreatorVerySlowTest, CreateGlobalPchIncludes)
-{
- auto includeIds = creator.generateGlobalPchIncludeIds();
-
- ASSERT_THAT(includeIds,
- AllOf(Contains(id(TESTDATA_DIR "/includecollector_external3.h")),
- Contains(id(TESTDATA_DIR "/includecollector_external1.h")),
- Contains(id(TESTDATA_DIR "/includecollector_external2.h"))));
-}
-
-TEST_F(PchCreatorVerySlowTest, CreateGlobalPchFileContent)
-{
- auto content = creator.generateGlobalPchHeaderFileContent();
-
- ASSERT_THAT(std::string(content),
- AllOf(HasSubstr("#include \"" TESTDATA_DIR "/includecollector_external3.h\"\n"),
- HasSubstr("#include \"" TESTDATA_DIR "/includecollector_external1.h\"\n"),
- HasSubstr("#include \"" TESTDATA_DIR "/includecollector_external2.h\"\n")));
-}
-
-TEST_F(PchCreatorVerySlowTest, CreateGlobalPchHeaderFile)
-{
- auto file = creator.generateGlobalPchHeaderFile();
- file->open(QIODevice::ReadOnly);
-
- auto content = file->readAll();
-
- ASSERT_THAT(content.toStdString(),
- AllOf(HasSubstr("#include \"" TESTDATA_DIR "/includecollector_external3.h\"\n"),
- HasSubstr("#include \"" TESTDATA_DIR "/includecollector_external1.h\"\n"),
- HasSubstr("#include \"" TESTDATA_DIR "/includecollector_external2.h\"\n")));
-}
-
TEST_F(PchCreator, ConvertToQStringList)
{
auto arguments = creator.convertToQStringList({"-I", TESTDATA_DIR});
@@ -184,23 +108,6 @@ TEST_F(PchCreator, ConvertToQStringList)
ASSERT_THAT(arguments, ElementsAre(QString("-I"), QString(TESTDATA_DIR)));
}
-TEST_F(PchCreator, CreateGlobalPchCompilerArguments)
-{
- auto arguments = creator.generateGlobalPchCompilerArguments();
-
- ASSERT_THAT(arguments, ElementsAre("-x","c++-header", "-Xclang", "-emit-pch", "-o", EndsWith(".pch"), EndsWith(".h")));
-}
-
-TEST_F(PchCreator, CreateGlobalClangCompilerArguments)
-{
- auto arguments = creator.generateGlobalClangCompilerArguments();
-
- ASSERT_THAT(arguments, AllOf(Contains("-Wno-pragma-once-outside-header"),
- Contains("-emit-pch"),
- Contains("-o"),
- Not(Contains(environment.clangCompilerPath()))));
-}
-
TEST_F(PchCreator, CreateProjectPartCommandLine)
{
auto commandLine = creator.generateProjectPartCommandLine(projectPart1);
@@ -275,10 +182,6 @@ TEST_F(PchCreator, CreateProjectPartPchCompilerArguments)
ASSERT_THAT(arguments, AllOf(Contains("-x"),
Contains("c++-header"),
-// Contains("-Xclang"),
-// Contains("-include-pch"),
-// Contains("-Xclang"),
-// Contains(EndsWith(".pch")),
Contains("-Xclang"),
Contains("-emit-pch"),
Contains("-o"),
@@ -295,63 +198,90 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArguments)
Not(Contains(environment.clangCompilerPath()))));
}
-TEST_F(PchCreatorVerySlowTest, ProjectPartPchsExistsAfterCreation)
+TEST_F(PchCreatorVerySlowTest, IncludesForCreatePchsForProjectParts)
+{
+ creator.generatePch(projectPart1);
+
+ ASSERT_THAT(creator.takeProjectIncludes().id, "project1");
+}
+
+TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
{
- creator.generateGlobalPch();
+ creator.generatePch(projectPart1);
- creator.generateProjectPartPch(projectPart1);
+ EXPECT_CALL(mockPchManagerClient,
+ precompiledHeadersUpdated(
+ Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartPchs,
+ ElementsAre(Eq(creator.projectPartPch())))));
- ASSERT_TRUE(QFileInfo::exists(QString(creator.generateProjectPathPchHeaderFilePath(projectPart1))));
+ creator.doInMainThreadAfterFinished();
}
-TEST_F(PchCreatorVerySlowTest, DISABLED_CreatePartPchs)
+TEST_F(PchCreatorVerySlowTest, UpdateFileWatcherIncludes)
{
- creator.generateGlobalPch();
+ creator.generatePch(projectPart1);
- auto includePaths = creator.generateProjectPartPch(projectPart1);
+ EXPECT_CALL(mockClangPathWatcher,
+ updateIdPaths(ElementsAre(creator.projectIncludes())));
- ASSERT_THAT(includePaths.id, projectPart1.projectPartId);
- ASSERT_THAT(includePaths.filePathIds,
- AllOf(Contains(FilePathId{1, 1}),
- Contains(FilePathId{1, 2}),
- Contains(FilePathId{1, 3})));
+ creator.doInMainThreadAfterFinished();
}
-TEST_F(PchCreatorVerySlowTest, IncludesForCreatePchsForProjectParts)
+TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
{
- creator.generatePchs();
+ creator.generatePch(projectPart1);
- ASSERT_THAT(creator.takeProjectsIncludes(),
- ElementsAre(Field(&IdPaths::id, "project1"),
- Field(&IdPaths::id, "project2")));
+ ASSERT_THAT(creator.takeProjectIncludes(),
+ AllOf(Field(&IdPaths::id, "project1"),
+ Field(&IdPaths::filePathIds, AllOf(Contains(id(TESTDATA_DIR "/includecollector_header2.h")),
+ Contains(id(TESTDATA_DIR "/includecollector_external1.h")),
+ Contains(id(TESTDATA_DIR "/includecollector_external2.h"))))));
}
-TEST_F(PchCreatorVerySlowTest, ProjectPartPchsForCreatePchsForProjectParts)
+TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForProjectPart)
{
- EXPECT_CALL(mockPchGeneratorNotifier,
- taskFinished(ClangBackEnd::TaskFinishStatus::Successfully,
- Field(&ProjectPartPch::projectPartId, "project1")));
- EXPECT_CALL(mockPchGeneratorNotifier,
- taskFinished(ClangBackEnd::TaskFinishStatus::Successfully,
- Field(&ProjectPartPch::projectPartId, "project2")));
-
- creator.generatePchs();
+ creator.generatePch(projectPart1);
+
+ ASSERT_THAT(creator.projectPartPch(),
+ AllOf(Field(&ProjectPartPch::projectPartId, Eq("project1")),
+ Field(&ProjectPartPch::pchPath, Not(IsEmpty())),
+ Field(&ProjectPartPch::lastModified, Not(Eq(-1)))));
}
-TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
+TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared)
+{
+ creator.generatePch(projectPart1);
+
+ creator.clear();
+
+ ASSERT_THAT(creator.projectPartPch(), ClangBackEnd::ProjectPartPch{});
+}
+
+
+TEST_F(PchCreatorVerySlowTest, ProjectIncludesCleared)
+{
+ creator.generatePch(projectPart1);
+
+ creator.clear();
+
+ ASSERT_THAT(creator.projectIncludes(), ClangBackEnd::IdPaths{});
+}
+
+TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesNoPchForProjectPart)
{
- creator.generatePchs();
-
- ASSERT_THAT(creator.takeProjectsIncludes(),
- ElementsAre(AllOf(Field(&IdPaths::id, "project1"),
- Field(&IdPaths::filePathIds, AllOf(Contains(id(TESTDATA_DIR "/includecollector_header2.h")),
- Contains(id(TESTDATA_DIR "/includecollector_external1.h")),
- Contains(id(TESTDATA_DIR "/includecollector_external2.h"))))),
- AllOf(Field(&IdPaths::id, "project2"),
- Field(&IdPaths::filePathIds, AllOf(Contains(id(TESTDATA_DIR "/includecollector_external1.h")),
- Contains(id(TESTDATA_DIR "/includecollector_external3.h")),
- Contains(id(TESTDATA_DIR "/includecollector_header1.h")),
- Contains(id(TESTDATA_DIR "/includecollector_external2.h")))))));
+ ProjectPartContainer faultyProjectPart{"faultyProject",
+ {"-I", TESTDATA_DIR},
+ {{"DEFINE", "1"}},
+ {"/includes"},
+ {},
+ {id(TESTDATA_DIR "/includecollector_faulty.cpp")}};
+
+ creator.generatePch(faultyProjectPart);
+
+ ASSERT_THAT(creator.projectPartPch(),
+ AllOf(Field(&ProjectPartPch::projectPartId, Eq("faultyProject")),
+ Field(&ProjectPartPch::pchPath, IsEmpty()),
+ Field(&ProjectPartPch::lastModified, Eq(-1))));
}
TEST_F(PchCreator, CreateProjectPartSourcesContent)
@@ -361,5 +291,12 @@ TEST_F(PchCreator, CreateProjectPartSourcesContent)
ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/includecollector_main3.cpp\"\n"));
}
+TEST_F(PchCreator, Call)
+{
+ auto content = creator.generateProjectPartSourcesContent(projectPart1);
+
+ ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/includecollector_main3.cpp\"\n"));
+}
+
}
diff --git a/tests/unit/unittest/pchgenerator-test.cpp b/tests/unit/unittest/pchgenerator-test.cpp
deleted file mode 100644
index 2bce237833..0000000000
--- a/tests/unit/unittest/pchgenerator-test.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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 "googletest.h"
-
-#include "fakeprocess.h"
-#include "testenvironment.h"
-#include "mockpchgeneratornotifier.h"
-
-#include <pchgenerator.h>
-
-namespace {
-
-using testing::_;
-using testing::Contains;
-using testing::Eq;
-using testing::NiceMock;
-using testing::Not;
-using testing::PrintToString;
-using ClangBackEnd::TaskFinishStatus;
-
-MATCHER_P(ContainsProcess, process,
- std::string(negation ? "isn't" : "is")
- + " process " + PrintToString(process))
-{
- auto found = std::find_if(arg.begin(),
- arg.end(),
- [&] (const std::unique_ptr<FakeProcess> &processOwner) {
- return processOwner.get() == process;
- });
-
- return found != arg.end();
-}
-
-class PchGenerator : public testing::Test
-{
-protected:
- TestEnvironment environment;
- NiceMock<MockPchGeneratorNotifier> mockNotifier;
- ClangBackEnd::PchGenerator<FakeProcess> generator{environment, &mockNotifier};
- Utils::SmallStringVector compilerArguments = {"-DXXXX", "-Ifoo"};
- ClangBackEnd::ProjectPartPch projectPartPch{"projectPartId", "/path/to/pch", 1};
-};
-
-TEST_F(PchGenerator, ProcessFinished)
-{
- EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Successfully, std::move(projectPartPch)));
-
- generator.startTask(compilerArguments.clone(), projectPartPch.clone());
-}
-
-TEST_F(PchGenerator, ProcessFinishedForDeferredProcess)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- generator.startTask(compilerArguments.clone(), projectPartPch.clone());
-
- EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Successfully, std::move(projectPartPch)))
- .Times(3);
-
- generator.startTask(compilerArguments.clone(), projectPartPch.clone());
- process->finish();
-}
-
-TEST_F(PchGenerator, ProcessSuccessfullyFinished)
-{
- EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Unsuccessfully, std::move(projectPartPch)));
-
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- process->finishUnsuccessfully();
-}
-
-TEST_F(PchGenerator, ProcessSuccessfullyFinishedByWrongExitCode)
-{
- EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Unsuccessfully, std::move(projectPartPch)));
-
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- process->finishUnsuccessfully();
-}
-
-TEST_F(PchGenerator, AddTaskAddsProcessToProcesses)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_THAT(generator.runningProcesses(), ContainsProcess(process));
-}
-
-TEST_F(PchGenerator, RemoveProcessAfterFinishingProcess)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- process->finish();
-
- ASSERT_THAT(generator.runningProcesses(), Not(ContainsProcess(process)));
-}
-
-TEST_F(PchGenerator, ProcessSuccessfullyFinishedByCrash)
-{
- EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Unsuccessfully, std::move(projectPartPch)));
-
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- process->finishByCrash();
-}
-
-TEST_F(PchGenerator, CreateProcess)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_THAT(generator.runningProcesses(), ContainsProcess(process));
-}
-
-TEST_F(PchGenerator, DeleteProcess)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- generator.deleteProcess(process);
-
- ASSERT_THAT(generator.runningProcesses(), Not(ContainsProcess(process)));
-}
-
-TEST_F(PchGenerator, StartProcessApplicationPath)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_THAT(process->applicationPath(), environment.clangCompilerPath());
-
-}
-
-TEST_F(PchGenerator, SetCompilerArguments)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_THAT(process->arguments(), compilerArguments);
-}
-
-TEST_F(PchGenerator, ProcessIsStartedAfterAddingTask)
-{
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_TRUE(process->isStarted());
-}
-
-TEST_F(PchGenerator, DeferProcess)
-{
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- auto deferProcess = generator.deferProcess();
-
- ASSERT_TRUE(deferProcess);
-}
-
-TEST_F(PchGenerator, ThirdTaskIsDeferred)
-{
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_THAT(process, generator.deferredProcesses().back().get());
-}
-
-TEST_F(PchGenerator, ThirdTaskIsNotRunning)
-{
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- ASSERT_THAT(generator.runningProcesses(), Not(ContainsProcess(process)));
-}
-
-TEST_F(PchGenerator, DoNotDeferProcess)
-{
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- auto deferProcess = generator.deferProcess();
-
- ASSERT_FALSE(deferProcess);
-}
-
-TEST_F(PchGenerator, DoNotActivateIfNothingIsDeferred)
-{
- generator.activateNextDeferredProcess();
-}
-
-TEST_F(PchGenerator, AfterActivationProcessIsRunning)
-{
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- generator.addTask(compilerArguments.clone(), projectPartPch.clone());
- auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
-
- generator.activateNextDeferredProcess();
-
- ASSERT_THAT(generator.runningProcesses(), ContainsProcess(process));
-}
-
-}
diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp
index 8c13055c5e..eceb32b0b0 100644
--- a/tests/unit/unittest/pchmanagerclient-test.cpp
+++ b/tests/unit/unittest/pchmanagerclient-test.cpp
@@ -52,8 +52,7 @@ class PchManagerClient : public ::testing::Test
{
protected:
NiceMock<MockPchManagerServer> mockPchManagerServer;
- NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
- ClangPchManager::PchManagerClient client{mockPrecompiledHeaderStorage};
+ ClangPchManager::PchManagerClient client;
NiceMock<MockPchManagerNotifier> mockPchManagerNotifier{client};
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
@@ -156,20 +155,4 @@ TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdIsUpdated)
42);
}
-TEST_F(PchManagerClient, ProjectPartPchAddedToDatabase)
-{
- EXPECT_CALL(mockPrecompiledHeaderStorage, insertPrecompiledHeader(TypedEq<Utils::SmallStringView>(projectPartId),
- TypedEq<Utils::SmallStringView>(pchFilePath),
- TypedEq<long long>(1)));
-
- client.precompiledHeadersUpdated(message.clone());
-}
-
-TEST_F(PchManagerClient, ProjectPartPchRemovedFromDatabase)
-{
- EXPECT_CALL(mockPrecompiledHeaderStorage, deletePrecompiledHeader(TypedEq<Utils::SmallStringView>(projectPartId)));
-
- projectUpdater.removeProjectParts({QString(projectPartId)});
-}
-
}
diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp
index 2e47694262..731960c4ed 100644
--- a/tests/unit/unittest/pchmanagerserver-test.cpp
+++ b/tests/unit/unittest/pchmanagerserver-test.cpp
@@ -27,7 +27,7 @@
#include "mockclangpathwatcher.h"
#include "mockpchmanagerclient.h"
-#include "mockpchcreator.h"
+#include "mockprojectpartqueue.h"
#include "mockprojectparts.h"
#include "mockgeneratedfiles.h"
@@ -46,25 +46,31 @@ using Utils::SmallString;
using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::V2::FileContainers;
using ClangBackEnd::V2::ProjectPartContainer;
-using ClangBackEnd::TaskFinishStatus;
class PchManagerServer : public ::testing::Test
{
- void SetUp() override;
+ void SetUp() override
+ {
+ server.setClient(&mockPchManagerClient);
+
+ ON_CALL(mockProjectParts, update(projectParts))
+ .WillByDefault(Return(projectParts));
+ }
+
ClangBackEnd::FilePathId id(Utils::SmallStringView path) const
{
return filePathCache.filePathId(ClangBackEnd::FilePathView(path));
}
protected:
- NiceMock<MockPchCreator> mockPchCreator;
+ NiceMock<MockProjectPartQueue> mockProjectPartQueue;
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
NiceMock<MockProjectParts> mockProjectParts;
NiceMock<MockGeneratedFiles> mockGeneratedFiles;
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
- ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchCreator, mockProjectParts, mockGeneratedFiles};
+ ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockProjectPartQueue, mockProjectParts, mockGeneratedFiles};
NiceMock<MockPchManagerClient> mockPchManagerClient;
SmallString projectPartId1 = "project1";
SmallString projectPartId2 = "project2";
@@ -72,7 +78,7 @@ protected:
PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
PathString header1Path = TESTDATA_DIR "/includecollector_header1.h";
PathString header2Path = TESTDATA_DIR "/includecollector_header2.h";
- std::vector<ClangBackEnd::IdPaths> idPaths = {{projectPartId1, {{1, 1}, {1, 2}}}};
+ ClangBackEnd::IdPaths idPath{projectPartId1, {{1, 1}, {1, 2}}};
ProjectPartContainer projectPart1{projectPartId1.clone(),
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
{{"DEFINE", "1"}},
@@ -86,35 +92,19 @@ protected:
{id(header2Path)},
{id(main2Path)}};
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
+ std::vector<ProjectPartContainer> projectParts2{projectPart2};
FileContainer generatedFile{{"/path/to/", "file"}, "content", {}};
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{Utils::clone(projectParts)};
- ClangBackEnd::ProjectPartPch projectPartPch1{projectPart1.projectPartId.clone(), "/path1/to/pch", 1};
- ClangBackEnd::ProjectPartPch projectPartPch2{projectPart2.projectPartId.clone(), "/path2/to/pch", 1};
- std::vector<ClangBackEnd::ProjectPartPch> projectPartPchs{projectPartPch1, projectPartPch2};
- ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage1{{projectPartPch1}};
- ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage2{{projectPartPch2}};
ClangBackEnd::RemoveProjectPartsMessage removeProjectPartsMessage{{projectPart1.projectPartId.clone(),
projectPart2.projectPartId.clone()}};
};
-TEST_F(PchManagerServer, CallPrecompiledHeadersForSuccessfullyFinishedTask)
-{
- EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage1));
-
- server.taskFinished(TaskFinishStatus::Successfully, projectPartPch1);
-}
-
-TEST_F(PchManagerServer, DoNotCallPrecompiledHeadersForUnsuccessfullyFinishedTask)
+TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue)
{
- EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage1))
- .Times(0);
+ InSequence s;
- server.taskFinished(TaskFinishStatus::Unsuccessfully, projectPartPch1);
-}
-
-TEST_F(PchManagerServer, CallBuildInPchCreator)
-{;
- EXPECT_CALL(mockPchCreator, generatePchs(updateProjectPartsMessage.projectsParts));
+ EXPECT_CALL(mockProjectParts, update(updateProjectPartsMessage.projectsParts)).WillOnce(Return(projectParts2));
+ EXPECT_CALL(mockProjectPartQueue, addProjectParts(Eq(projectParts2)));
server.updateProjectParts(updateProjectPartsMessage.clone());
}
@@ -137,20 +127,6 @@ TEST_F(PchManagerServer, RemoveGeneratedFilesCallsRemove)
server.removeGeneratedFiles(removeGeneratedFilesMessage.clone());
}
-TEST_F(PchManagerServer, UpdateIncludesOfFileWatcher)
-{
- EXPECT_CALL(mockClangPathWatcher, updateIdPaths(idPaths));
-
- server.updateProjectParts(updateProjectPartsMessage.clone());
-}
-
-TEST_F(PchManagerServer, GetChangedProjectPartsFromProjectParts)
-{
- EXPECT_CALL(mockProjectParts, update(_));
-
- server.updateProjectParts(updateProjectPartsMessage.clone());
-}
-
TEST_F(PchManagerServer, RemoveIncludesFromFileWatcher)
{
EXPECT_CALL(mockClangPathWatcher, removeIds(removeProjectPartsMessage.projectsPartIds));
@@ -169,45 +145,16 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
{
EXPECT_CALL(mockClangPathWatcher, setNotifier(_));
- ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchCreator, mockProjectParts, mockGeneratedFiles};
+ ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockProjectPartQueue, mockProjectParts, mockGeneratedFiles};
}
-TEST_F(PchManagerServer, CallProjectsInProjectPartsForIncludeChange)
+TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
{
- server.updateProjectParts(updateProjectPartsMessage.clone());
-
- EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId)));
-
- server.pathsWithIdsChanged({projectPartId1});
-}
-
-TEST_F(PchManagerServer, CallGeneratePchsInPchCreatorForIncludeChange)
-{
- server.updateProjectParts(updateProjectPartsMessage.clone());
-
- EXPECT_CALL(mockPchCreator, generatePchs(ElementsAre(projectPart1)));
+ EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId)))
+ .WillOnce(Return(std::vector<ClangBackEnd::V2::ProjectPartContainer>{{projectPart1}}));
+ EXPECT_CALL(mockProjectPartQueue, addProjectParts(ElementsAre(projectPart1)));
server.pathsWithIdsChanged({projectPartId1});
}
-TEST_F(PchManagerServer, CallUpdateIdPathsInFileSystemWatcherForIncludeChange)
-{
- server.updateProjectParts(updateProjectPartsMessage.clone());
-
- EXPECT_CALL(mockClangPathWatcher, updateIdPaths(idPaths));
-
- server.pathsWithIdsChanged({projectPartId1});
-}
-
-void PchManagerServer::SetUp()
-{
- server.setClient(&mockPchManagerClient);
-
- ON_CALL(mockProjectParts, update(projectParts))
- .WillByDefault(Return(projectParts));
- ON_CALL(mockProjectParts, projects(Utils::SmallStringVector{{projectPartId1}}))
- .WillByDefault(Return(std::vector<ClangBackEnd::V2::ProjectPartContainer>{{projectPart1}}));
- ON_CALL(mockPchCreator, takeProjectsIncludes())
- .WillByDefault(Return(idPaths));
-}
}
diff --git a/tests/unit/unittest/precompiledheaderstorage-test.cpp b/tests/unit/unittest/precompiledheaderstorage-test.cpp
index 86f46156cf..3910b9a370 100644
--- a/tests/unit/unittest/precompiledheaderstorage-test.cpp
+++ b/tests/unit/unittest/precompiledheaderstorage-test.cpp
@@ -34,7 +34,7 @@
namespace {
-using Storage = ClangPchManager::PrecompiledHeaderStorage<NiceMock<MockSqliteDatabase>>;
+using Storage = ClangBackEnd::PrecompiledHeaderStorage<NiceMock<MockSqliteDatabase>>;
class PrecompiledHeaderStorage : public testing::Test
{
@@ -133,7 +133,7 @@ TEST_F(PrecompiledHeaderStorage, CompilePrecompiledHeaderStatements)
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
- ASSERT_NO_THROW(ClangPchManager::PrecompiledHeaderStorage<>{database});
+ ASSERT_NO_THROW(ClangBackEnd::PrecompiledHeaderStorage<>{database});
}
}
diff --git a/tests/unit/unittest/processormanager-test.cpp b/tests/unit/unittest/processormanager-test.cpp
new file mode 100644
index 0000000000..c5da739b6c
--- /dev/null
+++ b/tests/unit/unittest/processormanager-test.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "googletest.h"
+
+#include "mockprocessor.h"
+
+#include <sqlitedatabase.h>
+#include <refactoringdatabaseinitializer.h>
+#include <processormanager.h>
+
+namespace {
+using ClangBackEnd::ProcessorInterface;
+
+class Manager final : public ClangBackEnd::ProcessorManager<NiceMock<MockProcessor>>
+{
+public:
+ using Processor = NiceMock<MockProcessor>;
+ Manager(const ClangBackEnd::GeneratedFiles &generatedFiles)
+ : ClangBackEnd::ProcessorManager<NiceMock<MockProcessor>>(generatedFiles)
+ {}
+
+protected:
+ std::unique_ptr<NiceMock<MockProcessor>> createProcessor() const override
+ {
+ return std::make_unique<NiceMock<MockProcessor>>();
+ }
+};
+
+class ProcessorManager : public testing::Test
+{
+protected:
+ ClangBackEnd::GeneratedFiles generatedFiles;
+ Manager manager{generatedFiles};
+};
+
+TEST_F(ProcessorManager, CreateUnsedProcessor)
+{
+ manager.unusedProcessor();
+
+ manager.unusedProcessor();
+
+ ASSERT_THAT(manager.processors(), SizeIs(2));
+}
+
+TEST_F(ProcessorManager, ReuseUnsedProcessor)
+{
+ auto &processor = manager.unusedProcessor();
+ processor.setIsUsed(false);
+
+ manager.unusedProcessor();
+
+ ASSERT_THAT(manager.processors(), SizeIs(1));
+}
+
+TEST_F(ProcessorManager, AsGetNewUnusedProcessorItIsSetUsed)
+{
+ auto &processor = manager.unusedProcessor();
+
+ ASSERT_TRUE(processor.isUsed());
+}
+
+TEST_F(ProcessorManager, AsGetReusedUnusedProcessorItIsSetUsed)
+{
+ auto &processor = manager.unusedProcessor();
+ processor.setIsUsed(false);
+
+ auto &processor2 = manager.unusedProcessor();
+
+ ASSERT_TRUE(processor2.isUsed());
+}
+
+TEST_F(ProcessorManager, UnusedProcessorIsInitializedWithUnsavedFiles)
+{
+ auto &processor = manager.unusedProcessor();
+
+ ASSERT_TRUE(processor.hasUnsavedFiles);
+}
+
+TEST_F(ProcessorManager, ReusedProcessorIsInitializedWithUnsavedFiles)
+{
+ auto &processor = manager.unusedProcessor();
+ processor.setIsUsed(false);
+
+ auto &processor2 = manager.unusedProcessor();
+
+ ASSERT_TRUE(processor2.hasUnsavedFiles);
+}
+
+}
diff --git a/tests/unit/unittest/projectpartqueue-test.cpp b/tests/unit/unittest/projectpartqueue-test.cpp
new file mode 100644
index 0000000000..3ab0430e39
--- /dev/null
+++ b/tests/unit/unittest/projectpartqueue-test.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "googletest.h"
+
+#include "mocktaskscheduler.h"
+#include "mockpchcreator.h"
+#include "mockprecompiledheaderstorage.h"
+#include "mocksqlitetransactionbackend.h"
+
+#include <projectpartqueue.h>
+
+namespace {
+
+class ProjectPartQueue : public testing::Test
+{
+protected:
+ MockTaskScheduler<ClangBackEnd::ProjectPartQueue::Task> mockTaskScheduler;
+ MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage;
+ MockSqliteTransactionBackend mockSqliteTransactionBackend;
+ ClangBackEnd::ProjectPartQueue queue{mockTaskScheduler, mockPrecompiledHeaderStorage, mockSqliteTransactionBackend};
+ ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
+ {"--yi"},
+ {{"YI","1"}},
+ {"/yi"},
+ {{1, 1}},
+ {{1, 2}}};
+ ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2",
+ {"--er"},
+ {{"ER","2"}},
+ {"/bar"},
+ {{2, 1}},
+ {{2, 2}}};
+ ClangBackEnd::V2::ProjectPartContainer projectPart2b{"ProjectPart2",
+ {"--liang"},
+ {{"LIANG","3"}},
+ {"/liang"},
+ {{2, 3}},
+ {{2, 2}, {2, 4}}};
+ ClangBackEnd::V2::ProjectPartContainer projectPart3{"ProjectPart3",
+ {"--san"},
+ {{"SAN","2"}},
+ {"/SAN"},
+ {{3, 1}},
+ {{3, 2}}};
+};
+
+TEST_F(ProjectPartQueue, AddProjectPart)
+{
+ queue.addProjectParts({projectPart1});
+
+ queue.addProjectParts({projectPart2});
+
+ ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
+}
+
+TEST_F(ProjectPartQueue, IgnoreIdenticalProjectPart)
+{
+ queue.addProjectParts({projectPart1, projectPart2});
+
+ queue.addProjectParts({projectPart1, projectPart2});
+
+ ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
+}
+
+TEST_F(ProjectPartQueue, ReplaceProjectPartWithSameId)
+{
+ queue.addProjectParts({projectPart1, projectPart2});
+
+ queue.addProjectParts({projectPart1, projectPart2b, projectPart3});
+
+ ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2b, projectPart3));
+}
+
+TEST_F(ProjectPartQueue, RemoveProjectPart)
+{
+ queue.addProjectParts({projectPart1, projectPart2, projectPart3});
+
+ queue.removeProjectParts({projectPart2.projectPartId});
+
+ ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart3));
+}
+
+TEST_F(ProjectPartQueue, ProcessTasksCallsFreeSlotsAndAddTasksInScheduler)
+{
+ InSequence s;
+ queue.addProjectParts({projectPart1, projectPart2});
+
+ EXPECT_CALL(mockTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
+ EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(2)));
+
+ queue.processEntries();
+}
+
+TEST_F(ProjectPartQueue, CreateTasksSizeEqualsInputSize)
+{
+ auto tasks = queue.createPchTasks({projectPart1, projectPart2});
+
+ ASSERT_THAT(tasks, SizeIs(2));
+}
+
+TEST_F(ProjectPartQueue, CreateTaskFromProjectPart)
+{
+ InSequence s;
+ MockPchCreator mockPchCreator;
+ ClangBackEnd::ProjectPartPch projectPartPch{"project1", "/path/to/pch", 99};
+ auto tasks = queue.createPchTasks({projectPart1});
+
+ EXPECT_CALL(mockPchCreator, generatePch(Eq(projectPart1)));
+ EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
+ EXPECT_CALL(mockSqliteTransactionBackend, lock());
+ EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
+ EXPECT_CALL(mockPrecompiledHeaderStorage, insertPrecompiledHeader(Eq("project1"), Eq("/path/to/pch"), 99));
+ EXPECT_CALL(mockSqliteTransactionBackend, commit());
+ EXPECT_CALL(mockSqliteTransactionBackend, unlock());
+
+ tasks.front()(mockPchCreator);
+}
+
+TEST_F(ProjectPartQueue, DeletePchEntryInDatabaseIfNoPchIsGenerated)
+{
+ InSequence s;
+ MockPchCreator mockPchCreator;
+ ClangBackEnd::ProjectPartPch projectPartPch{"project1", "", 0};
+ auto tasks = queue.createPchTasks({projectPart1});
+
+ EXPECT_CALL(mockPchCreator, generatePch(Eq(projectPart1)));
+ EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
+ EXPECT_CALL(mockSqliteTransactionBackend, lock());
+ EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
+ EXPECT_CALL(mockPrecompiledHeaderStorage, deletePrecompiledHeader(Eq("project1")));
+ EXPECT_CALL(mockSqliteTransactionBackend, commit());
+ EXPECT_CALL(mockSqliteTransactionBackend, unlock());
+
+ tasks.front()(mockPchCreator);
+}
+
+
+//TEST_F(PchManagerClient, ProjectPartPchRemovedFromDatabase)
+//{
+// EXPECT_CALL(mockPrecompiledHeaderStorage, deletePrecompiledHeader(TypedEq<Utils::SmallStringView>(projectPartId)));
+
+// projectUpdater.removeProjectParts({QString(projectPartId)});
+//}
+
+
+}
diff --git a/tests/unit/unittest/projectparts-test.cpp b/tests/unit/unittest/projectparts-test.cpp
index 50b838ca50..74d1c86338 100644
--- a/tests/unit/unittest/projectparts-test.cpp
+++ b/tests/unit/unittest/projectparts-test.cpp
@@ -88,16 +88,11 @@ TEST_F(ProjectParts, ProjectPartAdded)
ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1));
}
-TEST_F(ProjectParts, FilterDublicateProjectPartsForUpdating)
-{
- auto updatedProjectParts = projectParts.update({projectPartContainer1, projectPartContainer1});
-
- ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1));
-}
-
TEST_F(ProjectParts, FilteredProjectPartAdded)
{
- projectParts.update({projectPartContainer1, projectPartContainer1});
+ projectParts.update({projectPartContainer1});
+
+ projectParts.update({projectPartContainer1});
ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1));
}
@@ -120,13 +115,6 @@ TEST_F(ProjectParts, NoDuplicateProjectPartAfterUpdatingWithNotNewProjectPart)
ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1));
}
-TEST_F(ProjectParts, FilterUniqueProjectParts)
-{
- auto updatedProjectParts = projectParts.uniqueProjectParts({projectPartContainer1, projectPartContainer2, projectPartContainer1});
-
- ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1, projectPartContainer2));
-}
-
TEST_F(ProjectParts, MergeProjectParts)
{
projectParts.mergeProjectParts({projectPartContainer1, projectPartContainer2});
diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp
index 35813dfc02..a3c4b7b779 100644
--- a/tests/unit/unittest/projectupdater-test.cpp
+++ b/tests/unit/unittest/projectupdater-test.cpp
@@ -82,7 +82,7 @@ protected:
projectPart.files.push_back(header2ProjectFile);
projectPart.files.push_back(source1ProjectFile);
projectPart.files.push_back(source2ProjectFile);
- projectPart.displayName = "project1";
+ projectPart.displayName = "projectb";
projectPart.projectMacros = {{"FOO", "2"}, {"BAR", "1"}};
projectPartId = projectPart.id();
@@ -90,7 +90,7 @@ protected:
projectPart2.files.push_back(header1ProjectFile);
projectPart2.files.push_back(source2ProjectFile);
projectPart2.files.push_back(source1ProjectFile);
- projectPart2.displayName = "project2";
+ projectPart2.displayName = "projectaa";
projectPart2.projectMacros = {{"BAR", "1"}, {"FOO", "2"}};
projectPartId2 = projectPart2.id();
@@ -118,8 +118,7 @@ protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
- MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage;
- ClangPchManager::PchManagerClient pchManagerClient{mockPrecompiledHeaderStorage};
+ ClangPchManager::PchManagerClient pchManagerClient;
MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient};
NiceMock<MockPchManagerServer> mockPchManagerServer;
ClangPchManager::ProjectUpdater updater{mockPchManagerServer, filePathCache};
@@ -202,14 +201,13 @@ TEST_F(ProjectUpdater, CallRemoveProjectParts)
EXPECT_CALL(mockPchManagerServer, removeProjectParts(message));
- updater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
+ updater.removeProjectParts({QString(projectPartId2), QString(projectPartId)});
}
TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater)
{
ClangPchManager::PchManagerProjectUpdater pchUpdater{mockPchManagerServer, pchManagerClient, filePathCache};
ClangBackEnd::RemoveProjectPartsMessage message{{projectPartId, projectPartId2}};
- EXPECT_CALL(mockPrecompiledHeaderStorage, deletePrecompiledHeader(_)).Times(AnyNumber());
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId.toQString()));
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId2.toQString()));
diff --git a/tests/unit/unittest/refactoringprojectupdater-test.cpp b/tests/unit/unittest/refactoringprojectupdater-test.cpp
index 799ba44c49..95f00c0f38 100644
--- a/tests/unit/unittest/refactoringprojectupdater-test.cpp
+++ b/tests/unit/unittest/refactoringprojectupdater-test.cpp
@@ -27,7 +27,6 @@
#include "mockcppmodelmanager.h"
#include "mockrefactoringserver.h"
-#include "mockprecompiledheaderstorage.h"
#include <sqlitedatabase.h>
@@ -87,8 +86,7 @@ protected:
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
NiceMock<MockRefactoringServer> mockRefactoringServer;
- NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
- ClangPchManager::PchManagerClient pchManagerClient{mockPrecompiledHeaderStorage};
+ ClangPchManager::PchManagerClient pchManagerClient;
MockCppModelManager mockCppModelManager;
ClangRefactoring::RefactoringProjectUpdater updater{mockRefactoringServer, pchManagerClient, mockCppModelManager, filePathCache};
Utils::SmallString projectPartId;
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index f7364168d0..c7407297c6 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -34,10 +34,10 @@
#include <filestatuscache.h>
#include <projectpartcontainerv2.h>
#include <refactoringdatabaseinitializer.h>
-#include <symbolscollectormanager.h>
+#include <processormanager.h>
#include <symbolindexer.h>
#include <symbolindexertaskqueue.h>
-#include <symbolindexertaskscheduler.h>
+#include <taskscheduler.h>
#include <updateprojectpartsmessage.h>
#include <QCoreApplication>
@@ -60,8 +60,8 @@ using ClangBackEnd::SymbolEntries;
using ClangBackEnd::SymbolEntry;
using ClangBackEnd::SymbolIndexerTask;
using ClangBackEnd::SymbolIndexerTaskQueue;
-using ClangBackEnd::SymbolIndexerTaskScheduler;
-using ClangBackEnd::SymbolsCollectorManager;
+using ClangBackEnd::TaskScheduler;
+using ClangBackEnd::ProcessorManager;
using ClangBackEnd::SourceDependencies;
using ClangBackEnd::SourceLocationEntries;
using ClangBackEnd::SourceLocationEntry;
@@ -84,6 +84,21 @@ struct Data
ClangBackEnd::FilePathCaching filePathCache{database};
};
+class Manager final : public ProcessorManager<NiceMock<MockSymbolsCollector>>
+{
+public:
+ using Processor = NiceMock<MockSymbolsCollector>;
+ Manager(const ClangBackEnd::GeneratedFiles &generatedFiles)
+ : ProcessorManager(generatedFiles)
+ {}
+
+protected:
+ std::unique_ptr<NiceMock<MockSymbolsCollector>> createProcessor() const
+ {
+ return std::make_unique<NiceMock<MockSymbolsCollector>>();
+ }
+};
+
class SymbolIndexer : public testing::Test
{
protected:
@@ -140,6 +155,7 @@ protected:
protected:
static std::unique_ptr<Data> data; // it can be non const because data holds no tested classes
+ using Scheduler = TaskScheduler<Manager, ClangBackEnd::SymbolIndexerTask::Callable>;
ClangBackEnd::FilePathCaching &filePathCache = data->filePathCache;
ClangBackEnd::FilePathId main1PathId{filePathId(TESTDATA_DIR "/symbolindexer_main1.cpp")};
ClangBackEnd::FilePathId main2PathId{filePathId(TESTDATA_DIR "/symbolindexer_main2.cpp")};
@@ -183,8 +199,8 @@ protected:
NiceMock<MockClangPathWatcher> mockPathWatcher;
ClangBackEnd::FileStatusCache fileStatusCache{filePathCache};
ClangBackEnd::GeneratedFiles generatedFiles;
- SymbolsCollectorManager<NiceMock<MockSymbolsCollector>> collectorManger{data->database, generatedFiles};
- SymbolIndexerTaskScheduler indexerScheduler{collectorManger, mockStorage, mockSqliteTransactionBackend, indexerQueue, 1};
+ Manager collectorManger{generatedFiles};
+ Scheduler indexerScheduler{collectorManger, indexerQueue, 1};
SymbolIndexerTaskQueue indexerQueue{indexerScheduler};
ClangBackEnd::SymbolIndexer indexer{indexerQueue,
mockStorage,
@@ -192,7 +208,7 @@ protected:
filePathCache,
fileStatusCache,
mockSqliteTransactionBackend};
- NiceMock<MockSymbolsCollector> &mockCollector{collectorManger.unusedSymbolsCollector()};
+ MockSymbolsCollector &mockCollector{static_cast<MockSymbolsCollector&>(collectorManger.unusedProcessor())};
};
std::unique_ptr<Data> SymbolIndexer::data;
diff --git a/tests/unit/unittest/symbolindexertaskqueue-test.cpp b/tests/unit/unittest/symbolindexertaskqueue-test.cpp
index cf337e5e69..545f19f5b3 100644
--- a/tests/unit/unittest/symbolindexertaskqueue-test.cpp
+++ b/tests/unit/unittest/symbolindexertaskqueue-test.cpp
@@ -25,7 +25,7 @@
#include "googletest.h"
-#include "mocksymbolindexertaskscheduler.h"
+#include "mocktaskscheduler.h"
#include <symbolindexertaskqueue.h>
@@ -50,8 +50,8 @@ MATCHER_P2(IsTask, filePathId, projectPartId,
class SymbolIndexerTaskQueue : public testing::Test
{
protected:
- NiceMock<MockSymbolIndexerTaskScheduler> mockSymbolIndexerTaskScheduler;
- ClangBackEnd::SymbolIndexerTaskQueue queue{mockSymbolIndexerTaskScheduler};
+ NiceMock<MockTaskScheduler<Callable>> mockTaskScheduler;
+ ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler};
};
TEST_F(SymbolIndexerTaskQueue, AddTasks)
@@ -133,20 +133,20 @@ TEST_F(SymbolIndexerTaskQueue, ProcessTasksCallsFreeSlotsAndAddTasksInScheduler)
{{1, 3}, 1, Callable{}},
{{1, 5}, 1, Callable{}}});
- EXPECT_CALL(mockSymbolIndexerTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
- EXPECT_CALL(mockSymbolIndexerTaskScheduler, addTasks(SizeIs(2)));
+ EXPECT_CALL(mockTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
+ EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(2)));
- queue.processTasks();
+ queue.processEntries();
}
TEST_F(SymbolIndexerTaskQueue, ProcessTasksCallsFreeSlotsAndAddTasksWithNoTaskInSchedulerIfTaskAreEmpty)
{
InSequence s;
- EXPECT_CALL(mockSymbolIndexerTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
- EXPECT_CALL(mockSymbolIndexerTaskScheduler, addTasks(IsEmpty()));
+ EXPECT_CALL(mockTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
+ EXPECT_CALL(mockTaskScheduler, addTasks(IsEmpty()));
- queue.processTasks();
+ queue.processEntries();
}
TEST_F(SymbolIndexerTaskQueue, ProcessTasksCallsFreeSlotsAndMoveAllTasksInSchedulerIfMoreSlotsAreFree)
@@ -156,10 +156,10 @@ TEST_F(SymbolIndexerTaskQueue, ProcessTasksCallsFreeSlotsAndMoveAllTasksInSchedu
{{1, 3}, 1, Callable{}},
{{1, 5}, 1, Callable{}}});
- EXPECT_CALL(mockSymbolIndexerTaskScheduler, freeSlots()).WillRepeatedly(Return(4));
- EXPECT_CALL(mockSymbolIndexerTaskScheduler, addTasks(SizeIs(3)));
+ EXPECT_CALL(mockTaskScheduler, freeSlots()).WillRepeatedly(Return(4));
+ EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(3)));
- queue.processTasks();
+ queue.processEntries();
}
TEST_F(SymbolIndexerTaskQueue, ProcessTasksRemovesProcessedTasks)
@@ -167,9 +167,9 @@ TEST_F(SymbolIndexerTaskQueue, ProcessTasksRemovesProcessedTasks)
queue.addOrUpdateTasks({{{1, 1}, 1, Callable{}},
{{1, 3}, 1, Callable{}},
{{1, 5}, 1, Callable{}}});
- ON_CALL(mockSymbolIndexerTaskScheduler, freeSlots()).WillByDefault(Return(2));
+ ON_CALL(mockTaskScheduler, freeSlots()).WillByDefault(Return(2));
- queue.processTasks();
+ queue.processEntries();
ASSERT_THAT(queue.tasks(), SizeIs(1));
}
diff --git a/tests/unit/unittest/symbolscollectormanager-test.cpp b/tests/unit/unittest/symbolscollectormanager-test.cpp
deleted file mode 100644
index 3a740b1e89..0000000000
--- a/tests/unit/unittest/symbolscollectormanager-test.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 "googletest.h"
-
-#include "mocksymbolscollector.h"
-
-#include <sqlitedatabase.h>
-#include <refactoringdatabaseinitializer.h>
-#include <symbolscollectormanager.h>
-
-namespace {
-
-class SymbolsCollectorManager : public testing::Test
-{
-protected:
- Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
- ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
- ClangBackEnd::GeneratedFiles generatedFiles;
- ClangBackEnd::SymbolsCollectorManager<NiceMock<MockSymbolsCollector>> manager{database, generatedFiles};
-};
-
-TEST_F(SymbolsCollectorManager, CreateUnsedSystemCollector)
-{
- manager.unusedSymbolsCollector();
-
- manager.unusedSymbolsCollector();
-
- ASSERT_THAT(manager.collectors(), SizeIs(2));
-}
-
-TEST_F(SymbolsCollectorManager, ReuseUnsedSystemCollector)
-{
- auto &collector = manager.unusedSymbolsCollector();
- collector.setIsUsed(false);
-
- manager.unusedSymbolsCollector();
-
- ASSERT_THAT(manager.collectors(), SizeIs(1));
-}
-
-TEST_F(SymbolsCollectorManager, AsGetNewUnusedSymbolsCollectorItIsSetUsed)
-{
- auto &collector = manager.unusedSymbolsCollector();
-
- ASSERT_TRUE(collector.isUsed());
-}
-
-TEST_F(SymbolsCollectorManager, AsGetReusedUnusedSymbolsCollectorItIsSetUsed)
-{
- auto &collector = manager.unusedSymbolsCollector();
- collector.setIsUsed(false);
-
- auto &collector2 = manager.unusedSymbolsCollector();
-
- ASSERT_TRUE(collector2.isUsed());
-}
-
-TEST_F(SymbolsCollectorManager, UnusedSystemCollectorIsInitializedWithUnsavedFiles)
-{
- auto &collector = manager.unusedSymbolsCollector();
-
- ASSERT_TRUE(collector.hasUnsavedFiles);
-}
-
-TEST_F(SymbolsCollectorManager, ReusedSystemCollectorIsInitializedWithUnsavedFiles)
-{
- auto &collector = manager.unusedSymbolsCollector();
- collector.setIsUsed(false);
-
- auto &collector2 = manager.unusedSymbolsCollector();
-
- ASSERT_TRUE(collector2.hasUnsavedFiles);
-}
-
-}
diff --git a/tests/unit/unittest/symbolindexertaskscheduler-test.cpp b/tests/unit/unittest/taskscheduler-test.cpp
index 585102706a..d6755fa6c7 100644
--- a/tests/unit/unittest/symbolindexertaskscheduler-test.cpp
+++ b/tests/unit/unittest/taskscheduler-test.cpp
@@ -26,26 +26,29 @@
#include "googletest.h"
#include "mocksymbolindexertaskqueue.h"
-#include "mocksymbolscollectormanager.h"
+#include "mockprocessormanager.h"
#include "mocksymbolscollector.h"
-#include "mocksymbolstorage.h"
-#include "mocksqlitetransactionbackend.h"
-#include <symbolindexertaskscheduler.h>
+#include <taskscheduler.h>
#include <QCoreApplication>
namespace {
+using Task = std::function<void(ClangBackEnd::ProcessorInterface&)>;
+
+using ClangBackEnd::ProcessorInterface;
using ClangBackEnd::SymbolsCollectorInterface;
using ClangBackEnd::SymbolStorageInterface;
+using NiceMockProcessorManager = NiceMock<MockProcessorManager>;
+using Scheduler = ClangBackEnd::TaskScheduler<NiceMockProcessorManager, Task>;
-class SymbolIndexerTaskScheduler : public testing::Test
+class TaskScheduler : public testing::Test
{
protected:
void SetUp()
{
- ON_CALL(mockSymbolsCollectorManager, unusedSymbolsCollector()).WillByDefault(ReturnRef(mockSymbolsCollector));
+ ON_CALL(mockProcessorManager, unusedProcessor()).WillByDefault(ReturnRef(mockSymbolsCollector));
}
void TearDown()
{
@@ -55,63 +58,53 @@ protected:
protected:
MockFunction<void()> mock;
- ClangBackEnd::SymbolIndexerTaskScheduler::Task call{
- [&] (SymbolsCollectorInterface &, SymbolStorageInterface &, Sqlite::TransactionInterface &) {
- mock.Call(); }};
- ClangBackEnd::SymbolIndexerTaskScheduler::Task nocall{
- [&] (SymbolsCollectorInterface &, SymbolStorageInterface &, Sqlite::TransactionInterface &) {
- }};
- NiceMock<MockSymbolsCollectorManager> mockSymbolsCollectorManager;
+ Task call{[&] (ClangBackEnd::ProcessorInterface&) { mock.Call(); }};
+ Task nocall{[&] (ClangBackEnd::ProcessorInterface&) {}};
+ NiceMockProcessorManager mockProcessorManager;
NiceMock<MockSymbolsCollector> mockSymbolsCollector;
- MockSymbolStorage mockSymbolStorage;
NiceMock<MockSymbolIndexerTaskQueue> mockSymbolIndexerTaskQueue;
- MockSqliteTransactionBackend mockSqliteTransactionBackend;
- ClangBackEnd::SymbolIndexerTaskScheduler scheduler{mockSymbolsCollectorManager,
- mockSymbolStorage,
- mockSqliteTransactionBackend,
+ Scheduler scheduler{mockProcessorManager,
mockSymbolIndexerTaskQueue,
4};
- ClangBackEnd::SymbolIndexerTaskScheduler deferedScheduler{mockSymbolsCollectorManager,
- mockSymbolStorage,
- mockSqliteTransactionBackend,
+ Scheduler deferredScheduler{mockProcessorManager,
mockSymbolIndexerTaskQueue,
4,
std::launch::deferred};
};
-TEST_F(SymbolIndexerTaskScheduler, AddTasks)
+TEST_F(TaskScheduler, AddTasks)
{
- deferedScheduler.addTasks({nocall});
+ deferredScheduler.addTasks({nocall});
- ASSERT_THAT(deferedScheduler.futures(), SizeIs(1));
+ ASSERT_THAT(deferredScheduler.futures(), SizeIs(1));
}
-TEST_F(SymbolIndexerTaskScheduler, AddTasksCallsFunction)
+TEST_F(TaskScheduler, AddTasksCallsFunction)
{
EXPECT_CALL(mock, Call()).Times(2);
scheduler.addTasks({call, call});
}
-TEST_F(SymbolIndexerTaskScheduler, FreeSlots)
+TEST_F(TaskScheduler, FreeSlots)
{
- deferedScheduler.addTasks({nocall, nocall});
+ deferredScheduler.addTasks({nocall, nocall});
- auto count = deferedScheduler.freeSlots();
+ auto count = deferredScheduler.freeSlots();
ASSERT_THAT(count, 2);
}
-TEST_F(SymbolIndexerTaskScheduler, ReturnZeroFreeSlotsIfMoreCallsThanCores)
+TEST_F(TaskScheduler, ReturnZeroFreeSlotsIfMoreCallsThanCores)
{
- deferedScheduler.addTasks({nocall, nocall, nocall, nocall, nocall, nocall});
+ deferredScheduler.addTasks({nocall, nocall, nocall, nocall, nocall, nocall});
- auto count = deferedScheduler.freeSlots();
+ auto count = deferredScheduler.freeSlots();
ASSERT_THAT(count, 0);
}
-TEST_F(SymbolIndexerTaskScheduler, FreeSlotsAfterFinishing)
+TEST_F(TaskScheduler, FreeSlotsAfterFinishing)
{
scheduler.addTasks({nocall, nocall});
scheduler.syncTasks();
@@ -121,7 +114,7 @@ TEST_F(SymbolIndexerTaskScheduler, FreeSlotsAfterFinishing)
ASSERT_THAT(count, 4);
}
-TEST_F(SymbolIndexerTaskScheduler, NoFuturesAfterFreeSlots)
+TEST_F(TaskScheduler, NoFuturesAfterFreeSlots)
{
scheduler.addTasks({nocall, nocall});
scheduler.syncTasks();
@@ -131,41 +124,35 @@ TEST_F(SymbolIndexerTaskScheduler, NoFuturesAfterFreeSlots)
ASSERT_THAT(scheduler.futures(), IsEmpty());
}
-TEST_F(SymbolIndexerTaskScheduler, FreeSlotsCallSymbolsCollectorSetIsUnused)
+TEST_F(TaskScheduler, FreeSlotsCallsCleanupMethodsAfterTheWorkIsDone)
{
- InSequence s;
scheduler.addTasks({nocall, nocall});
scheduler.syncTasks();
-
- EXPECT_CALL(mockSymbolsCollector, setIsUsed(false)).Times(2);
-
- scheduler.freeSlots();
-}
-
-TEST_F(SymbolIndexerTaskScheduler, FreeSlotsCallClearsSymbolsCollector)
-{
InSequence s;
- scheduler.addTasks({nocall, nocall});
- scheduler.syncTasks();
- EXPECT_CALL(mockSymbolsCollector, clear()).Times(2);
+ EXPECT_CALL(mockSymbolsCollector, doInMainThreadAfterFinished());
+ EXPECT_CALL(mockSymbolsCollector, setIsUsed(false));
+ EXPECT_CALL(mockSymbolsCollector, clear());
+ EXPECT_CALL(mockSymbolsCollector, doInMainThreadAfterFinished());
+ EXPECT_CALL(mockSymbolsCollector, setIsUsed(false));
+ EXPECT_CALL(mockSymbolsCollector, clear());
scheduler.freeSlots();
}
-TEST_F(SymbolIndexerTaskScheduler, AddTaskCallSymbolsCollectorManagerUnusedSymbolsCollector)
+TEST_F(TaskScheduler, AddTaskCallSymbolsCollectorManagerUnusedSymbolsCollector)
{
- EXPECT_CALL(mockSymbolsCollectorManager, unusedSymbolsCollector()).Times(2);
+ EXPECT_CALL(mockProcessorManager, unusedProcessor()).Times(2);
scheduler.addTasks({nocall, nocall});
}
-TEST_F(SymbolIndexerTaskScheduler, CallProcessTasksInQueueAfterFinishedTasks)
+TEST_F(TaskScheduler, CallProcessTasksInQueueAfterFinishedTasks)
{
InSequence s;
EXPECT_CALL(mock, Call());
- EXPECT_CALL(mockSymbolIndexerTaskQueue, processTasks());
+ EXPECT_CALL(mockSymbolIndexerTaskQueue, processEntries());
scheduler.addTasks({call});
scheduler.syncTasks();
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index 09d1083a22..9f63ed748d 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -59,7 +59,6 @@ SOURCES += \
locatorfilter-test.cpp \
matchingtext-test.cpp \
mimedatabase-utilities.cpp \
- pchgenerator-test.cpp \
pchmanagerclientserverinprocess-test.cpp \
pchmanagerclient-test.cpp \
pchmanagerserver-test.cpp \
@@ -99,9 +98,10 @@ SOURCES += \
generatedfiles-test.cpp \
sourcesmanager-test.cpp \
symbolindexertaskqueue-test.cpp \
- symbolindexertaskscheduler-test.cpp \
- symbolscollectormanager-test.cpp \
- refactoringprojectupdater-test.cpp
+ refactoringprojectupdater-test.cpp \
+ projectpartqueue-test.cpp \
+ processormanager-test.cpp \
+ taskscheduler-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
@@ -203,7 +203,6 @@ HEADERS += \
mockclangpathwatcher.h \
mockclangpathwatchernotifier.h \
mockpchcreator.h \
- mockpchgeneratornotifier.h \
mockpchmanagerclient.h \
mockpchmanagernotifier.h \
mockpchmanagerserver.h \
@@ -238,11 +237,14 @@ HEADERS += \
mockprojectpartprovider.h \
mockprecompiledheaderstorage.h \
mockeditormanager.h \
- mocksymbolscollectormanager.h \
mocksymbolindexertaskqueue.h \
- mocksymbolindexertaskscheduler.h \
mockcppmodelmanager.h \
- mockgeneratedfiles.h
+ mockgeneratedfiles.h \
+ mockqueue.h \
+ mockprojectpartqueue.h \
+ mockprocessor.h \
+ mockprocessormanager.h \
+ mocktaskscheduler.h
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \