diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.cpp b/src/plugins/qmljstools/qmljsfunctionfilter.cpp index e39ba3de132..d24b02156ba 100644 --- a/src/plugins/qmljstools/qmljsfunctionfilter.cpp +++ b/src/plugins/qmljstools/qmljsfunctionfilter.cpp @@ -5,12 +5,16 @@ #include "qmljslocatordata.h" #include "qmljstoolstr.h" +#include + #include +#include #include using namespace Core; using namespace QmlJSTools::Internal; +using namespace Utils; Q_DECLARE_METATYPE(LocatorData::Entry) @@ -25,7 +29,66 @@ FunctionFilter::FunctionFilter(LocatorData *data, QObject *parent) setDefaultIncludedByDefault(false); } -FunctionFilter::~FunctionFilter() = default; +static void matches(QPromise &promise, const LocatorStorage &storage, + const QHash> &locatorEntries) +{ + const QString input = storage.input(); + const Qt::CaseSensitivity caseSensitivityForPrefix = ILocatorFilter::caseSensitivity(input); + const QRegularExpression regexp = ILocatorFilter::createRegExp(input); + if (!regexp.isValid()) + return; + + LocatorFilterEntries entries[int(ILocatorFilter::MatchLevel::Count)]; + for (const QList &items : locatorEntries) { + for (const LocatorData::Entry &info : items) { + if (promise.isCanceled()) + return; + + if (info.type != LocatorData::Function) + continue; + + const QRegularExpressionMatch match = regexp.match(info.symbolName); + if (match.hasMatch()) { + LocatorFilterEntry filterEntry; + filterEntry.displayName = info.displayName; + filterEntry.linkForEditor = {info.fileName, info.line, info.column}; + filterEntry.extraInfo = info.extraInfo; + filterEntry.highlightInfo = ILocatorFilter::highlightInfo(match); + + if (filterEntry.displayName.startsWith(input, caseSensitivityForPrefix)) + entries[int(ILocatorFilter::MatchLevel::Best)].append(filterEntry); + else if (filterEntry.displayName.contains(input, caseSensitivityForPrefix)) + entries[int(ILocatorFilter::MatchLevel::Better)].append(filterEntry); + else + entries[int(ILocatorFilter::MatchLevel::Good)].append(filterEntry); + } + } + } + + for (auto &entry : entries) { + if (promise.isCanceled()) + return; + + if (entry.size() < 1000) + Utils::sort(entry, LocatorFilterEntry::compareLexigraphically); + } + storage.reportOutput(std::accumulate(std::begin(entries), std::end(entries), + LocatorFilterEntries())); +} + +LocatorMatcherTasks FunctionFilter::matchers() +{ + using namespace Tasking; + + TreeStorage storage; + + const auto onSetup = [storage, entries = m_data->entries()](AsyncTask &async) { + async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); + async.setConcurrentCallData(matches, *storage, entries); + }; + + return {{Async(onSetup), storage}}; +} QList FunctionFilter::matchesFor(QFutureInterface &future, const QString &entry) diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.h b/src/plugins/qmljstools/qmljsfunctionfilter.h index 4334d5d9fca..71b3d0b5dd6 100644 --- a/src/plugins/qmljstools/qmljsfunctionfilter.h +++ b/src/plugins/qmljstools/qmljsfunctionfilter.h @@ -16,11 +16,12 @@ class FunctionFilter : public Core::ILocatorFilter public: explicit FunctionFilter(LocatorData *data, QObject *parent = nullptr); - ~FunctionFilter() override; QList matchesFor(QFutureInterface &future, const QString &entry) override; private: + Core::LocatorMatcherTasks matchers() final; + LocatorData *m_data = nullptr; };