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
qqmllanguageserver.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 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
9
10#include <QtCore/qdir.h>
11
12#include <iostream>
13#include <algorithm>
14
15QT_BEGIN_NAMESPACE
16
17namespace QmlLsp {
18
19using namespace QLspSpecification;
20using namespace Qt::StringLiterals;
21/*!
22\internal
23\class QmlLsp::QQmlLanguageServer
24\brief Sets up a QmlLanguageServer.
25
26This class sets up a QML language server.
27
28Use the following function to send replies:
29
30\code
31std::function<void(const QByteArray &)> sendData
32\endcode
33
34And, feed the data that the function receives to the \c {server()->receive()}
35method.
36
37Call this method only from a single thread, and do not block. To achieve this,
38avoid direct calls, and connect the method as a slot, while reading from another
39thread.
40
41The various tasks of the language server are divided between
42QLanguageServerModule instances. Each instance is responsible for handling a
43certain subset of client requests. For example, one instance handles completion
44requests, another one updates the code in the code model when the client sends a
45new file version, and so on. The QLanguageServerModule instances are
46constructed and registered with QLanguageServer in the constructor of
47this class.
48
49Generally, do all operations in the object thread and always call handlers from
50it. However, the operations can delegate the response to another thread, as the
51response handler is thread safe. All the methods of the \c server() object are
52also thread safe.
53
54The code model starts other threads to update its state. See its documentation
55for more information.
56*/
57QQmlLanguageServer::QQmlLanguageServer(std::function<void(const QByteArray &)> sendData,
58 QQmlToolingSharedSettings *settings)
59 : m_codeModelManager(nullptr, settings),
60 m_server(sendData),
61 m_textSynchronization(&m_codeModelManager),
62 m_lint(&m_server, &m_codeModelManager),
63 m_workspace(&m_codeModelManager),
64 m_completionSupport(&m_codeModelManager),
65 m_navigationSupport(&m_codeModelManager),
66 m_definitionSupport(&m_codeModelManager),
67 m_referencesSupport(&m_codeModelManager),
68 m_documentFormatting(&m_codeModelManager),
69 m_renameSupport(&m_codeModelManager),
70 m_rangeFormatting(&m_codeModelManager),
71 m_hover(&m_codeModelManager),
72 m_highlightSupport(&m_codeModelManager),
73 m_documentSymbolSupport(&m_codeModelManager)
74{
75 m_server.addServerModule(this);
76 m_server.addServerModule(&m_textSynchronization);
77 m_server.addServerModule(&m_lint);
78 m_server.addServerModule(&m_workspace);
79 m_server.addServerModule(&m_completionSupport);
80 m_server.addServerModule(&m_navigationSupport);
81 m_server.addServerModule(&m_definitionSupport);
82 m_server.addServerModule(&m_referencesSupport);
83 m_server.addServerModule(&m_documentFormatting);
84 m_server.addServerModule(&m_renameSupport);
85 m_server.addServerModule(&m_rangeFormatting);
86 m_server.addServerModule(&m_hover);
87 m_server.addServerModule(&m_highlightSupport);
88 m_server.addServerModule(&m_documentSymbolSupport);
89 m_server.finishSetup();
90 qCWarning(lspServerLog) << "Did Setup";
91}
92
94 QLanguageServerProtocol *protocol)
95{
96 Q_UNUSED(protocol);
97 QObject::connect(server, &QLanguageServer::lifecycleError, this,
98 &QQmlLanguageServer::errorExit);
99 QObject::connect(server, &QLanguageServer::exit, this, &QQmlLanguageServer::exit);
100 QObject::connect(
101 server, &QLanguageServer::runStatusChanged, this,
102 [](QLanguageServer::RunStatus r) { qCDebug(lspServerLog) << "runStatus" << int(r); });
103 protocol->typedRpc()->registerNotificationHandler<Notifications::AddBuildDirsParams>(
105 [this](const QByteArray &, const Notifications::AddBuildDirsParams &params) {
106 for (const auto &buildDirs : params.buildDirsToSet) {
107 QStringList dirPaths;
108 dirPaths.resize(buildDirs.buildDirs.size());
109 std::transform(buildDirs.buildDirs.begin(), buildDirs.buildDirs.end(),
110 dirPaths.begin(), [](const QByteArray &utf8Str) {
111 return QString::fromUtf8(utf8Str);
112 });
113 m_codeModelManager.setBuildPathsForRootUrl(buildDirs.baseUri, dirPaths);
114 }
115 });
116}
117
118void QQmlLanguageServer::setupCapabilities(const QLspSpecification::InitializeParams &,
119 QLspSpecification::InitializeResult &serverInfo)
120{
121 QJsonObject expCap;
122 if (serverInfo.capabilities.experimental.has_value() && serverInfo.capabilities.experimental->isObject())
123 expCap = serverInfo.capabilities.experimental->toObject();
124 expCap.insert(u"addBuildDirs"_s, QJsonObject({ { u"supported"_s, true } }));
125 serverInfo.capabilities.experimental = expCap;
126}
127
129{
130 return u"QQmlLanguageServer"_s;
131}
132
134{
135 qCWarning(lspServerLog) << "Error exit";
136 fclose(stdin);
137}
138
140{
141 m_returnValue = 0;
142 fclose(stdin);
143}
144
146{
147 return m_returnValue;
148}
149
151{
152 return &m_codeModelManager;
153}
154
156{
157 return &m_server;
158}
159
161{
162 return &m_textSynchronization;
163}
164
166{
167 return &m_lint;
168}
169
171{
172 return &m_workspace;
173}
174
175} // namespace QmlLsp
176
177QT_END_NAMESPACE
Implements a server for the language server protocol.
Sets up a QmlLanguageServer.
TextSynchronization * textSynchronization()
QQmlCodeModelManager * codeModelManager()
void setupCapabilities(const QLspSpecification::InitializeParams &clientInfo, QLspSpecification::InitializeResult &serverInfo) final
void registerHandlers(QLanguageServer *server, QLanguageServerProtocol *protocol) final