From d17277b5466ced5c39e615efcc7820be47d770f4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 26 Feb 2021 08:29:15 +0100 Subject: [PATCH] LSP: reduce error handling complexity Instead of checking recursively every possible object just check the required keys for an object and validate it on construction or assignment from json. This will reduce the implementation effort for protocol extensions and also reduce the false positives we might get if the protocol gets updated. Change-Id: I3df24e62430d2c7575d26c1581e6a9606e7da4c1 Reviewed-by: hjk Reviewed-by: Christian Stenger --- src/libs/languageserverprotocol/client.h | 12 +- .../clientcapabilities.cpp | 87 ---------- .../clientcapabilities.h | 51 +----- .../languageserverprotocol/completion.cpp | 30 +--- src/libs/languageserverprotocol/completion.h | 12 +- src/libs/languageserverprotocol/diagnostics.h | 3 +- src/libs/languageserverprotocol/icontent.h | 11 +- .../initializemessages.cpp | 19 +-- .../initializemessages.h | 11 +- .../languageserverprotocol/jsonobject.cpp | 67 -------- src/libs/languageserverprotocol/jsonobject.h | 145 +---------------- .../languageserverprotocol/jsonrpcmessages.h | 26 +-- .../languagefeatures.cpp | 153 ++++-------------- .../languageserverprotocol/languagefeatures.h | 90 ++++------- src/libs/languageserverprotocol/lsptypes.cpp | 65 +------- src/libs/languageserverprotocol/lsptypes.h | 55 +++---- src/libs/languageserverprotocol/lsputils.cpp | 32 +--- src/libs/languageserverprotocol/lsputils.h | 33 ++-- src/libs/languageserverprotocol/messages.cpp | 6 - src/libs/languageserverprotocol/messages.h | 8 +- .../servercapabilities.cpp | 72 +-------- .../servercapabilities.h | 39 +---- .../textsynchronization.cpp | 31 ---- .../textsynchronization.h | 20 +-- src/libs/languageserverprotocol/workspace.cpp | 21 --- src/libs/languageserverprotocol/workspace.h | 33 ++-- src/plugins/android/javalanguageserver.cpp | 2 +- src/plugins/languageclient/client.cpp | 46 +++--- .../languageclientcompletionassist.cpp | 2 +- .../languageclientformatter.cpp | 2 +- .../languageclienthoverhandler.cpp | 2 +- .../languageclient/languageclientoutline.cpp | 2 +- .../languageclientsymbolsupport.cpp | 6 +- .../languageclient/languageclientutils.cpp | 2 +- .../tst_languageserverprotocol.cpp | 123 -------------- 35 files changed, 215 insertions(+), 1104 deletions(-) diff --git a/src/libs/languageserverprotocol/client.h b/src/libs/languageserverprotocol/client.h index 4c04c2a90e8..67e5b755549 100644 --- a/src/libs/languageserverprotocol/client.h +++ b/src/libs/languageserverprotocol/client.h @@ -50,8 +50,7 @@ public: void setRegisterOptions(const QJsonValue ®isterOptions) { insert(registerOptionsKey, registerOptions); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, idKey) && check(error, methodKey); } + bool isValid() const override { return contains(idKey) && contains(methodKey); } }; class RegistrationParams : public JsonObject @@ -66,8 +65,7 @@ public: void setRegistrations(const QList ®istrations) { insertArray(registrationsKey, registrations); } - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, registrationsKey); } + bool isValid() const override { return contains(registrationsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT RegisterCapabilityRequest : public Request< @@ -90,8 +88,7 @@ public: QString method() const { return typedValue(methodKey); } void setMethod(const QString &method) { insert(methodKey, method); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, idKey) && check(error, methodKey); } + bool isValid() const override { return contains(idKey) && contains(methodKey); } }; class UnregistrationParams : public JsonObject @@ -104,8 +101,7 @@ public: void setUnregistrations(const QList &unregistrations) { insertArray(unregistrationsKey, unregistrations); } - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, unregistrationsKey); } + bool isValid() const override { return contains(unregistrationsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT UnregisterCapabilityRequest : public Request< diff --git a/src/libs/languageserverprotocol/clientcapabilities.cpp b/src/libs/languageserverprotocol/clientcapabilities.cpp index 4ee6d741665..c174f54c9cd 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.cpp +++ b/src/libs/languageserverprotocol/clientcapabilities.cpp @@ -42,96 +42,9 @@ void SymbolCapabilities::SymbolKindCapabilities::setValueSet(const QList(valueSet)); } -bool ClientCapabilities::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, workspaceKey) - && checkOptional(error, textDocumentKey); -} - WorkspaceClientCapabilities::WorkspaceClientCapabilities() { setWorkspaceFolders(true); } -bool WorkspaceClientCapabilities::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error,applyEditKey) - && checkOptional(error,workspaceEditKey) - && checkOptional(error,didChangeConfigurationKey) - && checkOptional(error,didChangeWatchedFilesKey) - && checkOptional(error,symbolKey) - && checkOptional(error,executeCommandKey) - && checkOptional(error,workspaceFoldersKey) - && checkOptional(error,configurationKey); -} - -bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(ErrorHierarchy *error) const -{ - return DynamicRegistrationCapabilities::isValid(error) - && checkOptional(error, willSaveKey) - && checkOptional(error, willSaveWaitUntilKey) - && checkOptional(error, didSaveKey); -} - -bool TextDocumentClientCapabilities::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, synchronizationKey) - && checkOptional(error, completionKey) - && checkOptional(error, hoverKey) - && checkOptional(error, signatureHelpKey) - && checkOptional(error, referencesKey) - && checkOptional(error, documentHighlightKey) - && checkOptional(error, documentSymbolKey) - && checkOptional(error, formattingKey) - && checkOptional(error, rangeFormattingKey) - && checkOptional(error, onTypeFormattingKey) - && checkOptional(error, definitionKey) - && checkOptional(error, typeDefinitionKey) - && checkOptional(error, implementationKey) - && checkOptional(error, codeActionKey) - && checkOptional(error, codeLensKey) - && checkOptional(error, documentLinkKey) - && checkOptional(error, colorProviderKey) - && checkOptional(error, renameKey) - && checkOptional(error, semanticHighlightingCapabilitiesKey); -} - -bool SymbolCapabilities::isValid(ErrorHierarchy *error) const -{ - return DynamicRegistrationCapabilities::isValid(error) - && checkOptional(error, symbolKindKey); -} - -bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(ErrorHierarchy *error) const -{ - return DynamicRegistrationCapabilities::isValid(error) - && checkOptional(error, completionItemKey) - && checkOptional(error, completionItemKindKey) - && checkOptional(error, contextSupportKey); -} - -bool TextDocumentClientCapabilities::HoverCapabilities::isValid(ErrorHierarchy *error) const -{ - return DynamicRegistrationCapabilities::isValid(error) - && checkOptionalArray(error, contentFormatKey); -} - -bool TextDocumentClientCapabilities::SignatureHelpCapabilities::isValid(ErrorHierarchy *error) const -{ - return DynamicRegistrationCapabilities::isValid(error) - && checkOptional(error, signatureInformationKey); -} - -bool TextDocumentClientCapabilities::CodeActionCapabilities::isValid(ErrorHierarchy *errorHierarchy) const -{ - return DynamicRegistrationCapabilities::isValid(errorHierarchy) - && checkOptional(errorHierarchy, codeActionLiteralSupportKey); -} - -bool TextDocumentClientCapabilities::RenameClientCapabilities::isValid(ErrorHierarchy *error) const -{ - return DynamicRegistrationCapabilities::isValid(error) - && checkOptional(error, prepareSupportKey); -} - } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h index 14490ae6ad1..b367d7af3f9 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.h +++ b/src/libs/languageserverprotocol/clientcapabilities.h @@ -38,9 +38,6 @@ public: Utils::optional dynamicRegistration() const { return optionalValue(dynamicRegistrationKey); } void setDynamicRegistration(bool dynamicRegistration) { insert(dynamicRegistrationKey, dynamicRegistration); } void clearDynamicRegistration() { remove(dynamicRegistrationKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptional(error, dynamicRegistrationKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT SymbolCapabilities : public DynamicRegistrationCapabilities @@ -66,9 +63,6 @@ public: Utils::optional> valueSet() const; void setValueSet(const QList &valueSet); void clearValueSet() { remove(valueSetKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptionalArray(error, valueSetKey); } }; // Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. @@ -76,8 +70,6 @@ public: { return optionalValue(symbolKindKey); } void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); } void clearSymbolKind() { remove(symbolKindKey); } - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentClientCapabilities : public JsonObject @@ -110,8 +102,6 @@ public: Utils::optional didSave() const { return optionalValue(didSaveKey); } void setDidSave(bool didSave) { insert(didSaveKey, didSave); } void clearDidSave() { remove(didSaveKey); } - - bool isValid(ErrorHierarchy *error) const override; }; Utils::optional synchronization() const @@ -129,8 +119,7 @@ public: void setSemanticHighlighting(bool semanticHighlighting) { insert(semanticHighlightingKey, semanticHighlighting); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, semanticHighlightingKey); } + bool isValid() const override { return contains(semanticHighlightingKey); } }; Utils::optional semanticHighlightingCapabilities() const @@ -178,13 +167,6 @@ public: Utils::optional> documentationFormat() const; void setDocumentationFormat(const QList &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } - - bool isValid(ErrorHierarchy *error) const override - { - return checkOptional(error, snippetSupportKey) - && checkOptional(error, commitCharacterSupportKey) - && checkOptionalArray(error, documentationFormatKey); - } }; // The client supports the following `CompletionItem` specific capabilities. @@ -212,9 +194,6 @@ public: Utils::optional> valueSet() const; void setValueSet(const QList &valueSet); void clearValueSet() { remove(valueSetKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptionalArray(error, valueSetKey); } }; Utils::optional completionItemKind() const @@ -230,8 +209,6 @@ public: Utils::optional contextSupport() const { return optionalValue(contextSupportKey); } void setContextSupport(bool contextSupport) { insert(contextSupportKey, contextSupport); } void clearContextSupport() { remove(contextSupportKey); } - - bool isValid(ErrorHierarchy *error) const override; }; // Capabilities specific to the `textDocument/completion` @@ -252,8 +229,6 @@ public: Utils::optional> contentFormat() const; void setContentFormat(const QList &contentFormat); void clearContentFormat() { remove(contentFormatKey); } - - bool isValid(ErrorHierarchy *error) const override; }; Utils::optional hover() const { return optionalValue(hoverKey); } @@ -276,9 +251,6 @@ public: Utils::optional> documentationFormat() const; void setDocumentationFormat(const QList &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptionalArray(error, documentationFormatKey); } }; // The client supports the following `SignatureInformation` specific properties. @@ -287,8 +259,6 @@ public: void setSignatureInformation(const SignatureInformationCapabilities &signatureInformation) { insert(signatureInformationKey, signatureInformation); } void clearSignatureInformation() { remove(signatureInformationKey); } - - bool isValid(ErrorHierarchy *error) const override; }; // Capabilities specific to the `textDocument/signatureHelp` @@ -390,8 +360,7 @@ public: void setValueSet(const QList &valueSet) { insertArray(valueSetKey, valueSet); } - bool isValid(ErrorHierarchy *errorHierarchy) const override - { return checkArray(errorHierarchy, valueSetKey); } + bool isValid() const override { return contains(valueSetKey); } }; CodeActionKind codeActionKind() const @@ -399,8 +368,7 @@ public: void setCodeActionKind(const CodeActionKind &codeActionKind) { insert(codeActionKindKey, codeActionKind); } - bool isValid(ErrorHierarchy *errorHierarchy) const override - { return check(errorHierarchy, codeActionKindKey); } + bool isValid() const override { return contains(codeActionKindKey); } }; Utils::optional codeActionLiteralSupport() const @@ -408,8 +376,6 @@ public: void setCodeActionLiteralSupport(const CodeActionLiteralSupport &codeActionLiteralSupport) { insert(codeActionLiteralSupportKey, codeActionLiteralSupport); } void clearCodeActionLiteralSupport() { remove(codeActionLiteralSupportKey); } - - bool isValid(ErrorHierarchy *errorHierarchy) const override; }; // Whether code action supports dynamic registration. @@ -458,8 +424,6 @@ public: Utils::optional prepareSupport() const { return optionalValue(prepareSupportKey); } void setPrepareSupport(bool prepareSupport) { insert(prepareSupportKey, prepareSupport); } void clearPrepareSupport() { remove(prepareSupportKey); } - - bool isValid(ErrorHierarchy *error) const override; }; // Whether rename supports dynamic registration. @@ -468,8 +432,6 @@ public: void setRename(const RenameClientCapabilities &rename) { insert(renameKey, rename); } void clearRename() { remove(renameKey); } - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject @@ -497,9 +459,6 @@ public: void setDocumentChanges(bool documentChanges) { insert(documentChangesKey, documentChanges); } void clearDocumentChanges() { remove(documentChangesKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptional(error, documentChangesKey); } }; // Capabilities specific to `WorkspaceEdit`s @@ -547,8 +506,6 @@ public: Utils::optional configuration() const { return optionalValue(configurationKey); } void setConfiguration(bool configuration) { insert(configurationKey, configuration); } void clearConfiguration() { remove(configurationKey); } - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject @@ -574,8 +531,6 @@ public: QJsonValue experimental() const { return value(experimentalKey); } void setExperimental(const QJsonValue &experimental) { insert(experimentalKey, experimental); } void clearExperimental() { remove(experimentalKey); } - - bool isValid(ErrorHierarchy *error) const override; }; } diff --git a/src/libs/languageserverprotocol/completion.cpp b/src/libs/languageserverprotocol/completion.cpp index ca34629805a..70c813a4ea2 100644 --- a/src/libs/languageserverprotocol/completion.cpp +++ b/src/libs/languageserverprotocol/completion.cpp @@ -49,40 +49,12 @@ Utils::optional CompletionItem::insertTextForm : Utils::make_optional(CompletionItem::InsertTextFormat(value.value())); } -bool CompletionItem::isValid(ErrorHierarchy *error) const -{ - return check(error, labelKey) - && checkOptional(error, kindKey) - && checkOptional(error, detailKey) - && checkOptional(error, documentationKey) - && checkOptional(error, sortTextKey) - && checkOptional(error, filterTextKey) - && checkOptional(error, insertTextKey) - && checkOptional(error, insertTextFormatKey) - && checkOptional(error, textEditKey) - && checkOptionalArray(error, additionalTextEditsKey) - && checkOptionalArray(error, commitCharactersKey) - && checkOptional(error, commandKey) - && checkOptional(error, dataKey); -} + CompletionItemResolveRequest::CompletionItemResolveRequest(const CompletionItem ¶ms) : Request(methodName, params) { } -bool CompletionList::isValid(ErrorHierarchy *error) const -{ - return check(error, isIncompleteKey) - && checkOptionalArray(error, itemsKey); - -} - -bool CompletionParams::isValid(ErrorHierarchy *error) const -{ - return TextDocumentPositionParams::isValid(error) - && checkOptional(error, contextKey); -} - CompletionResult::CompletionResult(const QJsonValue &value) { if (value.isNull()) { diff --git a/src/libs/languageserverprotocol/completion.h b/src/libs/languageserverprotocol/completion.h index 013136b58a0..ab5e43ac220 100644 --- a/src/libs/languageserverprotocol/completion.h +++ b/src/libs/languageserverprotocol/completion.h @@ -71,11 +71,7 @@ public: { insert(triggerCharacterKey, triggerCharacter); } void clearTriggerCharacter() { remove(triggerCharacterKey); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, triggerKindKey) - && checkOptional(error, triggerCharacterKey); - } + bool isValid() const override { return contains(triggerKindKey); } }; /** @@ -87,8 +83,6 @@ public: void setContext(const CompletionContext &context) { insert(contextKey, context); } void clearContext() { remove(contextKey); } - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CompletionItem : public JsonObject @@ -220,7 +214,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(labelKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT CompletionList : public JsonObject @@ -240,7 +234,7 @@ public: void setItems(const QList &items) { insertArray(itemsKey, items); } void clearItems() { remove(itemsKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(isIncompleteKey); } }; /// The result of a completion is CompletionItem[] | CompletionList | null diff --git a/src/libs/languageserverprotocol/diagnostics.h b/src/libs/languageserverprotocol/diagnostics.h index c7b6d7fefb8..03b6a224214 100644 --- a/src/libs/languageserverprotocol/diagnostics.h +++ b/src/libs/languageserverprotocol/diagnostics.h @@ -46,8 +46,7 @@ public: void setVersion(int version) { insert(versionKey, version); } void clearVersion() { remove(versionKey); } - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, diagnosticsKey); } + bool isValid() const override { return contains(diagnosticsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT PublishDiagnosticsNotification : public Notification diff --git a/src/libs/languageserverprotocol/icontent.h b/src/libs/languageserverprotocol/icontent.h index fb1b3b05fca..a6ecb407142 100644 --- a/src/libs/languageserverprotocol/icontent.h +++ b/src/libs/languageserverprotocol/icontent.h @@ -60,7 +60,7 @@ public: *this = MessageId(value.toString()); } - QJsonValue toJson() const + operator QJsonValue() const { QTC_CHECK(Utils::holds_alternative(*this) || Utils::holds_alternative(*this)); if (auto id = Utils::get_if(this)) @@ -70,14 +70,7 @@ public: return QJsonValue(); } - bool isValid(ErrorHierarchy *error = nullptr) const - { - if (Utils::holds_alternative(*this) || Utils::holds_alternative(*this)) - return true; - if (error) - error->setError("Expected int or string as MessageId"); - return false; - } + bool isValid() const { return true; } QString toString() const { diff --git a/src/libs/languageserverprotocol/initializemessages.cpp b/src/libs/languageserverprotocol/initializemessages.cpp index 1f46469438d..ab09cf1120c 100644 --- a/src/libs/languageserverprotocol/initializemessages.cpp +++ b/src/libs/languageserverprotocol/initializemessages.cpp @@ -132,6 +132,14 @@ InitializeParams::InitializeParams() setTrace(s_trace); } +Utils::optional InitializeParams::initializationOptions() const +{ + const QJsonValue &optionsValue = value(initializationOptionsKey); + if (optionsValue.isObject()) + return optionsValue.toObject(); + return Utils::nullopt; +} + Utils::optional InitializeParams::trace() const { const QJsonValue &traceValue = value(traceKey); @@ -140,17 +148,6 @@ Utils::optional InitializeParams::trace() const return Utils::make_optional(Trace(traceValue.toString())); } -bool InitializeParams::isValid(ErrorHierarchy *error) const -{ - return checkVariant(error, processIdKey) - && checkOptional(error, rootPathKey) - && checkOptional(error, rootUriKey) - && check(error, capabilitiesKey) - && checkOptional(error, traceKey) - && (checkOptional(error, workspaceFoldersKey) - || checkOptionalArray(error, workspaceFoldersKey)); -} - InitializeRequest::InitializeRequest(const InitializeParams ¶ms) : Request(methodName, params) { } diff --git a/src/libs/languageserverprotocol/initializemessages.h b/src/libs/languageserverprotocol/initializemessages.h index 5d88267b38f..527e978373d 100644 --- a/src/libs/languageserverprotocol/initializemessages.h +++ b/src/libs/languageserverprotocol/initializemessages.h @@ -91,8 +91,7 @@ public: { insert(rootUriKey, uri); } // User provided initialization options. - Utils::optional initializationOptions() const - { return optionalValue(initializationOptionsKey); } + Utils::optional initializationOptions() const; void setInitializationOptions(const QJsonObject &options) { insert(initializationOptionsKey, options); } void clearInitializationOptions() { remove(initializationOptionsKey); } @@ -121,7 +120,8 @@ public: { insert(workspaceFoldersKey, folders.toJson()); } void clearWorkSpaceFolders() { remove(workspaceFoldersKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(processIdKey) && contains(rootUriKey) && contains(capabilitiesKey); } }; using InitializedParams = JsonObject; @@ -146,9 +146,6 @@ public: void setCapabilities(const ServerCapabilities &capabilities) { insert(capabilitiesKey, capabilities); } void clearCapabilities() { remove(capabilitiesKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptional(error, capabilitiesKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT InitializeError : public JsonObject @@ -165,8 +162,6 @@ public: Utils::optional retry() const { return optionalValue(retryKey); } void setRetry(bool retry) { insert(retryKey, retry); } void clearRetry() { remove(retryKey); } - - bool isValid(ErrorHierarchy *error) const override { return checkOptional(error, retryKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT InitializeRequest : public Request< diff --git a/src/libs/languageserverprotocol/jsonobject.cpp b/src/libs/languageserverprotocol/jsonobject.cpp index 7bdf3f86888..75edb76de3b 100644 --- a/src/libs/languageserverprotocol/jsonobject.cpp +++ b/src/libs/languageserverprotocol/jsonobject.cpp @@ -29,34 +29,6 @@ namespace LanguageServerProtocol { -template <> -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ return checkType(val.type(), QJsonValue::String, errorHierarchy); } - -template <> -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ return checkType(val.type(), QJsonValue::Double, errorHierarchy); } - -template <> -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ return checkType(val.type(), QJsonValue::Double, errorHierarchy); } - -template <> -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ return checkType(val.type(), QJsonValue::Bool, errorHierarchy); } - -template <> -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ return checkType(val.type(), QJsonValue::Null, errorHierarchy); } - -template<> -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ return checkType(val.type(), QJsonValue::Array, errorHierarchy); } - -template<> -bool JsonObject::checkVal(ErrorHierarchy * /*errorHierarchy*/, const QJsonValue &/*val*/) -{ return true; } - JsonObject &JsonObject::operator=(const JsonObject &other) = default; JsonObject &JsonObject::operator=(JsonObject &&other) @@ -75,43 +47,4 @@ QJsonObject::iterator JsonObject::insert(const QString &key, const QJsonValue &v return m_jsonObject.insert(key, value); } -bool JsonObject::checkKey(ErrorHierarchy *errorHierarchy, const QString &key, - const std::function &predicate) const -{ - const bool valid = predicate(m_jsonObject.value(key)); - if (!valid && errorHierarchy) - errorHierarchy->prependMember(key); - return valid; -} - -QString JsonObject::valueTypeString(QJsonValue::Type type) -{ - switch (type) { - case QJsonValue::Null: return QString("Null"); - case QJsonValue::Bool: return QString("Bool"); - case QJsonValue::Double: return QString("Double"); - case QJsonValue::String: return QString("String"); - case QJsonValue::Array: return QString("Array"); - case QJsonValue::Object: return QString("Object"); - case QJsonValue::Undefined: return QString("Undefined"); - } - return QString(); -} - -QString JsonObject::errorString(QJsonValue::Type expected, QJsonValue::Type actual) -{ - return tr("Expected type %1 but value contained %2") - .arg(valueTypeString(expected), valueTypeString(actual)); -} - -bool JsonObject::checkType(QJsonValue::Type type, - QJsonValue::Type expectedType, - ErrorHierarchy *errorHierarchy) -{ - const bool ret = type == expectedType; - if (!ret && errorHierarchy) - errorHierarchy->setError(errorString(expectedType, type)); - return ret; -} - } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/jsonobject.h b/src/libs/languageserverprotocol/jsonobject.h index ff2f420c87c..ae2843774ec 100644 --- a/src/libs/languageserverprotocol/jsonobject.h +++ b/src/libs/languageserverprotocol/jsonobject.h @@ -61,7 +61,7 @@ public: operator const QJsonObject&() const { return m_jsonObject; } - virtual bool isValid(ErrorHierarchy * /*errorHierarchy*/) const { return true; } + virtual bool isValid() const { return true; } iterator end() { return m_jsonObject.end(); } const_iterator end() const { return m_jsonObject.end(); } @@ -105,31 +105,6 @@ protected: template void insertArray(const QString &key, const QList &array); - // value checking - bool checkKey(ErrorHierarchy *errorHierarchy, const QString &key, - const std::function &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, - ErrorHierarchy *errorHierarchy); - template - static bool checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val); - template - bool check(ErrorHierarchy *errorHierarchy, const QString &key) const; - template - bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const; - template - bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const; - template - bool checkArray(ErrorHierarchy *errorHierarchy, const QString &key) const; - template - bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const; - template - bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const; - template - bool checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const; - private: QJsonObject m_jsonObject; }; @@ -218,122 +193,4 @@ void JsonObject::insertArray(const QString &key, const QList &array) insert(key, jsonArray); } -template -bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) -{ - return checkType(val.type(), QJsonValue::Object, errorHierarchy) - && T(val).isValid(errorHierarchy); -} - -template -bool JsonObject::check(ErrorHierarchy *errorHierarchy, const QString &key) const -{ - return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val) { - return checkVal(errorHierarchy, val); - }); -} - -template -bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const -{ - if (checkVariant(errorHierarchy, key)) - return true; - - if (checkVariant(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 -bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const -{ - if (!errorHierarchy) - return check(nullptr, key); - ErrorHierarchy subError; - if (check(&subError, key)) - return true; - errorHierarchy->addVariantHierachy(subError); - return false; -} - -template -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){ - return checkVal(errorHierarchy, value); - }); - }); -} - -template -bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const -{ - if (!contains(key)) - return true; - - if (checkVariant(errorHierarchy, key)) - return true; - - if (checkVariant(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 -bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const -{ - if (contains(key)) - return check(errorHierarchy, key); - return true; -} - -template -bool JsonObject::checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const -{ - if (contains(key)) - return checkArray(errorHierarchy, key); - return true; -} - -template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - -template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - -template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - -template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - -template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - -template<> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - -template<> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, - const QJsonValue &val); - } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.h b/src/libs/languageserverprotocol/jsonrpcmessages.h index d0d3189e00d..f0247e3c56b 100644 --- a/src/libs/languageserverprotocol/jsonrpcmessages.h +++ b/src/libs/languageserverprotocol/jsonrpcmessages.h @@ -121,7 +121,7 @@ public: virtual bool parametersAreValid(QString *errorMessage) const { if (auto parameter = params()) - return parameter.value().isValid(nullptr); + return parameter.value().isValid(); if (errorMessage) *errorMessage = QCoreApplication::translate("LanguageServerProtocol::Notification", "No parameters in \"%1\".").arg(method()); @@ -179,12 +179,7 @@ public: void setData(const Error &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, codeKey) - && check(error, messageKey) - && checkOptional(error, dataKey); - } + bool isValid() const override { return contains(codeKey) && contains(messageKey); } QString toString() const { return errorCodesToString(code()) + ": " + message(); } @@ -237,7 +232,7 @@ public: MessageId id() const { return MessageId(m_jsonObject.value(idKey)); } void setId(MessageId id) - { this->m_jsonObject.insert(idKey, id.toJson()); } + { this->m_jsonObject.insert(idKey, id); } Utils::optional result() const { @@ -277,7 +272,7 @@ public: MessageId id() const { return MessageId(JsonRpcMessage::m_jsonObject.value(idKey)); } void setId(const MessageId &id) - { JsonRpcMessage::m_jsonObject.insert(idKey, id.toJson()); } + { JsonRpcMessage::m_jsonObject.insert(idKey, id); } using Response = LanguageServerProtocol::Response; using ResponseCallback = std::function; @@ -328,17 +323,10 @@ public: CancelParameter() = default; using JsonObject::JsonObject; - MessageId id() const { return MessageId(value(idKey)); } - void setId(const MessageId &id) { insert(idKey, id.toJson()); } + MessageId id() const { return typedValue(idKey); } + void setId(const MessageId &id) { insert(idKey, id); } - bool isValid(ErrorHierarchy *error) const override - { - if (MessageId(value(idKey)).isValid(error)) - return true; - if (error) - error->prependMember(idKey); - return false; - } + bool isValid() const override { return contains(idKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT CancelRequest : public Notification diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index de175b7e7e1..0d32fbcae05 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -80,11 +80,6 @@ Utils::optional ParameterInformation::documentation() const return MarkupOrString(documentation); } -bool SignatureHelp::isValid(ErrorHierarchy *error) const -{ - return checkArray(error, signaturesKey); -} - GotoDefinitionRequest::GotoDefinitionRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } @@ -119,18 +114,6 @@ void CodeActionParams::CodeActionContext::setOnly(const QList &o insertArray(onlyKey, only); } -bool CodeActionParams::CodeActionContext::isValid(ErrorHierarchy *error) const -{ - return checkArray(error, diagnosticsKey); -} - -bool CodeActionParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && check(error, rangeKey) - && check(error, contextKey); -} - CodeActionRequest::CodeActionRequest(const CodeActionParams ¶ms) : Request(methodName, params) { } @@ -155,21 +138,6 @@ DocumentColorRequest::DocumentColorRequest(const DocumentColorParams ¶ms) : Request(methodName, params) { } -bool Color::isValid(ErrorHierarchy *error) const -{ - return check(error, redKey) - && check(error, greenKey) - && check(error, blueKey) - && check(error, alphaKey); -} - -bool ColorPresentationParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && check(error, colorInfoKey) - && check(error, rangeKey); -} - ColorPresentationRequest::ColorPresentationRequest(const ColorPresentationParams ¶ms) : Request(methodName, params) { } @@ -202,43 +170,19 @@ void FormattingOptions::setProperty(const QString &key, const DocumentFormatting insert(key, *val); } -bool FormattingOptions::isValid(ErrorHierarchy *error) const -{ - return Utils::allOf(keys(), [this, &error](auto key){ - return (key == tabSizeKey && this->check(error, key)) - || (key == insertSpaceKey && this->check(error, key)) - || this->check(error, key); - }); -} - -bool DocumentFormattingParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && check(error, optionsKey); -} - DocumentFormattingRequest::DocumentFormattingRequest(const DocumentFormattingParams ¶ms) : Request(methodName, params) { } -bool DocumentRangeFormattingParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && check(error, rangeKey) - && check(error, optionsKey); -} - DocumentRangeFormattingRequest::DocumentRangeFormattingRequest( const DocumentRangeFormattingParams ¶ms) : Request(methodName, params) { } -bool DocumentOnTypeFormattingParams::isValid(ErrorHierarchy *error) const +bool DocumentOnTypeFormattingParams::isValid() const { - return check(error, textDocumentKey) - && check(error, positionKey) - && check(error, chKey) - && check(error, optionsKey); + return contains(textDocumentKey) && contains(positionKey) && contains(chKey) + && contains(optionsKey); } DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest( @@ -250,11 +194,9 @@ PrepareRenameRequest::PrepareRenameRequest(const TextDocumentPositionParams &par : Request(methodName, params) { } -bool RenameParams::isValid(ErrorHierarchy *error) const +bool RenameParams::isValid() const { - return check(error, textDocumentKey) - && check(error, positionKey) - && check(error, newNameKey); + return contains(textDocumentKey) && contains(positionKey) && contains(newNameKey); } RenameRequest::RenameRequest(const RenameParams ¶ms) @@ -269,6 +211,11 @@ Utils::optional DocumentLink::target() const : Utils::nullopt; } +Utils::optional DocumentLink::data() const +{ + return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt; +} + TextDocumentParams::TextDocumentParams() : TextDocumentParams(TextDocumentIdentifier()) { } @@ -340,13 +287,17 @@ DocumentHighlightsResult::DocumentHighlightsResult(const QJsonValue &value) MarkedString::MarkedString(const QJsonValue &value) { - if (value.isObject()) { - MarkedLanguageString string(value.toObject()); - if (string.isValid(nullptr)) - emplace(string); - } else if (value.isString()) { + if (value.isObject()) + emplace(MarkedLanguageString(value.toObject())); + else emplace(value.toString()); - } +} + +bool MarkedString::isValid() const +{ + if (auto markedLanguageString = Utils::get_if(this)) + return markedLanguageString->isValid(); + return true; } LanguageServerProtocol::MarkedString::operator QJsonValue() const @@ -365,7 +316,7 @@ HoverContent::HoverContent(const QJsonValue &value) } else if (value.isObject()) { const QJsonObject &object = value.toObject(); MarkedLanguageString markedLanguageString(object); - if (markedLanguageString.isValid(nullptr)) + if (markedLanguageString.isValid()) emplace(markedLanguageString); else emplace(MarkupContent(object)); @@ -374,20 +325,11 @@ HoverContent::HoverContent(const QJsonValue &value) } } -bool HoverContent::isValid(ErrorHierarchy *errorHierarchy) const +bool HoverContent::isValid() const { - if (Utils::holds_alternative(*this) - || Utils::holds_alternative(*this) - || Utils::holds_alternative>(*this)) { - return true; - } - if (errorHierarchy) { - errorHierarchy->setError( - QCoreApplication::translate("LanguageServerProtocol::HoverContent", - "HoverContent should be either MarkedString, " - "MarkupContent, or QList.")); - } - return false; + if (Utils::holds_alternative(*this)) + return Utils::get(*this).isValid(); + return true; } DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value) @@ -400,21 +342,6 @@ DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value) *this = value.toString(); } -bool DocumentFormattingProperty::isValid(ErrorHierarchy *error) const -{ - if (Utils::holds_alternative(*this) - || Utils::holds_alternative(*this) - || Utils::holds_alternative(*this)) { - return true; - } - if (error) { - error->setError(QCoreApplication::translate( - "LanguageServerProtocol::MarkedString", - "DocumentFormattingProperty should be either bool, double, or QString.")); - } - return false; -} - SignatureHelpRequest::SignatureHelpRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } @@ -427,7 +354,7 @@ CodeActionResult::CodeActionResult(const QJsonValue &val) ResultArray result; for (const QJsonValue &val : array) { Command command(val); - if (command.isValid(nullptr)) + if (command.isValid()) result << command; else result << CodeAction(val); @@ -438,15 +365,6 @@ CodeActionResult::CodeActionResult(const QJsonValue &val) emplace(nullptr); } -bool CodeAction::isValid(ErrorHierarchy *error) const -{ - return check(error, titleKey) - && checkOptional(error, codeActionKindKey) - && checkOptionalArray(error, diagnosticsKey) - && checkOptional(error, editKey) - && checkOptional(error, commandKey); -} - Utils::optional> SemanticHighlightingInformation::tokens() const { QList resultTokens; @@ -501,19 +419,7 @@ SemanticHighlightingParams::textDocument() const { VersionedTextDocumentIdentifier textDocument = fromJsonValue( value(textDocumentKey)); - ErrorHierarchy error; - if (!textDocument.isValid(&error)) { - return TextDocumentIdentifier(textDocument); - } else { - return textDocument; - } -} - -bool SemanticHighlightingParams::isValid(ErrorHierarchy *error) const -{ - return checkVariant(error, - textDocumentKey) - && checkArray(error, linesKey); + return textDocument.isValid() ? textDocument : TextDocumentIdentifier(textDocument); } PrepareRenameResult::PrepareRenameResult() @@ -551,4 +457,9 @@ SemanticHighlightNotification::SemanticHighlightNotification(const SemanticHighl : Notification(methodName, params) {} +Utils::optional CodeLens::data() const +{ + return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt; +} + } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index c1818b34f2c..fc8df0bc716 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -54,8 +54,7 @@ public: QString value() const { return typedValue(valueKey); } void setValue(const QString &value) { insert(valueKey, value); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, languageKey) && check(error, valueKey); } + bool isValid() const override { return contains(languageKey) && contains(valueKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT MarkedString @@ -71,6 +70,7 @@ public: {} explicit MarkedString(const QJsonValue &value); + bool isValid() const; operator QJsonValue() const; }; @@ -83,7 +83,7 @@ public: explicit HoverContent(const QList &other) : variant(other) {} explicit HoverContent(const MarkupContent &other) : variant(other) {} explicit HoverContent(const QJsonValue &value); - bool isValid(ErrorHierarchy *errorHierarchy) const; + bool isValid() const; }; class LANGUAGESERVERPROTOCOL_EXPORT Hover : public JsonObject @@ -98,8 +98,7 @@ public: void setRange(const Range &range) { insert(rangeKey, range); } void clearRange() { remove(rangeKey); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, contentsKey) && checkOptional(error, rangeKey); } + bool isValid() const override { return contains(contentsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT HoverRequest @@ -128,11 +127,7 @@ public: { insert(documentationKey, documentation.toJson()); } void clearDocumentation() { remove(documentationKey); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, labelKey) - && checkOptional(error, documentationKey); - } + bool isValid() const override { return contains(labelKey); } }; /** @@ -194,7 +189,7 @@ public: void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); } void clearActiveParameter() { remove(activeParameterKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(signaturesKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpRequest @@ -258,17 +253,14 @@ public: void setIncludeDeclaration(bool includeDeclaration) { insert(includeDeclarationKey, includeDeclaration); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, includeDeclarationKey); } + bool isValid() const override { return contains(includeDeclarationKey); } }; ReferenceContext context() const { return typedValue(contextKey); } void setContext(const ReferenceContext &context) { insert(contextKey, context); } - bool isValid(ErrorHierarchy *error) const override - { - return TextDocumentPositionParams::isValid(error) - && check(error, contextKey); } + bool isValid() const override + { return TextDocumentPositionParams::isValid() && contains(contextKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT FindReferencesRequest : public Request< @@ -298,8 +290,7 @@ public: void setKind(int kind) { insert(kindKey, kind); } void clearKind() { remove(kindKey); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, rangeKey) && checkOptional(error, kindKey); } + bool isValid() const override { return contains(rangeKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentHighlightsResult @@ -333,8 +324,7 @@ public: void setTextDocument(const TextDocumentIdentifier &textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, textDocumentKey); } + bool isValid() const override { return contains(textDocumentKey); } }; using DocumentSymbolParams = TextDocumentParams; @@ -417,7 +407,7 @@ public: void setOnly(const QList &only); void clearOnly() { remove(onlyKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(diagnosticsKey); } }; TextDocumentIdentifier textDocument() const @@ -431,7 +421,8 @@ public: CodeActionContext context() const { return typedValue(contextKey); } void setContext(const CodeActionContext &context) { insert(contextKey, context); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(textDocumentKey) && contains(rangeKey) && contains(contextKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT CodeAction : public JsonObject @@ -460,7 +451,7 @@ public: void setCommand(const Command &command) { insert(commandKey, command); } void clearCommand() { remove(commandKey); } - bool isValid(ErrorHierarchy *) const override; + bool isValid() const override { return contains(titleKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT CodeActionResult @@ -494,12 +485,11 @@ public: void setCommand(const Command &command) { insert(commandKey, command); } void clearCommand() { remove(commandKey); } - Utils::optional data() const { return optionalValue(dataKey); } + Utils::optional data() const; void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, rangeKey) && checkOptional(error, commandKey); } + bool isValid() const override { return contains(rangeKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT CodeLensRequest : public Request< @@ -532,12 +522,11 @@ public: void setTarget(const DocumentUri &target) { insert(targetKey, target.toString()); } void clearTarget() { remove(targetKey); } - Utils::optional data() const { return optionalValue(dataKey); } + Utils::optional data() const; void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, rangeKey) && checkOptional(error, targetKey); } + bool isValid() const override { return contains(rangeKey); } }; using DocumentLinkParams = TextDocumentParams; @@ -579,7 +568,8 @@ public: double alpha() const { return typedValue(alphaKey); } void setAlpha(double alpha) { insert(alphaKey, alpha); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(redKey) && contains(greenKey) && contains(blueKey) && contains(alphaKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ColorInformation : public JsonObject @@ -593,8 +583,7 @@ public: Color color() const { return typedValue(colorKey); } void setColor(const Color &color) { insert(colorKey, color); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, rangeKey) && check(error, colorKey); } + bool isValid() const override { return contains(rangeKey) && contains(colorKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentColorRequest : public Request< @@ -622,7 +611,8 @@ public: Range range() const { return typedValue(rangeKey); } void setRange(const Range &range) { insert(rangeKey, range); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(textDocumentKey) && contains(colorInfoKey) && contains(rangeKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentation : public JsonObject @@ -643,12 +633,7 @@ public: { insertArray(additionalTextEditsKey, additionalTextEdits); } void clearAdditionalTextEdits() { remove(additionalTextEditsKey); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, labelKey) - && checkOptional(error, textEditKey) - && checkOptionalArray(error, additionalTextEditsKey); - } + bool isValid() const override { return contains(labelKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentationRequest : public Request< @@ -670,8 +655,6 @@ public: using variant::variant; using variant::operator=; - - bool isValid(ErrorHierarchy *error) const; }; class LANGUAGESERVERPROTOCOL_EXPORT FormattingOptions : public JsonObject @@ -707,7 +690,7 @@ public: void setProperty(const QString &key, const DocumentFormattingProperty &property); void removeProperty(const QString &key) { remove(key); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(insertSpaceKey) && contains(tabSizeKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingParams : public JsonObject @@ -723,7 +706,7 @@ public: FormattingOptions options() const { return typedValue(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textDocumentKey) && contains(optionsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingRequest : public Request< @@ -751,7 +734,8 @@ public: FormattingOptions options() const { return typedValue(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(textDocumentKey) && contains(rangeKey) && contains(optionsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentRangeFormattingRequest : public Request< @@ -782,7 +766,7 @@ public: FormattingOptions options() const { return typedValue(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentOnTypeFormattingRequest : public Request< @@ -805,10 +789,7 @@ public: QString placeHolder() const { return typedValue(placeHolderKey); } void setPlaceHolder(const QString &placeHolder) { insert(placeHolderKey, placeHolder); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, rangeKey) && checkOptional(error, placeHolderKey); - } + bool isValid() const override { return contains(rangeKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT PrepareRenameResult @@ -821,7 +802,7 @@ public: explicit PrepareRenameResult(const Range &val); explicit PrepareRenameResult(const QJsonValue &val); - bool isValid(ErrorHierarchy *error) const; + bool isValid() const; }; class LANGUAGESERVERPROTOCOL_EXPORT PrepareRenameRequest @@ -849,7 +830,7 @@ public: QString newName() const { return typedValue(newNameKey); } void setNewName(const QString &newName) { insert(newNameKey, newName); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override; }; class LANGUAGESERVERPROTOCOL_EXPORT RenameRequest : public Request< @@ -887,8 +868,7 @@ public: void setTokens(const QList &tokens); void clearTokens() { remove(tokensKey); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, lineKey) && checkOptional(error, tokensKey); } + bool isValid() const override { return contains(lineKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingParams : public JsonObject @@ -907,7 +887,7 @@ public: void setLines(const QList &lines) { insertArray(linesKey, lines); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textDocumentKey) && contains(linesKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp index ddf2cc2ee3c..d6867590459 100644 --- a/src/libs/languageserverprotocol/lsptypes.cpp +++ b/src/libs/languageserverprotocol/lsptypes.cpp @@ -65,15 +65,6 @@ void Diagnostic::setCode(const Diagnostic::Code &code) insertVariant(codeKey, code); } -bool Diagnostic::isValid(ErrorHierarchy *error) const -{ - return check(error, rangeKey) - && checkOptional(error, severityKey) - && (checkOptional(error, codeKey) || checkOptional(error, codeKey)) - && checkOptional(error, sourceKey) - && check(error, messageKey); -} - Utils::optional WorkspaceEdit::changes() const { auto it = find(changesKey); @@ -123,23 +114,11 @@ MarkupOrString::MarkupOrString(const QJsonValue &val) emplace(val.toString()); } else { MarkupContent markupContent(val.toObject()); - if (markupContent.isValid(nullptr)) + if (markupContent.isValid()) emplace(MarkupContent(val.toObject())); } } -bool MarkupOrString::isValid(ErrorHierarchy *error) const -{ - if (Utils::holds_alternative(*this) || Utils::holds_alternative(*this)) - return true; - if (error) { - error->setError( - QCoreApplication::translate("LanguageServerProtocoll::MarkupOrString", - "Expected a string or MarkupContent in MarkupOrString.")); - } - return false; -} - QJsonValue MarkupOrString::toJson() const { if (Utils::holds_alternative(*this)) @@ -149,28 +128,6 @@ QJsonValue MarkupOrString::toJson() const return {}; } -bool SymbolInformation::isValid(ErrorHierarchy *error) const -{ - return check(error, nameKey) - && check(error, kindKey) - && check(error, locationKey) - && checkOptional(error, containerNameKey); -} - -bool TextDocumentEdit::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && checkArray(error, editsKey); -} - -bool TextDocumentItem::isValid(ErrorHierarchy *error) const -{ - return check(error, uriKey) - && check(error, languageIdKey) - && check(error, versionKey) - && check(error, textKey); -} - static QHash mimeTypeLanguageIdMap() { static QHash hash; @@ -281,6 +238,11 @@ QMap languageIds() return languages; } +bool TextDocumentItem::isValid() const +{ + return contains(uriKey) && contains(languageIdKey) && contains(versionKey) && contains(textKey); +} + QString TextDocumentItem::mimeTypeToLanguageId(const Utils::MimeType &mimeType) { return mimeTypeLanguageIdMap().value(mimeType); @@ -304,12 +266,6 @@ TextDocumentPositionParams::TextDocumentPositionParams( setPosition(position); } -bool TextDocumentPositionParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && check(error, positionKey); -} - Position::Position(int line, int character) { setLine(line); @@ -388,16 +344,9 @@ bool DocumentFilter::applies(const Utils::FilePath &fileName, const Utils::MimeT return !contains(schemeKey) && !contains(languageKey) && !contains(patternKey); } -bool DocumentFilter::isValid(ErrorHierarchy *error) const -{ - return Utils::allOf(QStringList{languageKey, schemeKey, patternKey}, [this, &error](auto key){ - return this->checkOptional(error, key); - }); -} - Utils::Link Location::toLink() const { - if (!isValid(nullptr)) + if (!isValid()) return Utils::Link(); // Ensure %xx like %20 are really decoded using fromPercentEncoding diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h index d6de79b4308..100fd2b80c9 100644 --- a/src/libs/languageserverprotocol/lsptypes.h +++ b/src/libs/languageserverprotocol/lsptypes.h @@ -83,8 +83,8 @@ public: int character() const { return typedValue(characterKey); } void setCharacter(int character) { insert(characterKey, character); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, lineKey) && check(error, characterKey); } + bool isValid() const override + { return contains(lineKey) && contains(characterKey); } int toPositionInDocument(QTextDocument *doc) const; QTextCursor toTextCursor(QTextDocument *doc) const; @@ -115,8 +115,8 @@ public: bool contains(const Position &pos) const { return start() <= pos && pos <= end(); } bool overlaps(const Range &range) const; - bool isValid(ErrorHierarchy *error) const override - { return check(error, startKey) && check(error, endKey); } + bool isValid() const override + { return JsonObject::contains(startKey) && JsonObject::contains(endKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT Location : public JsonObject @@ -133,8 +133,7 @@ public: Utils::Link toLink() const; - bool isValid(ErrorHierarchy *error) const override - { return check(error, uriKey) && check(error, rangeKey); } + bool isValid() const override { return contains(uriKey) && contains(rangeKey); } }; enum class DiagnosticSeverity @@ -180,7 +179,7 @@ public: { return typedValue(messageKey); } void setMessage(const QString &message) { insert(messageKey, message); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(rangeKey) && contains(messageKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT Command : public JsonObject @@ -203,10 +202,7 @@ public: void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void clearArguments() { remove(argumentsKey); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, titleKey) - && check(error, commandKey) - && checkOptional(error, argumentsKey); } + bool isValid() const override { return contains(titleKey) && contains(commandKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT TextEdit : public JsonObject @@ -225,8 +221,8 @@ public: Utils::Text::Replacement toReplacement(QTextDocument *document) const; - bool isValid(ErrorHierarchy *error) const override - { return check(error, rangeKey) && check(error, newTextKey); } + bool isValid() const override + { return contains(rangeKey) && contains(newTextKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentIdentifier : public JsonObject @@ -240,7 +236,7 @@ public: DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue(uriKey)); } void setUri(const DocumentUri &uri) { insert(uriKey, uri); } - bool isValid(ErrorHierarchy *error) const override { return check(error, uriKey); } + bool isValid() const override { return contains(uriKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT VersionedTextDocumentIdentifier : public TextDocumentIdentifier @@ -258,10 +254,9 @@ public: LanguageClientValue version() const { return clientValue(versionKey); } void setVersion(LanguageClientValue version) { insert(versionKey, version); } - bool isValid(ErrorHierarchy *error) const override + bool isValid() const override { - return TextDocumentIdentifier::isValid(error) - && checkVariant(error, versionKey); + return TextDocumentIdentifier::isValid() && contains(versionKey); } }; @@ -280,7 +275,7 @@ public: QList edits() const { return array(editsKey); } void setEdits(const QList edits) { insertArray(editsKey, edits); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textDocumentKey) && contains(editsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceEdit : public JsonObject @@ -306,9 +301,6 @@ public: { return optionalArray(documentChangesKey); } void setDocumentChanges(const QList &changes) { insertArray(documentChangesKey, changes); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptionalArray(error, documentChangesKey); } }; LANGUAGESERVERPROTOCOL_EXPORT QMap languageIds(); @@ -334,7 +326,7 @@ public: QString text() const { return typedValue(textKey); } void setText(const QString &text) { insert(textKey, text); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override; static QString mimeTypeToLanguageId(const Utils::MimeType &mimeType); static QString mimeTypeToLanguageId(const QString &mimeTypeName); @@ -356,7 +348,7 @@ public: Position position() const { return typedValue(positionKey); } void setPosition(const Position &position) { insert(positionKey, position); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textDocumentKey) && contains(positionKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFilter : public JsonObject @@ -381,8 +373,6 @@ public: bool applies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType = Utils::MimeType()) const; - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT MarkupKind @@ -400,7 +390,7 @@ public: bool operator==(const Value &value) const { return m_value == value; } - bool isValid(void *) const { return true; } + bool isValid() const { return true; } private: Value m_value = plaintext; }; @@ -420,8 +410,8 @@ public: QString content() const { return typedValue(contentKey); } void setContent(const QString &content) { insert(contentKey, content); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, kindKey) && check(error, contentKey); } + bool isValid() const override + { return contains(kindKey) && contains(contentKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT MarkupOrString : public Utils::variant @@ -433,7 +423,7 @@ public: explicit MarkupOrString(const MarkupContent &val); MarkupOrString(const QJsonValue &val); - bool isValid(ErrorHierarchy *error) const; + bool isValid() const { return true; } QJsonValue toJson() const; }; @@ -453,8 +443,8 @@ public: QString name() const { return typedValue(nameKey); } void setName(const QString &name) { insert(nameKey, name); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, uriKey) && check(error, nameKey); } + bool isValid() const override + { return contains(uriKey) && contains(nameKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT SymbolInformation : public JsonObject @@ -480,7 +470,8 @@ public: void setContainerName(const QString &containerName) { insert(containerNameKey, containerName); } void clearContainerName() { remove(containerNameKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(nameKey) && contains(kindKey) && contains(locationKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentSymbol : public JsonObject diff --git a/src/libs/languageserverprotocol/lsputils.cpp b/src/libs/languageserverprotocol/lsputils.cpp index ecb78129cc5..fdac50c3d13 100644 --- a/src/libs/languageserverprotocol/lsputils.cpp +++ b/src/libs/languageserverprotocol/lsputils.cpp @@ -75,34 +75,18 @@ QJsonArray fromJsonValue(const QJsonValue &value) return value.toArray(); } -void ErrorHierarchy::clear() +template<> +QJsonObject fromJsonValue(const QJsonValue &value) { - m_hierarchy.clear(); - m_children.clear(); - m_error.clear(); + if (conversionLog().isDebugEnabled() && !value.isObject()) + qCDebug(conversionLog) << "Expected Object in json value but got: " << value; + return value.toObject(); } -bool ErrorHierarchy::isEmpty() const +template<> +QJsonValue fromJsonValue(const QJsonValue &value) { - 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; + return value; } } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/lsputils.h b/src/libs/languageserverprotocol/lsputils.h index 677325448bb..08d5e1e3ec5 100644 --- a/src/libs/languageserverprotocol/lsputils.h +++ b/src/libs/languageserverprotocol/lsputils.h @@ -46,7 +46,10 @@ T fromJsonValue(const QJsonValue &value) { if (conversionLog().isDebugEnabled() && !value.isObject()) qCDebug(conversionLog) << "Expected Object in json value but got: " << value; - return T(value.toObject()); + T result(value.toObject()); + if (conversionLog().isDebugEnabled() && !result.isValid()) + qCDebug(conversionLog) << typeid(result).name() << " is not valid: " << result; + return result; } template<> @@ -61,9 +64,15 @@ LANGUAGESERVERPROTOCOL_EXPORT double fromJsonValue(const QJsonValue &val template<> LANGUAGESERVERPROTOCOL_EXPORT bool fromJsonValue(const QJsonValue &value); +template<> +LANGUAGESERVERPROTOCOL_EXPORT QJsonObject fromJsonValue(const QJsonValue &value); + template<> LANGUAGESERVERPROTOCOL_EXPORT QJsonArray fromJsonValue(const QJsonValue &value); +template<> +LANGUAGESERVERPROTOCOL_EXPORT QJsonValue fromJsonValue(const QJsonValue &value); + template class LanguageClientArray : public Utils::variant, std::nullptr_t> { @@ -165,24 +174,4 @@ QList 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 m_children; - QString m_error; -}; - -} // namespace LanguageClient +} // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/messages.cpp b/src/libs/languageserverprotocol/messages.cpp index 44a699ca257..2f658e3afe3 100644 --- a/src/libs/languageserverprotocol/messages.cpp +++ b/src/libs/languageserverprotocol/messages.cpp @@ -50,12 +50,6 @@ TelemetryNotification::TelemetryNotification(const JsonObject ¶ms) : Notification(methodName, params) { } -bool ShowMessageRequestParams::isValid(ErrorHierarchy *error) const -{ - return ShowMessageParams::isValid(error) - && checkOptionalArray(error, actionsKey); -} - static QString messageTypeName(int messageType) { switch (messageType) { diff --git a/src/libs/languageserverprotocol/messages.h b/src/libs/languageserverprotocol/messages.h index 6a9580e3e56..840f380ce0d 100644 --- a/src/libs/languageserverprotocol/messages.h +++ b/src/libs/languageserverprotocol/messages.h @@ -49,8 +49,8 @@ public: QString toString() const; - bool isValid(ErrorHierarchy *error) const override - { return check(error, typeKey) && check(error, messageKey); } + bool isValid() const override + { return contains(typeKey) && contains(messageKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageNotification : public Notification @@ -70,7 +70,7 @@ public: QString title() const { return typedValue(titleKey); } void setTitle(QString title) { insert(titleKey, title); } - bool isValid(ErrorHierarchy *error) const override { return check(error, titleKey); } + bool isValid() const override { return contains(titleKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequestParams : public ShowMessageParams @@ -82,8 +82,6 @@ public: { return optionalArray(actionsKey); } void setActions(const QList &actions) { insertArray(actionsKey, actions); } void clearActions() { remove(actionsKey); } - - 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 9c3d076f3c3..839f37c7f37 100644 --- a/src/libs/languageserverprotocol/servercapabilities.cpp +++ b/src/libs/languageserverprotocol/servercapabilities.cpp @@ -191,7 +191,7 @@ Utils::optional> ServerCapabilities::cod return Utils::make_optional(Utils::variant(provider.toBool())); if (provider.isObject()) { CodeActionOptions options(provider); - if (options.isValid(nullptr)) + if (options.isValid()) return Utils::make_optional(Utils::variant(options)); } return Utils::nullopt; @@ -267,31 +267,6 @@ void ServerCapabilities::setColorProvider(Utils::variant color insertVariant(renameProviderKey, colorProvider); } -bool ServerCapabilities::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, textDocumentSyncKey) - && checkOptional(error, hoverProviderKey) - && checkOptional(error, completionProviderKey) - && checkOptional(error, signatureHelpProviderKey) - && checkOptional(error, definitionProviderKey) - && checkOptional(error, typeDefinitionProviderKey) - && checkOptional(error, implementationProviderKey) - && checkOptional(error, referencesProviderKey) - && checkOptional(error, documentHighlightProviderKey) - && checkOptional(error, documentSymbolProviderKey) - && checkOptional(error, workspaceSymbolProviderKey) - && checkOptional(error, codeActionProviderKey) - && checkOptional(error, codeLensProviderKey) - && checkOptional(error, documentFormattingProviderKey) - && checkOptional(error, documentRangeFormattingProviderKey) - && checkOptional(error, renameProviderKey) - && checkOptional(error, documentLinkProviderKey) - && checkOptional(error, colorProviderKey) - && checkOptional(error, executeCommandProviderKey) - && checkOptional(error, workspaceKey) - && checkOptional(error, semanticHighlightingKey); -} - Utils::optional > ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const { @@ -309,12 +284,6 @@ void ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabiliti insertVariant(changeNotificationsKey, changeNotifications); } -bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, supportedKey) - && checkOptional(error, changeNotificationsKey); -} - bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType) const { @@ -326,15 +295,6 @@ bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileN }); } -bool TextDocumentSyncOptions::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, openCloseKey) - && checkOptional(error, changeKey) - && checkOptional(error, willSaveKey) - && checkOptional(error, willSaveWaitUntilKey) - && checkOptional(error, saveKey); -} - Utils::optional>> ServerCapabilities::SemanticHighlightingServerCapabilities::scopes() const { QList> scopes; @@ -367,7 +327,7 @@ void ServerCapabilities::SemanticHighlightingServerCapabilities::setScopes( insert(scopesKey, jsonScopes); } -bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(ErrorHierarchy *) const +bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid() const { return contains(scopesKey) && value(scopesKey).isArray() && Utils::allOf(value(scopesKey).toArray(), [](const QJsonValue &array) { @@ -379,34 +339,14 @@ bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(ErrorHi }); } -bool ServerCapabilities::ExecuteCommandOptions::isValid(ErrorHierarchy *error) const +bool ServerCapabilities::ExecuteCommandOptions::isValid() const { - return WorkDoneProgressOptions::isValid(error) && checkArray(error, commandsKey); + return WorkDoneProgressOptions::isValid() && contains(commandsKey); } -bool ServerCapabilities::CompletionOptions::isValid(ErrorHierarchy *error) const +bool CodeActionOptions::isValid() const { - return WorkDoneProgressOptions::isValid(error) - && checkOptionalArray(error, triggerCharactersKey) - && checkOptional(error, resolveProviderKey); -} - -bool ServerCapabilities::SignatureHelpOptions::isValid(ErrorHierarchy *error) const -{ - return WorkDoneProgressOptions::isValid(error) - && checkOptionalArray(error, triggerCharactersKey); -} - -bool CodeActionOptions::isValid(ErrorHierarchy *error) const -{ - return WorkDoneProgressOptions::isValid(error) - && checkArray(error, codeActionKindsKey); -} - -bool ServerCapabilities::RenameOptions::isValid(ErrorHierarchy *error) const -{ - return WorkDoneProgressOptions::isValid(error) - && checkOptional(error, prepareProviderKey); + return WorkDoneProgressOptions::isValid() && contains(codeActionKindsKey); } } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h index f575017ad9b..8d0e80bba56 100644 --- a/src/libs/languageserverprotocol/servercapabilities.h +++ b/src/libs/languageserverprotocol/servercapabilities.h @@ -37,9 +37,6 @@ public: Utils::optional workDoneProgress() const { return optionalValue(workDoneProgressKey); } void setWorkDoneProgress(bool workDoneProgress) { insert(workDoneProgressKey, workDoneProgress); } void clearWorkDoneProgress() { remove(workDoneProgressKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptional(error, workDoneProgressKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ResolveProviderOption : public JsonObject @@ -50,9 +47,6 @@ public: Utils::optional resolveProvider() const { return optionalValue(resolveProviderKey); } void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); } void clearResolveProvider() { remove(resolveProviderKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptional(error, resolveProviderKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentRegistrationOptions : public JsonObject @@ -68,8 +62,7 @@ public: bool filterApplies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType = Utils::MimeType()) const; - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, documentSelectorKey); } + bool isValid() const override { return contains(documentSelectorKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT SaveOptions : public JsonObject @@ -81,9 +74,6 @@ public: Utils::optional includeText() const { return optionalValue(includeTextKey); } void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void clearIncludeText() { remove(includeTextKey); } - - bool isValid(ErrorHierarchy *error) const override - { return checkOptional(error, includeTextKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentSyncOptions : public JsonObject @@ -118,8 +108,6 @@ public: Utils::optional save() const { return optionalValue(saveKey); } void setSave(const SaveOptions &save) { insert(saveKey, save); } void clearSave() { remove(saveKey); } - - bool isValid(ErrorHierarchy *error) const override; }; enum class TextDocumentSyncKind @@ -142,7 +130,7 @@ public: void setCodeActionKinds(const QList &codeActionKinds) { insertArray(codeActionKindsKey, codeActionKinds); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ServerCapabilities : public JsonObject @@ -167,8 +155,6 @@ public: Utils::optional resolveProvider() const { return optionalValue(resolveProviderKey); } void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); } void clearResolveProvider() { remove(resolveProviderKey); } - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpOptions : public WorkDoneProgressOptions @@ -182,8 +168,6 @@ public: void setTriggerCharacters(const QList &triggerCharacters) { insertArray(triggerCharactersKey, triggerCharacters); } void clearTriggerCharacters() { remove(triggerCharactersKey); } - - bool isValid(ErrorHierarchy *error) const override; }; using CodeLensOptions = ResolveProviderOption; @@ -205,11 +189,7 @@ public: { insertArray(moreTriggerCharacterKey, moreTriggerCharacter); } void clearMoreTriggerCharacter() { remove(moreTriggerCharacterKey); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, firstTriggerCharacterKey) - && checkOptionalArray(error, moreTriggerCharacterKey); - } + bool isValid() const override { return contains(firstTriggerCharacterKey); } }; using DocumentLinkOptions = ResolveProviderOption; @@ -222,7 +202,7 @@ public: QList commands() const { return array(commandsKey); } void setCommands(const QList &commands) { insertArray(commandsKey, commands); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override; }; using ColorProviderOptions = JsonObject; @@ -247,7 +227,7 @@ public: Utils::optional>> scopes() const; void setScopes(const QList> &scopes); - bool isValid(ErrorHierarchy *) const override; + bool isValid() const override; }; // Defines how text documents are synced. Is either a detailed structure defining each @@ -304,8 +284,7 @@ public: void setId(const QString &id) { insert(idKey, id); } void clearId() { remove(idKey); } - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, documentSelectorKey) && checkOptional(error, idKey); } + bool isValid() const override { return contains(documentSelectorKey); } }; // The server provides Goto Type Definition support. @@ -374,8 +353,6 @@ public: Utils::optional prepareProvider() const { return optionalValue(prepareProviderKey); } void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); } void clearPrepareProvider() { remove(prepareProviderKey); } - - bool isValid(ErrorHierarchy * error) const override; }; // The server provides rename support. @@ -420,8 +397,6 @@ public: Utils::optional> changeNotifications() const; void setChangeNotifications(Utils::variant changeNotifications); void clearChangeNotifications() { remove(changeNotificationsKey); } - - bool isValid(ErrorHierarchy *error) const override; }; Utils::optional workspaceFolders() const @@ -446,8 +421,6 @@ public: void setSemanticHighlighting(const SemanticHighlightingServerCapabilities &semanticHighlighting) { insert(semanticHighlightingKey, semanticHighlighting); } void clearSemanticHighlighting() { remove(semanticHighlightingKey); } - - bool isValid(ErrorHierarchy *error) const override; }; } // namespace LanguageClient diff --git a/src/libs/languageserverprotocol/textsynchronization.cpp b/src/libs/languageserverprotocol/textsynchronization.cpp index ec8ec0963f0..f18548f8205 100644 --- a/src/libs/languageserverprotocol/textsynchronization.cpp +++ b/src/libs/languageserverprotocol/textsynchronization.cpp @@ -74,12 +74,6 @@ DidChangeTextDocumentParams::DidChangeTextDocumentParams( setContentChanges({TextDocumentContentChangeEvent(text)}); } -bool DidChangeTextDocumentParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && checkArray(error, contentChangesKey); -} - DidOpenTextDocumentParams::DidOpenTextDocumentParams(const TextDocumentItem &document) { setTextDocument(document); @@ -96,24 +90,11 @@ DidChangeTextDocumentParams::TextDocumentContentChangeEvent::TextDocumentContent setText(text); } -bool DidChangeTextDocumentParams::TextDocumentContentChangeEvent::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, rangeKey) - && checkOptional(error, rangeLengthKey) - && check(error, textKey); -} - DidSaveTextDocumentParams::DidSaveTextDocumentParams(const TextDocumentIdentifier &document) { setTextDocument(document); } -bool DidSaveTextDocumentParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && checkOptional(error, textKey); -} - WillSaveTextDocumentParams::WillSaveTextDocumentParams( const TextDocumentIdentifier &document, const WillSaveTextDocumentParams::TextDocumentSaveReason &reason) @@ -122,16 +103,4 @@ WillSaveTextDocumentParams::WillSaveTextDocumentParams( setReason(reason); } -bool WillSaveTextDocumentParams::isValid(ErrorHierarchy *error) const -{ - return check(error, textDocumentKey) - && check(error, reasonKey); -} - -bool TextDocumentSaveRegistrationOptions::isValid(ErrorHierarchy *error) const -{ - return TextDocumentRegistrationOptions::isValid(error) - && checkOptional(error, includeTextKey); -} - } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/textsynchronization.h b/src/libs/languageserverprotocol/textsynchronization.h index 72746ad07de..3cf03b787aa 100644 --- a/src/libs/languageserverprotocol/textsynchronization.h +++ b/src/libs/languageserverprotocol/textsynchronization.h @@ -40,11 +40,9 @@ public: TextDocumentItem textDocument() const { return typedValue(textDocumentKey); } void setTextDocument(TextDocumentItem textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, textDocumentKey); } + bool isValid() const override { return contains(textDocumentKey); } }; - class LANGUAGESERVERPROTOCOL_EXPORT DidOpenTextDocumentNotification : public Notification< DidOpenTextDocumentParams> { @@ -66,7 +64,7 @@ public: void setSyncKind(TextDocumentSyncKind syncKind) { insert(syncKindKey, static_cast(syncKind)); } - bool isValid(ErrorHierarchy *error) const override { return check(error, syncKindKey); } + bool isValid() const override { return contains(syncKindKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentParams : public JsonObject @@ -107,7 +105,7 @@ public: QString text() const { return typedValue(textKey); } void setText(const QString &text) { insert(textKey, text); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textKey); } }; QList contentChanges() const @@ -115,7 +113,8 @@ public: void setContentChanges(const QList &contentChanges) { insertArray(contentChangesKey, contentChanges); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override + { return contains(textDocumentKey) && contains(contentChangesKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentNotification : public Notification< @@ -151,7 +150,7 @@ public: { return static_cast(typedValue(reasonKey)); } void setReason(TextDocumentSaveReason reason) { insert(reasonKey, static_cast(reason)); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textDocumentKey) && contains(reasonKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT WillSaveTextDocumentNotification : public Notification< @@ -181,8 +180,6 @@ public: Utils::optional includeText() const { return optionalValue(includeTextKey); } void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void clearIncludeText() { remove(includeTextKey); } - - bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentParams : public JsonObject @@ -201,7 +198,7 @@ public: void setText(const QString &text) { insert(textKey, text); } void clearText() { remove(textKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(textDocumentKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentNotification : public Notification< @@ -225,8 +222,7 @@ public: void setTextDocument(const TextDocumentIdentifier &textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, textDocumentKey); } + bool isValid() const override { return contains(textDocumentKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidCloseTextDocumentNotification : public Notification< diff --git a/src/libs/languageserverprotocol/workspace.cpp b/src/libs/languageserverprotocol/workspace.cpp index 53c20dd40bc..8b82a70dde4 100644 --- a/src/libs/languageserverprotocol/workspace.cpp +++ b/src/libs/languageserverprotocol/workspace.cpp @@ -72,27 +72,6 @@ WorkspaceFoldersChangeEvent::WorkspaceFoldersChangeEvent() insert(removedKey, QJsonArray()); } -bool WorkspaceFoldersChangeEvent::isValid(ErrorHierarchy *error) const -{ - return checkArray(error, addedKey) - && checkArray(error, removedKey); -} - -bool ConfigurationParams::ConfigureationItem::isValid(ErrorHierarchy *error) const -{ - return checkOptional(error, scopeUriKey) - && checkOptional(error, sectionKey); -} - -bool DidChangeConfigurationParams::isValid(ErrorHierarchy *error) const -{ - if (contains(settingsKey)) - return true; - if (error) - error->prependMember(settingsKey); - return false; -} - DidChangeWatchedFilesNotification::DidChangeWatchedFilesNotification( const DidChangeWatchedFilesParams ¶ms) : Notification(methodName, params) diff --git a/src/libs/languageserverprotocol/workspace.h b/src/libs/languageserverprotocol/workspace.h index 5747311d442..8a768e3e544 100644 --- a/src/libs/languageserverprotocol/workspace.h +++ b/src/libs/languageserverprotocol/workspace.h @@ -61,7 +61,7 @@ public: QList removed() const { return array(removedKey); } void setRemoved(const QList &removed) { insertArray(removedKey, removed); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(addedKey) && contains(removedKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersParams : public JsonObject @@ -73,8 +73,7 @@ public: { return typedValue(eventKey); } void setEvent(const WorkspaceFoldersChangeEvent &event) { insert(eventKey, event); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, eventKey); } + bool isValid() const override { return contains(eventKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersNotification : public Notification< @@ -91,10 +90,10 @@ class LANGUAGESERVERPROTOCOL_EXPORT DidChangeConfigurationParams : public JsonOb public: using JsonObject::JsonObject; - QJsonValue settings() const { return typedValue(settingsKey); } + QJsonValue settings() const { return value(settingsKey); } void setSettings(QJsonValue settings) { insert(settingsKey, settings); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(settingsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeConfigurationNotification : public Notification< @@ -123,14 +122,13 @@ public: void setSection(const QString §ion) { insert(sectionKey, section); } void clearSection() { remove(sectionKey); } - bool isValid(ErrorHierarchy *error) const override; + bool isValid() const override { return contains(scopeUriKey); } }; QList items() const { return array(itemsKey); } void setItems(const QList &items) { insertArray(itemsKey, items); } - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, itemsKey); } + bool isValid() const override { return contains(itemsKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ConfigurationRequest : public Request< @@ -164,15 +162,13 @@ public: Deleted = 3 }; - bool isValid(ErrorHierarchy *error) const override - { return check(error, uriKey) && check(error, typeKey); } + bool isValid() const override { return contains(uriKey) && contains(typeKey); } }; QList changes() const { return array(changesKey); } void setChanges(const QList &changes) { insertArray(changesKey, changes); } - bool isValid(ErrorHierarchy *error) const override - { return checkArray(error, changesKey); } + bool isValid() const override { return contains(changesKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWatchedFilesNotification : public Notification< @@ -192,7 +188,7 @@ public: QString query() const { return typedValue(queryKey); } void setQuery(const QString &query) { insert(queryKey, query); } - bool isValid(ErrorHierarchy *error) const override { return check(error, queryKey); } + bool isValid() const override { return contains(queryKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceSymbolRequest : public Request< @@ -219,11 +215,7 @@ public: void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void clearArguments() { remove(argumentsKey); } - bool isValid(ErrorHierarchy *error) const override - { - return check(error, commandKey) - && checkOptionalArray(error, argumentsKey); - } + bool isValid() const override { return contains(commandKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ExecuteCommandRequest : public Request< @@ -247,8 +239,7 @@ public: WorkspaceEdit edit() const { return typedValue(editKey); } void setEdit(const WorkspaceEdit &edit) { insert(editKey, edit); } - bool isValid(ErrorHierarchy *error) const override - { return check(error, editKey) && checkOptional(error, labelKey); } + bool isValid() const override { return contains(editKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditResponse : public JsonObject @@ -259,7 +250,7 @@ public: bool applied() const { return typedValue(appliedKey); } void setApplied(bool applied) { insert(appliedKey, applied); } - bool isValid(ErrorHierarchy *error) const override { return check(error, appliedKey); } + bool isValid() const override { return contains(appliedKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditRequest : public Request< diff --git a/src/plugins/android/javalanguageserver.cpp b/src/plugins/android/javalanguageserver.cpp index 42ee4529067..ab7341d349e 100644 --- a/src/plugins/android/javalanguageserver.cpp +++ b/src/plugins/android/javalanguageserver.cpp @@ -221,7 +221,7 @@ void JLSClient::executeCommand(const LanguageServerProtocol::Command &command) if (!argument.isObject()) continue; LanguageServerProtocol::WorkspaceEdit edit(argument.toObject()); - if (edit.isValid(nullptr)) + if (edit.isValid()) LanguageClient::applyWorkspaceEdit(edit); } } else { diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index ce2184d303a..881f94dd45e 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -314,7 +314,7 @@ void Client::openDocument(TextEditor::TextDocument *document) return; const TextDocumentRegistrationOptions option( m_dynamicCapabilities.option(method).toObject()); - if (option.isValid(nullptr) + if (option.isValid() && !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) { return; } @@ -387,7 +387,7 @@ void Client::updateCompletionProvider(TextEditor::TextDocument *document) Utils::mimeTypeForName(document->mimeType())); const ServerCapabilities::CompletionOptions completionOptions(options); - if (completionOptions.isValid(nullptr)) + if (completionOptions.isValid()) clientCompletionProvider->setTriggerCharacters(completionOptions.triggerCharacters()); } @@ -415,7 +415,7 @@ void Client::updateFunctionHintProvider(TextEditor::TextDocument *document) Utils::mimeTypeForName(document->mimeType())); const ServerCapabilities::SignatureHelpOptions signatureOptions(options); - if (signatureOptions.isValid(nullptr)) + if (signatureOptions.isValid()) clientFunctionHintProvider->setTriggerCharacters(signatureOptions.triggerCharacters()); } @@ -488,7 +488,7 @@ void Client::documentContentsSaved(TextEditor::TextDocument *document) if (sendMessage) { const TextDocumentSaveRegistrationOptions option( m_dynamicCapabilities.option(method).toObject()); - if (option.isValid(nullptr)) { + if (option.isValid()) { sendMessage = option.filterApplies(document->filePath(), Utils::mimeTypeForName(document->mimeType())); includeText = option.includeText().value_or(includeText); @@ -522,7 +522,7 @@ void Client::documentWillSave(Core::IDocument *document) sendMessage = registered.value(); if (sendMessage) { const TextDocumentRegistrationOptions option(m_dynamicCapabilities.option(method)); - if (option.isValid(nullptr)) { + if (option.isValid()) { sendMessage = option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType())); } @@ -553,7 +553,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document, if (syncKind != TextDocumentSyncKind::None) { const TextDocumentChangeRegistrationOptions option( m_dynamicCapabilities.option(method).toObject()); - syncKind = option.isValid(nullptr) ? option.syncKind() : syncKind; + syncKind = option.isValid() ? option.syncKind() : syncKind; } } @@ -618,7 +618,7 @@ void Client::unregisterCapabilities(const QList &unregistrations TextEditor::HighlightingResult createHighlightingResult(const SymbolInformation &info) { - if (!info.isValid(nullptr)) + if (!info.isValid()) return {}; const Position &start = info.location().range().start(); return TextEditor::HighlightingResult(start.line() + 1, @@ -730,7 +730,7 @@ void Client::requestCodeActions(const CodeActionRequest &request) return; const TextDocumentRegistrationOptions option( m_dynamicCapabilities.option(method).toObject()); - if (option.isValid(nullptr) && !option.filterApplies(fileName)) + if (option.isValid() && !option.filterApplies(fileName)) return; } else { Utils::variant provider @@ -965,8 +965,8 @@ void Client::showMessageBox(const ShowMessageRequestParams &message, const Messa connect(box, &QMessageBox::finished, this, [=]{ ShowMessageRequest::Response response(id); const MessageActionItem &item = itemForButton.value(box->clickedButton()); - response.setResult(item.isValid(nullptr) ? LanguageClientValue(item) - : LanguageClientValue()); + response.setResult(item.isValid() ? LanguageClientValue(item) + : LanguageClientValue()); sendContent(response); }); box->show(); @@ -1032,40 +1032,39 @@ void Client::handleResponse(const MessageId &id, const QByteArray &content, QTex void Client::handleMethod(const QString &method, const MessageId &id, const IContent *content) { - ErrorHierarchy error; auto logError = [&](const JsonObject &content) { log(QJsonDocument(content).toJson(QJsonDocument::Indented) + '\n' - + tr("Invalid parameter in \"%1\": %2").arg(method, error.toString())); + + tr("Invalid parameter in \"%1\"").arg(method)); }; if (method == PublishDiagnosticsNotification::methodName) { auto params = dynamic_cast(content)->params().value_or(PublishDiagnosticsParams()); - if (params.isValid(&error)) + if (params.isValid()) handleDiagnostics(params); else logError(params); } else if (method == LogMessageNotification::methodName) { auto params = dynamic_cast(content)->params().value_or(LogMessageParams()); - if (params.isValid(&error)) + if (params.isValid()) log(params); else logError(params); } else if (method == SemanticHighlightNotification::methodName) { auto params = dynamic_cast(content)->params().value_or(SemanticHighlightingParams()); - if (params.isValid(&error)) + if (params.isValid()) handleSemanticHighlight(params); else logError(params); } else if (method == ShowMessageNotification::methodName) { auto params = dynamic_cast(content)->params().value_or(ShowMessageParams()); - if (params.isValid(&error)) + if (params.isValid()) log(params); else logError(params); } else if (method == ShowMessageRequest::methodName) { auto request = dynamic_cast(content); auto params = request->params().value_or(ShowMessageRequestParams()); - if (params.isValid(&error)) { + if (params.isValid()) { showMessageBox(params, request->id()); } else { ShowMessageRequest::Response response(request->id()); @@ -1080,19 +1079,19 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon } } else if (method == RegisterCapabilityRequest::methodName) { auto params = dynamic_cast(content)->params().value_or(RegistrationParams()); - if (params.isValid(&error)) + if (params.isValid()) registerCapabilities(params.registrations()); else logError(params); } else if (method == UnregisterCapabilityRequest::methodName) { auto params = dynamic_cast(content)->params().value_or(UnregistrationParams()); - if (params.isValid(&error)) + if (params.isValid()) unregisterCapabilities(params.unregistrations()); else logError(params); } else if (method == ApplyWorkspaceEditRequest::methodName) { auto params = dynamic_cast(content)->params().value_or(ApplyWorkspaceEditParams()); - if (params.isValid(&error)) + if (params.isValid()) applyWorkspaceEdit(params.edit()); else logError(params); @@ -1111,7 +1110,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon } response.setResult(result); sendContent(response); - } else if (id.isValid(&error)) { + } else if (id.isValid()) { Response response(id); ResponseError error; error.setCode(ResponseError::MethodNotFound); @@ -1208,10 +1207,9 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse) log(tr("No initialize result.")); } else { const InitializeResult &result = _result.value(); - ErrorHierarchy error; - if (!result.isValid(&error)) { // continue on ill formed result + if (!result.isValid()) { // continue on ill formed result log(QJsonDocument(result).toJson(QJsonDocument::Indented) + '\n' - + tr("Initialize result is not valid: ") + error.toString()); + + tr("Initialize result is not valid")); } m_serverCapabilities = result.capabilities().value_or(ServerCapabilities()); diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index a0a9abd6cf1..a866cd6ba91 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -184,7 +184,7 @@ bool LanguageClientCompletionItem::isSnippet() const bool LanguageClientCompletionItem::isValid() const { - return m_item.isValid(nullptr); + return m_item.isValid(); } quint64 LanguageClientCompletionItem::hash() const diff --git a/src/plugins/languageclient/languageclientformatter.cpp b/src/plugins/languageclient/languageclientformatter.cpp index 31883d5fef0..566d1c829af 100644 --- a/src/plugins/languageclient/languageclientformatter.cpp +++ b/src/plugins/languageclient/languageclientformatter.cpp @@ -80,7 +80,7 @@ QFutureWatcher *LanguageClientFormatter::format( if (!registered.value()) return nullptr; const TextDocumentRegistrationOptions option(dynamicCapabilities.option(method).toObject()); - if (option.isValid(nullptr) + if (option.isValid() && !option.filterApplies(filePath, Utils::mimeTypeForName(m_document->mimeType()))) { return nullptr; } diff --git a/src/plugins/languageclient/languageclienthoverhandler.cpp b/src/plugins/languageclient/languageclienthoverhandler.cpp index 3ef437ac793..f9533ab4708 100644 --- a/src/plugins/languageclient/languageclienthoverhandler.cpp +++ b/src/plugins/languageclient/languageclienthoverhandler.cpp @@ -85,7 +85,7 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget, if (sendMessage) { const TextDocumentRegistrationOptions option( m_client->dynamicCapabilities().option(HoverRequest::methodName).toObject()); - if (option.isValid(nullptr)) { + if (option.isValid()) { sendMessage = option.filterApplies(editorWidget->textDocument()->filePath(), Utils::mimeTypeForName( editorWidget->textDocument()->mimeType())); diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp index 622b0100f08..c83a35411f8 100644 --- a/src/plugins/languageclient/languageclientoutline.cpp +++ b/src/plugins/languageclient/languageclientoutline.cpp @@ -231,7 +231,7 @@ bool LanguageClientOutlineWidgetFactory::clientSupportsDocumentSymbols( DynamicCapabilities dc = client->dynamicCapabilities(); if (dc.isRegistered(DocumentSymbolsRequest::methodName).value_or(false)) { TextDocumentRegistrationOptions options(dc.option(DocumentSymbolsRequest::methodName)); - return !options.isValid(nullptr) + return !options.isValid() || options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType())); } const Utils::optional> &provider diff --git a/src/plugins/languageclient/languageclientsymbolsupport.cpp b/src/plugins/languageclient/languageclientsymbolsupport.cpp index 8a29d0e510c..fc752548f07 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.cpp +++ b/src/plugins/languageclient/languageclientsymbolsupport.cpp @@ -56,7 +56,7 @@ static void sendTextDocumentPositionParamsRequest(Client *client, if (sendMessage) { const TextDocumentRegistrationOptions option( dynamicCapabilities.option(Request::methodName)); - if (option.isValid(nullptr)) + if (option.isValid()) sendMessage = option.filterApplies( Utils::FilePath::fromString(QUrl(uri).adjusted(QUrl::PreferLocalFile).toString())); else @@ -248,7 +248,7 @@ static bool supportsRename(Client *client, prepareSupported = ServerCapabilities::RenameOptions(options).prepareProvider().value_or( false); const TextDocumentRegistrationOptions docOps(options); - if (docOps.isValid(nullptr) + if (docOps.isValid() && !docOps.filterApplies(document->filePath(), Utils::mimeTypeForName(document->mimeType()))) { return false; @@ -411,7 +411,7 @@ void SymbolSupport::applyRename(const QList &checkedItem for (const Core::SearchResultItem &item : checkedItems) { auto uri = DocumentUri::fromFilePath(Utils::FilePath::fromString(item.path().value(0))); TextEdit edit(item.userData().toJsonObject()); - if (edit.isValid(nullptr)) + if (edit.isValid()) editsForDocuments[uri] << edit; } diff --git a/src/plugins/languageclient/languageclientutils.cpp b/src/plugins/languageclient/languageclientutils.cpp index 7f1f396d1f0..b94a9fc1c9e 100644 --- a/src/plugins/languageclient/languageclientutils.cpp +++ b/src/plugins/languageclient/languageclientutils.cpp @@ -152,7 +152,7 @@ void updateCodeActionRefactoringMarker(Client *client, RefactorMarkers markers; RefactorMarker marker; marker.type = client->id(); - if (action.isValid(nullptr)) + if (action.isValid()) marker.tooltip = action.title(); if (action.edit().has_value()) { WorkspaceEdit edit = action.edit().value(); diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp index 137d5f6327f..c5d7ffbd118 100644 --- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp +++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp @@ -60,8 +60,6 @@ private slots: void jsonMessageToBaseMessage_data(); void jsonMessageToBaseMessage(); - void jsonObject(); - void documentUri_data(); void documentUri(); @@ -478,127 +476,6 @@ void tst_LanguageServerProtocol::jsonMessageToBaseMessage() QCOMPARE(jsonMessage.toBaseMessage(), baseMessage); } -class JsonTestObject : public JsonObject -{ -public: - using JsonObject::JsonObject; - using JsonObject::insert; - using JsonObject::value; - using JsonObject::contains; - using JsonObject::find; - using JsonObject::end; - using JsonObject::remove; - using JsonObject::keys; - using JsonObject::typedValue; - using JsonObject::optionalValue; - using JsonObject::clientValue; - using JsonObject::optionalClientValue; - using JsonObject::array; - using JsonObject::optionalArray; - using JsonObject::clientArray; - using JsonObject::optionalClientArray; - using JsonObject::insertArray; - using JsonObject::checkKey; - using JsonObject::valueTypeString; - using JsonObject::check; - using JsonObject::checkType; - using JsonObject::checkVal; - using JsonObject::checkArray; - using JsonObject::checkOptional; - using JsonObject::checkOptionalArray; - using JsonObject::errorString; - using JsonObject::operator==; -}; - -void tst_LanguageServerProtocol::jsonObject() -{ - JsonTestObject obj; - - obj.insert("integer", 42); - obj.insert("double", 42.42); - obj.insert("bool", false); - obj.insert("null", QJsonValue::Null); - obj.insert("string", "foobar"); - obj.insertArray("strings", QStringList{"foo", "bar"}); - const JsonTestObject innerObj(obj); - obj.insert("object", innerObj); - - QCOMPARE(obj.value("integer"), QJsonValue(42)); - QCOMPARE(obj.value("double"), QJsonValue(42.42)); - QCOMPARE(obj.value("bool"), QJsonValue(false)); - QCOMPARE(obj.value("null"), QJsonValue(QJsonValue::Null)); - QCOMPARE(obj.value("string"), QJsonValue("foobar")); - QCOMPARE(obj.value("strings"), QJsonValue(QJsonArray({"foo", "bar"}))); - QCOMPARE(obj.value("object"), QJsonValue(QJsonObject(innerObj))); - - QCOMPARE(obj.typedValue("integer"), 42); - QCOMPARE(obj.typedValue("double"), 42.42); - QCOMPARE(obj.typedValue("bool"), false); - QCOMPARE(obj.typedValue("string"), QString("foobar")); - QCOMPARE(obj.typedValue("object"), innerObj); - - QVERIFY(!obj.optionalValue("doesNotExist").has_value()); - QVERIFY(obj.optionalValue("integer").has_value()); - QCOMPARE(obj.optionalValue("integer").value_or(0), 42); - - QVERIFY(obj.clientValue("null").isNull()); - QVERIFY(!obj.clientValue("integer").isNull()); - QCOMPARE(obj.clientValue("integer").value(), 42); - - QVERIFY(!obj.optionalClientValue("doesNotExist").has_value()); - QVERIFY(obj.optionalClientValue("null").has_value()); - QVERIFY(obj.optionalClientValue("null").value().isNull()); - QVERIFY(obj.optionalClientValue("integer").has_value()); - QVERIFY(!obj.optionalClientValue("integer").value().isNull()); - QCOMPARE(obj.optionalClientValue("integer").value().value(0), 42); - - QCOMPARE(obj.array("strings"), QList({"foo", "bar"})); - - QVERIFY(!obj.optionalArray("doesNotExist").has_value()); - QVERIFY(obj.optionalArray("strings").has_value()); - QCOMPARE(obj.optionalArray("strings").value_or(QList()), - QList({"foo", "bar"})); - - QVERIFY(obj.clientArray("null").isNull()); - QVERIFY(!obj.clientArray("strings").isNull()); - QCOMPARE(obj.clientArray("strings").toList(), QList({"foo", "bar"})); - - QVERIFY(!obj.optionalClientArray("doesNotExist").has_value()); - QVERIFY(obj.optionalClientArray("null").has_value()); - QVERIFY(obj.optionalClientArray("null").value().isNull()); - QVERIFY(obj.optionalClientArray("strings").has_value()); - QVERIFY(!obj.optionalClientArray("strings").value().isNull()); - QCOMPARE(obj.optionalClientArray("strings").value().toList(), - QList({"foo", "bar"})); - - ErrorHierarchy errorHierarchy; - QVERIFY(!obj.check(&errorHierarchy, "doesNotExist")); - ErrorHierarchy errorDoesNotExists; - errorDoesNotExists.setError( - JsonTestObject::errorString(QJsonValue::Double, QJsonValue::Undefined)); - errorDoesNotExists.prependMember("doesNotExist"); - QCOMPARE(errorHierarchy, errorDoesNotExists); - errorHierarchy.clear(); - - QVERIFY(!obj.check(&errorHierarchy, "bool")); - ErrorHierarchy errorWrongType; - errorWrongType.setError(JsonTestObject::errorString(QJsonValue::Double, QJsonValue::Bool)); - errorWrongType.prependMember("bool"); - QCOMPARE(errorHierarchy, errorWrongType); - errorHierarchy.clear(); - - QVERIFY(obj.check(&errorHierarchy, "integer")); - QVERIFY(errorHierarchy.isEmpty()); - QVERIFY(obj.check(&errorHierarchy, "double")); - QVERIFY(errorHierarchy.isEmpty()); - QVERIFY(obj.check(&errorHierarchy, "bool")); - QVERIFY(errorHierarchy.isEmpty()); - QVERIFY(obj.check(&errorHierarchy, "null")); - QVERIFY(errorHierarchy.isEmpty()); - QVERIFY(obj.check(&errorHierarchy, "string")); - QVERIFY(errorHierarchy.isEmpty()); -} - void tst_LanguageServerProtocol::documentUri_data() { QTest::addColumn("uri");