CppElementEvaluator: Use QtConcurrent invocation for async run

Change-Id: Idc67ecd4e9e95c5893a04ca1a9ee7b30662ec664
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2023-03-09 14:06:33 +01:00
parent 5effb95ad9
commit 169b411040
9 changed files with 57 additions and 80 deletions

View File

@@ -821,16 +821,10 @@ FilePaths Snapshot::filesDependingOn(const FilePath &filePath) const
return m_deps.filesDependingOn(filePath); return m_deps.filesDependingOn(filePath);
} }
void Snapshot::updateDependencyTable() const void Snapshot::updateDependencyTable(const std::optional<QFuture<void>> &future) const
{
QFutureInterfaceBase futureInterface;
updateDependencyTable(futureInterface);
}
void Snapshot::updateDependencyTable(QFutureInterfaceBase &futureInterface) const
{ {
if (m_deps.files.isEmpty()) if (m_deps.files.isEmpty())
m_deps.build(futureInterface, *this); m_deps.build(future, *this);
} }
bool Snapshot::operator==(const Snapshot &other) const bool Snapshot::operator==(const Snapshot &other) const

View File

@@ -15,12 +15,9 @@
#include <QDateTime> #include <QDateTime>
#include <QHash> #include <QHash>
#include <QFileInfo> #include <QFileInfo>
#include <QFuture>
#include <QAtomicInt> #include <QAtomicInt>
QT_BEGIN_NAMESPACE
class QFutureInterfaceBase;
QT_END_NAMESPACE
namespace CPlusPlus { namespace CPlusPlus {
class Macro; class Macro;
@@ -406,8 +403,7 @@ public:
Utils::FilePaths filesDependingOn(const Utils::FilePath &filePath) const; Utils::FilePaths filesDependingOn(const Utils::FilePath &filePath) const;
void updateDependencyTable() const; void updateDependencyTable(const std::optional<QFuture<void>> &future = {}) const;
void updateDependencyTable(QFutureInterfaceBase &futureInterface) const;
bool operator==(const Snapshot &other) const; bool operator==(const Snapshot &other) const;

View File

@@ -4,7 +4,7 @@
#include "CppDocument.h" #include "CppDocument.h"
#include <QDebug> #include <QDebug>
#include <QFutureInterface> #include <QFuture>
using namespace Utils; using namespace Utils;
@@ -28,14 +28,14 @@ Utils::FilePaths DependencyTable::filesDependingOn(const Utils::FilePath &fileNa
return deps; return deps;
} }
void DependencyTable::build(QFutureInterfaceBase &futureInterface, const Snapshot &snapshot) void DependencyTable::build(const std::optional<QFuture<void>> &future, const Snapshot &snapshot)
{ {
files.clear(); files.clear();
fileIndex.clear(); fileIndex.clear();
includes.clear(); includes.clear();
includeMap.clear(); includeMap.clear();
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
const int documentCount = snapshot.size(); const int documentCount = snapshot.size();
@@ -49,7 +49,7 @@ void DependencyTable::build(QFutureInterfaceBase &futureInterface, const Snapsho
fileIndex[it.key()] = i; fileIndex[it.key()] = i;
} }
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
for (int i = 0; i < files.size(); ++i) { for (int i = 0; i < files.size(); ++i) {
@@ -68,13 +68,13 @@ void DependencyTable::build(QFutureInterfaceBase &futureInterface, const Snapsho
directIncludes.append(index); directIncludes.append(index);
bitmap.setBit(index, true); bitmap.setBit(index, true);
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
} }
includeMap[i] = bitmap; includeMap[i] = bitmap;
includes[i] = directIncludes; includes[i] = directIncludes;
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
} }
} }
@@ -91,7 +91,7 @@ void DependencyTable::build(QFutureInterfaceBase &futureInterface, const Snapsho
const QList<int> includedFileIndexes = includes.value(i); const QList<int> includedFileIndexes = includes.value(i);
for (const int includedFileIndex : includedFileIndexes) { for (const int includedFileIndex : includedFileIndexes) {
bitmap |= includeMap.value(includedFileIndex); bitmap |= includeMap.value(includedFileIndex);
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
} }
@@ -99,10 +99,10 @@ void DependencyTable::build(QFutureInterfaceBase &futureInterface, const Snapsho
includeMap[i] = bitmap; includeMap[i] = bitmap;
changed = true; changed = true;
} }
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
} }
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
} while (changed); } while (changed);
} }

