6#include <QtLanguageServer/private/qlspnotifysignals_p.h>
7#include <QtJsonRpc/private/qjsonrpcprotocol_p_p.h>
14using namespace
Qt::StringLiterals;
42 registerMethods(*
d->protocol.typedRpc());
43 d->notifySignals.registerHandlers(&
d->protocol);
65 rStatus =
d->runStatus;
76 for (
auto module :
d->modules)
77 module->registerHandlers(
this, &
d->protocol);
81 rStatus =
d->runStatus;
99 rStatus =
d->runStatus;
101 if (
d->modules.contains(serverModule->name())) {
102 d->modules.insert(serverModule->name(), serverModule);
103 qCWarning(lspServerLog) <<
"Duplicate add of QLanguageServerModule named"
104 << serverModule->name() <<
", overwriting.";
106 d->modules.insert(serverModule->name(), serverModule);
111 qCWarning(lspServerLog) <<
"Called QLanguageServer::addServerModule after setup";
121 return d->modules.value(
n);
127 return &
d->notifySignals;
130void QLanguageServer::registerMethods(QJsonRpc::TypedRpc &typedRpc)
132 typedRpc.installMessagePreprocessor(
134 const QJsonRpcProtocol::Handler<QJsonRpcProtocol::Response> &responder) {
138 <<
"non object jsonrpc message" << doc << err.
errorString();
139 return QJsonRpcProtocol::Processing::Stop;
141 bool sendErrorResponse =
false;
149 && doc.
object()[u
"method"].toString()
151 QLspSpecification::Requests::InitializeMethod)) {
152 return QJsonRpcProtocol::Processing::Continue;
154 && doc.
object()[u
"method"].toString()
156 QLspSpecification::Notifications::ExitMethod)) {
157 return QJsonRpcProtocol::Processing::Continue;
159 if (
id.isString() ||
id.isDouble()) {
160 sendErrorResponse =
true;
161 rState =
d->runStatus;
163 return QJsonRpcProtocol::Processing::Stop;
167 if (!sendErrorResponse) {
168 if (
id.isString() ||
id.isDouble()) {
172 return QJsonRpcProtocol::Processing::Continue;
175 responder(QJsonRpcProtocol::MessageHandler::error(
176 int(QLspSpecification::ErrorCodes::ServerNotInitialized),
177 u
"Request on non initialized Language Server (runStatus %1): %2"_s
181 responder(QJsonRpcProtocol::MessageHandler::error(
182 int(QLspSpecification::ErrorCodes::InvalidRequest),
183 u
"Method called on stopping Language Server (runStatus %1)"_s.arg(
185 return QJsonRpcProtocol::Processing::Stop;
187 typedRpc.installOnCloseAction([
this](QJsonRpc::TypedResponse::Status,
188 const QJsonRpc::IdType &
id, QJsonRpc::TypedRpc &) {
190 QJsonValue idValue = QTypedJson::toJsonValue(
id);
194 d->requestsInProgress.remove(idValue);
205 QLspSpecification::InitializeResult &serverInfo)
208 for (
auto module : std::as_const(
d->modules))
217 qCWarning(lspServerLog) <<
"asked for Language Server clientInfo before initialization";
218 return d->clientInfo;
225 qCWarning(lspServerLog) <<
"asked for Language Server serverInfo before initialization";
226 return d->serverInfo;
243 [
this](
const QLspSpecification::Notifications::CancelParamsType &
params) {
247 if (
d->requestsInProgress.contains(
id))
248 d->requestsInProgress[
id].canceled =
true;
251 <<
"Ignoring cancellation of non in progress request" <<
id;
254 protocol->registerInitializeRequestHandler(
256 const QLspSpecification::Requests::InitializeParamsType &
params,
257 QLspSpecification::Responses::InitializeResponseType &&response) {
258 qCDebug(lspServerLog) <<
"init";
263 rStatus =
d->runStatus;
269 response.sendErrorResponse(
270 int(QLspSpecification::ErrorCodes::InvalidRequest),
271 u
"Initialization request received on non setup language server"_s
274 response.sendErrorResponse(
275 int(QLspSpecification::ErrorCodes::InvalidRequest),
276 u
"Received multiple initialization requests"_s.toUtf8());
288 response.sendResponse(
d->serverInfo);
292 [
this](
const QLspSpecification::Notifications::InitializedParamsType &) {
296 d->clientInitialized =
true;
301 protocol->registerShutdownRequestHandler(
302 [
this](
const QByteArray &,
const QLspSpecification::Requests::ShutdownParamsType &,
303 QLspSpecification::Responses::ShutdownResponseType &&response) {
306 bool shouldExecuteShutdown =
false;
309 rStatus =
d->runStatus;
311 d->shutdownResponse = std::move(response);
312 if (
d->requestsInProgress.size() <= 1) {
314 shouldExecuteShutdown =
true;
322 else if (shouldExecuteShutdown)
327 [
this](
const QLspSpecification::Notifications::ExitParamsType &) {
335void QLanguageServer::executeShutdown()
343 QLspSpecification::Responses::ShutdownResponseType shutdownResponse;
347 rStatus =
d->runStatus;
349 shutdownResponse = std::move(
d->shutdownResponse);
356 shutdownResponse.sendResponse(
nullptr);
362 QJsonValue idVal = QTypedJson::toJsonValue(
id);
\inmodule QtCore\reentrant
bool isNull() const
returns true if this document is null.
QByteArray toJson(JsonFormat format=Indented) const
QJsonObject object() const
Returns the QJsonObject contained in the document.
bool isObject() const
Returns true if the document contains an object.
\inmodule QtCore\reentrant
Implements a server for the language server protocol.
void registerHandlers(QLanguageServerProtocol *protocol)
void clientInitialized(QLanguageServer *server)
QLanguageServerProtocol * protocol()
const QLspSpecification::InitializeParams & clientInfo() const
QLanguageServer(const QJsonRpcTransport::DataHandler &h, QObject *parent=nullptr)
void setupCapabilities(const QLspSpecification::InitializeParams &clientInfo, QLspSpecification::InitializeResult &serverInfo)
bool isRequestCanceled(const QJsonRpc::IdType &id) const
QLspNotifySignals * notifySignals()
void receiveData(const QByteArray &d, bool isEndOfMessage)
void runStatusChanged(RunStatus)
const QLspSpecification::InitializeResult & serverInfo() const
void addServerModule(QLanguageServerModule *serverModule)
QLanguageServerModule * moduleByName(const QString &n) const
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
\inmodule QtCore\reentrant
QString errorString() const
\variable QJsonParseError::error