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 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | using namespace Qt::StringLiterals; |
13 | |
14 | QQmlFindUsagesSupport::QQmlFindUsagesSupport(QmlLsp::QQmlCodeModel *codeModel) |
15 | : BaseT(codeModel) { } |
16 | |
17 | QString QQmlFindUsagesSupport::name() const |
18 | { |
19 | return u"QmlFindUsagesSupport"_s; |
20 | } |
21 | |
22 | void 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 | |
32 | void QQmlFindUsagesSupport::registerHandlers(QLanguageServer *, QLanguageServerProtocol *protocol) |
33 | { |
34 | protocol->registerReferenceRequestHandler(handler: getRequestHandler()); |
35 | } |
36 | |
37 | void 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 | } |
76 | QT_END_NAMESPACE |
77 | |
78 |