1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmlfindusagessupport_p.h"
5#include "qqmllsutils_p.h"
6#include <QtLanguageServer/private/qlanguageserverspectypes_p.h>
7#include <QtQmlDom/private/qqmldomexternalitems_p.h>
8#include <QtQmlDom/private/qqmldomtop_p.h>
9
10QT_BEGIN_NAMESPACE
11
12using namespace Qt::StringLiterals;
13
14QQmlFindUsagesSupport::QQmlFindUsagesSupport(QmlLsp::QQmlCodeModel *codeModel)
15 : BaseT(codeModel) { }
16
17QString QQmlFindUsagesSupport::name() const
18{
19 return u"QmlFindUsagesSupport"_s;
20}
21
22void QQmlFindUsagesSupport::setupCapabilities(
23 const QLspSpecification::InitializeParams &,
24 QLspSpecification::InitializeResult &serverCapabilities)
25{
26 // just assume serverCapabilities.capabilities.typeDefinitionProvider is a bool for now
27 // handle the ReferenceOptions later if needed (it adds the possibility to communicate the
28 // current progress).
29 serverCapabilities.capabilities.referencesProvider = true;
30}
31
32void QQmlFindUsagesSupport::registerHandlers(QLanguageServer *, QLanguageServerProtocol *protocol)
33{
34 protocol->registerReferenceRequestHandler(handler: getRequestHandler());
35}
36
37void QQmlFindUsagesSupport::process(QQmlFindUsagesSupport::RequestPointerArgument request)
38{
39 QList<QLspSpecification::Location> results;
40 QScopeGuard onExit([&results, &request]() { request->m_response.sendResponse(r: results); });
41
42 auto itemsFound = itemsForRequest(request);
43 if (!itemsFound) {
44 return;
45 }
46
47 auto usages = QQmlLSUtils::findUsagesOf(item: itemsFound->front().domItem);
48
49 QQmlJS::Dom::DomItem files =
50 itemsFound->front().domItem.top().field(name: QQmlJS::Dom::Fields::qmlFileWithPath);
51
52 QHash<QString, QString> codeCache;
53
54 for (const auto &usage : usages) {
55 QLspSpecification::Location location;
56 location.uri = QUrl::fromLocalFile(localfile: usage.filename).toEncoded();
57
58 auto cacheEntry = codeCache.find(key: usage.filename);
59 if (cacheEntry == codeCache.end()) {
60 auto file = files.key(name: usage.filename)
61 .field(name: QQmlJS::Dom::Fields::currentItem)
62 .ownerAs<QQmlJS::Dom::QmlFile>();
63 if (!file) {
64 qDebug() << "File" << usage.filename << "not found in DOM! Available files are"
65 << files.keys();
66 continue;
67 }
68 cacheEntry = codeCache.insert(key: usage.filename, value: file->code());
69 }
70
71 location.range = QQmlLSUtils::qmlLocationToLspLocation(code: cacheEntry.value(), qmlLocation: usage.location);
72
73 results.append(t: location);
74 }
75}
76QT_END_NAMESPACE
77
78

source code of qtdeclarative/src/qmlls/qqmlfindusagessupport.cpp