diff options
author | David Schulz <david.schulz@qt.io> | 2020-02-10 10:31:32 +0100 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2020-02-12 11:25:01 +0000 |
commit | e3c7b7200356bdea292fd80a893940d53a231679 (patch) | |
tree | 77b831ae6cbae1d0c948d3e4248f0b705d795985 | |
parent | bf0f2ebea0029a82e37bb8085426330b55c6c31c (diff) | |
download | qt-creator-e3c7b7200356bdea292fd80a893940d53a231679.tar.gz |
LanguageClient: introduce new type for gorgeous formatted errors
Change-Id: Ia76bd768bcb6d33ce66319dddf8cc355a41ffa31
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
28 files changed, 319 insertions, 237 deletions
diff --git a/src/libs/languageserverprotocol/client.h b/src/libs/languageserverprotocol/client.h index bf2fe5421a..a07d48e94f 100644 --- a/src/libs/languageserverprotocol/client.h +++ b/src/libs/languageserverprotocol/client.h @@ -50,7 +50,7 @@ public: void setRegisterOptions(const QJsonValue ®isterOptions) { insert(registerOptionsKey, registerOptions); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, idKey) && check<QString>(error, methodKey); } }; @@ -65,7 +65,7 @@ public: void setRegistrations(const QList<Registration> ®istrations) { insertArray(registrationsKey, registrations); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<Registration>(error, registrationsKey); } }; @@ -89,7 +89,7 @@ public: QString method() const { return typedValue<QString>(methodKey); } void setMethod(const QString &method) { insert(methodKey, method); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, idKey) && check<QString>(error, methodKey); } }; @@ -103,7 +103,7 @@ public: void setUnregistrations(const QList<Unregistration> &unregistrations) { insertArray(unregistrationsKey, unregistrations); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<Unregistration>(error, unregistrationsKey); } }; diff --git a/src/libs/languageserverprotocol/clientcapabilities.cpp b/src/libs/languageserverprotocol/clientcapabilities.cpp index 1f79ffae0d..fac2d3f5d7 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.cpp +++ b/src/libs/languageserverprotocol/clientcapabilities.cpp @@ -42,7 +42,7 @@ void SymbolCapabilities::SymbolKindCapabilities::setValueSet(const QList<SymbolK insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet)); } -bool ClientCapabilities::isValid(QStringList *error) const +bool ClientCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<WorkspaceClientCapabilities>(error, workspaceKey) && checkOptional<TextDocumentClientCapabilities>(error, textDocumentKey); @@ -53,7 +53,7 @@ WorkspaceClientCapabilities::WorkspaceClientCapabilities() setWorkspaceFolders(true); } -bool WorkspaceClientCapabilities::isValid(QStringList *error) const +bool WorkspaceClientCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<bool>(error,applyEditKey) && checkOptional<WorkspaceEditCapabilities>(error,workspaceEditKey) @@ -65,7 +65,7 @@ bool WorkspaceClientCapabilities::isValid(QStringList *error) const && checkOptional<bool>(error,configurationKey); } -bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<bool>(error, willSaveKey) @@ -73,7 +73,7 @@ bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStrin && checkOptional<bool>(error, didSaveKey); } -bool TextDocumentClientCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<SynchronizationCapabilities>(error, synchronizationKey) && checkOptional<CompletionCapabilities>(error, completionKey) @@ -96,13 +96,13 @@ bool TextDocumentClientCapabilities::isValid(QStringList *error) const && checkOptional<SemanticHighlightingCapabilities>(error, semanticHighlightingCapabilitiesKey); } -bool SymbolCapabilities::isValid(QStringList *error) const +bool SymbolCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<SymbolKindCapabilities>(error, symbolKindKey); } -bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<CompletionItemCapbilities>(error, completionItemKey) @@ -110,19 +110,19 @@ bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(QStringList && checkOptional<bool>(error, contextSupportKey); } -bool TextDocumentClientCapabilities::HoverCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::HoverCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptionalArray<int>(error, contentFormatKey); } -bool TextDocumentClientCapabilities::SignatureHelpCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::SignatureHelpCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<SignatureHelpCapabilities>(error, signatureInformationKey); } -bool TextDocumentClientCapabilities::CodeActionCapabilities::isValid(QStringList *errorHierarchy) const +bool TextDocumentClientCapabilities::CodeActionCapabilities::isValid(ErrorHierarchy *errorHierarchy) const { return DynamicRegistrationCapabilities::isValid(errorHierarchy) && checkOptional<CodeActionLiteralSupport>(errorHierarchy, codeActionLiteralSupportKey); diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h index ec1bdd25b5..76462fa15b 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.h +++ b/src/libs/languageserverprotocol/clientcapabilities.h @@ -39,7 +39,7 @@ public: void setDynamicRegistration(bool dynamicRegistration) { insert(dynamicRegistrationKey, dynamicRegistration); } void clearDynamicRegistration() { remove(dynamicRegistrationKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, dynamicRegistrationKey); } }; @@ -67,7 +67,7 @@ public: void setValueSet(const QList<SymbolKind> &valueSet); void clearValueSet() { remove(valueSetKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<int>(error, valueSetKey); } }; @@ -77,7 +77,7 @@ public: void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); } void clearSymbolKind() { remove(symbolKindKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentClientCapabilities : public JsonObject @@ -111,7 +111,7 @@ public: void setDidSave(bool didSave) { insert(didSaveKey, didSave); } void clearDidSave() { remove(didSaveKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; Utils::optional<SynchronizationCapabilities> synchronization() const @@ -129,7 +129,7 @@ public: void setSemanticHighlighting(bool semanticHighlighting) { insert(semanticHighlightingKey, semanticHighlighting); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, semanticHighlightingKey); } }; @@ -179,7 +179,7 @@ public: void setDocumentationFormat(const QList<MarkupKind> &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, snippetSupportKey) && checkOptional<bool>(error, commitCharacterSupportKey) @@ -213,7 +213,7 @@ public: void setValueSet(const QList<CompletionItemKind::Kind> &valueSet); void clearValueSet() { remove(valueSetKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<int>(error, valueSetKey); } }; @@ -231,7 +231,7 @@ public: void setContextSupport(bool contextSupport) { insert(contextSupportKey, contextSupport); } void clearContextSupport() { remove(contextSupportKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; // Capabilities specific to the `textDocument/completion` @@ -253,7 +253,7 @@ public: void setContentFormat(const QList<MarkupKind> &contentFormat); void clearContentFormat() { remove(contentFormatKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; Utils::optional<HoverCapabilities> hover() const { return optionalValue<HoverCapabilities>(hoverKey); } @@ -277,7 +277,7 @@ public: void setDocumentationFormat(const QList<MarkupKind> &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<int>(error, documentationFormatKey); } }; @@ -288,7 +288,7 @@ public: { insert(signatureInformationKey, signatureInformation); } void clearSignatureInformation() { remove(signatureInformationKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; // Capabilities specific to the `textDocument/signatureHelp` @@ -390,7 +390,7 @@ public: void setValueSet(const QList<QString> &valueSet) { insertArray(valueSetKey, valueSet); } - bool isValid(QStringList *errorHierarchy) const override + bool isValid(ErrorHierarchy *errorHierarchy) const override { return checkArray<QString>(errorHierarchy, valueSetKey); } }; @@ -399,7 +399,7 @@ public: void setCodeActionKind(const CodeActionKind &codeActionKind) { insert(codeActionKindKey, codeActionKind); } - bool isValid(QStringList *errorHierarchy) const override + bool isValid(ErrorHierarchy *errorHierarchy) const override { return check<CodeActionKind>(errorHierarchy, codeActionKindKey); } }; @@ -409,7 +409,7 @@ public: { insert(codeActionLiteralSupportKey, codeActionLiteralSupport); } void clearCodeActionLiteralSupport() { remove(codeActionLiteralSupportKey); } - bool isValid(QStringList *errorHierarchy) const override; + bool isValid(ErrorHierarchy *errorHierarchy) const override; }; // Whether code action supports dynamic registration. @@ -451,7 +451,7 @@ public: { insert(renameKey, rename); } void clearRename() { remove(renameKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject @@ -480,7 +480,7 @@ public: { insert(documentChangesKey, documentChanges); } void clearDocumentChanges() { remove(documentChangesKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, documentChangesKey); } }; @@ -530,7 +530,7 @@ public: void setConfiguration(bool configuration) { insert(configurationKey, configuration); } void clearConfiguration() { remove(configurationKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject @@ -557,7 +557,7 @@ public: void setExperimental(const QJsonValue &experimental) { insert(experimentalKey, experimental); } void clearExperimental() { remove(experimentalKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; } diff --git a/src/libs/languageserverprotocol/completion.cpp b/src/libs/languageserverprotocol/completion.cpp index eb5f22cf6a..ca34629805 100644 --- a/src/libs/languageserverprotocol/completion.cpp +++ b/src/libs/languageserverprotocol/completion.cpp @@ -49,7 +49,7 @@ Utils::optional<CompletionItem::InsertTextFormat> CompletionItem::insertTextForm : Utils::make_optional(CompletionItem::InsertTextFormat(value.value())); } -bool CompletionItem::isValid(QStringList *error) const +bool CompletionItem::isValid(ErrorHierarchy *error) const { return check<QString>(error, labelKey) && checkOptional<int>(error, kindKey) @@ -70,14 +70,14 @@ CompletionItemResolveRequest::CompletionItemResolveRequest(const CompletionItem : Request(methodName, params) { } -bool CompletionList::isValid(QStringList *error) const +bool CompletionList::isValid(ErrorHierarchy *error) const { return check<bool>(error, isIncompleteKey) && checkOptionalArray<CompletionItem>(error, itemsKey); } -bool CompletionParams::isValid(QStringList *error) const +bool CompletionParams::isValid(ErrorHierarchy *error) const { return TextDocumentPositionParams::isValid(error) && checkOptional<CompletionContext>(error, contextKey); diff --git a/src/libs/languageserverprotocol/completion.h b/src/libs/languageserverprotocol/completion.h index 3db5be4d70..629f0eb398 100644 --- a/src/libs/languageserverprotocol/completion.h +++ b/src/libs/languageserverprotocol/completion.h @@ -71,7 +71,7 @@ public: { insert(triggerCharacterKey, triggerCharacter); } void clearTriggerCharacter() { remove(triggerCharacterKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, triggerKindKey) && checkOptional<QString>(error, triggerCharacterKey); @@ -88,7 +88,7 @@ public: { insert(contextKey, context); } void clearContext() { remove(contextKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CompletionItem : public JsonObject @@ -220,7 +220,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CompletionList : public JsonObject @@ -240,7 +240,7 @@ public: void setItems(const QList<CompletionItem> &items) { insertArray(itemsKey, items); } void clearItems() { remove(itemsKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; /// The result of a completion is CompletionItem[] | CompletionList | null diff --git a/src/libs/languageserverprotocol/diagnostics.h b/src/libs/languageserverprotocol/diagnostics.h index 30f5081f07..24c470b2d1 100644 --- a/src/libs/languageserverprotocol/diagnostics.h +++ b/src/libs/languageserverprotocol/diagnostics.h @@ -42,7 +42,7 @@ public: void setDiagnostics(const QList<Diagnostic> &diagnostics) { insertArray(diagnosticsKey, diagnostics); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<Diagnostic>(error, diagnosticsKey); } }; diff --git a/src/libs/languageserverprotocol/icontent.h b/src/libs/languageserverprotocol/icontent.h index 1b57165b2e..f1c02f5a1a 100644 --- a/src/libs/languageserverprotocol/icontent.h +++ b/src/libs/languageserverprotocol/icontent.h @@ -26,6 +26,7 @@ #pragma once #include "basemessage.h" +#include "lsputils.h" #include <utils/mimetypes/mimetype.h> #include <utils/qtcassert.h> @@ -69,12 +70,12 @@ public: return QJsonValue(); } - bool isValid(QStringList *error = nullptr) const + bool isValid(ErrorHierarchy *error = nullptr) const { if (Utils::holds_alternative<int>(*this) || Utils::holds_alternative<QString>(*this)) return true; if (error) - error->append("Expected int or string as MessageId"); + error->setError("Expected int or string as MessageId"); return false; } diff --git a/src/libs/languageserverprotocol/initializemessages.cpp b/src/libs/languageserverprotocol/initializemessages.cpp index 92e82d5107..66e3407fe1 100644 --- a/src/libs/languageserverprotocol/initializemessages.cpp +++ b/src/libs/languageserverprotocol/initializemessages.cpp @@ -140,9 +140,9 @@ Utils::optional<Trace> InitializeParams::trace() const return Utils::make_optional(Trace(traceValue.toString())); } -bool InitializeParams::isValid(QStringList *error) const +bool InitializeParams::isValid(ErrorHierarchy *error) const { - return check<int, std::nullptr_t>(error, processIdKey) + return checkVariant<int, std::nullptr_t>(error, processIdKey) && checkOptional<QString, std::nullptr_t>(error, rootPathKey) && checkOptional<QString, std::nullptr_t>(error, rootUriKey) && check<ClientCapabilities>(error, capabilitiesKey) diff --git a/src/libs/languageserverprotocol/initializemessages.h b/src/libs/languageserverprotocol/initializemessages.h index f0eb83beb3..a79d6e067a 100644 --- a/src/libs/languageserverprotocol/initializemessages.h +++ b/src/libs/languageserverprotocol/initializemessages.h @@ -121,7 +121,7 @@ public: { insert(workSpaceFoldersKey, folders.toJson()); } void clearWorkSpaceFolders() { remove(workSpaceFoldersKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; using InitializedParams = JsonObject; @@ -147,7 +147,7 @@ public: { insert(capabilitiesKey, capabilities); } void clearCapabilities() { remove(capabilitiesKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<ServerCapabilities>(error, capabilitiesKey); } }; @@ -166,7 +166,7 @@ public: void setRetry(bool retry) { insert(retryKey, retry); } void clearRetry() { remove(retryKey); } - bool isValid(QStringList *error) const override { return checkOptional<bool>(error, retryKey); } + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, retryKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT InitializeRequest : public Request< diff --git a/src/libs/languageserverprotocol/jsonobject.cpp b/src/libs/languageserverprotocol/jsonobject.cpp index 0156276a67..7bdf3f8688 100644 --- a/src/libs/languageserverprotocol/jsonobject.cpp +++ b/src/libs/languageserverprotocol/jsonobject.cpp @@ -30,31 +30,31 @@ namespace LanguageServerProtocol { template <> -bool JsonObject::checkVal<QString>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<QString>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::String, errorHierarchy); } template <> -bool JsonObject::checkVal<int>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<int>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Double, errorHierarchy); } template <> -bool JsonObject::checkVal<double>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<double>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Double, errorHierarchy); } template <> -bool JsonObject::checkVal<bool>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<bool>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Bool, errorHierarchy); } template <> -bool JsonObject::checkVal<std::nullptr_t>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<std::nullptr_t>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Null, errorHierarchy); } template<> -bool JsonObject::checkVal<QJsonArray>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<QJsonArray>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Array, errorHierarchy); } template<> -bool JsonObject::checkVal<QJsonValue>(QStringList * /*errorHierarchy*/, const QJsonValue &/*val*/) +bool JsonObject::checkVal<QJsonValue>(ErrorHierarchy * /*errorHierarchy*/, const QJsonValue &/*val*/) { return true; } JsonObject &JsonObject::operator=(const JsonObject &other) = default; @@ -75,12 +75,12 @@ QJsonObject::iterator JsonObject::insert(const QString &key, const QJsonValue &v return m_jsonObject.insert(key, value); } -bool JsonObject::checkKey(QStringList *errorHierarchy, const QString &key, +bool JsonObject::checkKey(ErrorHierarchy *errorHierarchy, const QString &key, const std::function<bool (const QJsonValue &)> &predicate) const { const bool valid = predicate(m_jsonObject.value(key)); if (!valid && errorHierarchy) - errorHierarchy->append(key); + errorHierarchy->prependMember(key); return valid; } @@ -106,11 +106,11 @@ QString JsonObject::errorString(QJsonValue::Type expected, QJsonValue::Type actu bool JsonObject::checkType(QJsonValue::Type type, QJsonValue::Type expectedType, - QStringList *errorHierarchy) + ErrorHierarchy *errorHierarchy) { const bool ret = type == expectedType; if (!ret && errorHierarchy) - errorHierarchy->append(errorString(expectedType, type)); + errorHierarchy->setError(errorString(expectedType, type)); return ret; } diff --git a/src/libs/languageserverprotocol/jsonobject.h b/src/libs/languageserverprotocol/jsonobject.h index 3b7329881b..828a116b91 100644 --- a/src/libs/languageserverprotocol/jsonobject.h +++ b/src/libs/languageserverprotocol/jsonobject.h @@ -58,7 +58,7 @@ public: operator const QJsonObject&() const { return m_jsonObject; } - virtual bool isValid(QStringList * /*errorHierarchy*/) const { return true; } + virtual bool isValid(ErrorHierarchy * /*errorHierarchy*/) const { return true; } protected: using iterator = QJsonObject::iterator; @@ -100,27 +100,29 @@ protected: void insertArray(const QString &key, const QList<JsonObject> &array); // value checking - bool checkKey(QStringList *errorHierarchy, const QString &key, + bool checkKey(ErrorHierarchy *errorHierarchy, const QString &key, const std::function<bool(const QJsonValue &val)> &predicate) const; static QString valueTypeString(QJsonValue::Type type); static QString errorString(QJsonValue::Type expected, QJsonValue::Type type2); static bool checkType(QJsonValue::Type type, QJsonValue::Type expectedType, - QStringList *errorHierarchy); + ErrorHierarchy *errorHierarchy); template <typename T> - static bool checkVal(QStringList *errorHierarchy, const QJsonValue &val); + static bool checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val); + template <typename T> + bool check(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T1, typename T2, typename... Args> - bool check(QStringList *errorHierarchy, const QString &key) const; + bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool check(QStringList *errorHierarchy, const QString &key) const; + bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool checkArray(QStringList *errorHierarchy, const QString &key) const; + bool checkArray(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T1, typename T2, typename... Args> - bool checkOptional(QStringList *errorHierarchy, const QString &key) const; + bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool checkOptional(QStringList *errorHierarchy, const QString &key) const; + bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool checkOptionalArray(QStringList *errorHierarchy, const QString &key) const; + bool checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const; private: QJsonObject m_jsonObject; @@ -198,35 +200,51 @@ void JsonObject::insertArray(const QString &key, const QList<JsonObject> &array) } template <typename T> -bool JsonObject::checkVal(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Object, errorHierarchy) && T(val).isValid(errorHierarchy); } +template <typename T> +bool JsonObject::check(ErrorHierarchy *errorHierarchy, const QString &key) const +{ + return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val) { + return checkVal<T>(errorHierarchy, val); + }); +} + template <typename T1, typename T2, typename... Args> -bool JsonObject::check(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const { - const QStringList errorBackUp = errorHierarchy ? *errorHierarchy : QStringList(); - if (check<T1>(errorHierarchy, key)) + if (checkVariant<T1>(errorHierarchy, key)) return true; - const bool ret = check<T2, Args...>(errorHierarchy, key); - if (ret && errorHierarchy) - *errorHierarchy = errorBackUp; - return ret; + if (checkVariant<T2, Args...>(errorHierarchy, key)) { + if (errorHierarchy) + errorHierarchy->clear(); + return true; + } + errorHierarchy->setError( + QCoreApplication::translate("LanguageServerProtocol::JsonObject", + "None of the following variants could be correctly parsed:")); + return false; } template <typename T> -bool JsonObject::check(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const { - return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val){ - return checkVal<T>(errorHierarchy, val); - }); + if (!errorHierarchy) + return check<T>(nullptr, key); + ErrorHierarchy subError; + if (check<T>(&subError, key)) + return true; + errorHierarchy->addVariantHierachy(subError); + return false; } template <typename T> -bool JsonObject::checkArray(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkArray(ErrorHierarchy *errorHierarchy, const QString &key) const { return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val){ return val.isArray() && Utils::allOf(val.toArray(), [&errorHierarchy](const QJsonValue &value){ @@ -236,20 +254,27 @@ bool JsonObject::checkArray(QStringList *errorHierarchy, const QString &key) con } template <typename T1, typename T2, typename... Args> -bool JsonObject::checkOptional(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const { - const QStringList errorBackUp = errorHierarchy ? *errorHierarchy : QStringList(); - if (checkOptional<T1>(errorHierarchy, key)) + if (!contains(key)) return true; - const bool ret = checkOptional<T2, Args...>(errorHierarchy, key); - if (ret && errorHierarchy) - *errorHierarchy = errorBackUp; - return ret; + if (checkVariant<T1>(errorHierarchy, key)) + return true; + + if (checkVariant<T2, Args...>(errorHierarchy, key)) { + if (errorHierarchy) + errorHierarchy->clear(); + return true; + } + errorHierarchy->setError( + QCoreApplication::translate("LanguageServerProtocol::JsonObject", + "None of the following variants could be correctly parsed:")); + return false; } template <typename T> -bool JsonObject::checkOptional(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const { if (contains(key)) return check<T>(errorHierarchy, key); @@ -257,7 +282,7 @@ bool JsonObject::checkOptional(QStringList *errorHierarchy, const QString &key) } template <typename T> -bool JsonObject::checkOptionalArray(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const { if (contains(key)) return checkArray<T>(errorHierarchy, key); @@ -265,31 +290,31 @@ bool JsonObject::checkOptionalArray(QStringList *errorHierarchy, const QString & } template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QString>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QString>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<int>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<int>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<double>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<double>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<bool>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<bool>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<std::nullptr_t>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<std::nullptr_t>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template<> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonArray>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonArray>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template<> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonValue>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonValue>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.h b/src/libs/languageserverprotocol/jsonrpcmessages.h index 473c9fe580..4dd4f7f900 100644 --- a/src/libs/languageserverprotocol/jsonrpcmessages.h +++ b/src/libs/languageserverprotocol/jsonrpcmessages.h @@ -119,10 +119,8 @@ public: virtual bool parametersAreValid(QString *errorMessage) const { - if (auto parameter = params()) { - QStringList error; - return parameter.value().isValid(&error); - } + if (auto parameter = params()) + return parameter.value().isValid(nullptr); if (errorMessage) *errorMessage = QCoreApplication::translate("LanguageServerProtocol::Notification", "No parameters in \"%1\".").arg(method()); @@ -180,7 +178,7 @@ public: void setData(const Error &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, codeKey) && check<QString>(error, messageKey) @@ -332,12 +330,12 @@ public: MessageId id() const { return MessageId(value(idKey)); } void setId(const MessageId &id) { insert(idKey, id.toJson()); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { if (MessageId(value(idKey)).isValid(error)) return true; if (error) - error->append(idKey); + error->prependMember(idKey); return false; } }; diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index 0af50c6fc5..d76f03f0b6 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -79,7 +79,7 @@ Utils::optional<MarkupOrString> ParameterInformation::documentation() const return MarkupOrString(documentation); } -bool SignatureHelp::isValid(QStringList *error) const +bool SignatureHelp::isValid(ErrorHierarchy *error) const { return checkArray<SignatureInformation>(error, signaturesKey); } @@ -118,12 +118,12 @@ void CodeActionParams::CodeActionContext::setOnly(const QList<CodeActionKind> &o insertArray(onlyKey, only); } -bool CodeActionParams::CodeActionContext::isValid(QStringList *error) const +bool CodeActionParams::CodeActionContext::isValid(ErrorHierarchy *error) const { return checkArray<Diagnostic>(error, diagnosticsKey); } -bool CodeActionParams::isValid(QStringList *error) const +bool CodeActionParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Range>(error, rangeKey) @@ -154,7 +154,7 @@ DocumentColorRequest::DocumentColorRequest(const DocumentColorParams ¶ms) : Request(methodName, params) { } -bool Color::isValid(QStringList *error) const +bool Color::isValid(ErrorHierarchy *error) const { return check<int>(error, redKey) && check<int>(error, greenKey) @@ -162,7 +162,7 @@ bool Color::isValid(QStringList *error) const && check<int>(error, alphaKey); } -bool ColorPresentationParams::isValid(QStringList *error) const +bool ColorPresentationParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Color>(error, colorInfoKey) @@ -201,7 +201,7 @@ void FormattingOptions::setProperty(const QString &key, const DocumentFormatting insert(key, *val); } -bool FormattingOptions::isValid(QStringList *error) const +bool FormattingOptions::isValid(ErrorHierarchy *error) const { return Utils::allOf(keys(), [this, &error](auto key){ return (key == tabSizeKey && this->check<int>(error, key)) @@ -210,7 +210,7 @@ bool FormattingOptions::isValid(QStringList *error) const }); } -bool DocumentFormattingParams::isValid(QStringList *error) const +bool DocumentFormattingParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<FormattingOptions>(error, optionsKey); @@ -220,7 +220,7 @@ DocumentFormattingRequest::DocumentFormattingRequest(const DocumentFormattingPar : Request(methodName, params) { } -bool DocumentRangeFormattingParams::isValid(QStringList *error) const +bool DocumentRangeFormattingParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Range>(error, rangeKey) @@ -232,7 +232,7 @@ DocumentRangeFormattingRequest::DocumentRangeFormattingRequest( : Request(methodName, params) { } -bool DocumentOnTypeFormattingParams::isValid(QStringList *error) const +bool DocumentOnTypeFormattingParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Position>(error, positionKey) @@ -245,7 +245,7 @@ DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest( : Request(methodName, params) { } -bool RenameParams::isValid(QStringList *error) const +bool RenameParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Position>(error, positionKey) @@ -369,7 +369,7 @@ HoverContent::HoverContent(const QJsonValue &value) } } -bool HoverContent::isValid(QStringList *errorHierarchy) const +bool HoverContent::isValid(ErrorHierarchy *errorHierarchy) const { if (Utils::holds_alternative<MarkedString>(*this) || Utils::holds_alternative<MarkupContent>(*this) @@ -377,10 +377,10 @@ bool HoverContent::isValid(QStringList *errorHierarchy) const return true; } if (errorHierarchy) { - *errorHierarchy << QCoreApplication::translate( - "LanguageServerProtocol::HoverContent", - "HoverContent should be either MarkedString, " - "MarkupContent, or QList<MarkedString>."); + errorHierarchy->setError( + QCoreApplication::translate("LanguageServerProtocol::HoverContent", + "HoverContent should be either MarkedString, " + "MarkupContent, or QList<MarkedString>.")); } return false; } @@ -395,7 +395,7 @@ DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value) *this = value.toString(); } -bool DocumentFormattingProperty::isValid(QStringList *error) const +bool DocumentFormattingProperty::isValid(ErrorHierarchy *error) const { if (Utils::holds_alternative<bool>(*this) || Utils::holds_alternative<double>(*this) @@ -403,9 +403,9 @@ bool DocumentFormattingProperty::isValid(QStringList *error) const return true; } if (error) { - *error << QCoreApplication::translate( - "LanguageServerProtocol::MarkedString", - "DocumentFormattingProperty should be either bool, double, or QString."); + error->setError(QCoreApplication::translate( + "LanguageServerProtocol::MarkedString", + "DocumentFormattingProperty should be either bool, double, or QString.")); } return false; } @@ -433,7 +433,7 @@ CodeActionResult::CodeActionResult(const QJsonValue &val) emplace<std::nullptr_t>(nullptr); } -bool CodeAction::isValid(QStringList *error) const +bool CodeAction::isValid(ErrorHierarchy *error) const { return check<QString>(error, titleKey) && checkOptional<CodeActionKind>(error, codeActionKindKey) @@ -491,7 +491,7 @@ void SemanticHighlightToken::appendToByteArray(QByteArray &byteArray) const byteArray.append(char((scope & 0x00ff))); } -bool SemanticHighlightingParams::isValid(QStringList *error) const +bool SemanticHighlightingParams::isValid(ErrorHierarchy *error) const { return check<VersionedTextDocumentIdentifier>(error, textDocumentKey) && checkArray<SemanticHighlightingInformation>(error, linesKey); diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index bba54c48be..bee7cbd04f 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -54,7 +54,7 @@ public: QString value() const { return typedValue<QString>(valueKey); } void setValue(const QString &value) { insert(valueKey, value); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, languageKey) && check<QString>(error, valueKey); } }; @@ -83,7 +83,7 @@ public: explicit HoverContent(const QList<MarkedString> &other) : variant(other) {} explicit HoverContent(const MarkupContent &other) : variant(other) {} explicit HoverContent(const QJsonValue &value); - bool isValid(QStringList *errorHierarchy) const; + bool isValid(ErrorHierarchy *errorHierarchy) const; }; class LANGUAGESERVERPROTOCOL_EXPORT Hover : public JsonObject @@ -98,7 +98,7 @@ public: void setRange(const Range &range) { insert(rangeKey, range); } void clearRange() { remove(rangeKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<HoverContent>(error, contentsKey) && checkOptional<Range>(error, rangeKey); } }; @@ -128,7 +128,7 @@ public: { insert(documentationKey, documentation.toJson()); } void clearDocumentation() { remove(documentationKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, labelKey) && checkOptional<MarkupOrString>(error, documentationKey); @@ -194,7 +194,7 @@ public: void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); } void clearActiveParameter() { remove(activeParameterKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpRequest @@ -260,14 +260,14 @@ public: void setIncludeDeclaration(bool includeDeclaration) { insert(includeDeclarationKey, includeDeclaration); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, includeDeclarationKey); } }; ReferenceContext context() const { return typedValue<ReferenceContext>(contextKey); } void setContext(const ReferenceContext &context) { insert(contextKey, context); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return TextDocumentPositionParams::isValid(error) && check<ReferenceContext>(error, contextKey); } @@ -300,7 +300,7 @@ public: void setKind(int kind) { insert(kindKey, kind); } void clearKind() { remove(kindKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && checkOptional<int>(error, kindKey); } }; @@ -336,7 +336,7 @@ public: void setTextDocument(const TextDocumentIdentifier &textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<TextDocumentIdentifier>(error, textDocumentKey); } }; @@ -418,7 +418,7 @@ public: void setOnly(const QList<CodeActionKind> &only); void clearOnly() { remove(onlyKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; TextDocumentIdentifier textDocument() const @@ -432,7 +432,7 @@ public: CodeActionContext context() const { return typedValue<CodeActionContext>(contextKey); } void setContext(const CodeActionContext &context) { insert(contextKey, context); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CodeAction : public JsonObject @@ -461,7 +461,7 @@ public: void setCommand(const Command &command) { insert(commandKey, command); } void clearCommand() { remove(commandKey); } - bool isValid(QStringList *) const override; + bool isValid(ErrorHierarchy *) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CodeActionResult @@ -499,7 +499,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && checkOptional<Command>(error, commandKey); } }; @@ -537,7 +537,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && checkOptional<QString>(error, targetKey); } }; @@ -580,7 +580,7 @@ public: double alpha() const { return typedValue<double>(alphaKey); } void setAlpha(double alpha) { insert(alphaKey, alpha); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ColorInformation : public JsonObject @@ -594,7 +594,7 @@ public: Color color() const { return typedValue<Color>(colorKey); } void setColor(const Color &color) { insert(colorKey, color); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && check<Color>(error, colorKey); } }; @@ -623,7 +623,7 @@ public: Range range() const { return typedValue<Range>(rangeKey); } void setRange(const Range &range) { insert(rangeKey, range); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentation : public JsonObject @@ -644,7 +644,7 @@ public: { insertArray(additionalTextEditsKey, additionalTextEdits); } void clearAdditionalTextEdits() { remove(additionalTextEditsKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, labelKey) && checkOptional<TextEdit>(error, textEditKey) @@ -672,7 +672,7 @@ public: using variant::variant; using variant::operator=; - bool isValid(QStringList *error) const; + bool isValid(ErrorHierarchy *error) const; }; class LANGUAGESERVERPROTOCOL_EXPORT FormattingOptions : public JsonObject @@ -690,7 +690,7 @@ public: void setProperty(const QString &key, const DocumentFormattingProperty &property); void removeProperty(const QString &key) { remove(key); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingParams : public JsonObject @@ -706,7 +706,7 @@ public: FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingRequest : public Request< @@ -734,7 +734,7 @@ public: FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentRangeFormattingRequest : public Request< @@ -765,7 +765,7 @@ public: FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentOnTypeFormattingRequest : public Request< @@ -794,7 +794,7 @@ public: QString newName() const { return typedValue<QString>(newNameKey); } void setNewName(const QString &newName) { insert(newNameKey, newName); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT RenameRequest : public Request< @@ -832,7 +832,7 @@ public: void setTokens(const QList<SemanticHighlightToken> &tokens); void clearTokens() { remove(tokensKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, lineKey) && checkOptional<QString>(error, tokensKey); } }; @@ -851,7 +851,7 @@ public: void setLines(const QList<SemanticHighlightingInformation> &lines) { insertArray(linesKey, lines); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp index ac5c4224dd..2a34a53fc6 100644 --- a/src/libs/languageserverprotocol/lsptypes.cpp +++ b/src/libs/languageserverprotocol/lsptypes.cpp @@ -67,7 +67,7 @@ void Diagnostic::setCode(const Diagnostic::Code &code) insert(codeKey, *val); } -bool Diagnostic::isValid(QStringList *error) const +bool Diagnostic::isValid(ErrorHierarchy *error) const { return check<Range>(error, rangeKey) && checkOptional<int>(error, severityKey) @@ -130,13 +130,14 @@ MarkupOrString::MarkupOrString(const QJsonValue &val) } } -bool MarkupOrString::isValid(QStringList *error) const +bool MarkupOrString::isValid(ErrorHierarchy *error) const { if (Utils::holds_alternative<MarkupContent>(*this) || Utils::holds_alternative<QString>(*this)) return true; if (error) { - *error << QCoreApplication::translate("LanguageServerProtocoll::MarkupOrString", - "Expected a string or MarkupContent in MarkupOrString."); + error->setError( + QCoreApplication::translate("LanguageServerProtocoll::MarkupOrString", + "Expected a string or MarkupContent in MarkupOrString.")); } return false; } @@ -150,7 +151,7 @@ QJsonValue MarkupOrString::toJson() const return {}; } -bool SymbolInformation::isValid(QStringList *error) const +bool SymbolInformation::isValid(ErrorHierarchy *error) const { return check<QString>(error, nameKey) && check<int>(error, kindKey) @@ -158,13 +159,13 @@ bool SymbolInformation::isValid(QStringList *error) const && checkOptional<QString>(error, containerNameKey); } -bool TextDocumentEdit::isValid(QStringList *error) const +bool TextDocumentEdit::isValid(ErrorHierarchy *error) const { return check<VersionedTextDocumentIdentifier>(error, idKey) && checkArray<TextEdit>(error, editsKey); } -bool TextDocumentItem::isValid(QStringList *error) const +bool TextDocumentItem::isValid(ErrorHierarchy *error) const { return check<QString>(error, uriKey) && check<QString>(error, languageIdKey) @@ -305,7 +306,7 @@ TextDocumentPositionParams::TextDocumentPositionParams( setPosition(position); } -bool TextDocumentPositionParams::isValid(QStringList *error) const +bool TextDocumentPositionParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Position>(error, positionKey); @@ -387,7 +388,7 @@ bool DocumentFilter::applies(const Utils::FilePath &fileName, const Utils::MimeT return !contains(schemeKey) && !contains(languageKey) && !contains(patternKey); } -bool DocumentFilter::isValid(QStringList *error) const +bool DocumentFilter::isValid(ErrorHierarchy *error) const { return Utils::allOf(QStringList{languageKey, schemeKey, patternKey}, [this, &error](auto key){ return this->checkOptional<QString>(error, key); diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h index 7910f26642..fa01862d8b 100644 --- a/src/libs/languageserverprotocol/lsptypes.h +++ b/src/libs/languageserverprotocol/lsptypes.h @@ -83,7 +83,7 @@ public: int character() const { return typedValue<int>(characterKey); } void setCharacter(int character) { insert(characterKey, character); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, lineKey) && check<int>(error, characterKey); } int toPositionInDocument(QTextDocument *doc) const; @@ -115,7 +115,7 @@ public: bool contains(const Position &pos) const { return start() <= pos && pos <= end(); } bool overlaps(const Range &range) const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Position>(error, startKey) && check<Position>(error, endKey); } }; @@ -133,7 +133,7 @@ public: Utils::Link toLink() const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey) && check<Range>(error, rangeKey); } }; @@ -180,7 +180,7 @@ public: { return typedValue<QString>(messageKey); } void setMessage(const QString &message) { insert(messageKey, message); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT Command : public JsonObject @@ -203,7 +203,7 @@ public: void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void clearArguments() { remove(argumentsKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, titleKey) && check<QString>(error, commandKey) && checkOptional<QJsonArray>(error, argumentsKey); } @@ -225,7 +225,7 @@ public: Utils::Text::Replacement toReplacement(QTextDocument *document) const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && check<QString>(error, newTextKey); } }; @@ -240,7 +240,7 @@ public: DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue<QString>(uriKey)); } void setUri(const DocumentUri &uri) { insert(uriKey, uri); } - bool isValid(QStringList *error) const override { return check<QString>(error, uriKey); } + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT VersionedTextDocumentIdentifier : public TextDocumentIdentifier @@ -258,8 +258,11 @@ public: LanguageClientValue<int> version() const { return clientValue<int>(versionKey); } void setVersion(LanguageClientValue<int> version) { insert(versionKey, version); } - bool isValid(QStringList *error) const override - { return TextDocumentIdentifier::isValid(error) && check<int, std::nullptr_t>(error, versionKey); } + bool isValid(ErrorHierarchy *error) const override + { + return TextDocumentIdentifier::isValid(error) + && checkVariant<int, std::nullptr_t>(error, versionKey); + } }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentEdit : public JsonObject @@ -276,7 +279,7 @@ public: QList<TextEdit> edits() const { return array<TextEdit>(editsKey); } void setEdits(const QList<TextEdit> edits) { insertArray(editsKey, edits); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceEdit : public JsonObject @@ -303,7 +306,7 @@ public: void setDocumentChanges(const QList<TextDocumentEdit> &changes) { insertArray(changesKey, changes); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<TextDocumentEdit>(error, documentChangesKey); } }; @@ -330,7 +333,7 @@ public: QString text() const { return typedValue<QString>(textKey); } void setText(const QString &text) { insert(textKey, text); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; static QString mimeTypeToLanguageId(const Utils::MimeType &mimeType); static QString mimeTypeToLanguageId(const QString &mimeTypeName); @@ -352,7 +355,7 @@ public: Position position() const { return typedValue<Position>(positionKey); } void setPosition(const Position &position) { insert(positionKey, position); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFilter : public JsonObject @@ -378,7 +381,7 @@ public: bool applies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType = Utils::MimeType()) const; - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT MarkupKind @@ -414,7 +417,7 @@ public: QString content() const { return typedValue<QString>(contentKey); } void setContent(const QString &content) { insert(contentKey, content); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<MarkupKind>(error, kindKey) && check<QString>(error, contentKey); } }; @@ -427,7 +430,7 @@ public: explicit MarkupOrString(const MarkupContent &val); MarkupOrString(const QJsonValue &val); - bool isValid(QStringList *error) const; + bool isValid(ErrorHierarchy *error) const; QJsonValue toJson() const; }; @@ -447,7 +450,7 @@ public: QString name() const { return typedValue<QString>(nameKey); } void setName(const QString &name) { insert(nameKey, name); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey) && check<QString>(error, nameKey); } }; @@ -474,7 +477,7 @@ public: void setContainerName(const QString &containerName) { insert(containerNameKey, containerName); } void clearContainerName() { remove(containerNameKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentSymbol : public JsonObject diff --git a/src/libs/languageserverprotocol/lsputils.cpp b/src/libs/languageserverprotocol/lsputils.cpp index aceeed7392..ecb78129cc 100644 --- a/src/libs/languageserverprotocol/lsputils.cpp +++ b/src/libs/languageserverprotocol/lsputils.cpp @@ -75,4 +75,34 @@ QJsonArray fromJsonValue<QJsonArray>(const QJsonValue &value) return value.toArray(); } +void ErrorHierarchy::clear() +{ + m_hierarchy.clear(); + m_children.clear(); + m_error.clear(); +} + +bool ErrorHierarchy::isEmpty() const +{ + return m_hierarchy.isEmpty() && m_children.isEmpty() && m_error.isEmpty(); +} + +QString ErrorHierarchy::toString() const +{ + if (m_error.isEmpty() && m_hierarchy.isEmpty()) + return {}; + QString error = m_hierarchy.join(" > ") + ": " + m_error; + if (!m_children.isEmpty()) { + error.append("\n\t"); + error.append(Utils::transform(m_children, &ErrorHierarchy::toString).join("\n\t")); + } + return error; +} + +bool ErrorHierarchy::operator==(const ErrorHierarchy &other) const +{ + return m_hierarchy == other.m_hierarchy && m_children == other.m_children + && m_error == other.m_error; +} + } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/lsputils.h b/src/libs/languageserverprotocol/lsputils.h index 4646f181e9..8da5fdd93a 100644 --- a/src/libs/languageserverprotocol/lsputils.h +++ b/src/libs/languageserverprotocol/lsputils.h @@ -165,4 +165,24 @@ QList<T> jsonArrayToList(const QJsonArray &array) return list; } +class LANGUAGESERVERPROTOCOL_EXPORT ErrorHierarchy +{ +public: + ErrorHierarchy() = default; + + void setError(const QString &error) { m_error = error; } + void prependMember(const QString &member) { m_hierarchy.prepend(member); } + void addVariantHierachy(const ErrorHierarchy &subError) { m_children.append(subError); } + void clear(); + + bool isEmpty() const; + QString toString() const; + + bool operator==(const ErrorHierarchy &other) const; +private: + QStringList m_hierarchy; + QList<ErrorHierarchy> m_children; + QString m_error; +}; + } // namespace LanguageClient diff --git a/src/libs/languageserverprotocol/messages.cpp b/src/libs/languageserverprotocol/messages.cpp index 6e02e5180e..149428b01a 100644 --- a/src/libs/languageserverprotocol/messages.cpp +++ b/src/libs/languageserverprotocol/messages.cpp @@ -50,7 +50,7 @@ TelemetryNotification::TelemetryNotification() : Notification(methodName) { } -bool ShowMessageRequestParams::isValid(QStringList *error) const +bool ShowMessageRequestParams::isValid(ErrorHierarchy *error) const { return ShowMessageParams::isValid(error) && checkOptionalArray<MessageActionItem>(error, actionsKey); diff --git a/src/libs/languageserverprotocol/messages.h b/src/libs/languageserverprotocol/messages.h index 1285ea82a9..0672ad2cc7 100644 --- a/src/libs/languageserverprotocol/messages.h +++ b/src/libs/languageserverprotocol/messages.h @@ -49,7 +49,7 @@ public: QString toString() const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, typeKey) && check<QString>(error, messageKey); } }; @@ -70,7 +70,7 @@ public: QString title() const { return typedValue<QString>(titleKey); } void setTitle(QString title) { insert(titleKey, title); } - bool isValid(QStringList *error) const override { return check<QString>(error, titleKey); } + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, titleKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequestParams : public ShowMessageParams @@ -83,7 +83,7 @@ public: void setActions(const QList<MessageActionItem> &actions) { insertArray(actionsKey, actions); } void clearActions() { remove(actionsKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequest : public Request< diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp index a000ad2c89..5d4574e64b 100644 --- a/src/libs/languageserverprotocol/servercapabilities.cpp +++ b/src/libs/languageserverprotocol/servercapabilities.cpp @@ -149,7 +149,7 @@ void ServerCapabilities::setColorProvider(Utils::variant<bool, JsonObject> color insert(renameProviderKey, Utils::get<JsonObject>(colorProvider)); } -bool ServerCapabilities::isValid(QStringList *error) const +bool ServerCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<TextDocumentSyncOptions, int>(error, textDocumentSyncKey) && checkOptional<bool>(error, hoverProviderKey) @@ -194,7 +194,7 @@ void ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabiliti insert(changeNotificationsKey, *val); } -bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::isValid(QStringList *error) const +bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<bool>(error, supportedKey) && checkOptional<QString, bool>(error, changeNotificationsKey); @@ -211,7 +211,7 @@ bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileN }); } -bool TextDocumentSyncOptions::isValid(QStringList *error) const +bool TextDocumentSyncOptions::isValid(ErrorHierarchy *error) const { return checkOptional<bool>(error, openCloseKey) && checkOptional<int>(error, changeKey) @@ -252,7 +252,7 @@ void ServerCapabilities::SemanticHighlightingServerCapabilities::setScopes( insert(scopesKey, jsonScopes); } -bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(QStringList *) const +bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(ErrorHierarchy *) const { return contains(scopesKey) && value(scopesKey).isArray() && Utils::allOf(value(scopesKey).toArray(), [](const QJsonValue &array) { diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h index 7365449b0f..5e7d67ea91 100644 --- a/src/libs/languageserverprotocol/servercapabilities.h +++ b/src/libs/languageserverprotocol/servercapabilities.h @@ -38,7 +38,7 @@ public: void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); } void clearResolveProvider() { remove(resolveProviderKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, resolveProviderKey); } }; @@ -55,7 +55,7 @@ public: bool filterApplies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType = Utils::MimeType()) const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<DocumentFilter>(error, documentSelectorKey); } }; @@ -69,7 +69,7 @@ public: void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void clearIncludeText() { remove(includeTextKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, includeTextKey); } }; @@ -106,7 +106,7 @@ public: void setSave(const SaveOptions &save) { insert(saveKey, save); } void clearSave() { remove(saveKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; enum class TextDocumentSyncKind @@ -129,7 +129,7 @@ public: void setCodeActionKinds(const QList<QString> &codeActionKinds) { insertArray(codeActionKindsKey, codeActionKinds); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<QString>(error, codeActionKindsKey); } }; @@ -152,7 +152,7 @@ public: { insertArray(triggerCharactersKey, triggerCharacters); } void clearTriggerCharacters() { remove(triggerCharactersKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<QString>(error, triggerCharactersKey); } }; @@ -188,7 +188,7 @@ public: { insertArray(moreTriggerCharacterKey, moreTriggerCharacter); } void clearMoreTriggerCharacter() { remove(moreTriggerCharacterKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, firstTriggerCharacterKey) && checkOptionalArray<QString>(error, moreTriggerCharacterKey); @@ -205,7 +205,7 @@ public: QList<QString> commands() const { return array<QString>(commandsKey); } void setCommands(const QList<QString> &commands) { insertArray(commandsKey, commands); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<QString>(error, commandsKey); } }; @@ -231,7 +231,7 @@ public: Utils::optional<QList<QList<QString>>> scopes() const; void setScopes(const QList<QList<QString>> &scopes); - bool isValid(QStringList *) const override; + bool isValid(ErrorHierarchy *) const override; }; // Defines how text documents are synced. Is either a detailed structure defining each @@ -288,7 +288,7 @@ public: void setId(const QString &id) { insert(idKey, id); } void clearId() { remove(idKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<DocumentFilter>(error, documentSelectorKey) && checkOptional<bool>(error, idKey); } }; @@ -367,7 +367,7 @@ public: void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); } void clearPrepareProvider() { remove(prepareProviderKey); } - bool isValid(QStringList * error) const override + bool isValid(ErrorHierarchy * error) const override { return checkOptional<bool>(error, prepareProviderKey); } }; @@ -414,7 +414,7 @@ public: void setChangeNotifications(Utils::variant<QString, bool> changeNotifications); void clearChangeNotifications() { remove(changeNotificationsKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; Utils::optional<WorkspaceFoldersCapabilities> workspaceFolders() const @@ -440,7 +440,7 @@ public: { insert(semanticHighlightingKey, semanticHighlighting); } void clearSemanticHighlighting() { remove(semanticHighlightingKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; } // namespace LanguageClient diff --git a/src/libs/languageserverprotocol/textsynchronization.cpp b/src/libs/languageserverprotocol/textsynchronization.cpp index e352921fba..a8760eeae5 100644 --- a/src/libs/languageserverprotocol/textsynchronization.cpp +++ b/src/libs/languageserverprotocol/textsynchronization.cpp @@ -74,7 +74,7 @@ DidChangeTextDocumentParams::DidChangeTextDocumentParams( setContentChanges({text}); } -bool DidChangeTextDocumentParams::isValid(QStringList *error) const +bool DidChangeTextDocumentParams::isValid(ErrorHierarchy *error) const { return check<VersionedTextDocumentIdentifier>(error, textDocumentKey) && checkArray<TextDocumentContentChangeEvent>(error, contentChangesKey); @@ -96,7 +96,7 @@ DidChangeTextDocumentParams::TextDocumentContentChangeEvent::TextDocumentContent setText(text); } -bool DidChangeTextDocumentParams::TextDocumentContentChangeEvent::isValid(QStringList *error) const +bool DidChangeTextDocumentParams::TextDocumentContentChangeEvent::isValid(ErrorHierarchy *error) const { return checkOptional<Range>(error, rangeKey) && checkOptional<int>(error, rangeLengthKey) @@ -108,7 +108,7 @@ DidSaveTextDocumentParams::DidSaveTextDocumentParams(const TextDocumentIdentifie setTextDocument(document); } -bool DidSaveTextDocumentParams::isValid(QStringList *error) const +bool DidSaveTextDocumentParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && checkOptional<QString>(error, textKey); @@ -122,13 +122,13 @@ WillSaveTextDocumentParams::WillSaveTextDocumentParams( setReason(reason); } -bool WillSaveTextDocumentParams::isValid(QStringList *error) const +bool WillSaveTextDocumentParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<int>(error, reasonKey); } -bool TextDocumentSaveRegistrationOptions::isValid(QStringList *error) const +bool TextDocumentSaveRegistrationOptions::isValid(ErrorHierarchy *error) const { return TextDocumentRegistrationOptions::isValid(error) && checkOptional<bool>(error, includeTextKey); diff --git a/src/libs/languageserverprotocol/textsynchronization.h b/src/libs/languageserverprotocol/textsynchronization.h index fa81cae51a..dbb3311ad9 100644 --- a/src/libs/languageserverprotocol/textsynchronization.h +++ b/src/libs/languageserverprotocol/textsynchronization.h @@ -40,7 +40,7 @@ public: TextDocumentItem textDocument() const { return typedValue<TextDocumentItem>(textDocumentKey); } void setTextDocument(TextDocumentItem textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<TextDocumentItem>(error, textDocumentKey); } }; @@ -67,7 +67,7 @@ public: void setSyncKind(TextDocumentSyncKind syncKind) { insert(syncKindKey, static_cast<int>(syncKind)); } - bool isValid(QStringList *error) const override { return check<int>(error, syncKindKey); } + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, syncKindKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentParams : public JsonObject @@ -108,7 +108,7 @@ public: QString text() const { return typedValue<QString>(textKey); } void setText(const QString &text) { insert(textKey, text); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; QList<TextDocumentContentChangeEvent> contentChanges() const @@ -116,7 +116,7 @@ public: void setContentChanges(const QList<TextDocumentContentChangeEvent> &contentChanges) { insertArray(contentChangesKey, contentChanges); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentNotification : public Notification< @@ -151,7 +151,7 @@ public: { return static_cast<TextDocumentSaveReason>(typedValue<int>(reasonKey)); } void setReason(TextDocumentSaveReason reason) { insert(reasonKey, static_cast<int>(reason)); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WillSaveTextDocumentNotification : public Notification< @@ -184,7 +184,7 @@ public: void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void clearIncludeText() { remove(includeTextKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentParams : public JsonObject @@ -203,7 +203,7 @@ public: void setText(const QString &text) { insert(textKey, text); } void clearText() { remove(textKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentNotification : public Notification< @@ -228,7 +228,7 @@ public: void setTextDocument(const TextDocumentIdentifier &textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<TextDocumentIdentifier>(error, textDocumentKey); } }; diff --git a/src/libs/languageserverprotocol/workspace.cpp b/src/libs/languageserverprotocol/workspace.cpp index e411878877..28af2cbafc 100644 --- a/src/libs/languageserverprotocol/workspace.cpp +++ b/src/libs/languageserverprotocol/workspace.cpp @@ -66,23 +66,24 @@ ApplyWorkspaceEditRequest::ApplyWorkspaceEditRequest(const ApplyWorkspaceEditPar : Request(methodName, params) { } -bool WorkspaceFoldersChangeEvent::isValid(QStringList *error) const +bool WorkspaceFoldersChangeEvent::isValid(ErrorHierarchy *error) const { return checkArray<WorkSpaceFolder>(error, addedKey) && checkArray<WorkSpaceFolder>(error, removedKey); } -bool ConfigurationParams::ConfigureationItem::isValid(QStringList *error) const +bool ConfigurationParams::ConfigureationItem::isValid(ErrorHierarchy *error) const { return checkOptional<QString>(error, scopeUriKey) && checkOptional<QString>(error, sectionKey); } -bool DidChangeConfigurationParams::isValid(QStringList *error) const +bool DidChangeConfigurationParams::isValid(ErrorHierarchy *error) const { if (contains(settingsKey)) return true; - *error << settingsKey; + if (error) + error->prependMember(settingsKey); return false; } diff --git a/src/libs/languageserverprotocol/workspace.h b/src/libs/languageserverprotocol/workspace.h index bf6a1b9096..dccd0c361a 100644 --- a/src/libs/languageserverprotocol/workspace.h +++ b/src/libs/languageserverprotocol/workspace.h @@ -60,7 +60,7 @@ public: QList<WorkSpaceFolder> removed() const { return array<WorkSpaceFolder>(removedKey); } void setRemoved(const QList<WorkSpaceFolder> &removed) { insertArray(removedKey, removed); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersParams : public JsonObject @@ -72,7 +72,7 @@ public: { return typedValue<WorkspaceFoldersChangeEvent>(eventKey); } void setEvent(const WorkspaceFoldersChangeEvent &event) { insert(eventKey, event); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<WorkspaceFoldersChangeEvent>(error, eventKey); } }; @@ -94,7 +94,7 @@ public: QJsonValue settings() const { return typedValue<QJsonValue>(settingsKey); } void setSettings(QJsonValue settings) { insert(settingsKey, settings); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeConfigurationNotification : public Notification< @@ -124,13 +124,13 @@ public: void setSection(const QString §ion) { insert(sectionKey, section); } void clearSection() { remove(sectionKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; QList<ConfigureationItem> items() const { return array<ConfigureationItem>(itemsKey); } void setItems(const QList<ConfigureationItem> &items) { insertArray(itemsKey, items); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<ConfigureationItem>(error, itemsKey); } }; @@ -165,14 +165,14 @@ public: Deleted = 3 }; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey) && check<int>(error, typeKey); } }; QList<FileEvent> changes() const { return array<FileEvent>(changesKey); } void setChanges(const QList<FileEvent> &changes) { insertArray(changesKey, changes); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<FileEvent>(error, changesKey); } }; @@ -193,7 +193,7 @@ public: QString query() const { return typedValue<QString>(queryKey); } void setQuery(const QString &query) { insert(queryKey, query); } - bool isValid(QStringList *error) const override { return check<QString>(error, queryKey); } + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, queryKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceSymbolRequest : public Request< @@ -220,7 +220,7 @@ public: void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void clearArguments() { remove(argumentsKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, commandKey) && checkOptionalArray<QJsonValue>(error, argumentsKey); @@ -248,7 +248,7 @@ public: WorkspaceEdit edit() const { return typedValue<WorkspaceEdit>(editKey); } void setEdit(const WorkspaceEdit &edit) { insert(editKey, edit); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<WorkspaceEdit>(error, editKey) && checkOptional<QString>(error, labelKey); } }; @@ -260,7 +260,7 @@ public: bool applied() const { return typedValue<bool>(appliedKey); } void setApplied(bool applied) { insert(appliedKey, applied); } - bool isValid(QStringList *error) const override { return check<bool>(error, appliedKey); } + bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, appliedKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditRequest : public Request< diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 50e743f71a..a55020f4d5 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -1054,7 +1054,7 @@ void Client::handleResponse(const MessageId &id, const QByteArray &content, QTex void Client::handleMethod(const QString &method, MessageId id, const IContent *content) { - QStringList error; + ErrorHierarchy error; bool paramsValid = true; if (method == PublishDiagnosticsNotification::methodName) { auto params = dynamic_cast<const PublishDiagnosticsNotification *>(content)->params().value_or(PublishDiagnosticsParams()); @@ -1130,9 +1130,8 @@ void Client::handleMethod(const QString &method, MessageId id, const IContent *c response.setError(error); sendContent(response); } - std::reverse(error.begin(), error.end()); if (!paramsValid) { - log(tr("Invalid parameter in \"%1\": %2").arg(method, error.join("->")), + log(tr("Invalid parameter in \"%1\": %2").arg(method, error.toString()), Core::MessageManager::Flash); } delete content; @@ -1210,11 +1209,9 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse) log(tr("No initialize result.")); } else { const InitializeResult &result = _result.value(); - QStringList error; - if (!result.isValid(&error)) { // continue on ill formed result - std::reverse(error.begin(), error.end()); - log(tr("Initialize result is not valid: ") + error.join("->")); - } + ErrorHierarchy error; + if (!result.isValid(&error)) // continue on ill formed result + log(tr("Initialize result is not valid: ") + error.toString()); m_serverCapabilities = result.capabilities().value_or(ServerCapabilities()); } diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp index 4efbacce88..cd2bdfd0d5 100644 --- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp +++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp @@ -570,13 +570,19 @@ void tst_LanguageServerProtocol::jsonObject() QCOMPARE(obj.optionalClientArray<QString>("strings").value().toList(), QList<QString>({"foo", "bar"})); - QStringList errorHierarchy; + ErrorHierarchy errorHierarchy; QVERIFY(!obj.check<int>(&errorHierarchy, "doesNotExist")); - QCOMPARE(errorHierarchy, QStringList({obj.errorString(QJsonValue::Double, QJsonValue::Undefined), "doesNotExist"})); + ErrorHierarchy errorDoesNotExists; + errorDoesNotExists.setError(obj.errorString(QJsonValue::Double, QJsonValue::Undefined)); + errorDoesNotExists.prependMember("doesNotExist"); + QCOMPARE(errorHierarchy, errorDoesNotExists); errorHierarchy.clear(); QVERIFY(!obj.check<int>(&errorHierarchy, "bool")); - QCOMPARE(errorHierarchy, QStringList({obj.errorString(QJsonValue::Double, QJsonValue::Bool), "bool"})); + ErrorHierarchy errorWrongType; + errorWrongType.setError(obj.errorString(QJsonValue::Double, QJsonValue::Bool)); + errorWrongType.prependMember("bool"); + QCOMPARE(errorHierarchy, errorWrongType); errorHierarchy.clear(); QVERIFY(obj.check<int>(&errorHierarchy, "integer")); |