QmlJSEditor/QmlDesigner: Use QtConcurrent invocation for async run

Change-Id: Ic3ad1bb4e2d473f6d5134d7e1eebef020bffee0d
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Jarek Kobus
2023-03-09 17:43:08 +01:00
parent 0bec769b69
commit 8709ab5ee5
5 changed files with 55 additions and 70 deletions

View File

@@ -10,11 +10,12 @@
#include "rewriterview.h" #include "rewriterview.h"
#include "qmlitemnode.h" #include "qmlitemnode.h"
#include "qmlobjectnode.h" #include "qmlobjectnode.h"
#include "coreplugin/editormanager/editormanager.h"
#include "utils/qtcassert.h" #include <coreplugin/editormanager/editormanager.h>
#include "utils/runextensions.h" #include <projectexplorer/project.h>
#include "projectexplorer/projectmanager.h" #include <projectexplorer/projectmanager.h>
#include "projectexplorer/project.h" #include <utils/asynctask.h>
#include <utils/qtcassert.h>
#include <auxiliarydataproperties.h> #include <auxiliarydataproperties.h>
@@ -69,7 +70,7 @@ public:
private: private:
void addAsset(const QPixmap &p, const Utils::FilePath &path); void addAsset(const QPixmap &p, const Utils::FilePath &path);
void doDumping(QFutureInterface<void> &fi); void doDumping(QPromise<void> &promise);
void savePixmap(const QPixmap &p, Utils::FilePath &path) const; void savePixmap(const QPixmap &p, Utils::FilePath &path) const;
QFuture<void> m_dumpFuture; QFuture<void> m_dumpFuture;
@@ -452,7 +453,7 @@ QDebug operator<<(QDebug os, const AssetExporter::ParsingState &s)
AssetDumper::AssetDumper(): AssetDumper::AssetDumper():
m_quitDumper(false) m_quitDumper(false)
{ {
m_dumpFuture = Utils::runAsync(&AssetDumper::doDumping, this); m_dumpFuture = Utils::asyncRun(&AssetDumper::doDumping, this);
} }
AssetDumper::~AssetDumper() AssetDumper::~AssetDumper()
@@ -489,7 +490,7 @@ void AssetDumper::addAsset(const QPixmap &p, const Utils::FilePath &path)
m_assets.push({p, path}); m_assets.push({p, path});
} }
void AssetDumper::doDumping(QFutureInterface<void> &fi) void AssetDumper::doDumping(QPromise<void> &promise)
{ {
auto haveAsset = [this] (std::pair<QPixmap, Utils::FilePath> *asset) { auto haveAsset = [this] (std::pair<QPixmap, Utils::FilePath> *asset) {
QMutexLocker locker(&m_queueMutex); QMutexLocker locker(&m_queueMutex);
@@ -503,7 +504,7 @@ void AssetDumper::doDumping(QFutureInterface<void> &fi)
forever { forever {
std::pair<QPixmap, Utils::FilePath> asset; std::pair<QPixmap, Utils::FilePath> asset;
if (haveAsset(&asset)) { if (haveAsset(&asset)) {
if (fi.isCanceled()) if (promise.isCanceled())
break; break;
savePixmap(asset.first, asset.second); savePixmap(asset.first, asset.second);
} else { } else {
@@ -513,10 +514,9 @@ void AssetDumper::doDumping(QFutureInterface<void> &fi)
m_queueCondition.wait(&m_queueMutex); m_queueCondition.wait(&m_queueMutex);
} }
if (fi.isCanceled()) if (promise.isCanceled())
break; break;
} }
fi.reportFinished();
} }
void AssetDumper::savePixmap(const QPixmap &p, Utils::FilePath &path) const void AssetDumper::savePixmap(const QPixmap &p, Utils::FilePath &path) const

View File

@@ -4,9 +4,10 @@
#include "exportnotification.h" #include "exportnotification.h"
#include "projectexplorer/project.h" #include <projectexplorer/project.h>
#include "projectexplorer/projectnodes.h" #include <projectexplorer/projectnodes.h>
#include "utils/runextensions.h"
#include <utils/asynctask.h>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QTimer> #include <QTimer>
@@ -17,19 +18,19 @@ namespace {
Q_LOGGING_CATEGORY(loggerError, "qtc.designer.assetExportPlugin.filePathModel", QtCriticalMsg) Q_LOGGING_CATEGORY(loggerError, "qtc.designer.assetExportPlugin.filePathModel", QtCriticalMsg)
Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.filePathModel", QtInfoMsg) Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.filePathModel", QtInfoMsg)
void findQmlFiles(QFutureInterface<Utils::FilePath> &f, const Project *project) void findQmlFiles(QPromise<Utils::FilePath> &promise, const Project *project)
{ {
if (!project || f.isCanceled()) if (!project || promise.isCanceled())
return; return;
int index = 0; int index = 0;
project->files([&f, &index](const Node* node) ->bool { project->files([&promise, &index](const Node* node) ->bool {
if (f.isCanceled()) if (promise.isCanceled())
return false; return false;
Utils::FilePath path = node->filePath(); Utils::FilePath path = node->filePath();
bool isComponent = !path.fileName().isEmpty() && path.fileName().front().isUpper(); bool isComponent = !path.fileName().isEmpty() && path.fileName().front().isUpper();
if (isComponent && node->filePath().endsWith(".ui.qml")) if (isComponent && node->filePath().endsWith(".ui.qml"))
f.reportResult(path, index++); promise.addResult(path, index++);
return true; return true;
}); });
} }
@@ -132,7 +133,7 @@ void FilePathModel::processProject()
connect(m_preprocessWatcher.get(), &QFutureWatcher<Utils::FilePath>::finished, connect(m_preprocessWatcher.get(), &QFutureWatcher<Utils::FilePath>::finished,
this, &FilePathModel::endResetModel); this, &FilePathModel::endResetModel);
QFuture<Utils::FilePath> f = Utils::runAsync(&findQmlFiles, m_project); QFuture<Utils::FilePath> f = Utils::asyncRun(&findQmlFiles, m_project);
m_preprocessWatcher->setFuture(f); m_preprocessWatcher->setFuture(f);
} }

