Clang: Add progress bars for creating PCHs and indexing

Task-number: QTCREATORBUG-21112
Change-Id: Ie0c00a58f479a2fe7cbc7322490808509733ff0f
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Marco Bubke
2018-09-27 17:52:44 +02:00
parent ffc070a3f2
commit 391cfab5d7
60 changed files with 865 additions and 49 deletions

View File

@@ -25,7 +25,8 @@
#pragma once
#include "alivemessage.h"
#include "progressmessage.h"
#include "sourcelocationsforrenamingmessage.h"
#include "sourcerangesanddiagnosticsforquerymessage.h"
#include "sourcerangesforquerymessage.h"
#include "alivemessage.h"

View File

@@ -203,6 +203,8 @@ HEADERS += \
$$PWD/updategeneratedfilesmessage.h \
$$PWD/removegeneratedfilesmessage.h \
$$PWD/generatedfiles.h \
$$PWD/generatedfilesinterface.h
$$PWD/generatedfilesinterface.h \
$$PWD/progressmessage.h \
$$PWD/progresscounter.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -177,7 +177,8 @@ enum class MessageType : quint8 {
RemoveProjectPartsMessage,
PrecompiledHeadersUpdatedMessage,
UpdateGeneratedFilesMessage,
RemoveGeneratedFilesMessage
RemoveGeneratedFilesMessage,
ProgressMessage
};
template<MessageType messageEnumeration>
@@ -234,4 +235,11 @@ enum class SymbolTag : uchar
using SymbolTags = Utils::SizedArray<SymbolTag, 7>;
enum class ProgressType
{
Invalid,
PrecompiledHeader,
Indexing
};
}

View File

@@ -27,6 +27,7 @@
#include "messageenvelop.h"
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <QDebug>
@@ -41,6 +42,9 @@ void PchManagerClientInterface::dispatch(const MessageEnvelop &messageEnvelop)
case MessageType::PrecompiledHeadersUpdatedMessage:
precompiledHeadersUpdated(messageEnvelop.message<PrecompiledHeadersUpdatedMessage>());
break;
case MessageType::ProgressMessage:
progress(messageEnvelop.message<ProgressMessage>());
break;
default:
qWarning() << "Unknown IpcClientMessage";
}

View File

@@ -30,6 +30,7 @@
namespace ClangBackEnd {
class PrecompiledHeadersUpdatedMessage;
class ProgressMessage;
class CLANGSUPPORT_EXPORT PchManagerClientInterface : public IpcClientInterface
{
@@ -38,6 +39,7 @@ public:
virtual void alive() = 0;
virtual void precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage &&message) = 0;
virtual void progress(ProgressMessage &&message) = 0;
protected:
~PchManagerClientInterface() = default;

View File

@@ -29,6 +29,7 @@
#include "messageenvelop.h"
#include "pchmanagerserverinterface.h"
#include "precompiledheadersupdatedmessage.h"
#include "progressmessage.h"
#include <QDebug>
#include <QIODevice>
@@ -78,4 +79,9 @@ void PchManagerClientProxy::precompiledHeadersUpdated(PrecompiledHeadersUpdatedM
writeMessageBlock.write(message);
}
void PchManagerClientProxy::progress(ProgressMessage &&message)
{
writeMessageBlock.write(message);
}
} // namespace ClangBackEnd

View File

@@ -48,6 +48,7 @@ public:
void alive() override;
void precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage &&message) override;
void progress(ProgressMessage &&message) override;
private:
ClangBackEnd::WriteMessageBlock writeMessageBlock;

View File

