qmljs: Use Utils::onFinished instead of manual QFutureWatcher

Change-Id: Iad6b958cb87ea5d4edaa270c27fac5ffdc334bba
Fixes: QTCREATORBUG-20243
Task-number: QTCREATORBUG-18533
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Philip Van Hoof
2020-04-24 16:08:25 +02:00
parent ba171172e4
commit a6f69d6142
2 changed files with 84 additions and 65 deletions

View File

@@ -296,11 +296,18 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
QStringList dependencies; QStringList dependencies;
}; };
auto watcher = QSharedPointer<QFutureWatcher<CppQmlTypesInfo>>(new QFutureWatcher<CppQmlTypesInfo>()); auto future = Utils::runAsync([output, libraryPath](QFutureInterface<CppQmlTypesInfo>& future)
{
CppQmlTypesInfo infos;
CppQmlTypesLoader::parseQmlTypeDescriptions(output, &infos.objectsList, &infos.moduleApis, &infos.dependencies,
&infos.error, &infos.warning,
QLatin1String("<dump of ") + libraryPath + QLatin1Char('>'));
future.reportFinished(&infos);
});
connect(watcher.data(), &QFutureWatcher<CppQmlTypesInfo>::finished, this, Utils::onFinished(future, this,
[this, watcher, libraryInfo, privatePlugin, libraryPath] { [this, libraryInfo, privatePlugin, libraryPath] (const QFuture<CppQmlTypesInfo>& future) {
CppQmlTypesInfo infos = watcher->result(); CppQmlTypesInfo infos = future.result();
LibraryInfo libInfo = libraryInfo; LibraryInfo libInfo = libraryInfo;
@@ -322,17 +329,6 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
m_modelManager->updateLibraryInfo(libraryPath, libInfo); m_modelManager->updateLibraryInfo(libraryPath, libInfo);
}); });
auto future = Utils::runAsync([output, libraryPath](QFutureInterface<CppQmlTypesInfo> &future)
{
CppQmlTypesInfo infos;
CppQmlTypesLoader::parseQmlTypeDescriptions(output, &infos.objectsList, &infos.moduleApis, &infos.dependencies,
&infos.error, &infos.warning,
QLatin1String("<dump of ") + libraryPath + QLatin1Char('>'));
future.reportFinished(&infos);
});
watcher->setFuture(future);
} else { } else {
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpDone); libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpDone);
libraryInfo.updateFingerprint(); libraryInfo.updateFingerprint();
@@ -469,81 +465,97 @@ QFuture<PluginDumper::DependencyInfo> PluginDumper::loadDependencies(const QStri
visited->insert(name); visited->insert(name);
} }
auto typesWatcher = QSharedPointer<QFutureWatcher<PluginDumper::QmlTypeDescription>>(new QFutureWatcher<PluginDumper::QmlTypeDescription>()); Utils::onFinished(loadQmlTypeDescription(dependenciesPaths), const_cast<PluginDumper*>(this), [=] (const QFuture<PluginDumper::QmlTypeDescription> &typesFuture) {
connect(typesWatcher.data(), &QFutureWatcher<PluginDumper::QmlTypeDescription>::finished, this, [this, iface, visited, typesWatcher] { PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
QStringList newDependencies = typesWatcher->result().dependencies; QStringList newDependencies = typesResult.dependencies;
newDependencies = Utils::toList(Utils::toSet(newDependencies) - *visited.data()); newDependencies = Utils::toList(Utils::toSet(newDependencies) - *visited.data());
if (!newDependencies.isEmpty()) { if (!newDependencies.isEmpty()) {
auto loadWatcher = QSharedPointer<QFutureWatcher<PluginDumper::DependencyInfo>>(new QFutureWatcher<PluginDumper::DependencyInfo>()); Utils::onFinished(loadDependencies(newDependencies, visited),
connect(loadWatcher.data(), &QFutureWatcher<PluginDumper::DependencyInfo>::finished, this, [iface, newDependencies, visited, typesWatcher, loadWatcher] { const_cast<PluginDumper*>(this), [typesResult, iface] (const QFuture<PluginDumper::DependencyInfo> &future) {
PluginDumper::DependencyInfo result = loadWatcher->result(); PluginDumper::DependencyInfo result = future.result();
result.errors += typesWatcher->result().errors; result.errors += typesResult.errors;
result.objects += typesWatcher->result().objects; result.objects += typesResult.objects;
result.warnings+= typesWatcher->result().warnings; result.warnings+= typesResult.warnings;
iface->reportFinished(&result); iface->reportFinished(&result);
}); });
loadWatcher->setFuture(loadDependencies(newDependencies, visited));
} else { } else {
PluginDumper::DependencyInfo result; PluginDumper::DependencyInfo result;
result.errors += typesWatcher->result().errors; result.errors += typesResult.errors;
result.objects += typesWatcher->result().objects; result.objects += typesResult.objects;
result.warnings+= typesWatcher->result().warnings; result.warnings+= typesResult.warnings;
iface->reportFinished(&result); iface->reportFinished(&result);
} }
}); });
typesWatcher->setFuture(loadQmlTypeDescription(dependenciesPaths));
return iface->future(); return iface->future();
} }
void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths, void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
const QString &libraryPath, const QString &libraryPath,
QmlJS::LibraryInfo libraryInfo) const QStringList &deps,
const QStringList &errors,
const QStringList &warnings,
const QList<ModuleApiInfo> &moduleApis,
QList<FakeMetaObject::ConstPtr> &objects)
{ {
auto typesWatcher = QSharedPointer<QFutureWatcher<PluginDumper::QmlTypeDescription>>(new QFutureWatcher<PluginDumper::QmlTypeDescription>()); QStringList errs = errors;
connect(typesWatcher.data(), &QFutureWatcher<PluginDumper::QmlTypeDescription>::finished, this, [this, typesWatcher, libraryPath, libraryInfo] {
auto loadWatcher = QSharedPointer<QFutureWatcher<PluginDumper::DependencyInfo>>(new QFutureWatcher<PluginDumper::DependencyInfo>());
connect(loadWatcher.data(), &QFutureWatcher<PluginDumper::DependencyInfo>::finished, this, [this, typesWatcher, loadWatcher, libraryPath, libraryInfo] {
QStringList deps = typesWatcher->result().dependencies;
QStringList errors = typesWatcher->result().errors;
QStringList warnings = typesWatcher->result().errors;
QList<FakeMetaObject::ConstPtr> objects = typesWatcher->result().objects;
errors += loadWatcher->result().errors;
warnings += loadWatcher->result().warnings;
objects += loadWatcher->result().objects;
QmlJS::LibraryInfo libInfo = libraryInfo;
libInfo.setMetaObjects(objects); libInfo.setMetaObjects(objects);
libInfo.setModuleApis(typesWatcher->result().moduleApis); libInfo.setModuleApis(moduleApis);
libInfo.setDependencies(typesWatcher->result().dependencies); libInfo.setDependencies(deps);
if (errors.isEmpty()) { if (errs.isEmpty()) {
libInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileDone); libInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileDone);
} else { } else {
printParseWarnings(libraryPath, errors.join(QLatin1Char('\n'))); printParseWarnings(libraryPath, errors.join(QLatin1Char('\n')));
errors.prepend(tr("Errors while reading typeinfo files:")); errs.prepend(tr("Errors while reading typeinfo files:"));
libInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, errors.join(QLatin1Char('\n'))); libInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, errs.join(QLatin1Char('\n')));
} }
if (!warnings.isEmpty()) if (!warnings.isEmpty())
printParseWarnings(libraryPath, warnings.join(QLatin1String("\n"))); printParseWarnings(libraryPath, warnings.join(QLatin1String("\n")));
libInfo.updateFingerprint(); libInfo.updateFingerprint();
}
void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths,
const QString &libraryPath,
QmlJS::LibraryInfo libraryInfo)
{
Utils::onFinished(loadQmlTypeDescription(qmltypesFilePaths), this, [=](const QFuture<PluginDumper::QmlTypeDescription> &typesFuture)
{
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
if (!typesResult.dependencies.isEmpty())
{
Utils::onFinished(loadDependencies(typesResult.dependencies, QSharedPointer<QSet<QString>>()), this,
[typesResult, libraryInfo, libraryPath, this] (const QFuture<PluginDumper::DependencyInfo> &loadFuture)
{
PluginDumper::DependencyInfo loadResult = loadFuture.result();
QStringList errors = typesResult.errors;
QStringList warnings = typesResult.errors;
QList<FakeMetaObject::ConstPtr> objects = typesResult.objects;
errors += loadResult.errors;
warnings += loadResult.warnings;
objects += loadResult.objects;
QmlJS::LibraryInfo libInfo = libraryInfo;
prepareLibraryInfo(libInfo, libraryPath, typesResult.dependencies,
errors, warnings,
typesResult.moduleApis, objects);
m_modelManager->updateLibraryInfo(libraryPath, libInfo); m_modelManager->updateLibraryInfo(libraryPath, libInfo);
}); });
if (!typesWatcher->result().dependencies.isEmpty()) { } else {
loadWatcher->setFuture(loadDependencies(typesWatcher->result().dependencies, QSharedPointer<QSet<QString>>())); QmlJS::LibraryInfo libInfo = libraryInfo;
prepareLibraryInfo(libInfo, libraryPath, typesResult.dependencies,
typesResult.errors, typesResult.warnings,
typesResult.moduleApis, typesResult.objects);
m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
} }
}); });
typesWatcher->setFuture(loadQmlTypeDescription(qmltypesFilePaths));
} }
void PluginDumper::runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &info, void PluginDumper::runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &info,

View File

@@ -106,6 +106,13 @@ private:
private: private:
Utils::FileSystemWatcher *pluginWatcher(); Utils::FileSystemWatcher *pluginWatcher();
void prepareLibraryInfo(LibraryInfo &libInfo,
const QString &libraryPath,
const QStringList &deps,
const QStringList &errors,
const QStringList &warnings,
const QList<ModuleApiInfo> &moduleApis,
QList<LanguageUtils::FakeMetaObject::ConstPtr> &objects);
ModelManagerInterface *m_modelManager; ModelManagerInterface *m_modelManager;
Utils::FileSystemWatcher *m_pluginWatcher; Utils::FileSystemWatcher *m_pluginWatcher;