forked from qt-creator/qt-creator
C++: Do not freeze Qt Creator while checking file sizes
Before actually indexing files, the C++ model checks the files against a file size limit (if set, which is the default). Do not iterate over all files and check their size in the main thread. If the files are on a device, this operation is not fast. Move the filtering to the parsing thread itself. Change-Id: I2202cc44c28f38159ca593db2399dde30f95f9bd Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -219,23 +219,22 @@ static void index(QPromise<void> &promise, const ParseParams params)
|
|||||||
qCDebug(indexerLog) << "Indexing finished.";
|
qCDebug(indexerLog) << "Indexing finished.";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse(QPromise<void> &promise, const ParseParams ¶ms)
|
static void parse(
|
||||||
|
QPromise<void> &promise,
|
||||||
|
const std::function<QSet<QString>()> &sourceFiles,
|
||||||
|
const ProjectExplorer::HeaderPaths &headerPaths,
|
||||||
|
const WorkingCopy &workingCopy)
|
||||||
{
|
{
|
||||||
const QSet<QString> &files = params.sourceFiles;
|
ParseParams params{headerPaths, workingCopy, sourceFiles()};
|
||||||
if (files.isEmpty()) {
|
promise.setProgressRange(0, params.sourceFiles.size());
|
||||||
CppModelManager::finishedRefreshingSourceFiles(files);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
promise.setProgressRange(0, files.size());
|
|
||||||
|
|
||||||
if (CppIndexingSupport::isFindErrorsIndexingActive())
|
if (CppIndexingSupport::isFindErrorsIndexingActive())
|
||||||
indexFindErrors(promise, params);
|
indexFindErrors(promise, params);
|
||||||
else
|
else
|
||||||
index(promise, params);
|
index(promise, params);
|
||||||
|
|
||||||
promise.setProgressValue(files.size());
|
promise.setProgressValue(params.sourceFiles.size());
|
||||||
CppModelManager::finishedRefreshingSourceFiles(files);
|
CppModelManager::finishedRefreshingSourceFiles(params.sourceFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@@ -302,18 +301,19 @@ bool CppIndexingSupport::isFindErrorsIndexingActive()
|
|||||||
return Utils::qtcEnvironmentVariable("QTC_FIND_ERRORS_INDEXING") == "1";
|
return Utils::qtcEnvironmentVariable("QTC_FIND_ERRORS_INDEXING") == "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<void> CppIndexingSupport::refreshSourceFiles(const QSet<QString> &sourceFiles,
|
QFuture<void> CppIndexingSupport::refreshSourceFiles(
|
||||||
CppModelManager::ProgressNotificationMode mode)
|
const std::function<QSet<QString>()> &sourceFiles,
|
||||||
|
CppModelManager::ProgressNotificationMode mode)
|
||||||
{
|
{
|
||||||
ParseParams params;
|
QFuture<void> result = Utils::asyncRun(
|
||||||
params.headerPaths = CppModelManager::headerPaths();
|
CppModelManager::sharedThreadPool(),
|
||||||
params.workingCopy = CppModelManager::workingCopy();
|
parse,
|
||||||
params.sourceFiles = sourceFiles;
|
sourceFiles,
|
||||||
|
CppModelManager::headerPaths(),
|
||||||
QFuture<void> result = Utils::asyncRun(CppModelManager::sharedThreadPool(), parse, params);
|
CppModelManager::workingCopy());
|
||||||
m_synchronizer.addFuture(result);
|
m_synchronizer.addFuture(result);
|
||||||
|
|
||||||
if (mode == CppModelManager::ForcedProgressNotification || sourceFiles.count() > 1) {
|
if (mode == CppModelManager::ForcedProgressNotification) {
|
||||||
Core::ProgressManager::addTask(result, Tr::tr("Parsing C/C++ Files"),
|
Core::ProgressManager::addTask(result, Tr::tr("Parsing C/C++ Files"),
|
||||||
CppEditor::Constants::TASK_INDEX);
|
CppEditor::Constants::TASK_INDEX);
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace Utils { class SearchResultItem; }
|
namespace Utils { class SearchResultItem; }
|
||||||
|
|
||||||
namespace CppEditor {
|
namespace CppEditor {
|
||||||
@@ -59,8 +61,10 @@ class CPPEDITOR_EXPORT CppIndexingSupport
|
|||||||
public:
|
public:
|
||||||
static bool isFindErrorsIndexingActive();
|
static bool isFindErrorsIndexingActive();
|
||||||
|
|
||||||
QFuture<void> refreshSourceFiles(const QSet<QString> &sourceFiles,
|
QFuture<void> refreshSourceFiles(
|
||||||
CppModelManager::ProgressNotificationMode mode);
|
const std::function<QSet<QString>()> &sourceFiles,
|
||||||
|
CppModelManager::ProgressNotificationMode mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::FutureSynchronizer m_synchronizer;
|
Utils::FutureSynchronizer m_synchronizer;
|
||||||
};
|
};
|
||||||
|
@@ -90,6 +90,7 @@
|
|||||||
#include <QWriteLocker>
|
#include <QWriteLocker>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
||||||
#define WITH_AST_DUMP
|
#define WITH_AST_DUMP
|
||||||
@@ -1353,15 +1354,25 @@ QFuture<void> CppModelManager::updateSourceFiles(const QSet<FilePath> &sourceFil
|
|||||||
if (sourceFiles.isEmpty() || !d->m_indexerEnabled)
|
if (sourceFiles.isEmpty() || !d->m_indexerEnabled)
|
||||||
return QFuture<void>();
|
return QFuture<void>();
|
||||||
|
|
||||||
QHash<Project *, QSet<QString>> sourcesPerProject; // TODO: Work with QList from here on?
|
std::unordered_map<Project *, QSet<QString>> sourcesPerProject;
|
||||||
for (const FilePath &fp : sourceFiles)
|
for (const FilePath &fp : sourceFiles)
|
||||||
sourcesPerProject[ProjectManager::projectForFile(fp)] << fp.toString();
|
sourcesPerProject[ProjectManager::projectForFile(fp)] << fp.toString();
|
||||||
QSet<QString> filteredFiles;
|
std::vector<std::pair<QSet<QString>, CppCodeModelSettings>> sourcesAndSettings;
|
||||||
for (auto it = sourcesPerProject.cbegin(); it != sourcesPerProject.cend(); ++it) {
|
for (const auto &it : sourcesPerProject) {
|
||||||
filteredFiles.unite(
|
sourcesAndSettings
|
||||||
filteredFilesRemoved(it.value(), CppCodeModelSettings::settingsForProject(it.key())));
|
.emplace_back(it.second, CppCodeModelSettings::settingsForProject(it.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto filteredFiles = [sourcesAndSettings = std::move(sourcesAndSettings)] {
|
||||||
|
QSet<QString> result;
|
||||||
|
for (const auto &it : sourcesAndSettings)
|
||||||
|
result.unite(filteredFilesRemoved(it.first, it.second));
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// "ReservedProgressNotification" should be shown if there is more than one source file.
|
||||||
|
if (sourceFiles.size() > 1)
|
||||||
|
mode = ForcedProgressNotification;
|
||||||
return d->m_internalIndexingSupport->refreshSourceFiles(filteredFiles, mode);
|
return d->m_internalIndexingSupport->refreshSourceFiles(filteredFiles, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user