forked from qt-creator/qt-creator
LanguageServerProtocol: remove IContent
Do not pretend to support multiple message types, while no other messages are actually implemented by us or even known to exist in the wild. Change-Id: I49ee2118b2e10f265ac641c195df8a9e5c97951c Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -6,7 +6,6 @@ add_qtc_library(LanguageServerProtocol
|
|||||||
clientcapabilities.cpp clientcapabilities.h
|
clientcapabilities.cpp clientcapabilities.h
|
||||||
completion.cpp completion.h
|
completion.cpp completion.h
|
||||||
diagnostics.cpp diagnostics.h
|
diagnostics.cpp diagnostics.h
|
||||||
icontent.h
|
|
||||||
initializemessages.cpp initializemessages.h
|
initializemessages.cpp initializemessages.h
|
||||||
jsonkeys.h
|
jsonkeys.h
|
||||||
jsonobject.cpp jsonobject.h
|
jsonobject.cpp jsonobject.h
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "basemessage.h"
|
|
||||||
#include "lsputils.h"
|
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <utils/variant.h>
|
|
||||||
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QJsonValue>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
namespace LanguageServerProtocol {
|
|
||||||
|
|
||||||
class IContent;
|
|
||||||
|
|
||||||
class LANGUAGESERVERPROTOCOL_EXPORT MessageId : public Utils::variant<int, QString>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MessageId() = default;
|
|
||||||
explicit MessageId(int id) : variant(id) {}
|
|
||||||
explicit MessageId(const QString &id) : variant(id) {}
|
|
||||||
explicit MessageId(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
if (value.isDouble())
|
|
||||||
*this = MessageId(value.toInt());
|
|
||||||
else if (value.isString())
|
|
||||||
*this = MessageId(value.toString());
|
|
||||||
else
|
|
||||||
m_valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator QJsonValue() const
|
|
||||||
{
|
|
||||||
if (auto id = Utils::get_if<int>(this))
|
|
||||||
return *id;
|
|
||||||
if (auto id = Utils::get_if<QString>(this))
|
|
||||||
return *id;
|
|
||||||
return QJsonValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isValid() const { return m_valid; }
|
|
||||||
|
|
||||||
QString toString() const
|
|
||||||
{
|
|
||||||
if (auto id = Utils::get_if<QString>(this))
|
|
||||||
return *id;
|
|
||||||
if (auto id = Utils::get_if<int>(this))
|
|
||||||
return QString::number(*id);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
friend auto qHash(const MessageId &id)
|
|
||||||
{
|
|
||||||
if (Utils::holds_alternative<int>(id))
|
|
||||||
return QT_PREPEND_NAMESPACE(qHash(Utils::get<int>(id)));
|
|
||||||
if (Utils::holds_alternative<QString>(id))
|
|
||||||
return QT_PREPEND_NAMESPACE(qHash(Utils::get<QString>(id)));
|
|
||||||
return QT_PREPEND_NAMESPACE(qHash(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_valid = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ResponseHandler
|
|
||||||
{
|
|
||||||
MessageId id;
|
|
||||||
using Callback = std::function<void(const IContent &)>;
|
|
||||||
Callback callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
using ResponseHandlers = std::function<void(const MessageId &, const IContent &)>;
|
|
||||||
using MethodHandler = std::function<void(const QString &, const MessageId &, const IContent &)>;
|
|
||||||
|
|
||||||
template <typename Error>
|
|
||||||
inline QDebug operator<<(QDebug stream, const LanguageServerProtocol::MessageId &id)
|
|
||||||
{
|
|
||||||
if (Utils::holds_alternative<int>(id))
|
|
||||||
stream << Utils::get<int>(id);
|
|
||||||
else
|
|
||||||
stream << Utils::get<QString>(id);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LANGUAGESERVERPROTOCOL_EXPORT IContent
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~IContent() = default;
|
|
||||||
|
|
||||||
virtual QByteArray toRawData() const = 0;
|
|
||||||
virtual QByteArray mimeType() const = 0;
|
|
||||||
virtual bool isValid(QString *errorMessage) const = 0;
|
|
||||||
|
|
||||||
virtual Utils::optional<ResponseHandler> responseHandler() const
|
|
||||||
{ return Utils::nullopt; }
|
|
||||||
|
|
||||||
BaseMessage toBaseMessage() const
|
|
||||||
{ return BaseMessage(mimeType(), toRawData()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LanguageClient
|
|
||||||
@@ -45,11 +45,6 @@ QByteArray JsonRpcMessage::toRawData() const
|
|||||||
return QJsonDocument(m_jsonObject).toJson(QJsonDocument::Compact);
|
return QJsonDocument(m_jsonObject).toJson(QJsonDocument::Compact);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray JsonRpcMessage::mimeType() const
|
|
||||||
{
|
|
||||||
return jsonRpcMimeType();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JsonRpcMessage::isValid(QString *errorMessage) const
|
bool JsonRpcMessage::isValid(QString *errorMessage) const
|
||||||
{
|
{
|
||||||
if (!m_parseError.isEmpty()) {
|
if (!m_parseError.isEmpty()) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "icontent.h"
|
#include "basemessage.h"
|
||||||
#include "lsptypes.h"
|
#include "lsptypes.h"
|
||||||
#include "jsonkeys.h"
|
#include "jsonkeys.h"
|
||||||
|
|
||||||
@@ -43,7 +43,75 @@
|
|||||||
|
|
||||||
namespace LanguageServerProtocol {
|
namespace LanguageServerProtocol {
|
||||||
|
|
||||||
class LANGUAGESERVERPROTOCOL_EXPORT JsonRpcMessage : public IContent
|
class JsonRpcMessage;
|
||||||
|
|
||||||
|
class LANGUAGESERVERPROTOCOL_EXPORT MessageId : public Utils::variant<int, QString>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageId() = default;
|
||||||
|
explicit MessageId(int id) : variant(id) {}
|
||||||
|
explicit MessageId(const QString &id) : variant(id) {}
|
||||||
|
explicit MessageId(const QJsonValue &value)
|
||||||
|
{
|
||||||
|
if (value.isDouble())
|
||||||
|
*this = MessageId(value.toInt());
|
||||||
|
else if (value.isString())
|
||||||
|
*this = MessageId(value.toString());
|
||||||
|
else
|
||||||
|
m_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator QJsonValue() const
|
||||||
|
{
|
||||||
|
if (auto id = Utils::get_if<int>(this))
|
||||||
|
return *id;
|
||||||
|
if (auto id = Utils::get_if<QString>(this))
|
||||||
|
return *id;
|
||||||
|
return QJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const { return m_valid; }
|
||||||
|
|
||||||
|
QString toString() const
|
||||||
|
{
|
||||||
|
if (auto id = Utils::get_if<QString>(this))
|
||||||
|
return *id;
|
||||||
|
if (auto id = Utils::get_if<int>(this))
|
||||||
|
return QString::number(*id);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
friend auto qHash(const MessageId &id)
|
||||||
|
{
|
||||||
|
if (Utils::holds_alternative<int>(id))
|
||||||
|
return QT_PREPEND_NAMESPACE(qHash(Utils::get<int>(id)));
|
||||||
|
if (Utils::holds_alternative<QString>(id))
|
||||||
|
return QT_PREPEND_NAMESPACE(qHash(Utils::get<QString>(id)));
|
||||||
|
return QT_PREPEND_NAMESPACE(qHash(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_valid = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Error>
|
||||||
|
inline QDebug operator<<(QDebug stream, const LanguageServerProtocol::MessageId &id)
|
||||||
|
{
|
||||||
|
if (Utils::holds_alternative<int>(id))
|
||||||
|
stream << Utils::get<int>(id);
|
||||||
|
else
|
||||||
|
stream << Utils::get<QString>(id);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ResponseHandler
|
||||||
|
{
|
||||||
|
MessageId id;
|
||||||
|
using Callback = std::function<void(const JsonRpcMessage &)>;
|
||||||
|
Callback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LANGUAGESERVERPROTOCOL_EXPORT JsonRpcMessage
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(JsonRpcMessage)
|
Q_DECLARE_TR_FUNCTIONS(JsonRpcMessage)
|
||||||
public:
|
public:
|
||||||
@@ -54,14 +122,19 @@ public:
|
|||||||
|
|
||||||
static QByteArray jsonRpcMimeType();
|
static QByteArray jsonRpcMimeType();
|
||||||
|
|
||||||
QByteArray toRawData() const final;
|
QByteArray toRawData() const;
|
||||||
QByteArray mimeType() const final;
|
virtual bool isValid(QString *errorMessage) const;
|
||||||
bool isValid(QString *errorMessage) const override;
|
|
||||||
|
|
||||||
const QJsonObject &toJsonObject() const;
|
const QJsonObject &toJsonObject() const;
|
||||||
|
|
||||||
const QString parseError() { return m_parseError; }
|
const QString parseError() { return m_parseError; }
|
||||||
|
|
||||||
|
virtual Utils::optional<ResponseHandler> responseHandler() const
|
||||||
|
{ return Utils::nullopt; }
|
||||||
|
|
||||||
|
BaseMessage toBaseMessage() const
|
||||||
|
{ return BaseMessage(jsonRpcMimeType(), toRawData()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QJsonObject m_jsonObject;
|
QJsonObject m_jsonObject;
|
||||||
|
|
||||||
@@ -306,12 +379,12 @@ public:
|
|||||||
QElapsedTimer timer;
|
QElapsedTimer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
auto callback = [callback = m_callBack, method = this->method(), t = std::move(timer)]
|
auto callback = [callback = m_callBack, method = this->method(), t = std::move(timer)]
|
||||||
(const IContent &content) {
|
(const JsonRpcMessage &message) {
|
||||||
if (!callback)
|
if (!callback)
|
||||||
return;
|
return;
|
||||||
logElapsedTime(method, t);
|
logElapsedTime(method, t);
|
||||||
|
|
||||||
callback(Response(static_cast<const JsonRpcMessage &>(content).toJsonObject()));
|
callback(Response(message.toJsonObject()));
|
||||||
};
|
};
|
||||||
return Utils::make_optional(ResponseHandler{id(), callback});
|
return Utils::make_optional(ResponseHandler{id(), callback});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ Project {
|
|||||||
"completion.h",
|
"completion.h",
|
||||||
"diagnostics.cpp",
|
"diagnostics.cpp",
|
||||||
"diagnostics.h",
|
"diagnostics.h",
|
||||||
"icontent.h",
|
|
||||||
"initializemessages.cpp",
|
"initializemessages.cpp",
|
||||||
"initializemessages.h",
|
"initializemessages.h",
|
||||||
"jsonkeys.h",
|
"jsonkeys.h",
|
||||||
|
|||||||
@@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
#include "icontent.h"
|
|
||||||
|
|
||||||
namespace LanguageServerProtocol {
|
namespace LanguageServerProtocol {
|
||||||
|
|
||||||
constexpr const char ShowMessageNotification::methodName[];
|
constexpr const char ShowMessageNotification::methodName[];
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include "clangdast.h"
|
#include "clangdast.h"
|
||||||
|
|
||||||
#include <languageclient/client.h>
|
#include <languageclient/client.h>
|
||||||
#include <languageserverprotocol/icontent.h>
|
|
||||||
#include <languageserverprotocol/jsonkeys.h>
|
#include <languageserverprotocol/jsonkeys.h>
|
||||||
#include <languageserverprotocol/lsptypes.h>
|
#include <languageserverprotocol/lsptypes.h>
|
||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
@@ -403,7 +402,7 @@ MessageId requestAst(Client *client, const FilePath &filePath, const Range range
|
|||||||
const auto result = response.result();
|
const auto result = response.result();
|
||||||
handler(result ? *result : ClangdAstNode(), reqId);
|
handler(result ? *result : ClangdAstNode(), reqId);
|
||||||
});
|
});
|
||||||
client->sendContent(request, Client::SendDocUpdates::Ignore);
|
client->sendMessage(request, Client::SendDocUpdates::Ignore);
|
||||||
return request.id();
|
return request.id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1271,13 +1271,13 @@ void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString
|
|||||||
item.setUri(DocumentUri::fromFilePath(filePath));
|
item.setUri(DocumentUri::fromFilePath(filePath));
|
||||||
item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll()));
|
item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll()));
|
||||||
item.setVersion(0);
|
item.setVersion(0);
|
||||||
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)),
|
sendMessage(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)),
|
||||||
SendDocUpdates::Ignore);
|
SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
|
void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
|
||||||
{
|
{
|
||||||
sendContent(DidCloseTextDocumentNotification(DidCloseTextDocumentParams(
|
sendMessage(DidCloseTextDocumentNotification(DidCloseTextDocumentParams(
|
||||||
TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)})),
|
TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)})),
|
||||||
SendDocUpdates::Ignore);
|
SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
@@ -1321,7 +1321,7 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
|
|||||||
return;
|
return;
|
||||||
d->findUsages(doc.data(), adjustedCursor, sd.name(), replacement, categorize);
|
d->findUsages(doc.data(), adjustedCursor, sd.name(), replacement, categorize);
|
||||||
});
|
});
|
||||||
sendContent(symReq);
|
sendMessage(symReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::handleDiagnostics(const PublishDiagnosticsParams ¶ms)
|
void ClangdClient::handleDiagnostics(const PublishDiagnosticsParams ¶ms)
|
||||||
@@ -1612,7 +1612,7 @@ void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
|
|||||||
addCompilationDb(settings, cdbChanges);
|
addCompilationDb(settings, cdbChanges);
|
||||||
DidChangeConfigurationParams configChangeParams;
|
DidChangeConfigurationParams configChangeParams;
|
||||||
configChangeParams.setSettings(settings);
|
configChangeParams.setSettings(settings);
|
||||||
sendContent(DidChangeConfigurationNotification(configChangeParams));
|
sendMessage(DidChangeConfigurationNotification(configChangeParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::switchIssuePaneEntries(const Utils::FilePath &filePath)
|
void ClangdClient::switchIssuePaneEntries(const Utils::FilePath &filePath)
|
||||||
@@ -1914,7 +1914,7 @@ void ClangdClient::switchHeaderSource(const Utils::FilePath &filePath, bool inNe
|
|||||||
CppEditor::openEditor(filePath, inNextSplit);
|
CppEditor::openEditor(filePath, inNextSplit);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sendContent(req);
|
sendMessage(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cursor,
|
void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cursor,
|
||||||
@@ -2103,7 +2103,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
|
|||||||
// with mainOverload = true, such information would get ignored anyway.
|
// with mainOverload = true, such information would get ignored anyway.
|
||||||
d->setHelpItemForTooltip(id, fqn, HelpItem::Function, isFunction ? type : "()");
|
d->setHelpItemForTooltip(id, fqn, HelpItem::Function, isFunction ? type : "()");
|
||||||
});
|
});
|
||||||
sendContent(symReq, SendDocUpdates::Ignore);
|
sendMessage(symReq, SendDocUpdates::Ignore);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((node.role() == "expression" && node.kind() == "DeclRef")
|
if ((node.role() == "expression" && node.kind() == "DeclRef")
|
||||||
@@ -2216,7 +2216,7 @@ void ClangdClient::Private::sendGotoImplementationRequest(const Utils::Link &lin
|
|||||||
followSymbolData->pendingGotoImplRequests.removeOne(reqId);
|
followSymbolData->pendingGotoImplRequests.removeOne(reqId);
|
||||||
handleGotoImplementationResult(response);
|
handleGotoImplementationResult(response);
|
||||||
});
|
});
|
||||||
q->sendContent(req, SendDocUpdates::Ignore);
|
q->sendMessage(req, SendDocUpdates::Ignore);
|
||||||
followSymbolData->pendingGotoImplRequests << req.id();
|
followSymbolData->pendingGotoImplRequests << req.id();
|
||||||
qCDebug(clangdLog) << "sending go to implementation request" << link.targetLine;
|
qCDebug(clangdLog) << "sending go to implementation request" << link.targetLine;
|
||||||
}
|
}
|
||||||
@@ -2303,7 +2303,7 @@ void ClangdClient::Private::handleGotoImplementationResult(
|
|||||||
});
|
});
|
||||||
followSymbolData->pendingSymbolInfoRequests << symReq.id();
|
followSymbolData->pendingSymbolInfoRequests << symReq.id();
|
||||||
qCDebug(clangdLog) << "sending symbol info request";
|
qCDebug(clangdLog) << "sending symbol info request";
|
||||||
q->sendContent(symReq, SendDocUpdates::Ignore);
|
q->sendMessage(symReq, SendDocUpdates::Ignore);
|
||||||
|
|
||||||
if (link == followSymbolData->defLink)
|
if (link == followSymbolData->defLink)
|
||||||
continue;
|
continue;
|
||||||
@@ -2337,7 +2337,7 @@ void ClangdClient::Private::handleGotoImplementationResult(
|
|||||||
followSymbolData->pendingGotoDefRequests << defReq.id();
|
followSymbolData->pendingGotoDefRequests << defReq.id();
|
||||||
qCDebug(clangdLog) << "sending additional go to definition request"
|
qCDebug(clangdLog) << "sending additional go to definition request"
|
||||||
<< link.targetFilePath << link.targetLine;
|
<< link.targetFilePath << link.targetLine;
|
||||||
q->sendContent(defReq, SendDocUpdates::Ignore);
|
q->sendMessage(defReq, SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Utils::FilePath defLinkFilePath = followSymbolData->defLink.targetFilePath;
|
const Utils::FilePath defLinkFilePath = followSymbolData->defLink.targetFilePath;
|
||||||
@@ -4094,7 +4094,7 @@ void MemoryUsageWidget::getMemoryTree()
|
|||||||
});
|
});
|
||||||
qCDebug(clangdLog) << "sending memory usage request";
|
qCDebug(clangdLog) << "sending memory usage request";
|
||||||
m_currentRequest = request.id();
|
m_currentRequest = request.id();
|
||||||
m_client->sendContent(request, ClangdClient::SendDocUpdates::Ignore);
|
m_client->sendMessage(request, ClangdClient::SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public:
|
|||||||
{
|
{
|
||||||
using Interface = BaseClientInterface;
|
using Interface = BaseClientInterface;
|
||||||
interface->moveToThread(&m_thread);
|
interface->moveToThread(&m_thread);
|
||||||
connect(interface, &Interface::contentReceived, this, &InterfaceController::contentReceived);
|
connect(interface, &Interface::messageReceived, this, &InterfaceController::messageReceived);
|
||||||
connect(interface, &Interface::error, this, &InterfaceController::error);
|
connect(interface, &Interface::error, this, &InterfaceController::error);
|
||||||
connect(interface, &Interface::finished, this, &InterfaceController::finished);
|
connect(interface, &Interface::finished, this, &InterfaceController::finished);
|
||||||
connect(interface, &Interface::started, this, &InterfaceController::started);
|
connect(interface, &Interface::started, this, &InterfaceController::started);
|
||||||
@@ -107,9 +107,9 @@ public:
|
|||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(m_interface, &BaseClientInterface::start);
|
QMetaObject::invokeMethod(m_interface, &BaseClientInterface::start);
|
||||||
}
|
}
|
||||||
void sendContent(const JsonRpcMessage message)
|
void sendMessage(const JsonRpcMessage &message)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(m_interface, [=]() { m_interface->sendContent(message); });
|
QMetaObject::invokeMethod(m_interface, [=]() { m_interface->sendMessage(message); });
|
||||||
}
|
}
|
||||||
void resetBuffer()
|
void resetBuffer()
|
||||||
{
|
{
|
||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void contentReceived(const JsonRpcMessage &message);
|
void messageReceived(const JsonRpcMessage &message);
|
||||||
void started();
|
void started();
|
||||||
void error(const QString &message);
|
void error(const QString &message);
|
||||||
void finished();
|
void finished();
|
||||||
@@ -152,7 +152,7 @@ Client::Client(BaseClientInterface *clientInterface)
|
|||||||
this, &Client::projectClosed);
|
this, &Client::projectClosed);
|
||||||
|
|
||||||
QTC_ASSERT(clientInterface, return);
|
QTC_ASSERT(clientInterface, return);
|
||||||
connect(m_clientInterface, &InterfaceController::contentReceived, this, &Client::handleContent);
|
connect(m_clientInterface, &InterfaceController::messageReceived, this, &Client::handleMessage);
|
||||||
connect(m_clientInterface, &InterfaceController::error, this, &Client::setError);
|
connect(m_clientInterface, &InterfaceController::error, this, &Client::setError);
|
||||||
connect(m_clientInterface, &InterfaceController::finished, this, &Client::finished);
|
connect(m_clientInterface, &InterfaceController::finished, this, &Client::finished);
|
||||||
connect(m_clientInterface, &InterfaceController::started, this, [this]() {
|
connect(m_clientInterface, &InterfaceController::started, this, [this]() {
|
||||||
@@ -209,8 +209,8 @@ Client::~Client()
|
|||||||
m_documentHighlightsTimer.clear();
|
m_documentHighlightsTimer.clear();
|
||||||
updateEditorToolBar(m_openedDocument.keys());
|
updateEditorToolBar(m_openedDocument.keys());
|
||||||
// do not handle messages while shutting down
|
// do not handle messages while shutting down
|
||||||
disconnect(m_clientInterface, &InterfaceController::contentReceived,
|
disconnect(m_clientInterface, &InterfaceController::messageReceived,
|
||||||
this, &Client::handleContent);
|
this, &Client::handleMessage);
|
||||||
delete m_diagnosticManager;
|
delete m_diagnosticManager;
|
||||||
delete m_clientInterface;
|
delete m_clientInterface;
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ void Client::initialize()
|
|||||||
m_responseHandlers[responseHandler->id] = responseHandler->callback;
|
m_responseHandlers[responseHandler->id] = responseHandler->callback;
|
||||||
|
|
||||||
// directly send content now otherwise the state check of sendContent would fail
|
// directly send content now otherwise the state check of sendContent would fail
|
||||||
sendContentNow(initRequest);
|
sendMessageNow(initRequest);
|
||||||
m_state = InitializeRequested;
|
m_state = InitializeRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +389,7 @@ void Client::shutdown()
|
|||||||
shutdown.setResponseCallback([this](const ShutdownRequest::Response &shutdownResponse){
|
shutdown.setResponseCallback([this](const ShutdownRequest::Response &shutdownResponse){
|
||||||
shutDownCallback(shutdownResponse);
|
shutDownCallback(shutdownResponse);
|
||||||
});
|
});
|
||||||
sendContent(shutdown);
|
sendMessage(shutdown);
|
||||||
m_state = ShutdownRequested;
|
m_state = ShutdownRequested;
|
||||||
m_shutdownTimer.start();
|
m_shutdownTimer.start();
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,7 @@ void Client::openDocument(TextEditor::TextDocument *document)
|
|||||||
if (!m_documentVersions.contains(filePath))
|
if (!m_documentVersions.contains(filePath))
|
||||||
m_documentVersions[filePath] = 0;
|
m_documentVersions[filePath] = 0;
|
||||||
item.setVersion(m_documentVersions[filePath]);
|
item.setVersion(m_documentVersions[filePath]);
|
||||||
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
|
sendMessage(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
|
||||||
handleDocumentOpened(document);
|
handleDocumentOpened(document);
|
||||||
|
|
||||||
const Client *currentClient = LanguageClientManager::clientForDocument(document);
|
const Client *currentClient = LanguageClientManager::clientForDocument(document);
|
||||||
@@ -482,24 +482,24 @@ void Client::openDocument(TextEditor::TextDocument *document)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::sendContent(const IContent &content, SendDocUpdates sendUpdates)
|
void Client::sendMessage(const JsonRpcMessage &message, SendDocUpdates sendUpdates)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_clientInterface, return);
|
QTC_ASSERT(m_clientInterface, return);
|
||||||
QTC_ASSERT(m_state == Initialized, return);
|
QTC_ASSERT(m_state == Initialized, return);
|
||||||
if (sendUpdates == SendDocUpdates::Send)
|
if (sendUpdates == SendDocUpdates::Send)
|
||||||
sendPostponedDocumentUpdates(Schedule::Delayed);
|
sendPostponedDocumentUpdates(Schedule::Delayed);
|
||||||
if (Utils::optional<ResponseHandler> responseHandler = content.responseHandler())
|
if (Utils::optional<ResponseHandler> responseHandler = message.responseHandler())
|
||||||
m_responseHandlers[responseHandler->id] = responseHandler->callback;
|
m_responseHandlers[responseHandler->id] = responseHandler->callback;
|
||||||
QString error;
|
QString error;
|
||||||
if (!QTC_GUARD(content.isValid(&error)))
|
if (!QTC_GUARD(message.isValid(&error)))
|
||||||
Core::MessageManager::writeFlashing(error);
|
Core::MessageManager::writeFlashing(error);
|
||||||
sendContentNow(content);
|
sendMessageNow(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::cancelRequest(const MessageId &id)
|
void Client::cancelRequest(const MessageId &id)
|
||||||
{
|
{
|
||||||
m_responseHandlers.remove(id);
|
m_responseHandlers.remove(id);
|
||||||
sendContent(CancelRequest(CancelParameter(id)), SendDocUpdates::Ignore);
|
sendMessage(CancelRequest(CancelParameter(id)), SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::closeDocument(TextEditor::TextDocument *document)
|
void Client::closeDocument(TextEditor::TextDocument *document)
|
||||||
@@ -511,7 +511,7 @@ void Client::closeDocument(TextEditor::TextDocument *document)
|
|||||||
handleDocumentClosed(document);
|
handleDocumentClosed(document);
|
||||||
if (m_state == Initialized) {
|
if (m_state == Initialized) {
|
||||||
DidCloseTextDocumentParams params(TextDocumentIdentifier{uri});
|
DidCloseTextDocumentParams params(TextDocumentIdentifier{uri});
|
||||||
sendContent(DidCloseTextDocumentNotification(params));
|
sendMessage(DidCloseTextDocumentNotification(params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -652,7 +652,7 @@ void Client::requestDocumentHighlightsNow(TextEditor::TextEditorWidget *widget)
|
|||||||
widget->setExtraSelections(id, selections);
|
widget->setExtraSelections(id, selections);
|
||||||
});
|
});
|
||||||
m_highlightRequests[widget] = request.id();
|
m_highlightRequests[widget] = request.id();
|
||||||
sendContent(request);
|
sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::activateDocument(TextEditor::TextDocument *document)
|
void Client::activateDocument(TextEditor::TextDocument *document)
|
||||||
@@ -722,16 +722,16 @@ void Client::documentContentsSaved(TextEditor::TextDocument *document)
|
|||||||
{
|
{
|
||||||
if (!m_openedDocument.contains(document))
|
if (!m_openedDocument.contains(document))
|
||||||
return;
|
return;
|
||||||
bool sendMessage = true;
|
bool send = true;
|
||||||
bool includeText = false;
|
bool includeText = false;
|
||||||
const QString method(DidSaveTextDocumentNotification::methodName);
|
const QString method(DidSaveTextDocumentNotification::methodName);
|
||||||
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
||||||
sendMessage = *registered;
|
send = *registered;
|
||||||
if (sendMessage) {
|
if (send) {
|
||||||
const TextDocumentSaveRegistrationOptions option(
|
const TextDocumentSaveRegistrationOptions option(
|
||||||
m_dynamicCapabilities.option(method).toObject());
|
m_dynamicCapabilities.option(method).toObject());
|
||||||
if (option.isValid()) {
|
if (option.isValid()) {
|
||||||
sendMessage = option.filterApplies(document->filePath(),
|
send = option.filterApplies(document->filePath(),
|
||||||
Utils::mimeTypeForName(document->mimeType()));
|
Utils::mimeTypeForName(document->mimeType()));
|
||||||
includeText = option.includeText().value_or(includeText);
|
includeText = option.includeText().value_or(includeText);
|
||||||
}
|
}
|
||||||
@@ -743,13 +743,13 @@ void Client::documentContentsSaved(TextEditor::TextDocument *document)
|
|||||||
includeText = saveOptions->includeText().value_or(includeText);
|
includeText = saveOptions->includeText().value_or(includeText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sendMessage)
|
if (!send)
|
||||||
return;
|
return;
|
||||||
DidSaveTextDocumentParams params(
|
DidSaveTextDocumentParams params(
|
||||||
TextDocumentIdentifier(DocumentUri::fromFilePath(document->filePath())));
|
TextDocumentIdentifier(DocumentUri::fromFilePath(document->filePath())));
|
||||||
if (includeText)
|
if (includeText)
|
||||||
params.setText(document->plainText());
|
params.setText(document->plainText());
|
||||||
sendContent(DidSaveTextDocumentNotification(params));
|
sendMessage(DidSaveTextDocumentNotification(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::documentWillSave(Core::IDocument *document)
|
void Client::documentWillSave(Core::IDocument *document)
|
||||||
@@ -758,27 +758,27 @@ void Client::documentWillSave(Core::IDocument *document)
|
|||||||
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
|
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
|
||||||
if (!m_openedDocument.contains(textDocument))
|
if (!m_openedDocument.contains(textDocument))
|
||||||
return;
|
return;
|
||||||
bool sendMessage = false;
|
bool send = false;
|
||||||
const QString method(WillSaveTextDocumentNotification::methodName);
|
const QString method(WillSaveTextDocumentNotification::methodName);
|
||||||
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
||||||
sendMessage = *registered;
|
send = *registered;
|
||||||
if (sendMessage) {
|
if (send) {
|
||||||
const TextDocumentRegistrationOptions option(m_dynamicCapabilities.option(method));
|
const TextDocumentRegistrationOptions option(m_dynamicCapabilities.option(method));
|
||||||
if (option.isValid()) {
|
if (option.isValid()) {
|
||||||
sendMessage = option.filterApplies(filePath,
|
send = option.filterApplies(filePath,
|
||||||
Utils::mimeTypeForName(document->mimeType()));
|
Utils::mimeTypeForName(document->mimeType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Utils::optional<ServerCapabilities::TextDocumentSync> _sync
|
} else if (Utils::optional<ServerCapabilities::TextDocumentSync> _sync
|
||||||
= m_serverCapabilities.textDocumentSync()) {
|
= m_serverCapabilities.textDocumentSync()) {
|
||||||
if (auto options = Utils::get_if<TextDocumentSyncOptions>(&*_sync))
|
if (auto options = Utils::get_if<TextDocumentSyncOptions>(&*_sync))
|
||||||
sendMessage = options->willSave().value_or(sendMessage);
|
send = options->willSave().value_or(send);
|
||||||
}
|
}
|
||||||
if (!sendMessage)
|
if (!send)
|
||||||
return;
|
return;
|
||||||
const WillSaveTextDocumentParams params(
|
const WillSaveTextDocumentParams params(
|
||||||
TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)));
|
TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)));
|
||||||
sendContent(WillSaveTextDocumentNotification(params));
|
sendMessage(WillSaveTextDocumentNotification(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
||||||
@@ -996,7 +996,7 @@ void Client::requestCodeActions(const CodeActionRequest &request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendContent(request);
|
sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handleCodeActionResponse(const CodeActionRequest::Response &response,
|
void Client::handleCodeActionResponse(const CodeActionRequest::Response &response,
|
||||||
@@ -1025,7 +1025,7 @@ void Client::executeCommand(const Command &command)
|
|||||||
.isRegistered(ExecuteCommandRequest::methodName)
|
.isRegistered(ExecuteCommandRequest::methodName)
|
||||||
.value_or(serverSupportsExecuteCommand);
|
.value_or(serverSupportsExecuteCommand);
|
||||||
if (serverSupportsExecuteCommand)
|
if (serverSupportsExecuteCommand)
|
||||||
sendContent(ExecuteCommandRequest(ExecuteCommandParams(command)));
|
sendMessage(ExecuteCommandRequest(ExecuteCommandParams(command)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::Project *Client::project() const
|
ProjectExplorer::Project *Client::project() const
|
||||||
@@ -1059,7 +1059,7 @@ void Client::projectOpened(ProjectExplorer::Project *project)
|
|||||||
DidChangeWorkspaceFoldersParams params;
|
DidChangeWorkspaceFoldersParams params;
|
||||||
params.setEvent(event);
|
params.setEvent(event);
|
||||||
DidChangeWorkspaceFoldersNotification change(params);
|
DidChangeWorkspaceFoldersNotification change(params);
|
||||||
sendContent(change);
|
sendMessage(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::projectClosed(ProjectExplorer::Project *project)
|
void Client::projectClosed(ProjectExplorer::Project *project)
|
||||||
@@ -1071,7 +1071,7 @@ void Client::projectClosed(ProjectExplorer::Project *project)
|
|||||||
DidChangeWorkspaceFoldersParams params;
|
DidChangeWorkspaceFoldersParams params;
|
||||||
params.setEvent(event);
|
params.setEvent(event);
|
||||||
DidChangeWorkspaceFoldersNotification change(params);
|
DidChangeWorkspaceFoldersNotification change(params);
|
||||||
sendContent(change);
|
sendMessage(change);
|
||||||
}
|
}
|
||||||
if (project == m_project) {
|
if (project == m_project) {
|
||||||
if (m_state == Initialized) {
|
if (m_state == Initialized) {
|
||||||
@@ -1091,7 +1091,7 @@ void Client::updateConfiguration(const QJsonValue &configuration)
|
|||||||
DidChangeConfigurationParams params;
|
DidChangeConfigurationParams params;
|
||||||
params.setSettings(configuration);
|
params.setSettings(configuration);
|
||||||
DidChangeConfigurationNotification notification(params);
|
DidChangeConfigurationNotification notification(params);
|
||||||
sendContent(notification);
|
sendMessage(notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1265,7 +1265,7 @@ void Client::setProgressTitleForToken(const LanguageServerProtocol::ProgressToke
|
|||||||
m_progressManager.setTitleForToken(token, message);
|
m_progressManager.setTitleForToken(token, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handleContent(const LanguageServerProtocol::JsonRpcMessage &message)
|
void Client::handleMessage(const LanguageServerProtocol::JsonRpcMessage &message)
|
||||||
{
|
{
|
||||||
LanguageClientManager::logJsonRpcMessage(LspLogMessage::ServerMessage, name(), message);
|
LanguageClientManager::logJsonRpcMessage(LspLogMessage::ServerMessage, name(), message);
|
||||||
const MessageId id(message.toJsonObject().value(idKey));
|
const MessageId id(message.toJsonObject().value(idKey));
|
||||||
@@ -1383,7 +1383,7 @@ void Client::sendPostponedDocumentUpdates(Schedule semanticTokensSchedule)
|
|||||||
m_documentsToUpdate.clear();
|
m_documentsToUpdate.clear();
|
||||||
|
|
||||||
for (const DocumentUpdate &update : updates) {
|
for (const DocumentUpdate &update : updates) {
|
||||||
sendContent(update.notification, SendDocUpdates::Ignore);
|
sendMessage(update.notification, SendDocUpdates::Ignore);
|
||||||
emit documentUpdated(update.document);
|
emit documentUpdated(update.document);
|
||||||
|
|
||||||
if (currentWidget && currentWidget->textDocument() == update.document)
|
if (currentWidget && currentWidget->textDocument() == update.document)
|
||||||
@@ -1404,10 +1404,10 @@ void Client::sendPostponedDocumentUpdates(Schedule semanticTokensSchedule)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handleResponse(const MessageId &id, const IContent &content)
|
void Client::handleResponse(const MessageId &id, const JsonRpcMessage &message)
|
||||||
{
|
{
|
||||||
if (auto handler = m_responseHandlers[id])
|
if (auto handler = m_responseHandlers[id])
|
||||||
handler(content);
|
handler(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -1419,12 +1419,7 @@ static ResponseError<T> createInvalidParamsError(const QString &message)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
void Client::handleMethod(const QString &method, const MessageId &id, const JsonRpcMessage &message)
|
||||||
static T asJsonContent(const IContent &content) {
|
|
||||||
return T(static_cast<const JsonRpcMessage &>(content).toJsonObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::handleMethod(const QString &method, const MessageId &id, const IContent &content)
|
|
||||||
{
|
{
|
||||||
auto invalidParamsErrorMessage = [&](const JsonObject ¶ms) {
|
auto invalidParamsErrorMessage = [&](const JsonObject ¶ms) {
|
||||||
return tr("Invalid parameter in \"%1\":\n%2")
|
return tr("Invalid parameter in \"%1\":\n%2")
|
||||||
@@ -1443,10 +1438,10 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
|
|
||||||
bool responseSend = false;
|
bool responseSend = false;
|
||||||
auto sendResponse =
|
auto sendResponse =
|
||||||
[&](const IContent &response) {
|
[&](const JsonRpcMessage &response) {
|
||||||
responseSend = true;
|
responseSend = true;
|
||||||
if (reachable()) {
|
if (reachable()) {
|
||||||
sendContent(response);
|
sendMessage(response);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(LOGLSPCLIENT)
|
qCDebug(LOGLSPCLIENT)
|
||||||
<< QString("Dropped response to request %1 id %2 for unreachable server %3")
|
<< QString("Dropped response to request %1 id %2 for unreachable server %3")
|
||||||
@@ -1455,28 +1450,28 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (method == PublishDiagnosticsNotification::methodName) {
|
if (method == PublishDiagnosticsNotification::methodName) {
|
||||||
auto params = asJsonContent<PublishDiagnosticsNotification>(content).params().value_or(
|
auto params = PublishDiagnosticsNotification(message.toJsonObject()).params().value_or(
|
||||||
PublishDiagnosticsParams());
|
PublishDiagnosticsParams());
|
||||||
if (params.isValid())
|
if (params.isValid())
|
||||||
handleDiagnostics(params);
|
handleDiagnostics(params);
|
||||||
else
|
else
|
||||||
log(invalidParamsErrorMessage(params));
|
log(invalidParamsErrorMessage(params));
|
||||||
} else if (method == LogMessageNotification::methodName) {
|
} else if (method == LogMessageNotification::methodName) {
|
||||||
auto params = asJsonContent<LogMessageNotification>(content).params().value_or(
|
auto params = LogMessageNotification(message.toJsonObject()).params().value_or(
|
||||||
LogMessageParams());
|
LogMessageParams());
|
||||||
if (params.isValid())
|
if (params.isValid())
|
||||||
log(params);
|
log(params);
|
||||||
else
|
else
|
||||||
log(invalidParamsErrorMessage(params));
|
log(invalidParamsErrorMessage(params));
|
||||||
} else if (method == ShowMessageNotification::methodName) {
|
} else if (method == ShowMessageNotification::methodName) {
|
||||||
auto params = asJsonContent<ShowMessageNotification>(content).params().value_or(
|
auto params = ShowMessageNotification(message.toJsonObject()).params().value_or(
|
||||||
ShowMessageParams());
|
ShowMessageParams());
|
||||||
if (params.isValid())
|
if (params.isValid())
|
||||||
log(params);
|
log(params);
|
||||||
else
|
else
|
||||||
log(invalidParamsErrorMessage(params));
|
log(invalidParamsErrorMessage(params));
|
||||||
} else if (method == ShowMessageRequest::methodName) {
|
} else if (method == ShowMessageRequest::methodName) {
|
||||||
auto request = asJsonContent<ShowMessageRequest>(content);
|
auto request = ShowMessageRequest(message.toJsonObject());
|
||||||
ShowMessageRequest::Response response(id);
|
ShowMessageRequest::Response response(id);
|
||||||
auto params = request.params().value_or(ShowMessageRequestParams());
|
auto params = request.params().value_or(ShowMessageRequestParams());
|
||||||
if (params.isValid()) {
|
if (params.isValid()) {
|
||||||
@@ -1488,7 +1483,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
}
|
}
|
||||||
sendResponse(response);
|
sendResponse(response);
|
||||||
} else if (method == RegisterCapabilityRequest::methodName) {
|
} else if (method == RegisterCapabilityRequest::methodName) {
|
||||||
auto params = asJsonContent<RegisterCapabilityRequest>(content).params().value_or(
|
auto params = RegisterCapabilityRequest(message.toJsonObject()).params().value_or(
|
||||||
RegistrationParams());
|
RegistrationParams());
|
||||||
if (params.isValid()) {
|
if (params.isValid()) {
|
||||||
registerCapabilities(params.registrations());
|
registerCapabilities(params.registrations());
|
||||||
@@ -1501,7 +1496,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
sendResponse(response);
|
sendResponse(response);
|
||||||
}
|
}
|
||||||
} else if (method == UnregisterCapabilityRequest::methodName) {
|
} else if (method == UnregisterCapabilityRequest::methodName) {
|
||||||
auto params = asJsonContent<UnregisterCapabilityRequest>(content).params().value_or(
|
auto params = UnregisterCapabilityRequest(message.toJsonObject()).params().value_or(
|
||||||
UnregistrationParams());
|
UnregistrationParams());
|
||||||
if (params.isValid()) {
|
if (params.isValid()) {
|
||||||
unregisterCapabilities(params.unregistrations());
|
unregisterCapabilities(params.unregistrations());
|
||||||
@@ -1515,7 +1510,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
}
|
}
|
||||||
} else if (method == ApplyWorkspaceEditRequest::methodName) {
|
} else if (method == ApplyWorkspaceEditRequest::methodName) {
|
||||||
ApplyWorkspaceEditRequest::Response response(id);
|
ApplyWorkspaceEditRequest::Response response(id);
|
||||||
auto params = asJsonContent<ApplyWorkspaceEditRequest>(content).params().value_or(
|
auto params = ApplyWorkspaceEditRequest(message.toJsonObject()).params().value_or(
|
||||||
ApplyWorkspaceEditParams());
|
ApplyWorkspaceEditParams());
|
||||||
if (params.isValid()) {
|
if (params.isValid()) {
|
||||||
ApplyWorkspaceEditResult result;
|
ApplyWorkspaceEditResult result;
|
||||||
@@ -1549,7 +1544,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
sendResponse(createDefaultResponse());
|
sendResponse(createDefaultResponse());
|
||||||
} else if (method == ProgressNotification::methodName) {
|
} else if (method == ProgressNotification::methodName) {
|
||||||
if (Utils::optional<ProgressParams> params
|
if (Utils::optional<ProgressParams> params
|
||||||
= asJsonContent<ProgressNotification>(content).params()) {
|
= ProgressNotification(message.toJsonObject()).params()) {
|
||||||
if (!params->isValid())
|
if (!params->isValid())
|
||||||
log(invalidParamsErrorMessage(*params));
|
log(invalidParamsErrorMessage(*params));
|
||||||
m_progressManager.handleProgress(*params);
|
m_progressManager.handleProgress(*params);
|
||||||
@@ -1583,14 +1578,10 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::sendContentNow(const IContent &content)
|
void Client::sendMessageNow(const JsonRpcMessage &message)
|
||||||
{
|
{
|
||||||
if (content.mimeType() == JsonRpcMessage::jsonRpcMimeType()) {
|
LanguageClientManager::logJsonRpcMessage(LspLogMessage::ClientMessage, name(), message);
|
||||||
LanguageClientManager::logJsonRpcMessage(LspLogMessage::ClientMessage,
|
m_clientInterface->sendMessage(message);
|
||||||
name(),
|
|
||||||
static_cast<const JsonRpcMessage &>(content));
|
|
||||||
m_clientInterface->sendContent(static_cast<const JsonRpcMessage &>(content));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::documentUpdatePostponed(const Utils::FilePath &fileName) const
|
bool Client::documentUpdatePostponed(const Utils::FilePath &fileName) const
|
||||||
@@ -1676,7 +1667,7 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse)
|
|||||||
|
|
||||||
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized";
|
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized";
|
||||||
m_state = Initialized;
|
m_state = Initialized;
|
||||||
sendContent(InitializeNotification(InitializedParams()));
|
sendMessage(InitializeNotification(InitializedParams()));
|
||||||
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentSymbolProvider
|
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentSymbolProvider
|
||||||
= capabilities().documentSymbolProvider();
|
= capabilities().documentSymbolProvider();
|
||||||
if (documentSymbolProvider.has_value()) {
|
if (documentSymbolProvider.has_value()) {
|
||||||
@@ -1707,7 +1698,7 @@ void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse)
|
|||||||
if (optional<ShutdownRequest::Response::Error> error = shutdownResponse.error())
|
if (optional<ShutdownRequest::Response::Error> error = shutdownResponse.error())
|
||||||
log(*error);
|
log(*error);
|
||||||
// directly send content now otherwise the state check of sendContent would fail
|
// directly send content now otherwise the state check of sendContent would fail
|
||||||
sendContentNow(ExitNotification());
|
sendMessageNow(ExitNotification());
|
||||||
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown";
|
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown";
|
||||||
m_state = Shutdown;
|
m_state = Shutdown;
|
||||||
m_shutdownTimer.start();
|
m_shutdownTimer.start();
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public:
|
|||||||
QString name() const;
|
QString name() const;
|
||||||
|
|
||||||
enum class SendDocUpdates { Send, Ignore };
|
enum class SendDocUpdates { Send, Ignore };
|
||||||
void sendContent(const LanguageServerProtocol::IContent &content,
|
void sendMessage(const LanguageServerProtocol::JsonRpcMessage &message,
|
||||||
SendDocUpdates sendUpdates = SendDocUpdates::Send);
|
SendDocUpdates sendUpdates = SendDocUpdates::Send);
|
||||||
|
|
||||||
void cancelRequest(const LanguageServerProtocol::MessageId &id);
|
void cancelRequest(const LanguageServerProtocol::MessageId &id);
|
||||||
@@ -226,17 +226,17 @@ protected:
|
|||||||
void setError(const QString &message);
|
void setError(const QString &message);
|
||||||
void setProgressTitleForToken(const LanguageServerProtocol::ProgressToken &token,
|
void setProgressTitleForToken(const LanguageServerProtocol::ProgressToken &token,
|
||||||
const QString &message);
|
const QString &message);
|
||||||
void handleContent(const LanguageServerProtocol::JsonRpcMessage &message);
|
void handleMessage(const LanguageServerProtocol::JsonRpcMessage &message);
|
||||||
virtual void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms);
|
virtual void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms);
|
||||||
virtual DiagnosticManager *createDiagnosticManager();
|
virtual DiagnosticManager *createDiagnosticManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendContentNow(const LanguageServerProtocol::IContent &content);
|
void sendMessageNow(const LanguageServerProtocol::JsonRpcMessage &message);
|
||||||
void handleResponse(const LanguageServerProtocol::MessageId &id,
|
void handleResponse(const LanguageServerProtocol::MessageId &id,
|
||||||
const LanguageServerProtocol::IContent &content);
|
const LanguageServerProtocol::JsonRpcMessage &message);
|
||||||
void handleMethod(const QString &method,
|
void handleMethod(const QString &method,
|
||||||
const LanguageServerProtocol::MessageId &id,
|
const LanguageServerProtocol::MessageId &id,
|
||||||
const LanguageServerProtocol::IContent &content);
|
const LanguageServerProtocol::JsonRpcMessage &message);
|
||||||
|
|
||||||
void initializeCallback(const LanguageServerProtocol::InitializeRequest::Response &initResponse);
|
void initializeCallback(const LanguageServerProtocol::InitializeRequest::Response &initResponse);
|
||||||
void shutDownCallback(const LanguageServerProtocol::ShutdownRequest::Response &shutdownResponse);
|
void shutDownCallback(const LanguageServerProtocol::ShutdownRequest::Response &shutdownResponse);
|
||||||
@@ -268,10 +268,6 @@ private:
|
|||||||
virtual QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor,
|
virtual QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor,
|
||||||
TextEditor::TextDocument *doc);
|
TextEditor::TextDocument *doc);
|
||||||
|
|
||||||
using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &,
|
|
||||||
LanguageServerProtocol::ResponseHandlers,
|
|
||||||
LanguageServerProtocol::MethodHandler)>;
|
|
||||||
|
|
||||||
State m_state = Uninitialized;
|
State m_state = Uninitialized;
|
||||||
QHash<LanguageServerProtocol::MessageId,
|
QHash<LanguageServerProtocol::MessageId,
|
||||||
LanguageServerProtocol::ResponseHandler::Callback> m_responseHandlers;
|
LanguageServerProtocol::ResponseHandler::Callback> m_responseHandlers;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ void DocumentSymbolCache::requestSymbolsImpl()
|
|||||||
self->handleResponse(uri, response);
|
self->handleResponse(uri, response);
|
||||||
});
|
});
|
||||||
m_runningRequests[uri] = request.id();
|
m_runningRequests[uri] = request.id();
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
}
|
}
|
||||||
m_compressedUris.clear();
|
m_compressedUris.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistIn
|
|||||||
completionRequest.setResponseCallback([this](auto response) {
|
completionRequest.setResponseCallback([this](auto response) {
|
||||||
this->handleCompletionResponse(response);
|
this->handleCompletionResponse(response);
|
||||||
});
|
});
|
||||||
m_client->sendContent(completionRequest);
|
m_client->sendMessage(completionRequest);
|
||||||
m_client->addAssistProcessor(this);
|
m_client->addAssistProcessor(this);
|
||||||
m_currentRequest = completionRequest.id();
|
m_currentRequest = completionRequest.id();
|
||||||
m_document = interface->textDocument();
|
m_document = interface->textDocument();
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ QFutureWatcher<ChangeSet> *LanguageClientFormatter::format(
|
|||||||
handleResponse(response);
|
handleResponse(response);
|
||||||
});
|
});
|
||||||
m_currentRequest = request.id();
|
m_currentRequest = request.id();
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
// ignore first contents changed, because this function is called inside a begin/endEdit block
|
// ignore first contents changed, because this function is called inside a begin/endEdit block
|
||||||
m_ignoreCancel = true;
|
m_ignoreCancel = true;
|
||||||
m_progress.reportStarted();
|
m_progress.reportStarted();
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <languageserverprotocol/icontent.h>
|
|
||||||
#include <languageserverprotocol/languagefeatures.h>
|
#include <languageserverprotocol/languagefeatures.h>
|
||||||
|
|
||||||
#include <texteditor/formatter.h>
|
#include <texteditor/formatter.h>
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ IAssistProposal *FunctionHintProcessor::perform(const AssistInterface *interface
|
|||||||
SignatureHelpRequest request((TextDocumentPositionParams(TextDocumentIdentifier(uri), Position(cursor))));
|
SignatureHelpRequest request((TextDocumentPositionParams(TextDocumentIdentifier(uri), Position(cursor))));
|
||||||
request.setResponseCallback([this](auto response) { this->handleSignatureResponse(response); });
|
request.setResponseCallback([this](auto response) { this->handleSignatureResponse(response); });
|
||||||
m_client->addAssistProcessor(this);
|
m_client->addAssistProcessor(this);
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
m_currentRequest = request.id();
|
m_currentRequest = request.id();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
|
|||||||
m_currentRequest = request.id();
|
m_currentRequest = request.id();
|
||||||
request.setResponseCallback(
|
request.setResponseCallback(
|
||||||
[this](const HoverRequest::Response &response) { handleResponse(response); });
|
[this](const HoverRequest::Response &response) { handleResponse(response); });
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HoverHandler::handleResponse(const HoverRequest::Response &response)
|
void HoverHandler::handleResponse(const HoverRequest::Response &response)
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ BaseClientInterface::~BaseClientInterface()
|
|||||||
m_buffer.close();
|
m_buffer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseClientInterface::sendContent(const IContent &content)
|
void BaseClientInterface::sendMessage(const JsonRpcMessage message)
|
||||||
{
|
{
|
||||||
const BaseMessage message = content.toBaseMessage();
|
const BaseMessage baseMessage = message.toBaseMessage();
|
||||||
sendData(message.header());
|
sendData(baseMessage.header());
|
||||||
sendData(message.content);
|
sendData(baseMessage.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseClientInterface::resetBuffer()
|
void BaseClientInterface::resetBuffer()
|
||||||
@@ -91,7 +91,7 @@ void BaseClientInterface::parseData(const QByteArray &data)
|
|||||||
void BaseClientInterface::parseCurrentMessage()
|
void BaseClientInterface::parseCurrentMessage()
|
||||||
{
|
{
|
||||||
if (m_currentMessage.mimeType == JsonRpcMessage::jsonRpcMimeType()) {
|
if (m_currentMessage.mimeType == JsonRpcMessage::jsonRpcMimeType()) {
|
||||||
emit contentReceived(JsonRpcMessage(m_currentMessage));
|
emit messageReceived(JsonRpcMessage(m_currentMessage));
|
||||||
} else {
|
} else {
|
||||||
emit error(tr("Cannot handle mimetype of message %1")
|
emit error(tr("Cannot handle mimetype of message %1")
|
||||||
.arg(QString::fromUtf8(m_currentMessage.mimeType)));
|
.arg(QString::fromUtf8(m_currentMessage.mimeType)));
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ public:
|
|||||||
|
|
||||||
~BaseClientInterface() override;
|
~BaseClientInterface() override;
|
||||||
|
|
||||||
void sendContent(const LanguageServerProtocol::IContent &content);
|
void sendMessage(const LanguageServerProtocol::JsonRpcMessage message);
|
||||||
void start() { startImpl(); }
|
void start() { startImpl(); }
|
||||||
|
|
||||||
void resetBuffer();
|
void resetBuffer();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void contentReceived(const LanguageServerProtocol::JsonRpcMessage message);
|
void messageReceived(const LanguageServerProtocol::JsonRpcMessage message);
|
||||||
void finished();
|
void finished();
|
||||||
void error(const QString &message);
|
void error(const QString &message);
|
||||||
void started();
|
void started();
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ static void sendTextDocumentPositionParamsRequest(Client *client,
|
|||||||
sendMessage = Utils::get<bool>(*provider);
|
sendMessage = Utils::get<bool>(*provider);
|
||||||
}
|
}
|
||||||
if (sendMessage)
|
if (sendMessage)
|
||||||
client->sendContent(request);
|
client->sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleGotoDefinitionResponse(const GotoDefinitionRequest::Response &response,
|
static void handleGotoDefinitionResponse(const GotoDefinitionRequest::Response &response,
|
||||||
@@ -313,7 +313,7 @@ void SymbolSupport::requestPrepareRename(const TextDocumentPositionParams ¶m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolSupport::requestRename(const TextDocumentPositionParams &positionParams,
|
void SymbolSupport::requestRename(const TextDocumentPositionParams &positionParams,
|
||||||
@@ -326,7 +326,7 @@ void SymbolSupport::requestRename(const TextDocumentPositionParams &positionPara
|
|||||||
request.setResponseCallback([this, search](const RenameRequest::Response &response) {
|
request.setResponseCallback([this, search](const RenameRequest::Response &response) {
|
||||||
handleRenameResponse(search, response);
|
handleRenameResponse(search, response);
|
||||||
});
|
});
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
search->setTextToReplace(newName);
|
search->setTextToReplace(newName);
|
||||||
search->popup();
|
search->popup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ void WorkspaceLocatorFilter::prepareSearch(const QString &entry,
|
|||||||
handleResponse(client, response);
|
handleResponse(client, response);
|
||||||
});
|
});
|
||||||
m_pendingRequests[client] = request.id();
|
m_pendingRequests[client] = request.id();
|
||||||
client->sendContent(request);
|
client->sendMessage(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ void SemanticTokenSupport::reloadSemanticTokensImpl(TextDocument *textDocument,
|
|||||||
request.setResponseCallback(responseCallback);
|
request.setResponseCallback(responseCallback);
|
||||||
qCDebug(LOGLSPHIGHLIGHT) << "Requesting all tokens for" << filePath << "with version"
|
qCDebug(LOGLSPHIGHLIGHT) << "Requesting all tokens for" << filePath << "with version"
|
||||||
<< m_client->documentVersion(filePath);
|
<< m_client->documentVersion(filePath);
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ void SemanticTokenSupport::updateSemanticTokensImpl(TextDocument *textDocument,
|
|||||||
});
|
});
|
||||||
qCDebug(LOGLSPHIGHLIGHT)
|
qCDebug(LOGLSPHIGHLIGHT)
|
||||||
<< "Requesting delta for" << filePath << "with version" << documentVersion;
|
<< "Requesting delta for" << filePath << "with version" << documentVersion;
|
||||||
m_client->sendContent(request);
|
m_client->sendMessage(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ public:
|
|||||||
DidChangeWorkspaceFoldersParams params;
|
DidChangeWorkspaceFoldersParams params;
|
||||||
params.setEvent(event);
|
params.setEvent(event);
|
||||||
DidChangeWorkspaceFoldersNotification change(params);
|
DidChangeWorkspaceFoldersNotification change(params);
|
||||||
sendContent(change);
|
sendMessage(change);
|
||||||
extraWorkspaceDirs.append(workspacePath);
|
extraWorkspaceDirs.append(workspacePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user