View File

@@ -14,7 +14,8 @@
#include <QVector> #include <QVector>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QFutureInterfaceBase; template <typename T>
class QFuture;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace CPlusPlus { namespace CPlusPlus {
@@ -25,7 +26,7 @@ class CPLUSPLUS_EXPORT DependencyTable
{ {
private: private:
friend class Snapshot; friend class Snapshot;
void build(QFutureInterfaceBase &futureInterface, const Snapshot &snapshot); void build(const std::optional<QFuture<void>> &future, const Snapshot &snapshot);
Utils::FilePaths filesDependingOn(const Utils::FilePath &fileName) const; Utils::FilePaths filesDependingOn(const Utils::FilePath &fileName) const;
QVector<Utils::FilePath> files; QVector<Utils::FilePath> files;

View File

@@ -14,7 +14,7 @@
#include <cplusplus/Icons.h> #include <cplusplus/Icons.h>
#include <cplusplus/TypeOfExpression.h> #include <cplusplus/TypeOfExpression.h>
#include <utils/runextensions.h> #include <utils/asynctask.h>
#include <QDir> #include <QDir>
#include <QQueue> #include <QQueue>
@@ -140,20 +140,20 @@ CppClass *CppClass::toCppClass()
return this; return this;
} }
void CppClass::lookupBases(QFutureInterfaceBase &futureInterface, void CppClass::lookupBases(const QFuture<void> &future, Symbol *declaration,
Symbol *declaration, const LookupContext &context) const LookupContext &context)
{ {
ClassOrNamespace *hierarchy = context.lookupType(declaration); ClassOrNamespace *hierarchy = context.lookupType(declaration);
if (!hierarchy) if (!hierarchy)
return; return;
QSet<ClassOrNamespace *> visited; QSet<ClassOrNamespace *> visited;
addBaseHierarchy(futureInterface, context, hierarchy, &visited); addBaseHierarchy(future, context, hierarchy, &visited);
} }
void CppClass::addBaseHierarchy(QFutureInterfaceBase &futureInterface, const LookupContext &context, void CppClass::addBaseHierarchy(const QFuture<void> &future, const LookupContext &context,
ClassOrNamespace *hierarchy, QSet<ClassOrNamespace *> *visited) ClassOrNamespace *hierarchy, QSet<ClassOrNamespace *> *visited)
{ {
if (futureInterface.isCanceled()) if (future.isCanceled())
return; return;
visited->insert(hierarchy); visited->insert(hierarchy);
const QList<ClassOrNamespace *> &baseClasses = hierarchy->usings(); const QList<ClassOrNamespace *> &baseClasses = hierarchy->usings();
@@ -165,21 +165,21 @@ void CppClass::addBaseHierarchy(QFutureInterfaceBase &futureInterface, const Loo
ClassOrNamespace *baseHierarchy = context.lookupType(symbol); ClassOrNamespace *baseHierarchy = context.lookupType(symbol);
if (baseHierarchy && !visited->contains(baseHierarchy)) { if (baseHierarchy && !visited->contains(baseHierarchy)) {
CppClass classSymbol(symbol); CppClass classSymbol(symbol);
classSymbol.addBaseHierarchy(futureInterface, context, baseHierarchy, visited); classSymbol.addBaseHierarchy(future, context, baseHierarchy, visited);
bases.append(classSymbol); bases.append(classSymbol);
} }
} }
} }
} }
void CppClass::lookupDerived(QFutureInterfaceBase &futureInterface, void CppClass::lookupDerived(const QFuture<void> &future, Symbol *declaration,
Symbol *declaration, const Snapshot &snapshot) const Snapshot &snapshot)
{ {
snapshot.updateDependencyTable(futureInterface); snapshot.updateDependencyTable(future);
if (futureInterface.isCanceled()) if (future.isCanceled())
return; return;
addDerivedHierarchy(TypeHierarchyBuilder::buildDerivedTypeHierarchy( addDerivedHierarchy(TypeHierarchyBuilder::buildDerivedTypeHierarchy(
futureInterface, declaration, snapshot)); declaration, snapshot, future));
} }
void CppClass::addDerivedHierarchy(const TypeHierarchy &hierarchy) void CppClass::addDerivedHierarchy(const TypeHierarchy &hierarchy)
@@ -340,13 +340,13 @@ static Symbol *followTemplateAsClass(Symbol *symbol)
return symbol; return symbol;
} }
static void createTypeHierarchy(QFutureInterface<QSharedPointer<CppElement>> &futureInterface, static void createTypeHierarchy(QPromise<QSharedPointer<CppElement>> &promise,
const Snapshot &snapshot, const Snapshot &snapshot,
const LookupItem &lookupItem, const LookupItem &lookupItem,
const LookupContext &context, const LookupContext &context,
SymbolFinder symbolFinder) SymbolFinder symbolFinder)
{ {
if (futureInterface.isCanceled()) if (promise.isCanceled())
return; return;
Symbol *declaration = lookupItem.declaration(); Symbol *declaration = lookupItem.declaration();
@@ -360,16 +360,17 @@ static void createTypeHierarchy(QFutureInterface<QSharedPointer<CppElement>> &fu
declaration = followClassDeclaration(declaration, snapshot, symbolFinder, &contextToUse); declaration = followClassDeclaration(declaration, snapshot, symbolFinder, &contextToUse);
declaration = followTemplateAsClass(declaration); declaration = followTemplateAsClass(declaration);
if (futureInterface.isCanceled()) if (promise.isCanceled())
return; return;
QSharedPointer<CppClass> cppClass(new CppClass(declaration)); QSharedPointer<CppClass> cppClass(new CppClass(declaration));
cppClass->lookupBases(futureInterface, declaration, contextToUse); const QFuture<void> future = QFuture<void>(promise.future());
if (futureInterface.isCanceled()) cppClass->lookupBases(future, declaration, contextToUse);
if (promise.isCanceled())
return; return;
cppClass->lookupDerived(futureInterface, declaration, snapshot); cppClass->lookupDerived(future, declaration, snapshot);
if (futureInterface.isCanceled()) if (promise.isCanceled())
return; return;
futureInterface.reportResult(cppClass); promise.addResult(cppClass);
} }
static QSharedPointer<CppElement> handleLookupItemMatch(const Snapshot &snapshot, static QSharedPointer<CppElement> handleLookupItemMatch(const Snapshot &snapshot,
@@ -495,7 +496,7 @@ static QFuture<QSharedPointer<CppElement>> asyncExec(
const CPlusPlus::Snapshot &snapshot, const CPlusPlus::LookupItem &lookupItem, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::LookupItem &lookupItem,
const CPlusPlus::LookupContext &lookupContext) const CPlusPlus::LookupContext &lookupContext)
{ {
return Utils::runAsync(&createTypeHierarchy, snapshot, lookupItem, lookupContext, return Utils::asyncRun(&createTypeHierarchy, snapshot, lookupItem, lookupContext,
*CppModelManager::instance()->symbolFinder()); *CppModelManager::instance()->symbolFinder());
} }

View File

@@ -92,16 +92,16 @@ public:
CppClass *toCppClass() final; CppClass *toCppClass() final;
void lookupBases(QFutureInterfaceBase &futureInterface, void lookupBases(const QFuture<void> &future, CPlusPlus::Symbol *declaration,
CPlusPlus::Symbol *declaration, const CPlusPlus::LookupContext &context); const CPlusPlus::LookupContext &context);
void lookupDerived(QFutureInterfaceBase &futureInterface, void lookupDerived(const QFuture<void> &future, CPlusPlus::Symbol *declaration,
CPlusPlus::Symbol *declaration, const CPlusPlus::Snapshot &snapshot); const CPlusPlus::Snapshot &snapshot);
QList<CppClass> bases; QList<CppClass> bases;
QList<CppClass> derived; QList<CppClass> derived;
private: private:
void addBaseHierarchy(QFutureInterfaceBase &futureInterface, void addBaseHierarchy(const QFuture<void> &future,
const CPlusPlus::LookupContext &context, const CPlusPlus::LookupContext &context,
CPlusPlus::ClassOrNamespace *hierarchy, CPlusPlus::ClassOrNamespace *hierarchy,
QSet<CPlusPlus::ClassOrNamespace *> *visited); QSet<CPlusPlus::ClassOrNamespace *> *visited);

View File

@@ -183,7 +183,8 @@ void CppTypeHierarchyWidget::perform()
m_futureWatcher.setFuture(QFuture<void>(m_future)); m_futureWatcher.setFuture(QFuture<void>(m_future));
m_synchronizer.addFuture(m_future); m_synchronizer.addFuture(m_future);
Core::ProgressManager::addTask(m_future, Tr::tr("Evaluating Type Hierarchy"), "TypeHierarchy"); Core::ProgressManager::addTimedTask(m_futureWatcher.future(),
Tr::tr("Evaluating Type Hierarchy"), "TypeHierarchy", 2);
} }
void CppTypeHierarchyWidget::performFromExpression(const QString &expression, const FilePath &filePath) void CppTypeHierarchyWidget::performFromExpression(const QString &expression, const FilePath &filePath)