@@ -0,0 +1,88 @@
/****************************************************************************
**
** 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 <functional>
namespace ClangBackEnd {
class ProgressCounter
{
public:
using SetProgressCallback = std::function<void(int, int)>;
ProgressCounter(SetProgressCallback &&progressCallback)
: m_progressCallback(std::move(progressCallback))
{}
void addTotal(int total)
{
m_total += total;
m_progressCallback(m_progress, m_total);
}
void removeTotal(int total)
{
m_total -= total;
sendProgress();
}
void addProgress(int progress)
{
m_progress += progress;
sendProgress();
}
void sendProgress()
{
m_progressCallback(m_progress, m_total);
if (m_progress >= m_total) {
m_progress = 0;
m_total = 0;
}
}
int total() const
{
return m_total;
}
int progress() const
{
return m_total;
}
private:
std::function<void(int, int)> m_progressCallback;
int m_progress = 0;
int m_total = 0;
};
}

View File

@@ -0,0 +1,79 @@
/****************************************************************************
**
** 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 "clangsupport_global.h"
#include <QDataStream>
namespace ClangBackEnd {
class ProgressMessage
{
public:
ProgressMessage() = default;
ProgressMessage(ProgressType progressType, int progress, int total)
: progressType(progressType),
progress(progress),
total(total)
{}
friend QDataStream &operator<<(QDataStream &out, const ProgressMessage &message)
{
out << message.progress;
out << message.total;
return out;
}
friend QDataStream &operator>>(QDataStream &in, ProgressMessage &message)
{
in >> message.progress;
in >> message.total;
return in;
}
friend bool operator==(const ProgressMessage &first, const ProgressMessage &second)
{
return first.progress == second.progress
&& first.total == second.total;
}
ProgressMessage clone() const
{
return *this;
}
public:
ProgressType progressType = ProgressType::Invalid;
int progress = 0;
int total = 0;
};
DECLARE_MESSAGE(ProgressMessage)
} // namespace ClangBackEnd

View File

@@ -47,6 +47,9 @@ void RefactoringClientInterface::dispatch(const MessageEnvelop &messageEnvelop)
case MessageType::SourceRangesForQueryMessage:
sourceRangesForQueryMessage(messageEnvelop.message<SourceRangesForQueryMessage>());
break;
case MessageType::ProgressMessage:
progress(messageEnvelop.message<ProgressMessage>());
break;
default:
qWarning() << "Unknown IpcClientMessage";
}

View File

@@ -31,6 +31,7 @@
namespace ClangBackEnd {
class ProgressMessage;
class SourceLocationsForRenamingMessage;
class SourceRangesAndDiagnosticsForQueryMessage;
class SourceRangesForQueryMessage;
@@ -49,8 +50,8 @@ public:
virtual void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) = 0;
virtual void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) = 0;
virtual void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) = 0;
virtual void setLocalRenamingCallback(RenameCallback &&localRenamingCallback) = 0;
virtual void progress(ProgressMessage &&message) = 0;
protected:
~RefactoringClientInterface() = default;

View File

@@ -86,7 +86,12 @@ void RefactoringClientProxy::sourceRangesAndDiagnosticsForQueryMessage(SourceRan
void RefactoringClientProxy::sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message)
{
writeMessageBlock.write(message);
writeMessageBlock.write(message);
}
void RefactoringClientProxy::progress(ProgressMessage &&message)
{
writeMessageBlock.write(message);
}
} // namespace ClangBackEnd

View File

@@ -52,6 +52,7 @@ public:
void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) override;
void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) override;
void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) override;
void progress(ProgressMessage &&message) override;
void setLocalRenamingCallback(RenameCallback &&) final {}

View File

@@ -12,7 +12,9 @@ HEADERS += \
$$PWD/pchmanagerconnectionclient.h \
$$PWD/clangpchmanager_global.h \
$$PWD/projectupdater.h \
$$PWD/pchmanagerprojectupdater.h
$$PWD/pchmanagerprojectupdater.h \
$$PWD/progressmanager.h \
$$PWD/progressmanagerinterface.h
SOURCES += \
$$PWD/pchmanagerclient.cpp \

View File

@@ -13,6 +13,7 @@ win32 {
HEADERS += \
$$PWD/clangpchmanagerplugin.h \
qtcreatorprojectupdater.h
SOURCES += \
$$PWD/clangpchmanagerplugin.cpp \
qtcreatorprojectupdater.cpp

View File

@@ -27,6 +27,7 @@
#include "pchmanagerconnectionclient.h"
#include "pchmanagerclient.h"
#include "progressmanager.h"
#include "qtcreatorprojectupdater.h"
#include <filepathcaching.h>
@@ -34,10 +35,13 @@
#include <sqlitedatabase.h>
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/hostosinfo.h>
#include <QFutureInterface>
#include <chrono>
using namespace std::chrono_literals;
@@ -61,7 +65,12 @@ public:
Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
PchManagerClient pchManagerClient;
ClangPchManager::ProgressManager progressManager{
[] (QFutureInterface<void> &promise) {
auto title = QCoreApplication::translate("ClangPchProgressManager", "Creating PCHs", "PCH stands for precompiled header");
Core::ProgressManager::addTask(promise.future(), title, "pch creation", nullptr);
}};
PchManagerClient pchManagerClient{progressManager};
PchManagerConnectionClient connectionClient{&pchManagerClient};
QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(),
pchManagerClient,

View File

@@ -26,8 +26,9 @@
#include "pchmanagerclient.h"
#include <precompiledheadersupdatedmessage.h>
#include <progressmanagerinterface.h>
#include <progressmessage.h>
#include <pchmanagerconnectionclient.h>
#include <pchmanagernotifierinterface.h>
#include <algorithm>
@@ -50,6 +51,11 @@ void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeader
}
}
void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message)
{
m_progressManager.setProgress(message.progress, message.total);
}
void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)
{
for (auto notifier : m_notifiers) {

View File

@@ -34,7 +34,7 @@
namespace ClangPchManager {
class PchManagerConnectionClient;
class ProgressManagerInterface;
class PchManagerNotifierInterface;
class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchManagerClientInterface,
@@ -42,9 +42,13 @@ class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchMa
{
friend class PchManagerNotifierInterface;
public:
PchManagerClient() = default;
PchManagerClient(ProgressManagerInterface &progressManager)
: m_progressManager(progressManager)
{}
void alive() override;
void precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) override;
void progress(ClangBackEnd::ProgressMessage &&message) override;
void precompiledHeaderRemoved(const QString &projectPartId);
@@ -74,6 +78,7 @@ private:
ClangBackEnd::ProjectPartPchs m_projectPartPchs;
std::vector<PchManagerNotifierInterface*> m_notifiers;
PchManagerConnectionClient *m_connectionClient=nullptr;
ProgressManagerInterface &m_progressManager;
};
} // namespace ClangPchManager

View File

@@ -0,0 +1,84 @@
/****************************************************************************
**
** 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 "progressmanagerinterface.h"
#include <QFutureInterface>
#include <QCoreApplication>
#include <QString>
#include <functional>
#include <memory>
namespace ClangPchManager {
class ProgressManager : public ProgressManagerInterface
{
public:
using Promise = QFutureInterface<void>;
using Callback = std::function<void(Promise &)>;
ProgressManager(Callback &&callback)
: m_callback(std::move(callback))
{}
void setProgress(int currentProgress, int maximumProgress)
{
if (!m_promise)
initialize();
m_promise->setExpectedResultCount(maximumProgress);
m_promise->setProgressValue(currentProgress);
if (currentProgress >= maximumProgress)
finish();
}
Promise *promise()
{
return m_promise.get();
}
private:
void initialize()
{
m_promise = std::make_unique<Promise>();
m_callback(*m_promise);
}
void finish()
{
m_promise->reportFinished();
m_promise.reset();
}
private:
Callback m_callback;
std::unique_ptr<Promise> m_promise;
};
} // namespace ClangPchManager

View File

@@ -0,0 +1,39 @@
/****************************************************************************
**
** 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
namespace ClangPchManager {
class ProgressManagerInterface
{
public:
virtual void setProgress(int currentProgress, int maximumProgress) = 0;
protected:
~ProgressManagerInterface() = default;
};
} // namespace ClangPchManager

View File

@@ -34,11 +34,13 @@
#include "symbolquery.h"
#include <clangpchmanager/clangpchmanagerplugin.h>
#include <clangpchmanager/progressmanager.h>
#include <clangsupport/refactoringdatabaseinitializer.h>
#include <cpptools/cppmodelmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <cpptools/cpptoolsconstants.h>
@@ -46,7 +48,6 @@
#include <filepathcaching.h>
#include <sqlitedatabase.h>
#include <utils/hostosinfo.h>
#include <QDir>
@@ -79,13 +80,16 @@ public:
Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
RefactoringClient refactoringClient;
ClangPchManager::ProgressManager progressManager{
[] (QFutureInterface<void> &promise) {
auto title = QCoreApplication::translate("ClangRefactoringProgressManager", "C++ Indexing");
Core::ProgressManager::addTask(promise.future(), title, "clang indexing", nullptr);}};
RefactoringClient refactoringClient{progressManager};
QtCreatorEditorManager editorManager{filePathCache};
ClangBackEnd::RefactoringConnectionClient connectionClient{&refactoringClient};
QuerySqliteReadStatementFactory statementFactory{database};
SymbolQuery<QuerySqliteReadStatementFactory> symbolQuery{statementFactory};
RefactoringEngine engine{connectionClient.serverProxy(), refactoringClient, filePathCache, symbolQuery};
QtCreatorSearch qtCreatorSearch;
QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(),
qtCreatorSearch,

View File

@@ -70,6 +70,11 @@ void RefactoringClient::setLocalRenamingCallback(
m_localRenamingCallback = std::move(localRenamingCallback);
}
void RefactoringClient::progress(ClangBackEnd::ProgressMessage &&message)
{
m_progressManager.setProgress(message.progress, message.total);
}
void RefactoringClient::setRefactoringEngine(RefactoringEngine *refactoringEngine)
{
m_refactoringEngine = refactoringEngine;

View File

@@ -30,6 +30,7 @@
#include "searchhandle.h"
#include <refactoringclientinterface.h>
#include <clangpchmanager/progressmanager.h>
#include <functional>
@@ -48,6 +49,10 @@ class ClangQueryHighlighter;
class RefactoringClient final : public ClangBackEnd::RefactoringClientInterface
{
public:
RefactoringClient(ClangPchManager::ProgressManagerInterface &progressManager)
: m_progressManager(progressManager)
{}
void alive() override;
void sourceLocationsForRenamingMessage(
ClangBackEnd::SourceLocationsForRenamingMessage &&message) override;
@@ -58,6 +63,8 @@ public:
void setLocalRenamingCallback(
CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) override;
void progress(ClangBackEnd::ProgressMessage &&message) override;
void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine);
void setSearchHandle(ClangRefactoring::SearchHandle *searchHandleInterface);
ClangRefactoring::SearchHandle *searchHandle() const;
@@ -72,6 +79,7 @@ public:
void setRefactoringConnectionClient(ClangBackEnd::RefactoringConnectionClient *connectionClient);
unittest_public:
void addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRange);
@@ -88,6 +96,7 @@ private:
RefactoringEngine *m_refactoringEngine = nullptr;
ClangQueryExampleHighlighter *m_clangQueryExampleHighlighter = nullptr;
ClangQueryHighlighter *m_clangQueryHighlighter = nullptr;
ClangPchManager::ProgressManagerInterface &m_progressManager;
uint m_expectedResultCount = 0;
uint m_resultCounter = 0;
};

View File

@@ -32,6 +32,7 @@
#include <pchmanagerclientproxy.h>
#include <precompiledheaderstorage.h>
#include <processormanager.h>
#include <progresscounter.h>
#include <projectparts.h>
#include <projectpartqueue.h>
#include <filepathcaching.h>
@@ -174,8 +175,9 @@ struct Data // because we have a cycle dependency
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};
ClangBackEnd::ProgressCounter progressCounter{[&] (int progress, int total) { clangPchManagerServer.setProgress(progress, total); }};
TaskScheduler taskScheduler{pchCreatorManager, projectPartQueue, progressCounter, std::thread::hardware_concurrency()};
ClangBackEnd::ProjectPartQueue projectPartQueue{taskScheduler, preCompiledHeaderStorage, database, progressCounter};
PchManagerServer clangPchManagerServer{includeWatcher, projectPartQueue, projectParts, generatedFiles};
};

View File

@@ -27,6 +27,7 @@
#include <pchmanagerclientinterface.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <projectpartqueue.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
@@ -90,4 +91,9 @@ void PchManagerServer::pathsChanged(const FilePathIds &/*filePathIds*/)
{
}
void PchManagerServer::setProgress(int progress, int total)
{
client()->progress({ProgressType::PrecompiledHeader, progress, total});
}
} // namespace ClangBackEnd

