CppModelManager: Use locator matcher for unused functions

With this patch, when both cpp and lsp function filters
are available, they now run in parallel. The execution time
for getting the filter results (~110 K hits) for the
Creator codebase went goes from ~1100 ms into ~650 ms.

This patch also solves the potential issue with interference
between parallel runs of functions filter in locator and
in find unused functions.

Change-Id: I8f7f0b85d325848c04760ab76a7b9f02bcb5991e
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2023-04-06 15:13:59 +02:00
parent 8f44964059
commit 6e8988c926

View File

@@ -65,7 +65,6 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/runextensions.h>
#include <utils/savefile.h> #include <utils/savefile.h>
#include <utils/temporarydirectory.h> #include <utils/temporarydirectory.h>
@@ -535,8 +534,8 @@ void CppModelManager::findUnusedFunctions(const FilePath &folder)
const auto actionsSwitcher = std::make_shared<FindUnusedActionsEnabledSwitcher>(); const auto actionsSwitcher = std::make_shared<FindUnusedActionsEnabledSwitcher>();
// Step 1: Employ locator to find all functions // Step 1: Employ locator to find all functions
ILocatorFilter *const functionsFilter = CppModelManager::instance()->functionsFilter(); LocatorMatcher *matcher = new LocatorMatcher;
QTC_ASSERT(functionsFilter, return); matcher->setTasks(LocatorMatcher::functionMatchers());
const QPointer<SearchResult> search const QPointer<SearchResult> search
= SearchResultWindow::instance()->startNewSearch(Tr::tr("Find Unused Functions"), = SearchResultWindow::instance()->startNewSearch(Tr::tr("Find Unused Functions"),
{}, {},
@@ -544,25 +543,22 @@ void CppModelManager::findUnusedFunctions(const FilePath &folder)
SearchResultWindow::SearchOnly, SearchResultWindow::SearchOnly,
SearchResultWindow::PreserveCaseDisabled, SearchResultWindow::PreserveCaseDisabled,
"CppEditor"); "CppEditor");
matcher->setParent(search);
connect(search, &SearchResult::activated, [](const SearchResultItem &item) { connect(search, &SearchResult::activated, [](const SearchResultItem &item) {
EditorManager::openEditorAtSearchResult(item); EditorManager::openEditorAtSearchResult(item);
}); });
SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus); SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus);
const auto locatorWatcher = new QFutureWatcher<LocatorFilterEntry>(search); connect(search, &SearchResult::canceled, matcher, [matcher] { delete matcher; });
functionsFilter->prepareSearch({}); connect(matcher, &LocatorMatcher::done, search,
connect(search, &SearchResult::canceled, locatorWatcher, [locatorWatcher] { [matcher, search, folder, actionsSwitcher](bool success) {
locatorWatcher->cancel(); matcher->deleteLater();
}); if (!success) {
connect(locatorWatcher, &QFutureWatcher<LocatorFilterEntry>::finished, search,
[locatorWatcher, search, folder, actionsSwitcher] {
locatorWatcher->deleteLater();
if (locatorWatcher->isCanceled()) {
search->finishSearch(true); search->finishSearch(true);
return; return;
} }
Links links; Links links;
for (int i = 0; i < locatorWatcher->future().resultCount(); ++i) { const auto entries = matcher->outputData();
const LocatorFilterEntry &entry = locatorWatcher->resultAt(i); for (const LocatorFilterEntry &entry : entries) {
static const QStringList prefixBlacklist{"main(", "~", "qHash(", "begin()", "end()", static const QStringList prefixBlacklist{"main(", "~", "qHash(", "begin()", "end()",
"cbegin()", "cend()", "constBegin()", "constEnd()"}; "cbegin()", "cend()", "constBegin()", "constEnd()"};
if (Utils::anyOf(prefixBlacklist, [&entry](const QString &prefix) { if (Utils::anyOf(prefixBlacklist, [&entry](const QString &prefix) {
@@ -614,10 +610,7 @@ void CppModelManager::findUnusedFunctions(const FilePath &folder)
for (int i = 0; i < inFlightCount; ++i) for (int i = 0; i < inFlightCount; ++i)
checkNextFunctionForUnused(search, findRefsFuture, actionsSwitcher); checkNextFunctionForUnused(search, findRefsFuture, actionsSwitcher);
}); });
locatorWatcher->setFuture( matcher->start();
Utils::runAsync([functionsFilter](QFutureInterface<LocatorFilterEntry> &future) {
future.reportResults(functionsFilter->matchesFor(future, {}));
}));
} }
void CppModelManager::checkForUnusedSymbol(SearchResult *search, void CppModelManager::checkForUnusedSymbol(SearchResult *search,