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
17{
18 return u"QmlRenameSymbolSupport"_s;
19}
20
22 const QLspSpecification::InitializeParams &,
23 QLspSpecification::InitializeResult &serverCapabilities)
24{
25 // use a bool for now. Alternatively, if the client supports "prepareSupport", one could
26 // use a RenameOptions here. See following page for more information about prepareSupport:
27 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareRename
28 serverCapabilities.capabilities.renameProvider = true;
29}
30
31void QQmlRenameSymbolSupport::registerHandlers(QLanguageServer *, QLanguageServerProtocol *protocol)
32{
33 protocol->registerRenameRequestHandler(getRequestHandler());
34}
35
36void QQmlRenameSymbolSupport::process(QQmlRenameSymbolSupport::RequestPointerArgument request)
37{
38 QLspSpecification::WorkspaceEdit result;
39 ResponseScopeGuard guard(result, request->m_response);
40
41 auto itemsFound = itemsForRequest(request);
42 if (guard.setErrorFrom(itemsFound))
43 return;
44
46 std::get<QList<QQmlLSUtils::ItemLocation>>(itemsFound).front();
47
48 const QString newName = QString::fromUtf8(request->m_parameters.newName);
49 auto expressionType =
50 QQmlLSUtils::resolveExpressionType(front.domItem, QQmlLSUtils::ResolveOwnerType);
51
52 if (!expressionType) {
53 guard.setError(QQmlLSUtils::ErrorMessage{ 0, u"Cannot rename the requested object"_s });
54 return;
55 }
56
57 if (guard.setErrorFrom(QQmlLSUtils::checkNameForRename(front.domItem, newName, expressionType)))
58 return;
59
60 auto &editsByFileForResult = result.documentChanges.emplace();
61
62 // The QLspSpecification::WorkspaceEdit requires the changes to be grouped by files, so
63 // collect them into editsByFileUris.
64 QMap<QUrl, QList<QLspSpecification::TextEdit>> editsByFileUris;
65
66 const auto renames = QQmlLSUtils::renameUsagesOf(front.domItem, newName, expressionType);
67 for (const auto &rename : renames.renameInFile()) {
68 QLspSpecification::TextEdit edit;
69
70 const QUrl uri = QUrl::fromLocalFile(rename.location.filename());
71 edit.range = QQmlLSUtils::qmlLocationToLspLocation(rename.location);
72 edit.newText = rename.replacement.toUtf8();
73
74 editsByFileUris[uri].append(edit);
75 }
76
77 for (auto it = editsByFileUris.keyValueBegin(); it != editsByFileUris.keyValueEnd(); ++it) {
78 QLspSpecification::TextDocumentEdit editsForCurrentFile;
79 editsForCurrentFile.textDocument.uri = it->first.toEncoded();
80
81 // TODO: do we need to take care of the optional versioning in
82 // editsForCurrentFile.textDocument.version? see
83 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#optionalVersionedTextDocumentIdentifier
84 // for more details
85
86 for (const auto &x : std::as_const(it->second)) {
87 editsForCurrentFile.edits.append(x);
88 }
89 editsByFileForResult.append(editsForCurrentFile);
90 }
91
92 // if files need to be renamed, then do it after the text edits
93 for (const auto &rename : renames.renameInFilename()) {
94 QLspSpecification::RenameFile currentRenameFile;
95 currentRenameFile.kind = "rename";
96 currentRenameFile.oldUri = QUrl::fromLocalFile(rename.oldFilename).toEncoded();
97 currentRenameFile.newUri = QUrl::fromLocalFile(rename.newFilename).toEncoded();
98 editsByFileForResult.append(currentRenameFile);
99 }
100}
101
102QT_END_NAMESPACE
Implements a server for the language server protocol.
void setupCapabilities(const QLspSpecification::InitializeParams &clientInfo, QLspSpecification::InitializeResult &) override
void process(RequestPointerArgument request) override
void registerHandlers(QLanguageServer *server, QLanguageServerProtocol *protocol) override
QString name() const override
This class sends a result or an error when going out of scope.