From 0b6bc0d187363d7286e5e5be92b4939876a05178 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 10 May 2022 11:40:56 +0200 Subject: [PATCH] LanguageClient: Move the BaseMessage to JsonRpcMessage conversion ... to the client interface. JsonRpcMessages are the only messages used so far and no other types of messages are currently used by any of the supported Language Servers. If a client is going to need special message parsing it can still implement a specialized client interface and overwrite parseCurrentMessage. This is the preparation to move receiving and parsing data passed to and from the language server out of the GUI thread. Change-Id: Ibd4cd95daab7efff947273ca9e7d457de0286f47 Reviewed-by: Reviewed-by: Christian Kandeler --- .../languageserverprotocol/basemessage.cpp | 6 +- .../jsonrpcmessages.cpp | 87 ++++++++----------- .../languageserverprotocol/jsonrpcmessages.h | 19 ++-- src/plugins/languageclient/client.cpp | 52 +++++------ src/plugins/languageclient/client.h | 5 +- .../languageclientinterface.cpp | 17 +++- .../languageclient/languageclientinterface.h | 7 +- .../languageclient/languageclientmanager.cpp | 6 +- .../languageclient/languageclientmanager.h | 7 +- src/plugins/languageclient/lspinspector.cpp | 70 ++++----------- src/plugins/languageclient/lspinspector.h | 8 +- .../tst_languageserverprotocol.cpp | 20 ++--- 12 files changed, 126 insertions(+), 178 deletions(-) diff --git a/src/libs/languageserverprotocol/basemessage.cpp b/src/libs/languageserverprotocol/basemessage.cpp index 6f0145d7c55..4e5f621ca01 100644 --- a/src/libs/languageserverprotocol/basemessage.cpp +++ b/src/libs/languageserverprotocol/basemessage.cpp @@ -38,12 +38,12 @@ namespace LanguageServerProtocol { Q_LOGGING_CATEGORY(parseLog, "qtc.languageserverprotocol.parse", QtWarningMsg) BaseMessage::BaseMessage() - : mimeType(JsonRpcMessageHandler::jsonRpcMimeType()) + : mimeType(JsonRpcMessage::jsonRpcMimeType()) { } BaseMessage::BaseMessage(const QByteArray &mimeType, const QByteArray &content, int expectedLength, QTextCodec *codec) - : mimeType(mimeType.isEmpty() ? JsonRpcMessageHandler::jsonRpcMimeType() : mimeType) + : mimeType(mimeType.isEmpty() ? JsonRpcMessage::jsonRpcMimeType() : mimeType) , content(content) , contentLength(expectedLength) , codec(codec) @@ -177,7 +177,7 @@ QByteArray BaseMessage::header() const QByteArray header; header.append(lengthHeader()); if (codec != defaultCodec() - || (!mimeType.isEmpty() && mimeType != JsonRpcMessageHandler::jsonRpcMimeType())) { + || (!mimeType.isEmpty() && mimeType != JsonRpcMessage::jsonRpcMimeType())) { header.append(typeHeader()); } header.append(headerSeparator); diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.cpp b/src/libs/languageserverprotocol/jsonrpcmessages.cpp index 517ffd5f8fb..73e457547d7 100644 --- a/src/libs/languageserverprotocol/jsonrpcmessages.cpp +++ b/src/libs/languageserverprotocol/jsonrpcmessages.cpp @@ -47,11 +47,16 @@ QByteArray JsonRpcMessage::toRawData() const QByteArray JsonRpcMessage::mimeType() const { - return JsonRpcMessageHandler::jsonRpcMimeType(); + return jsonRpcMimeType(); } -bool JsonRpcMessage::isValid(QString * /*errorMessage*/) const +bool JsonRpcMessage::isValid(QString *errorMessage) const { + if (!m_parseError.isEmpty()) { + if (errorMessage) + *errorMessage = m_parseError; + return false; + } return m_jsonObject[jsonRpcVersionKey] == "2.0"; } @@ -66,38 +71,6 @@ JsonRpcMessage::JsonRpcMessage() m_jsonObject[jsonRpcVersionKey] = "2.0"; } -JsonRpcMessage::JsonRpcMessage(const QJsonObject &jsonObject) - : m_jsonObject(jsonObject) -{ } - -JsonRpcMessage::JsonRpcMessage(QJsonObject &&jsonObject) - : m_jsonObject(std::move(jsonObject)) -{ } - -QByteArray JsonRpcMessageHandler::jsonRpcMimeType() -{ - return "application/vscode-jsonrpc"; -} - -void JsonRpcMessageHandler::parseContent(const QByteArray &content, - QTextCodec *codec, - QString &parseError, - const ResponseHandlers &responseHandlers, - const MethodHandler &methodHandler) -{ - const QJsonObject &jsonObject = toJsonObject(content, codec, parseError); - if (jsonObject.isEmpty()) - return; - - const MessageId id(jsonObject.value(idKey)); - const QString &method = jsonObject.value(methodKey).toString(); - const JsonRpcMessage jsonContent(jsonObject); - if (method.isEmpty()) - responseHandlers(id, jsonContent); - else - methodHandler(method, id, jsonContent); -} - constexpr int utf8mib = 106; static QString docTypeName(const QJsonDocument &doc) @@ -113,29 +86,43 @@ static QString docTypeName(const QJsonDocument &doc) return {}; } -QJsonObject JsonRpcMessageHandler::toJsonObject(const QByteArray &_content, - QTextCodec *codec, - QString &parseError) +JsonRpcMessage::JsonRpcMessage(const BaseMessage &message) { - if (_content.isEmpty()) - return QJsonObject(); + if (message.content.isEmpty()) + return; QByteArray content; - if (codec && codec->mibEnum() != utf8mib) { + if (message.codec && message.codec->mibEnum() != utf8mib) { QTextCodec *utf8 = QTextCodec::codecForMib(utf8mib); if (utf8) - content = utf8->fromUnicode(codec->toUnicode(_content)); + content = utf8->fromUnicode(message.codec->toUnicode(message.content)); } if (content.isEmpty()) - content = _content; - QJsonParseError error = {0 , QJsonParseError::NoError}; + content = message.content; + QJsonParseError error = {0, QJsonParseError::NoError}; const QJsonDocument doc = QJsonDocument::fromJson(content, &error); - if (doc.isObject()) - return doc.object(); - if (doc.isNull()) - parseError = tr("Could not parse JSON message \"%1\".").arg(error.errorString()); - else - parseError = tr("Expected a JSON object, but got a JSON \"%1\" value.").arg(docTypeName(doc)); - return QJsonObject(); + if (doc.isObject()) { + m_jsonObject = doc.object(); + } else if (doc.isNull()) { + m_parseError = tr("LanguageServerProtocol::JsonRpcMessage", + "Could not parse JSON message \"%1\".") + .arg(error.errorString()); + } else { + m_parseError = tr("Expected a JSON object, but got a JSON \"%1\" value.") + .arg(docTypeName(doc)); + } +} + +JsonRpcMessage::JsonRpcMessage(const QJsonObject &jsonObject) + : m_jsonObject(jsonObject) +{ } + +JsonRpcMessage::JsonRpcMessage(QJsonObject &&jsonObject) + : m_jsonObject(std::move(jsonObject)) +{ } + +QByteArray JsonRpcMessage::jsonRpcMimeType() +{ + return "application/vscode-jsonrpc"; } CancelRequest::CancelRequest(const CancelParameter ¶ms) diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.h b/src/libs/languageserverprotocol/jsonrpcmessages.h index 7b24bc9b901..53bcfafba38 100644 --- a/src/libs/languageserverprotocol/jsonrpcmessages.h +++ b/src/libs/languageserverprotocol/jsonrpcmessages.h @@ -45,16 +45,23 @@ namespace LanguageServerProtocol { class LANGUAGESERVERPROTOCOL_EXPORT JsonRpcMessage : public IContent { + Q_DECLARE_TR_FUNCTIONS(JsonRpcMessage) public: JsonRpcMessage(); + explicit JsonRpcMessage(const BaseMessage &message); explicit JsonRpcMessage(const QJsonObject &jsonObject); explicit JsonRpcMessage(QJsonObject &&jsonObject); + static QByteArray jsonRpcMimeType(); + QByteArray toRawData() const final; QByteArray mimeType() const final; bool isValid(QString *errorMessage) const override; const QJsonObject &toJsonObject() const; + + const QString parseError() { return m_parseError; } + protected: QJsonObject m_jsonObject; @@ -62,18 +69,6 @@ private: QString m_parseError; }; -class LANGUAGESERVERPROTOCOL_EXPORT JsonRpcMessageHandler -{ - Q_DECLARE_TR_FUNCTIONS(JsonRpcMessageHandler) - -public: - static QByteArray jsonRpcMimeType(); - static void parseContent(const QByteArray &content, QTextCodec *codec, QString &errorMessage, - const ResponseHandlers &responseHandlers, - const MethodHandler &methodHandler); - static QJsonObject toJsonObject(const QByteArray &content, QTextCodec *codec, QString &parseError); -}; - template class Notification : public JsonRpcMessage { diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 4c360a15f70..b2be6a03fbc 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -104,10 +104,8 @@ Client::Client(BaseClientInterface *clientInterface) connect(SessionManager::instance(), &SessionManager::projectRemoved, this, &Client::projectClosed); - m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(), - &JsonRpcMessageHandler::parseContent); QTC_ASSERT(clientInterface, return); - connect(clientInterface, &BaseClientInterface::messageReceived, this, &Client::handleMessage); + connect(clientInterface, &BaseClientInterface::contentReceived, this, &Client::handleContent); connect(clientInterface, &BaseClientInterface::error, this, &Client::setError); connect(clientInterface, &BaseClientInterface::finished, this, &Client::finished); connect(Core::EditorManager::instance(), @@ -161,8 +159,8 @@ Client::~Client() m_documentHighlightsTimer.clear(); updateEditorToolBar(m_openedDocument.keys()); // do not handle messages while shutting down - disconnect(m_clientInterface.data(), &BaseClientInterface::messageReceived, - this, &Client::handleMessage); + disconnect(m_clientInterface.data(), &BaseClientInterface::contentReceived, + this, &Client::handleContent); delete m_diagnosticManager; } @@ -327,8 +325,8 @@ void Client::initialize() if (Utils::optional responseHandler = initRequest.responseHandler()) m_responseHandlers[responseHandler->id] = responseHandler->callback; - // directly send message otherwise the state check of sendContent would fail - sendMessage(initRequest.toBaseMessage()); + // directly send content now otherwise the state check of sendContent would fail + sendContentNow(initRequest); m_state = InitializeRequested; } @@ -444,7 +442,7 @@ void Client::sendContent(const IContent &content, SendDocUpdates sendUpdates) QString error; if (!QTC_GUARD(content.isValid(&error))) Core::MessageManager::writeFlashing(error); - sendMessage(content.toBaseMessage()); + sendContentNow(content); } void Client::cancelRequest(const MessageId &id) @@ -1218,23 +1216,15 @@ void Client::setProgressTitleForToken(const LanguageServerProtocol::ProgressToke m_progressManager.setTitleForToken(token, message); } -void Client::handleMessage(const BaseMessage &message) +void Client::handleContent(const LanguageServerProtocol::JsonRpcMessage &message) { - LanguageClientManager::logBaseMessage(LspLogMessage::ServerMessage, name(), message); - if (auto handler = m_contentHandler[message.mimeType]) { - QString parseError; - handler(message.content, message.codec, parseError, - [this](const MessageId &id, const IContent &content){ - this->handleResponse(id, content); - }, - [this](const QString &method, const MessageId &id, const IContent &content){ - this->handleMethod(method, id, content); - }); - if (!parseError.isEmpty()) - log(parseError); - } else { - log(tr("Cannot handle content of type: %1").arg(QLatin1String(message.mimeType))); - } + LanguageClientManager::logJsonRpcMessage(LspLogMessage::ServerMessage, name(), message); + const MessageId id(message.toJsonObject().value(idKey)); + const QString method = message.toJsonObject().value(methodKey).toString(); + if (method.isEmpty()) + handleResponse(id, message); + else + handleMethod(method, id, message); } void Client::log(const QString &message) const @@ -1544,10 +1534,14 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms) } } -void Client::sendMessage(const BaseMessage &message) +void Client::sendContentNow(const IContent &content) { - LanguageClientManager::logBaseMessage(LspLogMessage::ClientMessage, name(), message); - m_clientInterface->sendMessage(message); + if (content.mimeType() == JsonRpcMessage::jsonRpcMimeType()) { + LanguageClientManager::logJsonRpcMessage(LspLogMessage::ClientMessage, + name(), + static_cast(content)); + } + m_clientInterface->sendContent(content); } bool Client::documentUpdatePostponed(const Utils::FilePath &fileName) const @@ -1663,8 +1657,8 @@ void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse) QTC_ASSERT(m_clientInterface, return); if (optional error = shutdownResponse.error()) log(*error); - // directly send message otherwise the state check of sendContent would fail - sendMessage(ExitNotification().toBaseMessage()); + // directly send content now otherwise the state check of sendContent would fail + sendContentNow(ExitNotification()); qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown"; m_state = Shutdown; m_shutdownTimer.start(); diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index adb16e5d4cc..98de0835554 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -225,12 +225,12 @@ protected: void setError(const QString &message); void setProgressTitleForToken(const LanguageServerProtocol::ProgressToken &token, const QString &message); - void handleMessage(const LanguageServerProtocol::BaseMessage &message); + void handleContent(const LanguageServerProtocol::JsonRpcMessage &message); virtual void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms); virtual DiagnosticManager *createDiagnosticManager(); private: - void sendMessage(const LanguageServerProtocol::BaseMessage &message); + void sendContentNow(const LanguageServerProtocol::IContent &content); void handleResponse(const LanguageServerProtocol::MessageId &id, const LanguageServerProtocol::IContent &content); void handleMethod(const QString &method, @@ -274,7 +274,6 @@ private: State m_state = Uninitialized; QHash m_responseHandlers; - QHash m_contentHandler; QString m_displayName; LanguageFilter m_languagFilter; QJsonObject m_initializationOptions; diff --git a/src/plugins/languageclient/languageclientinterface.cpp b/src/plugins/languageclient/languageclientinterface.cpp index 62b7dc8b4ae..5425933ef73 100644 --- a/src/plugins/languageclient/languageclientinterface.cpp +++ b/src/plugins/languageclient/languageclientinterface.cpp @@ -46,8 +46,9 @@ BaseClientInterface::~BaseClientInterface() m_buffer.close(); } -void BaseClientInterface::sendMessage(const BaseMessage &message) +void BaseClientInterface::sendContent(const IContent &content) { + const BaseMessage message = content.toBaseMessage(); sendData(message.header()); sendData(message.content); } @@ -78,8 +79,7 @@ void BaseClientInterface::parseData(const QByteArray &data) emit error(parseError); if (!m_currentMessage.isComplete()) break; - emit messageReceived(m_currentMessage); - m_currentMessage = BaseMessage(); + parseCurrentMessage(); } if (m_buffer.atEnd()) { m_buffer.close(); @@ -88,6 +88,17 @@ void BaseClientInterface::parseData(const QByteArray &data) } } +void BaseClientInterface::parseCurrentMessage() +{ + if (m_currentMessage.mimeType == JsonRpcMessage::jsonRpcMimeType()) { + emit contentReceived(JsonRpcMessage(m_currentMessage)); + } else { + emit error(tr("Cannot handle mimetype of message %1") + .arg(QString::fromUtf8(m_currentMessage.mimeType))); + } + m_currentMessage = BaseMessage(); +} + StdIOClientInterface::StdIOClientInterface() { m_process.setProcessMode(ProcessMode::Writer); diff --git a/src/plugins/languageclient/languageclientinterface.h b/src/plugins/languageclient/languageclientinterface.h index 17cf222fd3f..db5f33ff65b 100644 --- a/src/plugins/languageclient/languageclientinterface.h +++ b/src/plugins/languageclient/languageclientinterface.h @@ -27,7 +27,7 @@ #include "languageclient_global.h" -#include +#include #include @@ -45,19 +45,20 @@ public: ~BaseClientInterface() override; - void sendMessage(const LanguageServerProtocol::BaseMessage &message); + void sendContent(const LanguageServerProtocol::IContent &content); virtual bool start() { return true; } void resetBuffer(); signals: - void messageReceived(LanguageServerProtocol::BaseMessage message); + void contentReceived(const LanguageServerProtocol::JsonRpcMessage message); void finished(); void error(const QString &message); protected: virtual void sendData(const QByteArray &data) = 0; void parseData(const QByteArray &data); + virtual void parseCurrentMessage(); private: QBuffer m_buffer; diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 092b95f3717..2d0ff7f77e9 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -424,9 +424,9 @@ void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *doc TextEditor::IOutlineWidgetFactory::updateOutline(); } -void LanguageClientManager::logBaseMessage(const LspLogMessage::MessageSender sender, - const QString &clientName, - const BaseMessage &message) +void LanguageClientManager::logJsonRpcMessage(const LspLogMessage::MessageSender sender, + const QString &clientName, + const LanguageServerProtocol::JsonRpcMessage &message) { instance()->m_inspector.log(sender, clientName, message); } diff --git a/src/plugins/languageclient/languageclientmanager.h b/src/plugins/languageclient/languageclientmanager.h index c0bcd258b3d..c5c8e9e86ad 100644 --- a/src/plugins/languageclient/languageclientmanager.h +++ b/src/plugins/languageclient/languageclientmanager.h @@ -96,9 +96,10 @@ public: /// static void openDocumentWithClient(TextEditor::TextDocument *document, Client *client); - static void logBaseMessage(const LspLogMessage::MessageSender sender, - const QString &clientName, - const LanguageServerProtocol::BaseMessage &message); + static void logJsonRpcMessage(const LspLogMessage::MessageSender sender, + const QString &clientName, + const LanguageServerProtocol::JsonRpcMessage &message); + static void showInspector(); signals: diff --git a/src/plugins/languageclient/lspinspector.cpp b/src/plugins/languageclient/lspinspector.cpp index e6e81a2a1f4..33c179416bf 100644 --- a/src/plugins/languageclient/lspinspector.cpp +++ b/src/plugins/languageclient/lspinspector.cpp @@ -120,8 +120,7 @@ public: void clear(); private: - QLabel *m_contentLength = nullptr; - QLabel *m_mimeType = nullptr; + QTreeView *m_jsonTree = nullptr; }; class LspCapabilitiesWidget : public QWidget @@ -258,8 +257,11 @@ LspLogWidget::LspLogWidget() void LspLogWidget::currentMessageChanged(const QModelIndex &index) { m_messages->clearSelection(); - if (!index.isValid()) + if (!index.isValid()) { + m_clientDetails->clear(); + m_serverDetails->clear(); return; + } LspLogMessage message = m_model.itemAt(index.row())->itemData; if (message.sender == LspLogMessage::ClientMessage) m_clientDetails->setMessage(message); @@ -274,8 +276,6 @@ static bool matches(LspLogMessage::MessageSender sender, { if (message.sender != sender) return false; - if (message.message.mimeType != JsonRpcMessageHandler::jsonRpcMimeType()) - return false; return message.id() == id; } @@ -322,7 +322,7 @@ void LspLogWidget::saveLog() stream << (message.sender == LspLogMessage::ClientMessage ? QString{"Client"} : QString{"Server"}); stream << '\n'; - stream << message.message.codec->toUnicode(message.message.content); + stream << QJsonDocument(message.message.toJsonObject()).toJson(); stream << "\n\n"; }); @@ -365,7 +365,7 @@ QWidget *LspInspector::createWidget(const QString &defaultClient) void LspInspector::log(const LspLogMessage::MessageSender sender, const QString &clientName, - const BaseMessage &message) + const JsonRpcMessage &message) { std::list &clientLog = m_logs[clientName]; while (clientLog.size() >= static_cast(m_logSize)) @@ -510,50 +510,27 @@ LspCapabilitiesWidget *LspInspectorWidget::capabilities() const MessageDetailWidget::MessageDetailWidget() { - auto layout = new QFormLayout; + auto layout = new QVBoxLayout; setLayout(layout); - m_contentLength = new QLabel; - m_mimeType = new QLabel; + m_jsonTree = new QTreeView; - layout->addRow("Content Length:", m_contentLength); - layout->addRow("MIME Type:", m_mimeType); + layout->addWidget(m_jsonTree); } void MessageDetailWidget::setMessage(const LspLogMessage &message) { - m_contentLength->setText(QString::number(message.message.contentLength)); - m_mimeType->setText(QString::fromLatin1(message.message.mimeType)); - - QWidget *newContentWidget = nullptr; - if (message.message.mimeType == JsonRpcMessageHandler::jsonRpcMimeType()) { - newContentWidget = createJsonTreeView("content", message.json()); - } else { - auto edit = new QPlainTextEdit(); - edit->setReadOnly(true); - edit->setPlainText(message.message.codec->toUnicode(message.message.content)); - newContentWidget = edit; - } - auto formLayout = static_cast(layout()); - if (formLayout->rowCount() > 2) - formLayout->removeRow(2); - formLayout->setWidget(2, QFormLayout::SpanningRole, newContentWidget); + m_jsonTree->setModel(createJsonModel("content", message.message.toJsonObject())); } void MessageDetailWidget::clear() { - m_contentLength->setText({}); - m_mimeType->setText({}); - auto formLayout = static_cast(layout()); - if (formLayout->rowCount() > 2) - formLayout->removeRow(2); + m_jsonTree->setModel(createJsonModel("", QJsonObject())); } LspLogMessage::LspLogMessage() = default; -LspLogMessage::LspLogMessage(MessageSender sender, - const QTime &time, - const LanguageServerProtocol::BaseMessage &message) +LspLogMessage::LspLogMessage(MessageSender sender, const QTime &time, const JsonRpcMessage &message) : sender(sender) , time(time) , message(message) @@ -562,7 +539,7 @@ LspLogMessage::LspLogMessage(MessageSender sender, MessageId LspLogMessage::id() const { if (!m_id.has_value()) - m_id = MessageId(json().value(idKey)); + m_id = MessageId(message.toJsonObject().value(idKey)); return *m_id; } @@ -570,25 +547,10 @@ QString LspLogMessage::displayText() const { if (!m_displayText.has_value()) { m_displayText = QString(time.toString("hh:mm:ss.zzz") + '\n'); - if (message.mimeType == JsonRpcMessageHandler::jsonRpcMimeType()) - m_displayText->append(json().value(QString{methodKey}).toString(id().toString())); - else - m_displayText->append(message.codec->toUnicode(message.content)); + m_displayText->append( + message.toJsonObject().value(QString{methodKey}).toString(id().toString())); } return *m_displayText; } -QJsonObject &LspLogMessage::json() const -{ - if (!m_json.has_value()) { - if (message.mimeType == JsonRpcMessageHandler::jsonRpcMimeType()) { - QString error; - m_json = JsonRpcMessageHandler::toJsonObject(message.content, message.codec, error); - } else { - m_json = QJsonObject(); - } - } - return *m_json; -} - } // namespace LanguageClient diff --git a/src/plugins/languageclient/lspinspector.h b/src/plugins/languageclient/lspinspector.h index 6d3cb048e83..81eb16a2b75 100644 --- a/src/plugins/languageclient/lspinspector.h +++ b/src/plugins/languageclient/lspinspector.h @@ -45,18 +45,16 @@ public: LspLogMessage(); LspLogMessage(MessageSender sender, const QTime &time, - const LanguageServerProtocol::BaseMessage &message); + const LanguageServerProtocol::JsonRpcMessage &message); QTime time; - LanguageServerProtocol::BaseMessage message; + LanguageServerProtocol::JsonRpcMessage message; LanguageServerProtocol::MessageId id() const; QString displayText() const; - QJsonObject &json() const; private: mutable Utils::optional m_id; mutable Utils::optional m_displayText; - mutable Utils::optional m_json; }; struct Capabilities @@ -76,7 +74,7 @@ public: void log(const LspLogMessage::MessageSender sender, const QString &clientName, - const LanguageServerProtocol::BaseMessage &message); + const LanguageServerProtocol::JsonRpcMessage &message); void clientInitialized(const QString &clientName, const LanguageServerProtocol::ServerCapabilities &capabilities); void updateCapabilities(const QString &clientName, diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp index 6b36b8e366d..a3c79033653 100644 --- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp +++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp @@ -72,7 +72,7 @@ private: void tst_LanguageServerProtocol::initTestCase() { - defaultMimeType = JsonRpcMessageHandler::jsonRpcMimeType(); + defaultMimeType = JsonRpcMessage::jsonRpcMimeType(); defaultCodec = QTextCodec::codecForName("utf-8"); } @@ -447,13 +447,13 @@ void tst_LanguageServerProtocol::toJsonObject() QFETCH(bool, error); QFETCH(QJsonObject, expected); - QString parseError; - const QJsonObject object = JsonRpcMessageHandler::toJsonObject(content, codec, parseError); + BaseMessage baseMessage(JsonRpcMessage::jsonRpcMimeType(), content, content.length(), codec); + JsonRpcMessage jsonRpcMessage(baseMessage); - if (!error && !parseError.isEmpty()) - QFAIL(parseError.toLocal8Bit().data()); - QCOMPARE(object, expected); - QCOMPARE(!parseError.isEmpty(), error); + if (!error && !jsonRpcMessage.parseError().isEmpty()) + QFAIL(jsonRpcMessage.parseError().toLocal8Bit().data()); + QCOMPARE(jsonRpcMessage.toJsonObject(), expected); + QCOMPARE(!jsonRpcMessage.parseError().isEmpty(), error); } void tst_LanguageServerProtocol::jsonMessageToBaseMessage_data() @@ -462,11 +462,11 @@ void tst_LanguageServerProtocol::jsonMessageToBaseMessage_data() QTest::addColumn("baseMessage"); QTest::newRow("empty object") << JsonRpcMessage(QJsonObject()) - << BaseMessage(JsonRpcMessageHandler::jsonRpcMimeType(), + << BaseMessage(JsonRpcMessage::jsonRpcMimeType(), "{}"); - QTest::newRow("key value pair") << JsonRpcMessage({{"key", "value"}}) - << BaseMessage(JsonRpcMessageHandler::jsonRpcMimeType(), + QTest::newRow("key value pair") << JsonRpcMessage(QJsonObject{{"key", "value"}}) + << BaseMessage(JsonRpcMessage::jsonRpcMimeType(), R"({"key":"value"})"); }