View File

@@ -108,20 +108,12 @@ const QList<TypeHierarchy> &TypeHierarchy::hierarchy() const
} }
TypeHierarchy TypeHierarchyBuilder::buildDerivedTypeHierarchy(Symbol *symbol, TypeHierarchy TypeHierarchyBuilder::buildDerivedTypeHierarchy(Symbol *symbol,
const Snapshot &snapshot) const Snapshot &snapshot, const std::optional<QFuture<void>> &future)
{
QFutureInterfaceBase dummy;
return TypeHierarchyBuilder::buildDerivedTypeHierarchy(dummy, symbol, snapshot);
}
TypeHierarchy TypeHierarchyBuilder::buildDerivedTypeHierarchy(QFutureInterfaceBase &futureInterface,
Symbol *symbol,
const Snapshot &snapshot)
{ {
TypeHierarchy hierarchy(symbol); TypeHierarchy hierarchy(symbol);
TypeHierarchyBuilder builder; TypeHierarchyBuilder builder;
QHash<QString, QHash<QString, QString>> cache; QHash<QString, QHash<QString, QString>> cache;
builder.buildDerived(futureInterface, &hierarchy, snapshot, cache); builder.buildDerived(future, &hierarchy, snapshot, cache);
return hierarchy; return hierarchy;
} }
@@ -172,11 +164,10 @@ static FilePaths filesDependingOn(const Snapshot &snapshot, Symbol *symbol)
return FilePaths{file} + snapshot.filesDependingOn(file); return FilePaths{file} + snapshot.filesDependingOn(file);
} }
void TypeHierarchyBuilder::buildDerived(QFutureInterfaceBase &futureInterface, void TypeHierarchyBuilder::buildDerived(const std::optional<QFuture<void>> &future,
TypeHierarchy *typeHierarchy, TypeHierarchy *typeHierarchy,
const Snapshot &snapshot, const Snapshot &snapshot,
QHash<QString, QHash<QString, QString>> &cache, QHash<QString, QHash<QString, QString>> &cache)
int depth)
{ {
Symbol *symbol = typeHierarchy->_symbol; Symbol *symbol = typeHierarchy->_symbol;
if (_visited.contains(symbol)) if (_visited.contains(symbol))
@@ -188,15 +179,10 @@ void TypeHierarchyBuilder::buildDerived(QFutureInterfaceBase &futureInterface,
DerivedHierarchyVisitor visitor(symbolName, cache); DerivedHierarchyVisitor visitor(symbolName, cache);
const FilePaths dependingFiles = filesDependingOn(snapshot, symbol); const FilePaths dependingFiles = filesDependingOn(snapshot, symbol);
if (depth == 0)
futureInterface.setProgressRange(0, dependingFiles.size());
int i = -1;
for (const FilePath &fileName : dependingFiles) { for (const FilePath &fileName : dependingFiles) {
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
if (depth == 0)
futureInterface.setProgressValue(++i);
Document::Ptr doc = snapshot.document(fileName); Document::Ptr doc = snapshot.document(fileName);
if ((_candidates.contains(fileName) && !_candidates.value(fileName).contains(symbolName)) if ((_candidates.contains(fileName) && !_candidates.value(fileName).contains(symbolName))
|| !doc->control()->findIdentifier(symbol->identifier()->chars(), || !doc->control()->findIdentifier(symbol->identifier()->chars(),
@@ -210,8 +196,8 @@ void TypeHierarchyBuilder::buildDerived(QFutureInterfaceBase &futureInterface,
const QList<Symbol *> &derived = visitor.derived(); const QList<Symbol *> &derived = visitor.derived();
for (Symbol *s : derived) { for (Symbol *s : derived) {
TypeHierarchy derivedHierarchy(s); TypeHierarchy derivedHierarchy(s);
buildDerived(futureInterface, &derivedHierarchy, snapshot, cache, depth + 1); buildDerived(future, &derivedHierarchy, snapshot, cache);
if (futureInterface.isCanceled()) if (future && future->isCanceled())
return; return;
typeHierarchy->_hierarchy.append(derivedHierarchy); typeHierarchy->_hierarchy.append(derivedHierarchy);
} }

View File

@@ -6,7 +6,7 @@
#include <cplusplus/CppDocument.h> #include <cplusplus/CppDocument.h>
#include <cplusplus/Overview.h> #include <cplusplus/Overview.h>
#include <QFutureInterface> #include <QFuture>
#include <QList> #include <QList>
#include <QSet> #include <QSet>
@@ -44,19 +44,17 @@ class TypeHierarchyBuilder
{ {
public: public:
static TypeHierarchy buildDerivedTypeHierarchy(CPlusPlus::Symbol *symbol, static TypeHierarchy buildDerivedTypeHierarchy(CPlusPlus::Symbol *symbol,
const CPlusPlus::Snapshot &snapshot); const CPlusPlus::Snapshot &snapshot,
static TypeHierarchy buildDerivedTypeHierarchy(QFutureInterfaceBase &futureInterface, const std::optional<QFuture<void>> &future = {});
CPlusPlus::Symbol *symbol,
const CPlusPlus::Snapshot &snapshot);
static CPlusPlus::LookupItem followTypedef(const CPlusPlus::LookupContext &context, static CPlusPlus::LookupItem followTypedef(const CPlusPlus::LookupContext &context,
const CPlusPlus::Name *symbolName, const CPlusPlus::Name *symbolName,
CPlusPlus::Scope *enclosingScope, CPlusPlus::Scope *enclosingScope,
std::set<const CPlusPlus::Symbol *> typedefs = {}); std::set<const CPlusPlus::Symbol *> typedefs = {});
private: private:
TypeHierarchyBuilder() = default; TypeHierarchyBuilder() = default;
void buildDerived(QFutureInterfaceBase &futureInterface, TypeHierarchy *typeHierarchy, void buildDerived(const std::optional<QFuture<void>> &future, TypeHierarchy *typeHierarchy,
const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Snapshot &snapshot,
QHash<QString, QHash<QString, QString> > &cache, int depth = 0); QHash<QString, QHash<QString, QString> > &cache);
QSet<CPlusPlus::Symbol *> _visited; QSet<CPlusPlus::Symbol *> _visited;
QHash<Utils::FilePath, QSet<QString> > _candidates; QHash<Utils::FilePath, QSet<QString> > _candidates;