diff --git a/src/plugins/cppeditor/cppincludesfilter.cpp b/src/plugins/cppeditor/cppincludesfilter.cpp index c4588bf78c7..7f84b55932c 100644 --- a/src/plugins/cppeditor/cppincludesfilter.cpp +++ b/src/plugins/cppeditor/cppincludesfilter.cpp @@ -97,6 +97,36 @@ void CppIncludesIterator::fetchMore() } } +static FilePaths generateFilePaths(const QFuture &future, + const CPlusPlus::Snapshot &snapshot, + const std::unordered_set &inputFilePaths) +{ + FilePaths results; + std::unordered_set resultsCache; + std::unordered_set queuedPaths = inputFilePaths; + + while (!queuedPaths.empty()) { + if (future.isCanceled()) + return {}; + + const auto iterator = queuedPaths.cbegin(); + const FilePath filePath = *iterator; + queuedPaths.erase(iterator); + const CPlusPlus::Document::Ptr doc = snapshot.document(filePath); + if (!doc) + continue; + const FilePaths includedFiles = doc->includedFiles(); + for (const FilePath &includedFile : includedFiles) { + if (resultsCache.emplace(includedFile).second) { + queuedPaths.emplace(includedFile); + results.append(includedFile); + } + } + } + + return results; +} + CppIncludesFilter::CppIncludesFilter() { setId(Constants::INCLUDES_FILTER_ID); @@ -124,6 +154,27 @@ CppIncludesFilter::CppIncludesFilter() this, &CppIncludesFilter::invalidateCache); connect(DocumentModel::model(), &QAbstractItemModel::modelReset, this, &CppIncludesFilter::invalidateCache); + + const auto generatorProvider = [] { + // This body runs in main thread + std::unordered_set inputFilePaths; + for (Project *project : ProjectManager::projects()) { + const FilePaths allFiles = project->files(Project::SourceFiles); + for (const FilePath &filePath : allFiles) + inputFilePaths.insert(filePath); + } + const QList entries = DocumentModel::entries(); + for (DocumentModel::Entry *entry : entries) { + if (entry) + inputFilePaths.insert(entry->filePath()); + } + const CPlusPlus::Snapshot snapshot = CppModelManager::instance()->snapshot(); + return [snapshot, inputFilePaths](const QFuture &future) { + // This body runs in non-main thread + return generateFilePaths(future, snapshot, inputFilePaths); + }; + }; + m_cache.setGeneratorProvider(generatorProvider); } void CppIncludesFilter::prepareSearch(const QString &entry) @@ -150,6 +201,7 @@ void CppIncludesFilter::prepareSearch(const QString &entry) void CppIncludesFilter::invalidateCache() { + m_cache.invalidate(); m_needsUpdate = true; setFileIterator(nullptr); // clean up } diff --git a/src/plugins/cppeditor/cppincludesfilter.h b/src/plugins/cppeditor/cppincludesfilter.h index 303de152d60..d86b9991858 100644 --- a/src/plugins/cppeditor/cppincludesfilter.h +++ b/src/plugins/cppeditor/cppincludesfilter.h @@ -12,13 +12,14 @@ class CppIncludesFilter : public Core::BaseFileFilter public: CppIncludesFilter(); - // ILocatorFilter interface public: void prepareSearch(const QString &entry) override; private: + Core::LocatorMatcherTasks matchers() final { return {m_cache.matcher()}; } void invalidateCache(); + Core::LocatorFileCache m_cache; bool m_needsUpdate = true; };