View File

@@ -59,6 +59,8 @@ public:
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
void pathsChanged(const FilePathIds &filePathIds) override;
void setProgress(int progress, int total);
private:
ClangPathWatcherInterface &m_fileSystemWatcher;
ProjectPartQueueInterface &m_projectPartQueue;

View File

@@ -27,6 +27,7 @@
#include <pchcreatorinterface.h>
#include <precompiledheaderstorageinterface.h>
#include <progresscounter.h>
#include <sqlitetransaction.h>
namespace ClangBackEnd {
@@ -37,6 +38,8 @@ void ProjectPartQueue::addProjectParts(V2::ProjectPartContainers &&projectParts)
return first.projectPartId < second.projectPartId;
};
const std::size_t oldSize = m_projectParts.size();
V2::ProjectPartContainers mergedProjectParts;
mergedProjectParts.reserve(m_projectParts.size() + projectParts.size());
std::set_union(std::make_move_iterator(projectParts.begin()),
@@ -47,6 +50,10 @@ void ProjectPartQueue::addProjectParts(V2::ProjectPartContainers &&projectParts)
compare);
m_projectParts = std::move(mergedProjectParts);
m_progressCounter.addTotal(int(m_projectParts.size() - oldSize));
processEntries();
}
class CompareDifference
@@ -65,6 +72,8 @@ public:
void ProjectPartQueue::removeProjectParts(const Utils::SmallStringVector &projectsPartIds)
{
const std::size_t oldSize = m_projectParts.size();
V2::ProjectPartContainers notToBeRemovedProjectParts;
notToBeRemovedProjectParts.reserve(m_projectParts.size());
std::set_difference(std::make_move_iterator(m_projectParts.begin()),
@@ -75,6 +84,8 @@ void ProjectPartQueue::removeProjectParts(const Utils::SmallStringVector &projec
CompareDifference{});
m_projectParts = std::move(notToBeRemovedProjectParts);
m_progressCounter.removeTotal(int(oldSize - m_projectParts.size()));
}
void ProjectPartQueue::processEntries()

View File

@@ -35,6 +35,7 @@ class TransactionInterface;
namespace ClangBackEnd {
class PrecompiledHeaderStorageInterface;
class ProgressCounter;
class PchTaskSchedulerInterface;
class PchCreatorInterface;
@@ -45,10 +46,12 @@ public:
ProjectPartQueue(TaskSchedulerInterface<Task> &taskScheduler,
PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
Sqlite::TransactionInterface &transactionsInterface)
Sqlite::TransactionInterface &transactionsInterface,
ProgressCounter &progressCounter)
: m_taskScheduler(taskScheduler),
m_precompiledHeaderStorage(precompiledHeaderStorage),
m_transactionsInterface(transactionsInterface)
m_transactionsInterface(transactionsInterface),
m_progressCounter(progressCounter)
{}
void addProjectParts(V2::ProjectPartContainers &&projectParts);
@@ -65,6 +68,7 @@ private:
TaskSchedulerInterface<Task> &m_taskScheduler;
PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage;
Sqlite::TransactionInterface &m_transactionsInterface;
ProgressCounter &m_progressCounter;
};
} // namespace ClangBackEnd