View File

@@ -12,8 +12,8 @@
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <texteditor/basefilefind.h> #include <texteditor/basefilefind.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/asynctask.h>
#include <utils/filesearch.h> #include <utils/filesearch.h>
#include <utils/runextensions.h>
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljs/qmljsbind.h> #include <qmljs/qmljsbind.h>
@@ -26,19 +26,10 @@
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <qmljstools/qmljsmodelmanager.h> #include <qmljstools/qmljsmodelmanager.h>
#include "qmljseditorconstants.h"
#include <QApplication>
#include <QDebug> #include <QDebug>
#include <QDir>
#include <QFuture> #include <QFuture>
#include <QLabel>
#include <QTime>
#include <QTimer>
#include <QtConcurrentMap> #include <QtConcurrentMap>
#include <functional>
using namespace Core; using namespace Core;
using namespace QmlJS; using namespace QmlJS;
using namespace QmlJS::AST; using namespace QmlJS::AST;
@@ -704,7 +695,7 @@ class ProcessFile
using Usage = FindReferences::Usage; using Usage = FindReferences::Usage;
const QString name; const QString name;
const ObjectValue *scope; const ObjectValue *scope;
QFutureInterface<Usage> *future; QPromise<Usage> &m_promise;
public: public:
// needed by QtConcurrent // needed by QtConcurrent
@@ -714,16 +705,15 @@ public:
ProcessFile(const ContextPtr &context, ProcessFile(const ContextPtr &context,
const QString &name, const QString &name,
const ObjectValue *scope, const ObjectValue *scope,
QFutureInterface<Usage> *future) QPromise<Usage> &promise)
: context(context), name(name), scope(scope), future(future) : context(context), name(name), scope(scope), m_promise(promise)
{ } { }
QList<Usage> operator()(const Utils::FilePath &fileName) QList<Usage> operator()(const Utils::FilePath &fileName)
{ {
QList<Usage> usages; QList<Usage> usages;
if (future->isPaused()) m_promise.suspendIfRequested();
future->waitForResume(); if (m_promise.isCanceled())
if (future->isCanceled())
return usages; return usages;
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
Document::Ptr doc = context->snapshot().document(fileName); Document::Ptr doc = context->snapshot().document(fileName);
@@ -739,8 +729,7 @@ public:
loc.startLine, loc.startLine,
loc.startColumn - 1, loc.startColumn - 1,
loc.length)); loc.length));
if (future->isPaused()) m_promise.suspendIfRequested();
future->waitForResume();
return usages; return usages;
} }
}; };
@@ -751,7 +740,7 @@ class SearchFileForType
using Usage = FindReferences::Usage; using Usage = FindReferences::Usage;
const QString name; const QString name;
const ObjectValue *scope; const ObjectValue *scope;
QFutureInterface<Usage> *future; QPromise<Usage> &m_promise;
public: public:
// needed by QtConcurrent // needed by QtConcurrent
@@ -761,16 +750,15 @@ public:
SearchFileForType(const ContextPtr &context, SearchFileForType(const ContextPtr &context,
const QString &name, const QString &name,
const ObjectValue *scope, const ObjectValue *scope,
QFutureInterface<Usage> *future) QPromise<Usage> &promise)
: context(context), name(name), scope(scope), future(future) : context(context), name(name), scope(scope), m_promise(promise)
{ } { }
QList<Usage> operator()(const Utils::FilePath &fileName) QList<Usage> operator()(const Utils::FilePath &fileName)
{ {
QList<Usage> usages; QList<Usage> usages;
if (future->isPaused()) m_promise.suspendIfRequested();
future->waitForResume(); if (m_promise.isCanceled())
if (future->isCanceled())
return usages; return usages;
Document::Ptr doc = context->snapshot().document(fileName); Document::Ptr doc = context->snapshot().document(fileName);
if (!doc) if (!doc)
@@ -781,8 +769,7 @@ public:
const FindTypeUsages::Result results = findUsages(name, scope); const FindTypeUsages::Result results = findUsages(name, scope);
for (const SourceLocation &loc : results) for (const SourceLocation &loc : results)
usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length));
if (future->isPaused()) m_promise.suspendIfRequested();
future->waitForResume();
return usages; return usages;
} }
}; };
@@ -790,7 +777,7 @@ public:
class UpdateUI class UpdateUI
{ {
using Usage = FindReferences::Usage; using Usage = FindReferences::Usage;
QFutureInterface<Usage> *future; QPromise<Usage> &m_promise;
public: public:
// needed by QtConcurrent // needed by QtConcurrent
@@ -798,14 +785,13 @@ public:
using second_argument_type = const QList<Usage> &; using second_argument_type = const QList<Usage> &;
using result_type = void; using result_type = void;
UpdateUI(QFutureInterface<Usage> *future): future(future) {} UpdateUI(QPromise<Usage> &promise): m_promise(promise) {}
void operator()(QList<Usage> &, const QList<Usage> &usages) void operator()(QList<Usage> &, const QList<Usage> &usages)
{ {
for (const Usage &u : usages) for (const Usage &u : usages)
future->reportResult(u); m_promise.addResult(u);
m_promise.setProgressValue(m_promise.future().progressValue() + 1);
future->setProgressValue(future->progressValue() + 1);
} }
}; };
@@ -822,7 +808,7 @@ FindReferences::FindReferences(QObject *parent)
FindReferences::~FindReferences() = default; FindReferences::~FindReferences() = default;
static void find_helper(QFutureInterface<FindReferences::Usage> &future, static void find_helper(QPromise<FindReferences::Usage> &promise,
const ModelManagerInterface::WorkingCopy &workingCopy, const ModelManagerInterface::WorkingCopy &workingCopy,
Snapshot snapshot, Snapshot snapshot,
const Utils::FilePath &fileName, const Utils::FilePath &fileName,
@@ -885,7 +871,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
} }
files = Utils::filteredUnique(files); files = Utils::filteredUnique(files);
future.setProgressRange(0, files.size()); promise.setProgressRange(0, files.size());
// report a dummy usage to indicate the search is starting // report a dummy usage to indicate the search is starting
FindReferences::Usage searchStarting(Utils::FilePath::fromString(replacement), name, 0, 0, 0); FindReferences::Usage searchStarting(Utils::FilePath::fromString(replacement), name, 0, 0, 0);
@@ -894,10 +880,10 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
const ObjectValue *typeValue = value_cast<ObjectValue>(findTarget.targetValue()); const ObjectValue *typeValue = value_cast<ObjectValue>(findTarget.targetValue());
if (!typeValue) if (!typeValue)
return; return;
future.reportResult(searchStarting); promise.addResult(searchStarting);
SearchFileForType process(context, name, typeValue, &future); SearchFileForType process(context, name, typeValue, promise);
UpdateUI reduce(&future); UpdateUI reduce(promise);
QtConcurrent::blockingMappedReduced<QList<FindReferences::Usage> > (files, process, reduce); QtConcurrent::blockingMappedReduced<QList<FindReferences::Usage> > (files, process, reduce);
} else { } else {
@@ -909,21 +895,21 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
return; return;
if (!scope->className().isEmpty()) if (!scope->className().isEmpty())
searchStarting.lineText.prepend(scope->className() + QLatin1Char('.')); searchStarting.lineText.prepend(scope->className() + QLatin1Char('.'));
future.reportResult(searchStarting); promise.addResult(searchStarting);
ProcessFile process(context, name, scope, &future); ProcessFile process(context, name, scope, promise);
UpdateUI reduce(&future); UpdateUI reduce(promise);
QtConcurrent::blockingMappedReduced<QList<FindReferences::Usage> > (files, process, reduce); QtConcurrent::blockingMappedReduced<QList<FindReferences::Usage> > (files, process, reduce);
} }
future.setProgressValue(files.size()); promise.setProgressValue(files.size());
} }
void FindReferences::findUsages(const Utils::FilePath &fileName, quint32 offset) void FindReferences::findUsages(const Utils::FilePath &fileName, quint32 offset)
{ {
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
QFuture<Usage> result = Utils::runAsync(&find_helper, ModelManagerInterface::workingCopy(), QFuture<Usage> result = Utils::asyncRun(&find_helper, ModelManagerInterface::workingCopy(),
modelManager->snapshot(), fileName, offset, QString()); modelManager->snapshot(), fileName, offset, QString());
m_watcher.setFuture(result); m_watcher.setFuture(result);
m_synchronizer.addFuture(result); m_synchronizer.addFuture(result);
@@ -940,7 +926,7 @@ void FindReferences::renameUsages(const Utils::FilePath &fileName,
if (newName.isNull()) if (newName.isNull())
newName = QLatin1String(""); newName = QLatin1String("");
QFuture<Usage> result = Utils::runAsync(&find_helper, ModelManagerInterface::workingCopy(), QFuture<Usage> result = Utils::asyncRun(&find_helper, ModelManagerInterface::workingCopy(),
modelManager->snapshot(), fileName, offset, newName); modelManager->snapshot(), fileName, offset, newName);
m_watcher.setFuture(result); m_watcher.setFuture(result);
m_synchronizer.addFuture(result); m_synchronizer.addFuture(result);

View File

@@ -2,7 +2,6 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmltaskmanager.h" #include "qmltaskmanager.h"
#include "qmljseditor.h"
#include "qmljseditorconstants.h" #include "qmljseditorconstants.h"
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
@@ -13,7 +12,7 @@
#include <qmljs/qmljsconstants.h> #include <qmljs/qmljsconstants.h>
#include <qmljs/qmljslink.h> #include <qmljs/qmljslink.h>
#include <qmljs/qmljscheck.h> #include <qmljs/qmljscheck.h>
#include <utils/runextensions.h> #include <utils/asynctask.h>
#include <QDebug> #include <QDebug>
#include <QtConcurrentRun> #include <QtConcurrentRun>
@@ -57,7 +56,7 @@ static Tasks convertToTasks(const QList<StaticAnalysis::Message> &messages, cons
return convertToTasks(diagnostics, fileName, category); return convertToTasks(diagnostics, fileName, category);
} }
void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future, void QmlTaskManager::collectMessages(QPromise<FileErrorMessages> &promise,
Snapshot snapshot, Snapshot snapshot,
const QList<ModelManagerInterface::ProjectInfo> &projectInfos, const QList<ModelManagerInterface::ProjectInfo> &projectInfos,
ViewerContext vContext, ViewerContext vContext,
@@ -96,8 +95,8 @@ void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future
} }
if (!result.tasks.isEmpty()) if (!result.tasks.isEmpty())
future.reportResult(result); promise.addResult(result);
if (future.isCanceled()) if (promise.isCanceled())
break; break;
} }
} }
@@ -127,8 +126,7 @@ void QmlTaskManager::updateMessagesNow(bool updateSemantic)
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
// process them // process them
QFuture<FileErrorMessages> future = QFuture<FileErrorMessages> future = Utils::asyncRun(
Utils::runAsync(
&collectMessages, modelManager->newestSnapshot(), modelManager->projectInfos(), &collectMessages, modelManager->newestSnapshot(), modelManager->projectInfos(),
modelManager->defaultVContext(Dialect::AnyLanguage), updateSemantic); modelManager->defaultVContext(Dialect::AnyLanguage), updateSemantic);
m_messageCollector.setFuture(future); m_messageCollector.setFuture(future);

View File

@@ -45,7 +45,7 @@ private:
Utils::FilePath fileName; Utils::FilePath fileName;
ProjectExplorer::Tasks tasks; ProjectExplorer::Tasks tasks;
}; };
static void collectMessages(QFutureInterface<FileErrorMessages> &future, static void collectMessages(QPromise<FileErrorMessages> &promise,
QmlJS::Snapshot snapshot, QmlJS::Snapshot snapshot,
const QList<QmlJS::ModelManagerInterface::ProjectInfo> &projectInfos, const QList<QmlJS::ModelManagerInterface::ProjectInfo> &projectInfos,
QmlJS::ViewerContext vContext, QmlJS::ViewerContext vContext,