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
qqmlformatting.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
5#include <qqmlformatting_p.h>
6#include <qqmlcodemodel_p.h>
7#include <qqmllsutils_p.h>
8
9#include <QtQmlDom/private/qqmldomitem_p.h>
10#include <QtQmlDom/private/qqmldomindentinglinewriter_p.h>
11#include <QtQmlDom/private/qqmldomoutwriter_p.h>
12#include <QtQmlFormat/private/qqmlformatsettings_p.h>
13
15
16Q_LOGGING_CATEGORY(formatLog, "qt.languageserver.formatting")
17
18QQmlDocumentFormatting::QQmlDocumentFormatting(QmlLsp::QQmlCodeModelManager *codeModelManager)
19 : QQmlBaseModule(codeModelManager)
20{
21}
22
24{
25 return u"QQmlDocumentFormatting"_s;
26}
27
28void QQmlDocumentFormatting::registerHandlers(QLanguageServer *, QLanguageServerProtocol *protocol)
29{
30 protocol->registerDocumentFormattingRequestHandler(getRequestHandler());
31}
32
34 const QLspSpecification::InitializeParams &,
35 QLspSpecification::InitializeResult &serverCapabilities)
36{
37 // TODO: Allow customized formatting in future
38 serverCapabilities.capabilities.documentFormattingProvider = true;
39}
40
41void QQmlDocumentFormatting::process(RequestPointerArgument request)
42{
43 QList<QLspSpecification::TextEdit> result;
44 ResponseScopeGuard guard(result, request->m_response);
45
46 using namespace QQmlJS::Dom;
47 QmlLsp::OpenDocument doc = m_codeModelManager->openDocumentByUrl(
48 QQmlLSUtils::lspUriToQmlUrl(request->m_parameters.textDocument.uri));
49
50 DomItem file = doc.snapshot.doc.fileObject(GoTo::MostLikely);
51 if (!file) {
52 guard.setError(QQmlLSUtils::ErrorMessage{
53 0, u"Could not find the file %1."_s.arg(doc.snapshot.doc.canonicalFilePath()) });
54 return;
55 }
56 if (!file.field(Fields::isValid).value().toBool(false)) {
57 guard.setError(QQmlLSUtils::ErrorMessage{ 0, u"Cannot format invalid documents!"_s });
58 return;
59 }
60 if (auto envPtr = file.environment().ownerAs<DomEnvironment>())
61 envPtr->clearReferenceCache();
62
63 auto qmlFile = file.ownerAs<QmlFile>();
64 if (!qmlFile || !qmlFile->isValid()) {
65 file.iterateErrors(
66 [](const DomItem &, const ErrorMessage &msg) {
67 errorToQDebug(msg);
68 return true;
69 },
70 true);
71 guard.setError(QQmlLSUtils::ErrorMessage{
72 0, u"Failed to parse %1."_s.arg(file.canonicalFilePath()) });
73 return;
74 }
75
76 // TODO: implement formatting options via LSP
77 // For now, qmlformat's default options via m_formatOptions and read .qmlformat.ini
78 QQmlFormatSettings settings(QLatin1String("qmlformat"));
79 settings.search(qmlFile->canonicalFilePath());
80
81 QQmlFormatOptions currentFormatOptions = m_formatOptions;
82 currentFormatOptions.applySettings(settings);
83
84 QLspSpecification::TextEdit formattedText;
85 LineWriter lw([&formattedText](QStringView s) { formattedText.newText += s.toUtf8(); },
86 QString(), currentFormatOptions.optionsForCode(qmlFile->code()));
87 OutWriter ow(qmlFile, lw);
88 file.writeOutForFile(ow, WriteOutCheck::None);
89 ow.flush();
90 const auto &code = qmlFile->code();
91 const auto [endLine, endColumn] = QQmlLSUtils::textRowAndColumnFrom(code, code.length());
92
93 Q_UNUSED(endColumn);
94 formattedText.range = QLspSpecification::Range{ QLspSpecification::Position{ 0, 0 },
95 QLspSpecification::Position{ endLine + 1, 0 } };
96
97 result.append(formattedText);
98}
99
100QT_END_NAMESPACE
Implements a server for the language server protocol.
void setupCapabilities(const QLspSpecification::InitializeParams &clientInfo, QLspSpecification::InitializeResult &) override
void process(RequestPointerArgument req) 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.