View File

@@ -28,6 +28,7 @@
#include "taskschedulerinterface.h"
#include "symbolindexertask.h"
#include "queueinterface.h"
#include "progresscounter.h"
#include <processormanagerinterface.h>
#include <symbolindexertaskqueueinterface.h>
@@ -65,10 +66,12 @@ public:
TaskScheduler(ProcessorManager &symbolsCollectorManager,
QueueInterface &queue,
ProgressCounter &progressCounter,
uint hardwareConcurrency,
std::launch launchPolicy = std::launch::async)
: m_processorManager(symbolsCollectorManager),
m_queue(queue),
m_progressCounter(progressCounter),
m_hardwareConcurrency(hardwareConcurrency),
m_launchPolicy(launchPolicy)
{}
@@ -133,6 +136,8 @@ private:
processor.clear();
});
m_progressCounter.addProgress(std::distance(split, m_futures.end()));
m_futures.erase(split, m_futures.end());
}
@@ -181,6 +186,7 @@ private:
std::vector<Future> m_futures;
ProcessorManager &m_processorManager;
QueueInterface &m_queue;
ProgressCounter &m_progressCounter;
uint m_hardwareConcurrency;
std::launch m_launchPolicy;
bool m_isDisabled = false;

View File

@@ -83,6 +83,20 @@ public:
}
};
struct Data // because we have a cycle dependency
{
Data(const QString &databasePath)
: database{Utils::PathString{databasePath}, 100000ms}
{}
Sqlite::Database database;
RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
FilePathCaching filePathCache{database};
GeneratedFiles generatedFiles;
SymbolIndexing symbolIndexing{database, filePathCache, generatedFiles, [&] (int progress, int total) { clangCodeModelServer.setProgress(progress, total); }};
RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache, generatedFiles};
};
int main(int argc, char *argv[])
{
try {
@@ -99,14 +113,10 @@ int main(int argc, char *argv[])
const QString connectionName = arguments[0];
const QString databasePath = arguments[1];
Sqlite::Database database{Utils::PathString{databasePath}, 100000ms};
RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
FilePathCaching filePathCache{database};
GeneratedFiles generatedFiles;
SymbolIndexing symbolIndexing{database, filePathCache, generatedFiles};
RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache, generatedFiles};
Data data{databasePath};
ConnectionServer<RefactoringServer, RefactoringClientProxy> connectionServer;
connectionServer.setServer(&clangCodeModelServer);
connectionServer.setServer(&data.clangCodeModelServer);
connectionServer.start(connectionName);
return application.exec();

View File

@@ -158,6 +158,11 @@ void RefactoringServer::setGathererProcessingSlotCount(uint count)
m_gatherer.setProcessingSlotCount(count);
}
void RefactoringServer::setProgress(int progress, int total)
{
client()->progress({ProgressType::Indexing, progress, total});
}
void RefactoringServer::gatherSourceRangesForQueryMessages(
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,

View File

@@ -79,6 +79,8 @@ public:
void setGathererProcessingSlotCount(uint count);
void setProgress(int progress, int total);
private:
void gatherSourceRangesForQueryMessages(std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,

View File

@@ -29,6 +29,7 @@
#include "symbolindexertask.h"
#include <filepathid.h>
#include <progresscounter.h>
#include <taskschedulerinterface.h>
#include <utils/algorithm.h>
@@ -51,8 +52,10 @@ class SymbolIndexerTaskQueue final : public SymbolIndexerTaskQueueInterface
public:
using Task = SymbolIndexerTask::Callable;
SymbolIndexerTaskQueue(TaskSchedulerInterface<Task> &symbolIndexerTaskScheduler)
: m_symbolIndexerScheduler(symbolIndexerTaskScheduler)
SymbolIndexerTaskQueue(TaskSchedulerInterface<Task> &symbolIndexerTaskScheduler,
ProgressCounter &progressCounter)
: m_symbolIndexerScheduler(symbolIndexerTaskScheduler),
m_progressCounter(progressCounter)
{}
void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
@@ -63,7 +66,11 @@ public:
return std::move(first);
};
const std::size_t oldSize = m_tasks.size();
m_tasks = Utils::setUnionMerge<std::vector<SymbolIndexerTask>>(tasks, m_tasks, merge);
m_progressCounter.addTotal(int(m_tasks.size() - oldSize));
}
void removeTasks(const std::vector<int> &projectPartIds)
{
@@ -71,9 +78,13 @@ public:
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
};
const std::size_t oldSize = m_tasks.size();
auto newEnd = std::remove_if(m_tasks.begin(), m_tasks.end(), shouldBeRemoved);
m_tasks.erase(newEnd, m_tasks.end());
m_progressCounter.removeTotal(int(oldSize -m_tasks.size()));
}
const std::vector<SymbolIndexerTask> &tasks() const
@@ -96,6 +107,7 @@ private:
std::vector<Utils::SmallString> m_projectPartIds;
std::vector<SymbolIndexerTask> m_tasks;
TaskSchedulerInterface<Task> &m_symbolIndexerScheduler;
ProgressCounter &m_progressCounter;
};
} // namespace ClangBackEnd

