Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlrenamesymbolsupport.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
7#include <utility>
8
9QT_BEGIN_NAMESPACE
10
11using namespace Qt::StringLiterals;
12QQmlRenameSymbolSupport::QQmlRenameSymbolSupport(QmlLsp::QQmlCodeModelManager *model) : BaseT(model)
13{
14}
15
16void QQmlRenameSymbolSupport::setupCapabilities(QLspSpecification::ServerCapabilities &caps)
17{
18 // use a bool for now. Alternatively, if the client supports "prepareSupport", one could
19 // use a RenameOptions here. See following page for more information about prepareSupport:
20 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareRename
21 caps.renameProvider = true;
22}
23
24void QQmlRenameSymbolSupport::registerHandlers(QLanguageServer *, QLanguageServerProtocol *protocol)
25{
26 protocol->registerRenameRequestHandler(getRequestHandler());
27}
28
29void QQmlRenameSymbolSupport::process(QQmlRenameSymbolSupport::RequestPointerArgument request)
30{
31 QLspSpecification::WorkspaceEdit result;
32 ResponseScopeGuard guard(result, request->m_response);
33
34 auto itemsFound = itemsForRequest(request);
35 if (!itemsFound.has_value()) {
36 guard.setError(itemsFound.error());
37 return;
38 }
39
40 QQmlLSUtils::ItemLocation &front = itemsFound.value().front();
41
42 const QString newName = QString::fromUtf8(request->m_parameters.newName);
43 auto expressionType =
44 QQmlLSUtils::resolveExpressionType(front.domItem, QQmlLSUtils::ResolveOwnerType);
45
46 if (!expressionType) {
47 guard.setError(QQmlLSUtils::ErrorMessage{ 0, u"Cannot rename the requested object"_s });
48 return;
49 }
50
51 if (const auto renameCheckError =
52 QQmlLSUtils::checkNameForRename(front.domItem, newName, expressionType)) {
53 guard.setError(renameCheckError.value());
54 return;
55 }
56
57 auto &editsByFileForResult = result.documentChanges.emplace();
58
59 // The QLspSpecification::WorkspaceEdit requires the changes to be grouped by files, so
60 // collect them into editsByFileUris.
61 QMap<QUrl, QList<QLspSpecification::TextEdit>> editsByFileUris;
62
63 const auto renames = QQmlLSUtils::renameUsagesOf(front.domItem, newName, expressionType);
64 for (const auto &rename : renames.renameInFile()) {
65 QLspSpecification::TextEdit edit;
66
67 const QUrl uri = QUrl::fromLocalFile(rename.location.filename());
68 edit.range = QQmlLSUtils::qmlLocationToLspLocation(rename.location);
69 edit.newText = rename.replacement.toUtf8();
70
71 editsByFileUris[uri].append(edit);
72 }
73
74 for (auto it = editsByFileUris.keyValueBegin(); it != editsByFileUris.keyValueEnd(); ++it) {
75 QLspSpecification::TextDocumentEdit editsForCurrentFile;
76 editsForCurrentFile.textDocument.uri = it->first.toEncoded();
77
78 // TODO: do we need to take care of the optional versioning in
79 // editsForCurrentFile.textDocument.version? see
80 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#optionalVersionedTextDocumentIdentifier
81 // for more details
82
83 for (const auto &x : std::as_const(it->second)) {
84 editsForCurrentFile.edits.append(x);
85 }
86 editsByFileForResult.append(editsForCurrentFile);
87 }
88
89 // if files need to be renamed, then do it after the text edits
90 for (const auto &rename : renames.renameInFilename()) {
91 QLspSpecification::RenameFile currentRenameFile;
92 currentRenameFile.oldUri = QUrl::fromLocalFile(rename.oldFilename).toEncoded();
93 currentRenameFile.newUri = QUrl::fromLocalFile(rename.newFilename).toEncoded();
94 editsByFileForResult.append(currentRenameFile);
95 }
96}
97
98QT_END_NAMESPACE
void process(RequestPointerArgument request) override
void registerHandlers(QLanguageServer *server, QLanguageServerProtocol *protocol) override
void setupCapabilities(QLspSpecification::ServerCapabilities &caps) override