View File

@@ -49,6 +49,7 @@
namespace ClangBackEnd {
class SymbolsCollectorManager;
class RefactoringServer;
class SymbolsCollectorManager final : public ClangBackEnd::ProcessorManager<SymbolsCollector>
{
@@ -77,11 +78,13 @@ public:
using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
SymbolIndexing(Sqlite::Database &database,
FilePathCachingInterface &filePathCache,
const GeneratedFiles &generatedFiles)
const GeneratedFiles &generatedFiles,
ProgressCounter::SetProgressCallback &&setProgressCallback)
: m_filePathCache(filePathCache),
m_statementFactory(database),
m_collectorManger(generatedFiles, database),
m_indexerScheduler(m_collectorManger, m_indexerQueue, std::thread::hardware_concurrency())
m_progressCounter(std::move(setProgressCallback)),
m_indexerScheduler(m_collectorManger, m_indexerQueue, m_progressCounter, std::thread::hardware_concurrency())
{
}
@@ -114,8 +117,9 @@ private:
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
FileStatusCache m_fileStatusCache{m_filePathCache};
SymbolsCollectorManager m_collectorManger;
ProgressCounter m_progressCounter;
SymbolIndexerTaskScheduler m_indexerScheduler;
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler};
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter};
SymbolIndexer m_indexer{m_indexerQueue,
m_symbolStorage,
m_sourceWatcher,

View File

@@ -25,6 +25,7 @@
#include "googletest.h"
#include "mockprogressmanager.h"
#include "mockrefactoringserver.h"
#include "mocksearch.h"
#include "mocksearchhandle.h"
@@ -61,7 +62,8 @@ protected:
protected:
NiceMock<MockRefactoringServer> mockRefactoringServer;
NiceMock<MockSearch> mockSearch;
ClangRefactoring::RefactoringClient refactoringClient;
NiceMock<MockProgressManager> mockProgressManager;
ClangRefactoring::RefactoringClient refactoringClient{mockProgressManager};
ClangRefactoring::ClangQueryProjectsFindFilter findFilter{mockRefactoringServer, mockSearch, refactoringClient};
QString findDeclQueryText{"functionDecl()"};
QString curentDocumentFilePath{"/path/to/file.cpp"};

View File

@@ -44,10 +44,12 @@ using testing::HasSubstr;
using testing::InSequence;
using testing::Invoke;
using testing::IsEmpty;
using testing::IsNull;
using testing::Matcher;
using testing::Mock;
using testing::MockFunction;
using testing::NiceMock;
using testing::NotNull;
using testing::Not;
using testing::Pair;
using testing::PrintToString;

View File

@@ -1000,6 +1000,24 @@ std::ostream &operator<<(std::ostream &out, const SymbolIndexerTask &task)
return out << "(" << task.filePathId << ", " << task.projectPartId << ")";
}
const char* progressTypeToString(ClangBackEnd::ProgressType type)
{
switch (type) {
case ProgressType::Invalid: return "Invalid";
case ProgressType::PrecompiledHeader: return "PrecompiledHeader";
case ProgressType::Indexing: return "Indexing";
}
return nullptr;
}
std::ostream &operator<<(std::ostream &out, const ProgressMessage &message)
{
return out << "(" << progressTypeToString(message.progressType) << ", "
<< message.progress << ", "
<< message.total << ")";
}
void PrintTo(const FilePath &filePath, ::std::ostream *os)
{
*os << filePath;

View File

@@ -169,6 +169,7 @@ class RemoveGeneratedFilesMessage;
class SuspendResumeJobsEntry;
class ReferencesResult;
class SymbolIndexerTask;
class ProgressMessage;
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths);
@@ -248,6 +249,7 @@ std::ostream &operator<<(std::ostream &out, const RemoveGeneratedFilesMessage &m
std::ostream &operator<<(std::ostream &os, const SuspendResumeJobsEntry &entry);
std::ostream &operator<<(std::ostream &os, const ReferencesResult &value);
std::ostream &operator<<(std::ostream &out, const SymbolIndexerTask &task);
std::ostream &operator<<(std::ostream &out, const ProgressMessage &message);
void PrintTo(const FilePath &filePath, ::std::ostream *os);
void PrintTo(const FilePathView &filePathView, ::std::ostream *os);

View File

@@ -0,0 +1,42 @@
/****************************************************************************
**
** 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"
class MockQFutureInterface
{
public:
MOCK_METHOD1(setExpectedResultCount,
void (int));
MOCK_METHOD1(setProgressValue,
void (int));
MOCK_CONST_METHOD0(isRunning,
bool ());
MOCK_METHOD0(reportFinished,
void ());
};

View File

@@ -36,9 +36,16 @@ public:
void());
MOCK_METHOD1(precompiledHeadersUpdated,
void(const ClangBackEnd::PrecompiledHeadersUpdatedMessage &message));
MOCK_METHOD1(progress,
void(const ClangBackEnd::ProgressMessage &message));
void precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) override
{
precompiledHeadersUpdated(message);
}
void progress(ClangBackEnd::ProgressMessage &&message) override
{
progress(message);
}
};

View File

@@ -42,6 +42,8 @@ public:
void (const ClangBackEnd::UpdateGeneratedFilesMessage&));
MOCK_METHOD1(removeGeneratedFiles,
void (const ClangBackEnd::RemoveGeneratedFilesMessage&));
MOCK_METHOD2(setProgress,
void(int, int));
void updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage &&message) override
{

View File

@@ -0,0 +1,37 @@
/****************************************************************************
**
** 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 <progressmanagerinterface.h>
class MockProgressManager : public ClangPchManager::ProgressManagerInterface
{
public:
MOCK_METHOD2(setProgress,
void (int, int));
};

View File

@@ -40,6 +40,8 @@ public:
void (const ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage&));
MOCK_METHOD1(sourceRangesForQueryMessage,
void (const ClangBackEnd::SourceRangesForQueryMessage&));
MOCK_METHOD1(progress,
void (const ClangBackEnd::ProgressMessage&));
void sourceLocationsForRenamingMessage(ClangBackEnd::SourceLocationsForRenamingMessage &&message) override
{
@@ -56,7 +58,13 @@ public:
sourceRangesForQueryMessage(message);
}
void setLocalRenamingCallback(RenameCallback &&)
void setLocalRenamingCallback(RenameCallback &&) override
{
}
void progress(ClangBackEnd::ProgressMessage &&message) override
{
progress(message);
}
};

View File

@@ -59,6 +59,9 @@ public:
MOCK_METHOD0(cancel,
void());
MOCK_METHOD2(setProgress,
void(int, int));
void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override
{
requestSourceLocationsForRenamingMessage(message);

View File

@@ -36,6 +36,7 @@
#include <generatedfiles.h>
#include <pchcreator.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <sqlitedatabase.h>

View File

@@ -28,6 +28,7 @@
#include "mockpchmanagernotifier.h"
#include "mockpchmanagerserver.h"
#include "mockprecompiledheaderstorage.h"
#include "mockprogressmanager.h"
#include <pchmanagerclient.h>
#include <pchmanagerprojectupdater.h>
@@ -35,6 +36,7 @@
#include <filepathcaching.h>
#include <refactoringdatabaseinitializer.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
#include <updategeneratedfilesmessage.h>
@@ -51,8 +53,9 @@ using testing::Not;
class PchManagerClient : public ::testing::Test
{
protected:
NiceMock<MockProgressManager> mockProgressManager;
NiceMock<MockPchManagerServer> mockPchManagerServer;
ClangPchManager::PchManagerClient client;
ClangPchManager::PchManagerClient client{mockProgressManager};
NiceMock<MockPchManagerNotifier> mockPchManagerNotifier{client};
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
@@ -155,4 +158,11 @@ TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdIsUpdated)
42);
}
TEST_F(PchManagerClient, SetProgress)
{
EXPECT_CALL(mockProgressManager, setProgress(10, 20));
client.progress({ClangBackEnd::ProgressType::PrecompiledHeader, 10, 20});
}
}

View File

@@ -32,6 +32,7 @@
#include <pchmanagerclientproxy.h>
#include <pchmanagerserverproxy.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
#include <updategeneratedfilesmessage.h>
@@ -152,6 +153,17 @@ TEST_F(PchManagerClientServerInProcess, SendPrecompiledHeaderUpdatedMessage)
scheduleClientMessages();
}
TEST_F(PchManagerClientServerInProcess, SendProgressMessage)
{
ClangBackEnd::ProgressMessage message{ClangBackEnd::ProgressType::PrecompiledHeader, 10, 50};
EXPECT_CALL(mockPchManagerClient, progress(message));
clientProxy.progress(message.clone());
scheduleClientMessages();
}
PchManagerClientServerInProcess::PchManagerClientServerInProcess()
: serverProxy(&mockPchManagerClient, &buffer),
clientProxy(&mockPchManagerServer, &buffer)

View File

@@ -34,6 +34,7 @@
#include <filepathcaching.h>
#include <pchmanagerserver.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <refactoringdatabaseinitializer.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
@@ -157,4 +158,12 @@ TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
server.pathsWithIdsChanged({projectPartId1});
}
TEST_F(PchManagerServer, SetProgress)
{
EXPECT_CALL(mockPchManagerClient, progress(AllOf(Field(&ClangBackEnd::ProgressMessage::progress, 20),
Field(&ClangBackEnd::ProgressMessage::total, 30))));
server.setProgress(20, 30);
}
}

View File

@@ -0,0 +1,125 @@
/****************************************************************************
**
** 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 <progresscounter.h>
namespace {
class ProgressCounter : public testing::Test
{
protected:
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter counter{mockSetProgressCallback.AsStdFunction()};
};
TEST_F(ProgressCounter, TotalAfterInitializing)
{
ASSERT_THAT(counter.total(), 0);
}
TEST_F(ProgressCounter, ProgressAfterInitializing)
{
ASSERT_THAT(counter.progress(), 0);
}
TEST_F(ProgressCounter, AddTotal)
{
counter.addTotal(5);
counter.addProgress(3);
EXPECT_CALL(mockSetProgressCallback, Call(3, 12));
counter.addTotal(7);
}
TEST_F(ProgressCounter, RemoveTotal)
{
counter.addTotal(11);
counter.addProgress(2);
EXPECT_CALL(mockSetProgressCallback, Call(2, 4));
counter.removeTotal(7);
}
TEST_F(ProgressCounter, AddProgress)
{
counter.addTotal(11);
counter.addProgress(3);
EXPECT_CALL(mockSetProgressCallback, Call(7, 11));
counter.addProgress(4);
}
TEST_F(ProgressCounter, AddTotalAfterFinishingProgress)
{
counter.addTotal(11);
counter.addProgress(3);
counter.addProgress(8);
EXPECT_CALL(mockSetProgressCallback, Call(0, 9));
counter.addTotal(9);
}
TEST_F(ProgressCounter, AddProgressAfterFinishingProgress)
{
counter.addTotal(11);
counter.addProgress(3);
counter.addProgress(8);
counter.addTotal(9);
EXPECT_CALL(mockSetProgressCallback, Call(4, 9));
counter.addProgress(4);
}
TEST_F(ProgressCounter, AddTotalAfterFinishingProgressByRemoving)
{
counter.addTotal(11);
counter.addProgress(3);
counter.removeTotal(8);
EXPECT_CALL(mockSetProgressCallback, Call(0, 9));
counter.addTotal(9);
}
TEST_F(ProgressCounter, AddProgressAfterFinishingProgressByRemoving)
{
counter.addTotal(11);
counter.addProgress(3);
counter.removeTotal(8);
counter.addTotal(9);
EXPECT_CALL(mockSetProgressCallback, Call(4, 9));
counter.addProgress(4);
}
}

View File

@@ -31,16 +31,19 @@
#include "mocksqlitetransactionbackend.h"
#include <projectpartqueue.h>
#include <progresscounter.h>
namespace {
class ProjectPartQueue : public testing::Test
{
protected:
MockTaskScheduler<ClangBackEnd::ProjectPartQueue::Task> mockTaskScheduler;
NiceMock<MockTaskScheduler<ClangBackEnd::ProjectPartQueue::Task>> mockTaskScheduler;
MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage;
MockSqliteTransactionBackend mockSqliteTransactionBackend;
ClangBackEnd::ProjectPartQueue queue{mockTaskScheduler, mockPrecompiledHeaderStorage, mockSqliteTransactionBackend};
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
ClangBackEnd::ProjectPartQueue queue{mockTaskScheduler, mockPrecompiledHeaderStorage, mockSqliteTransactionBackend, progressCounter};
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
{"--yi"},
{{"YI","1"}},
@@ -76,6 +79,25 @@ TEST_F(ProjectPartQueue, AddProjectPart)
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
}
TEST_F(ProjectPartQueue, AddProjectPartCallsProcessEntries)
{
InSequence s;
EXPECT_CALL(mockTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(2)));
queue.addProjectParts({projectPart1, projectPart2});
}
TEST_F(ProjectPartQueue, AddProjectPartCallsProgressCounter)
{
queue.addProjectParts({projectPart1, projectPart2});
EXPECT_CALL(mockSetProgressCallback, Call(0, 3));
queue.addProjectParts({projectPart2b, projectPart3});
}
TEST_F(ProjectPartQueue, IgnoreIdenticalProjectPart)
{
queue.addProjectParts({projectPart1, projectPart2});
@@ -103,15 +125,13 @@ TEST_F(ProjectPartQueue, RemoveProjectPart)
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart3));
}
TEST_F(ProjectPartQueue, ProcessTasksCallsFreeSlotsAndAddTasksInScheduler)
TEST_F(ProjectPartQueue, RemoveProjectPartCallsProgressCounter)
{
InSequence s;
queue.addProjectParts({projectPart1, projectPart2});
queue.addProjectParts({projectPart1, projectPart2, projectPart3});
EXPECT_CALL(mockTaskScheduler, freeSlots()).WillRepeatedly(Return(2));
EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(2)));
EXPECT_CALL(mockSetProgressCallback, Call(0, 2));
queue.processEntries();
queue.removeProjectParts({projectPart2.projectPartId});
}
TEST_F(ProjectPartQueue, CreateTasksSizeEqualsInputSize)

View File

@@ -29,6 +29,7 @@
#include "mockpchmanagernotifier.h"
#include "mockpchmanagerserver.h"
#include "mockprecompiledheaderstorage.h"
#include "mockprogressmanager.h"
#include <pchmanagerprojectupdater.h>
@@ -118,7 +119,8 @@ protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
ClangPchManager::PchManagerClient pchManagerClient;
NiceMock<MockProgressManager> mockProgressManager;
ClangPchManager::PchManagerClient pchManagerClient{mockProgressManager};
MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient};
NiceMock<MockPchManagerServer> mockPchManagerServer;
ClangPchManager::ProjectUpdater updater{mockPchManagerServer, filePathCache};

View File

@@ -26,6 +26,7 @@
#include "googletest.h"
#include "mocksearchhandle.h"
#include "mockfilepathcaching.h"
#include "mockprogressmanager.h"
#include "mocksymbolquery.h"
#include <clangqueryprojectsfindfilter.h>
@@ -72,7 +73,8 @@ protected:
MockFunction<void(const QString &,
const ClangBackEnd::SourceLocationsContainer &,
int)> mockLocalRenaming;
ClangRefactoring::RefactoringClient client;
NiceMock<MockProgressManager> mockProgressManager;
ClangRefactoring::RefactoringClient client{mockProgressManager};
ClangBackEnd::RefactoringServerProxy serverProxy{&client, &ioDevice};
RefactoringEngine engine{serverProxy, client, mockFilePathCaching, mockSymbolQuery};
QString fileContent{QStringLiteral("int x;\nint y;")};
@@ -220,6 +222,13 @@ TEST_F(RefactoringClient, XXX)
client.addSearchResult(sourceRange);
}
TEST_F(RefactoringClient, SetProgress)
{
EXPECT_CALL(mockProgressManager, setProgress(10, 20));
client.progress({ClangBackEnd::ProgressType::Indexing, 10, 20});
}
void RefactoringClient::SetUp()
{
using Filter = ClangRefactoring::ClangQueryProjectsFindFilter;

View File

@@ -140,6 +140,17 @@ TEST_F(RefactoringClientServerInProcess, SourceRangesForQueryMessage)
scheduleClientMessages();
}
TEST_F(RefactoringClientServerInProcess, SendProgressMessage)
{
ClangBackEnd::ProgressMessage message{ClangBackEnd::ProgressType::PrecompiledHeader, 10, 50};
EXPECT_CALL(mockRefactoringClient, progress(message));
clientProxy.progress(message.clone());
scheduleClientMessages();
}
TEST_F(RefactoringClientServerInProcess, RequestSourceRangesAndDiagnosticsForQueryMessage)
{
RequestSourceRangesForQueryMessage message{"functionDecl()",

View File

@@ -26,6 +26,7 @@
#include "googletest.h"
#include "mockcppmodelmanager.h"
#include "mockprogressmanager.h"
#include "mockrefactoringserver.h"
#include <sqlitedatabase.h>
@@ -86,7 +87,8 @@ protected:
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
NiceMock<MockRefactoringServer> mockRefactoringServer;
ClangPchManager::PchManagerClient pchManagerClient;
NiceMock<MockProgressManager> mockProgressManager;
ClangPchManager::PchManagerClient pchManagerClient{mockProgressManager};
MockCppModelManager mockCppModelManager;
ClangRefactoring::RefactoringProjectUpdater updater{mockRefactoringServer, pchManagerClient, mockCppModelManager, filePathCache};
Utils::SmallString projectPartId;

View File

@@ -338,6 +338,13 @@ TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectPart
refactoringServer.updateProjectParts({Utils::clone(projectParts)});
}
TEST_F(RefactoringServer, SetProgress)
{
EXPECT_CALL(mockRefactoringClient, progress(AllOf(Field(&ClangBackEnd::ProgressMessage::progress, 20),
Field(&ClangBackEnd::ProgressMessage::total, 30))));
refactoringServer.setProgress(20, 30);
}
void RefactoringServer::SetUp()
{

View File

@@ -200,8 +200,10 @@ protected:
ClangBackEnd::FileStatusCache fileStatusCache{filePathCache};
ClangBackEnd::GeneratedFiles generatedFiles;
Manager collectorManger{generatedFiles};
Scheduler indexerScheduler{collectorManger, indexerQueue, 1};
SymbolIndexerTaskQueue indexerQueue{indexerScheduler};
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
Scheduler indexerScheduler{collectorManger, indexerQueue, progressCounter, 1};
SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter};
ClangBackEnd::SymbolIndexer indexer{indexerQueue,
mockStorage,
mockPathWatcher,

View File

@@ -50,8 +50,10 @@ MATCHER_P2(IsTask, filePathId, projectPartId,
class SymbolIndexerTaskQueue : public testing::Test
{
protected:
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
NiceMock<MockTaskScheduler<Callable>> mockTaskScheduler;
ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler};
ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler, progressCounter};
};
TEST_F(SymbolIndexerTaskQueue, AddTasks)
@@ -71,6 +73,20 @@ TEST_F(SymbolIndexerTaskQueue, AddTasks)
IsTask(FilePathId{1, 5}, 1)));
}
TEST_F(SymbolIndexerTaskQueue, AddTasksCallsProgressCounter)
{
queue.addOrUpdateTasks({{{1, 1}, 1, Callable{}},
{{1, 3}, 1, Callable{}},
{{1, 5}, 1, Callable{}}});
EXPECT_CALL(mockSetProgressCallback, Call(0, 4));
queue.addOrUpdateTasks({{{1, 2}, 1, Callable{}},
{{1, 3}, 1, Callable{}}});
}
TEST_F(SymbolIndexerTaskQueue, ReplaceTask)
{
queue.addOrUpdateTasks({{{1, 1}, 1, Callable{}},
@@ -126,6 +142,24 @@ TEST_F(SymbolIndexerTaskQueue, RemoveTaskByProjectParts)
IsTask(FilePathId{1, 5}, 1)));
}
TEST_F(SymbolIndexerTaskQueue, RemoveTasksCallsProgressCounter)
{
queue.addOrUpdateTasks({{{1, 1}, 1, Callable{}},
{{1, 3}, 1, Callable{}},
{{1, 5}, 1, Callable{}}});
queue.addOrUpdateTasks({{{1, 2}, 2, Callable{}},
{{1, 3}, 2, Callable{}}});
queue.addOrUpdateTasks({{{1, 2}, 3, Callable{}},
{{1, 3}, 3, Callable{}}});
queue.addOrUpdateTasks({{{1, 2}, 4, Callable{}},
{{1, 3}, 4, Callable{}}});
EXPECT_CALL(mockSetProgressCallback, Call(0, 5));
queue.removeTasks({2, 3});
}
TEST_F(SymbolIndexerTaskQueue, ProcessTasksCallsFreeSlotsAndAddTasksInScheduler)
{
InSequence s;

View File

@@ -82,7 +82,8 @@ protected:
RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
FilePathCaching filePathCache{database};
ClangBackEnd::GeneratedFiles generatedFiles;
ClangBackEnd::SymbolIndexing indexing{database, filePathCache, generatedFiles};
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::SymbolIndexing indexing{database, filePathCache, generatedFiles, mockSetProgressCallback.AsStdFunction()};
StatementFactory queryFactory{database};
Query query{queryFactory};
PathString main1Path = TESTDATA_DIR "/symbolindexing_main1.cpp";

View File

@@ -49,6 +49,7 @@ protected:
void SetUp()
{
ON_CALL(mockProcessorManager, unusedProcessor()).WillByDefault(ReturnRef(mockSymbolsCollector));
progressCounter.addTotal(100);
}
void TearDown()
{
@@ -63,11 +64,15 @@ protected:
NiceMockProcessorManager mockProcessorManager;
NiceMock<MockSymbolsCollector> mockSymbolsCollector;
NiceMock<MockSymbolIndexerTaskQueue> mockSymbolIndexerTaskQueue;
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
Scheduler scheduler{mockProcessorManager,
mockSymbolIndexerTaskQueue,
progressCounter,
4};
Scheduler deferredScheduler{mockProcessorManager,
mockSymbolIndexerTaskQueue,
progressCounter,
4,
std::launch::deferred};
};
@@ -140,6 +145,17 @@ TEST_F(TaskScheduler, FreeSlotsCallsCleanupMethodsAfterTheWorkIsDone)
scheduler.freeSlots();
}
TEST_F(TaskScheduler, FreeSlotsCallsProgressMethodsAfterTheWorkIsDone)
{
scheduler.addTasks({nocall, nocall});
scheduler.syncTasks();
InSequence s;
EXPECT_CALL(mockSetProgressCallback, Call(2, 100));
scheduler.freeSlots();
}
TEST_F(TaskScheduler, AddTaskCallSymbolsCollectorManagerUnusedSymbolsCollector)
{
EXPECT_CALL(mockProcessorManager, unusedProcessor()).Times(2);

View File

@@ -103,7 +103,8 @@ SOURCES += \
projectpartqueue-test.cpp \
processormanager-test.cpp \
taskscheduler-test.cpp \
compileroptionsbuilder-test.cpp
compileroptionsbuilder-test.cpp \
progresscounter-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
@@ -245,7 +246,9 @@ HEADERS += \
mockprojectpartqueue.h \
mockprocessor.h \
mockprocessormanager.h \
mocktaskscheduler.h
mocktaskscheduler.h \
mockprogressmanager.h \
mockfutureinterface.h
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \