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 <hjk@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-02-26 08:29:15 +01:00
parent 687597152e
commit d17277b546
35 changed files with 215 additions and 1104 deletions

View File

@@ -50,8 +50,7 @@ public:
void setRegisterOptions(const QJsonValue &registerOptions) void setRegisterOptions(const QJsonValue &registerOptions)
{ insert(registerOptionsKey, registerOptions); } { insert(registerOptionsKey, registerOptions); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(idKey) && contains(methodKey); }
{ return check<QString>(error, idKey) && check<QString>(error, methodKey); }
}; };
class RegistrationParams : public JsonObject class RegistrationParams : public JsonObject
@@ -66,8 +65,7 @@ public:
void setRegistrations(const QList<Registration> &registrations) void setRegistrations(const QList<Registration> &registrations)
{ insertArray(registrationsKey, registrations); } { insertArray(registrationsKey, registrations); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(registrationsKey); }
{ return checkArray<Registration>(error, registrationsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT RegisterCapabilityRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT RegisterCapabilityRequest : public Request<
@@ -90,8 +88,7 @@ public:
QString method() const { return typedValue<QString>(methodKey); } QString method() const { return typedValue<QString>(methodKey); }
void setMethod(const QString &method) { insert(methodKey, method); } void setMethod(const QString &method) { insert(methodKey, method); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(idKey) && contains(methodKey); }
{ return check<QString>(error, idKey) && check<QString>(error, methodKey); }
}; };
class UnregistrationParams : public JsonObject class UnregistrationParams : public JsonObject
@@ -104,8 +101,7 @@ public:
void setUnregistrations(const QList<Unregistration> &unregistrations) void setUnregistrations(const QList<Unregistration> &unregistrations)
{ insertArray(unregistrationsKey, unregistrations); } { insertArray(unregistrationsKey, unregistrations); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(unregistrationsKey); }
{ return checkArray<Unregistration>(error, unregistrationsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT UnregisterCapabilityRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT UnregisterCapabilityRequest : public Request<

View File

@@ -42,96 +42,9 @@ void SymbolCapabilities::SymbolKindCapabilities::setValueSet(const QList<SymbolK
insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet)); insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet));
} }
bool ClientCapabilities::isValid(ErrorHierarchy *error) const
{
return checkOptional<WorkspaceClientCapabilities>(error, workspaceKey)
&& checkOptional<TextDocumentClientCapabilities>(error, textDocumentKey);
}
WorkspaceClientCapabilities::WorkspaceClientCapabilities() WorkspaceClientCapabilities::WorkspaceClientCapabilities()
{ {
setWorkspaceFolders(true); setWorkspaceFolders(true);
} }
bool WorkspaceClientCapabilities::isValid(ErrorHierarchy *error) const
{
return checkOptional<bool>(error,applyEditKey)
&& checkOptional<WorkspaceEditCapabilities>(error,workspaceEditKey)
&& checkOptional<DynamicRegistrationCapabilities>(error,didChangeConfigurationKey)
&& checkOptional<DynamicRegistrationCapabilities>(error,didChangeWatchedFilesKey)
&& checkOptional<SymbolCapabilities>(error,symbolKey)
&& checkOptional<DynamicRegistrationCapabilities>(error,executeCommandKey)
&& checkOptional<bool>(error,workspaceFoldersKey)
&& checkOptional<bool>(error,configurationKey);
}
bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(ErrorHierarchy *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptional<bool>(error, willSaveKey)
&& checkOptional<bool>(error, willSaveWaitUntilKey)
&& checkOptional<bool>(error, didSaveKey);
}
bool TextDocumentClientCapabilities::isValid(ErrorHierarchy *error) const
{
return checkOptional<SynchronizationCapabilities>(error, synchronizationKey)
&& checkOptional<CompletionCapabilities>(error, completionKey)
&& checkOptional<HoverCapabilities>(error, hoverKey)
&& checkOptional<SignatureHelpCapabilities>(error, signatureHelpKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, referencesKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, documentHighlightKey)
&& checkOptional<SymbolCapabilities>(error, documentSymbolKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, formattingKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, rangeFormattingKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, onTypeFormattingKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, definitionKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, typeDefinitionKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, implementationKey)
&& checkOptional<CodeActionCapabilities>(error, codeActionKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, codeLensKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, documentLinkKey)
&& checkOptional<DynamicRegistrationCapabilities>(error, colorProviderKey)
&& checkOptional<RenameClientCapabilities>(error, renameKey)
&& checkOptional<SemanticHighlightingCapabilities>(error, semanticHighlightingCapabilitiesKey);
}
bool SymbolCapabilities::isValid(ErrorHierarchy *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptional<SymbolKindCapabilities>(error, symbolKindKey);
}
bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(ErrorHierarchy *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptional<CompletionItemCapbilities>(error, completionItemKey)
&& checkOptional<CompletionItemKindCapabilities>(error, completionItemKindKey)
&& checkOptional<bool>(error, contextSupportKey);
}
bool TextDocumentClientCapabilities::HoverCapabilities::isValid(ErrorHierarchy *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptionalArray<int>(error, contentFormatKey);
}
bool TextDocumentClientCapabilities::SignatureHelpCapabilities::isValid(ErrorHierarchy *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptional<SignatureHelpCapabilities>(error, signatureInformationKey);
}
bool TextDocumentClientCapabilities::CodeActionCapabilities::isValid(ErrorHierarchy *errorHierarchy) const
{
return DynamicRegistrationCapabilities::isValid(errorHierarchy)
&& checkOptional<CodeActionLiteralSupport>(errorHierarchy, codeActionLiteralSupportKey);
}
bool TextDocumentClientCapabilities::RenameClientCapabilities::isValid(ErrorHierarchy *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptional<bool>(error, prepareSupportKey);
}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -38,9 +38,6 @@ public:
Utils::optional<bool> dynamicRegistration() const { return optionalValue<bool>(dynamicRegistrationKey); } Utils::optional<bool> dynamicRegistration() const { return optionalValue<bool>(dynamicRegistrationKey); }
void setDynamicRegistration(bool dynamicRegistration) { insert(dynamicRegistrationKey, dynamicRegistration); } void setDynamicRegistration(bool dynamicRegistration) { insert(dynamicRegistrationKey, dynamicRegistration); }
void clearDynamicRegistration() { remove(dynamicRegistrationKey); } void clearDynamicRegistration() { remove(dynamicRegistrationKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<bool>(error, dynamicRegistrationKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SymbolCapabilities : public DynamicRegistrationCapabilities class LANGUAGESERVERPROTOCOL_EXPORT SymbolCapabilities : public DynamicRegistrationCapabilities
@@ -66,9 +63,6 @@ public:
Utils::optional<QList<SymbolKind>> valueSet() const; Utils::optional<QList<SymbolKind>> valueSet() const;
void setValueSet(const QList<SymbolKind> &valueSet); void setValueSet(const QList<SymbolKind> &valueSet);
void clearValueSet() { remove(valueSetKey); } void clearValueSet() { remove(valueSetKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptionalArray<int>(error, valueSetKey); }
}; };
// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. // Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
@@ -76,8 +70,6 @@ public:
{ return optionalValue<SymbolKindCapabilities>(symbolKindKey); } { return optionalValue<SymbolKindCapabilities>(symbolKindKey); }
void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); } void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); }
void clearSymbolKind() { remove(symbolKindKey); } void clearSymbolKind() { remove(symbolKindKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentClientCapabilities : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentClientCapabilities : public JsonObject
@@ -110,8 +102,6 @@ public:
Utils::optional<bool> didSave() const { return optionalValue<bool>(didSaveKey); } Utils::optional<bool> didSave() const { return optionalValue<bool>(didSaveKey); }
void setDidSave(bool didSave) { insert(didSaveKey, didSave); } void setDidSave(bool didSave) { insert(didSaveKey, didSave); }
void clearDidSave() { remove(didSaveKey); } void clearDidSave() { remove(didSaveKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
Utils::optional<SynchronizationCapabilities> synchronization() const Utils::optional<SynchronizationCapabilities> synchronization() const
@@ -129,8 +119,7 @@ public:
void setSemanticHighlighting(bool semanticHighlighting) void setSemanticHighlighting(bool semanticHighlighting)
{ insert(semanticHighlightingKey, semanticHighlighting); } { insert(semanticHighlightingKey, semanticHighlighting); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(semanticHighlightingKey); }
{ return check<bool>(error, semanticHighlightingKey); }
}; };
Utils::optional<SemanticHighlightingCapabilities> semanticHighlightingCapabilities() const Utils::optional<SemanticHighlightingCapabilities> semanticHighlightingCapabilities() const
@@ -178,13 +167,6 @@ public:
Utils::optional<QList<MarkupKind>> documentationFormat() const; Utils::optional<QList<MarkupKind>> documentationFormat() const;
void setDocumentationFormat(const QList<MarkupKind> &documentationFormat); void setDocumentationFormat(const QList<MarkupKind> &documentationFormat);
void clearDocumentationFormat() { remove(documentationFormatKey); } void clearDocumentationFormat() { remove(documentationFormatKey); }
bool isValid(ErrorHierarchy *error) const override
{
return checkOptional<bool>(error, snippetSupportKey)
&& checkOptional<bool>(error, commitCharacterSupportKey)
&& checkOptionalArray<int>(error, documentationFormatKey);
}
}; };
// The client supports the following `CompletionItem` specific capabilities. // The client supports the following `CompletionItem` specific capabilities.
@@ -212,9 +194,6 @@ public:
Utils::optional<QList<CompletionItemKind::Kind>> valueSet() const; Utils::optional<QList<CompletionItemKind::Kind>> valueSet() const;
void setValueSet(const QList<CompletionItemKind::Kind> &valueSet); void setValueSet(const QList<CompletionItemKind::Kind> &valueSet);
void clearValueSet() { remove(valueSetKey); } void clearValueSet() { remove(valueSetKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptionalArray<int>(error, valueSetKey); }
}; };
Utils::optional<CompletionItemKindCapabilities> completionItemKind() const Utils::optional<CompletionItemKindCapabilities> completionItemKind() const
@@ -230,8 +209,6 @@ public:
Utils::optional<bool> contextSupport() const { return optionalValue<bool>(contextSupportKey); } Utils::optional<bool> contextSupport() const { return optionalValue<bool>(contextSupportKey); }
void setContextSupport(bool contextSupport) { insert(contextSupportKey, contextSupport); } void setContextSupport(bool contextSupport) { insert(contextSupportKey, contextSupport); }
void clearContextSupport() { remove(contextSupportKey); } void clearContextSupport() { remove(contextSupportKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
// Capabilities specific to the `textDocument/completion` // Capabilities specific to the `textDocument/completion`
@@ -252,8 +229,6 @@ public:
Utils::optional<QList<MarkupKind>> contentFormat() const; Utils::optional<QList<MarkupKind>> contentFormat() const;
void setContentFormat(const QList<MarkupKind> &contentFormat); void setContentFormat(const QList<MarkupKind> &contentFormat);
void clearContentFormat() { remove(contentFormatKey); } void clearContentFormat() { remove(contentFormatKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
Utils::optional<HoverCapabilities> hover() const { return optionalValue<HoverCapabilities>(hoverKey); } Utils::optional<HoverCapabilities> hover() const { return optionalValue<HoverCapabilities>(hoverKey); }
@@ -276,9 +251,6 @@ public:
Utils::optional<QList<MarkupKind>> documentationFormat() const; Utils::optional<QList<MarkupKind>> documentationFormat() const;
void setDocumentationFormat(const QList<MarkupKind> &documentationFormat); void setDocumentationFormat(const QList<MarkupKind> &documentationFormat);
void clearDocumentationFormat() { remove(documentationFormatKey); } void clearDocumentationFormat() { remove(documentationFormatKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptionalArray<int>(error, documentationFormatKey); }
}; };
// The client supports the following `SignatureInformation` specific properties. // The client supports the following `SignatureInformation` specific properties.
@@ -287,8 +259,6 @@ public:
void setSignatureInformation(const SignatureInformationCapabilities &signatureInformation) void setSignatureInformation(const SignatureInformationCapabilities &signatureInformation)
{ insert(signatureInformationKey, signatureInformation); } { insert(signatureInformationKey, signatureInformation); }
void clearSignatureInformation() { remove(signatureInformationKey); } void clearSignatureInformation() { remove(signatureInformationKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
// Capabilities specific to the `textDocument/signatureHelp` // Capabilities specific to the `textDocument/signatureHelp`
@@ -390,8 +360,7 @@ public:
void setValueSet(const QList<QString> &valueSet) void setValueSet(const QList<QString> &valueSet)
{ insertArray(valueSetKey, valueSet); } { insertArray(valueSetKey, valueSet); }
bool isValid(ErrorHierarchy *errorHierarchy) const override bool isValid() const override { return contains(valueSetKey); }
{ return checkArray<QString>(errorHierarchy, valueSetKey); }
}; };
CodeActionKind codeActionKind() const CodeActionKind codeActionKind() const
@@ -399,8 +368,7 @@ public:
void setCodeActionKind(const CodeActionKind &codeActionKind) void setCodeActionKind(const CodeActionKind &codeActionKind)
{ insert(codeActionKindKey, codeActionKind); } { insert(codeActionKindKey, codeActionKind); }
bool isValid(ErrorHierarchy *errorHierarchy) const override bool isValid() const override { return contains(codeActionKindKey); }
{ return check<CodeActionKind>(errorHierarchy, codeActionKindKey); }
}; };
Utils::optional<CodeActionLiteralSupport> codeActionLiteralSupport() const Utils::optional<CodeActionLiteralSupport> codeActionLiteralSupport() const
@@ -408,8 +376,6 @@ public:
void setCodeActionLiteralSupport(const CodeActionLiteralSupport &codeActionLiteralSupport) void setCodeActionLiteralSupport(const CodeActionLiteralSupport &codeActionLiteralSupport)
{ insert(codeActionLiteralSupportKey, codeActionLiteralSupport); } { insert(codeActionLiteralSupportKey, codeActionLiteralSupport); }
void clearCodeActionLiteralSupport() { remove(codeActionLiteralSupportKey); } void clearCodeActionLiteralSupport() { remove(codeActionLiteralSupportKey); }
bool isValid(ErrorHierarchy *errorHierarchy) const override;
}; };
// Whether code action supports dynamic registration. // Whether code action supports dynamic registration.
@@ -458,8 +424,6 @@ public:
Utils::optional<bool> prepareSupport() const { return optionalValue<bool>(prepareSupportKey); } Utils::optional<bool> prepareSupport() const { return optionalValue<bool>(prepareSupportKey); }
void setPrepareSupport(bool prepareSupport) { insert(prepareSupportKey, prepareSupport); } void setPrepareSupport(bool prepareSupport) { insert(prepareSupportKey, prepareSupport); }
void clearPrepareSupport() { remove(prepareSupportKey); } void clearPrepareSupport() { remove(prepareSupportKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
// Whether rename supports dynamic registration. // Whether rename supports dynamic registration.
@@ -468,8 +432,6 @@ public:
void setRename(const RenameClientCapabilities &rename) void setRename(const RenameClientCapabilities &rename)
{ insert(renameKey, rename); } { insert(renameKey, rename); }
void clearRename() { remove(renameKey); } void clearRename() { remove(renameKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject
@@ -497,9 +459,6 @@ public:
void setDocumentChanges(bool documentChanges) void setDocumentChanges(bool documentChanges)
{ insert(documentChangesKey, documentChanges); } { insert(documentChangesKey, documentChanges); }
void clearDocumentChanges() { remove(documentChangesKey); } void clearDocumentChanges() { remove(documentChangesKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<bool>(error, documentChangesKey); }
}; };
// Capabilities specific to `WorkspaceEdit`s // Capabilities specific to `WorkspaceEdit`s
@@ -547,8 +506,6 @@ public:
Utils::optional<bool> configuration() const { return optionalValue<bool>(configurationKey); } Utils::optional<bool> configuration() const { return optionalValue<bool>(configurationKey); }
void setConfiguration(bool configuration) { insert(configurationKey, configuration); } void setConfiguration(bool configuration) { insert(configurationKey, configuration); }
void clearConfiguration() { remove(configurationKey); } void clearConfiguration() { remove(configurationKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject
@@ -574,8 +531,6 @@ public:
QJsonValue experimental() const { return value(experimentalKey); } QJsonValue experimental() const { return value(experimentalKey); }
void setExperimental(const QJsonValue &experimental) { insert(experimentalKey, experimental); } void setExperimental(const QJsonValue &experimental) { insert(experimentalKey, experimental); }
void clearExperimental() { remove(experimentalKey); } void clearExperimental() { remove(experimentalKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
} }

View File

@@ -49,40 +49,12 @@ Utils::optional<CompletionItem::InsertTextFormat> CompletionItem::insertTextForm
: Utils::make_optional(CompletionItem::InsertTextFormat(value.value())); : Utils::make_optional(CompletionItem::InsertTextFormat(value.value()));
} }
bool CompletionItem::isValid(ErrorHierarchy *error) const
{
return check<QString>(error, labelKey)
&& checkOptional<int>(error, kindKey)
&& checkOptional<QString>(error, detailKey)
&& checkOptional<QString>(error, documentationKey)
&& checkOptional<QString>(error, sortTextKey)
&& checkOptional<QString>(error, filterTextKey)
&& checkOptional<QString>(error, insertTextKey)
&& checkOptional<int>(error, insertTextFormatKey)
&& checkOptional<TextEdit>(error, textEditKey)
&& checkOptionalArray<TextEdit>(error, additionalTextEditsKey)
&& checkOptionalArray<QString>(error, commitCharactersKey)
&& checkOptional<Command>(error, commandKey)
&& checkOptional<QJsonValue>(error, dataKey);
}
CompletionItemResolveRequest::CompletionItemResolveRequest(const CompletionItem &params) CompletionItemResolveRequest::CompletionItemResolveRequest(const CompletionItem &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
bool CompletionList::isValid(ErrorHierarchy *error) const
{
return check<bool>(error, isIncompleteKey)
&& checkOptionalArray<CompletionItem>(error, itemsKey);
}
bool CompletionParams::isValid(ErrorHierarchy *error) const
{
return TextDocumentPositionParams::isValid(error)
&& checkOptional<CompletionContext>(error, contextKey);
}
CompletionResult::CompletionResult(const QJsonValue &value) CompletionResult::CompletionResult(const QJsonValue &value)
{ {
if (value.isNull()) { if (value.isNull()) {

View File

@@ -71,11 +71,7 @@ public:
{ insert(triggerCharacterKey, triggerCharacter); } { insert(triggerCharacterKey, triggerCharacter); }
void clearTriggerCharacter() { remove(triggerCharacterKey); } void clearTriggerCharacter() { remove(triggerCharacterKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(triggerKindKey); }
{
return check<int>(error, triggerKindKey)
&& checkOptional<QString>(error, triggerCharacterKey);
}
}; };
/** /**
@@ -87,8 +83,6 @@ public:
void setContext(const CompletionContext &context) void setContext(const CompletionContext &context)
{ insert(contextKey, context); } { insert(contextKey, context); }
void clearContext() { remove(contextKey); } void clearContext() { remove(contextKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT CompletionItem : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT CompletionItem : public JsonObject
@@ -220,7 +214,7 @@ public:
void setData(const QJsonValue &data) { insert(dataKey, data); } void setData(const QJsonValue &data) { insert(dataKey, data); }
void clearData() { remove(dataKey); } void clearData() { remove(dataKey); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(labelKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT CompletionList : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT CompletionList : public JsonObject
@@ -240,7 +234,7 @@ public:
void setItems(const QList<CompletionItem> &items) { insertArray(itemsKey, items); } void setItems(const QList<CompletionItem> &items) { insertArray(itemsKey, items); }
void clearItems() { remove(itemsKey); } 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 /// The result of a completion is CompletionItem[] | CompletionList | null

View File

@@ -46,8 +46,7 @@ public:
void setVersion(int version) { insert(versionKey, version); } void setVersion(int version) { insert(versionKey, version); }
void clearVersion() { remove(versionKey); } void clearVersion() { remove(versionKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(diagnosticsKey); }
{ return checkArray<Diagnostic>(error, diagnosticsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT PublishDiagnosticsNotification : public Notification<PublishDiagnosticsParams> class LANGUAGESERVERPROTOCOL_EXPORT PublishDiagnosticsNotification : public Notification<PublishDiagnosticsParams>

View File

@@ -60,7 +60,7 @@ public:
*this = MessageId(value.toString()); *this = MessageId(value.toString());
} }
QJsonValue toJson() const operator QJsonValue() const
{ {
QTC_CHECK(Utils::holds_alternative<int>(*this) || Utils::holds_alternative<QString>(*this)); QTC_CHECK(Utils::holds_alternative<int>(*this) || Utils::holds_alternative<QString>(*this));
if (auto id = Utils::get_if<int>(this)) if (auto id = Utils::get_if<int>(this))
@@ -70,14 +70,7 @@ public:
return QJsonValue(); return QJsonValue();
} }
bool isValid(ErrorHierarchy *error = nullptr) const bool isValid() const { return true; }
{
if (Utils::holds_alternative<int>(*this) || Utils::holds_alternative<QString>(*this))
return true;
if (error)
error->setError("Expected int or string as MessageId");
return false;
}
QString toString() const QString toString() const
{ {

View File

@@ -132,6 +132,14 @@ InitializeParams::InitializeParams()
setTrace(s_trace); setTrace(s_trace);
} }
Utils::optional<QJsonObject> InitializeParams::initializationOptions() const
{
const QJsonValue &optionsValue = value(initializationOptionsKey);
if (optionsValue.isObject())
return optionsValue.toObject();
return Utils::nullopt;
}
Utils::optional<Trace> InitializeParams::trace() const Utils::optional<Trace> InitializeParams::trace() const
{ {
const QJsonValue &traceValue = value(traceKey); const QJsonValue &traceValue = value(traceKey);
@@ -140,17 +148,6 @@ Utils::optional<Trace> InitializeParams::trace() const
return Utils::make_optional(Trace(traceValue.toString())); return Utils::make_optional(Trace(traceValue.toString()));
} }
bool InitializeParams::isValid(ErrorHierarchy *error) const
{
return checkVariant<int, std::nullptr_t>(error, processIdKey)
&& checkOptional<QString, std::nullptr_t>(error, rootPathKey)
&& checkOptional<QString, std::nullptr_t>(error, rootUriKey)
&& check<ClientCapabilities>(error, capabilitiesKey)
&& checkOptional<int>(error, traceKey)
&& (checkOptional<std::nullptr_t>(error, workspaceFoldersKey)
|| checkOptionalArray<WorkSpaceFolder>(error, workspaceFoldersKey));
}
InitializeRequest::InitializeRequest(const InitializeParams &params) InitializeRequest::InitializeRequest(const InitializeParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }

View File

@@ -91,8 +91,7 @@ public:
{ insert(rootUriKey, uri); } { insert(rootUriKey, uri); }
// User provided initialization options. // User provided initialization options.
Utils::optional<QJsonObject> initializationOptions() const Utils::optional<QJsonObject> initializationOptions() const;
{ return optionalValue<QJsonObject>(initializationOptionsKey); }
void setInitializationOptions(const QJsonObject &options) void setInitializationOptions(const QJsonObject &options)
{ insert(initializationOptionsKey, options); } { insert(initializationOptionsKey, options); }
void clearInitializationOptions() { remove(initializationOptionsKey); } void clearInitializationOptions() { remove(initializationOptionsKey); }
@@ -121,7 +120,8 @@ public:
{ insert(workspaceFoldersKey, folders.toJson()); } { insert(workspaceFoldersKey, folders.toJson()); }
void clearWorkSpaceFolders() { remove(workspaceFoldersKey); } void clearWorkSpaceFolders() { remove(workspaceFoldersKey); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override
{ return contains(processIdKey) && contains(rootUriKey) && contains(capabilitiesKey); }
}; };
using InitializedParams = JsonObject; using InitializedParams = JsonObject;
@@ -146,9 +146,6 @@ public:
void setCapabilities(const ServerCapabilities &capabilities) void setCapabilities(const ServerCapabilities &capabilities)
{ insert(capabilitiesKey, capabilities); } { insert(capabilitiesKey, capabilities); }
void clearCapabilities() { remove(capabilitiesKey); } void clearCapabilities() { remove(capabilitiesKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<ServerCapabilities>(error, capabilitiesKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT InitializeError : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT InitializeError : public JsonObject
@@ -165,8 +162,6 @@ public:
Utils::optional<bool> retry() const { return optionalValue<bool>(retryKey); } Utils::optional<bool> retry() const { return optionalValue<bool>(retryKey); }
void setRetry(bool retry) { insert(retryKey, retry); } void setRetry(bool retry) { insert(retryKey, retry); }
void clearRetry() { remove(retryKey); } void clearRetry() { remove(retryKey); }
bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, retryKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT InitializeRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT InitializeRequest : public Request<

View File

@@ -29,34 +29,6 @@
namespace LanguageServerProtocol { namespace LanguageServerProtocol {
template <>
bool JsonObject::checkVal<QString>(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{ return checkType(val.type(), QJsonValue::String, errorHierarchy); }
template <>
bool JsonObject::checkVal<int>(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{ return checkType(val.type(), QJsonValue::Double, errorHierarchy); }
template <>
bool JsonObject::checkVal<double>(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{ return checkType(val.type(), QJsonValue::Double, errorHierarchy); }
template <>
bool JsonObject::checkVal<bool>(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{ return checkType(val.type(), QJsonValue::Bool, errorHierarchy); }
template <>
bool JsonObject::checkVal<std::nullptr_t>(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{ return checkType(val.type(), QJsonValue::Null, errorHierarchy); }
template<>
bool JsonObject::checkVal<QJsonArray>(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{ return checkType(val.type(), QJsonValue::Array, errorHierarchy); }
template<>
bool JsonObject::checkVal<QJsonValue>(ErrorHierarchy * /*errorHierarchy*/, const QJsonValue &/*val*/)
{ return true; }
JsonObject &JsonObject::operator=(const JsonObject &other) = default; JsonObject &JsonObject::operator=(const JsonObject &other) = default;
JsonObject &JsonObject::operator=(JsonObject &&other) 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); return m_jsonObject.insert(key, value);
} }
bool JsonObject::checkKey(ErrorHierarchy *errorHierarchy, const QString &key,
const std::function<bool (const QJsonValue &)> &predicate) const
{
const bool valid = predicate(m_jsonObject.value(key));
if (!valid && errorHierarchy)
errorHierarchy->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 } // namespace LanguageServerProtocol

View File

@@ -61,7 +61,7 @@ public:
operator const QJsonObject&() const { return m_jsonObject; } 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(); } iterator end() { return m_jsonObject.end(); }
const_iterator end() const { return m_jsonObject.end(); } const_iterator end() const { return m_jsonObject.end(); }
@@ -105,31 +105,6 @@ protected:
template<typename> template<typename>
void insertArray(const QString &key, const QList<JsonObject> &array); void insertArray(const QString &key, const QList<JsonObject> &array);
// value checking
bool checkKey(ErrorHierarchy *errorHierarchy, const QString &key,
const std::function<bool(const QJsonValue &val)> &predicate) const;
static QString valueTypeString(QJsonValue::Type type);
static QString errorString(QJsonValue::Type expected, QJsonValue::Type type2);
static bool checkType(QJsonValue::Type type,
QJsonValue::Type expectedType,
ErrorHierarchy *errorHierarchy);
template <typename T>
static bool checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val);
template <typename T>
bool check(ErrorHierarchy *errorHierarchy, const QString &key) const;
template <typename T1, typename T2, typename... Args>
bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const;
template <typename T>
bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const;
template <typename T>
bool checkArray(ErrorHierarchy *errorHierarchy, const QString &key) const;
template <typename T1, typename T2, typename... Args>
bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const;
template <typename T>
bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const;
template <typename T>
bool checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const;
private: private:
QJsonObject m_jsonObject; QJsonObject m_jsonObject;
}; };
@@ -218,122 +193,4 @@ void JsonObject::insertArray(const QString &key, const QList<JsonObject> &array)
insert(key, jsonArray); insert(key, jsonArray);
} }
template <typename T>
bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val)
{
return checkType(val.type(), QJsonValue::Object, errorHierarchy)
&& T(val).isValid(errorHierarchy);
}
template <typename T>
bool JsonObject::check(ErrorHierarchy *errorHierarchy, const QString &key) const
{
return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val) {
return checkVal<T>(errorHierarchy, val);
});
}
template <typename T1, typename T2, typename... Args>
bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const
{
if (checkVariant<T1>(errorHierarchy, key))
return true;
if (checkVariant<T2, Args...>(errorHierarchy, key)) {
if (errorHierarchy)
errorHierarchy->clear();
return true;
}
errorHierarchy->setError(
QCoreApplication::translate("LanguageServerProtocol::JsonObject",
"None of the following variants could be correctly parsed:"));
return false;
}
template <typename T>
bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const
{
if (!errorHierarchy)
return check<T>(nullptr, key);
ErrorHierarchy subError;
if (check<T>(&subError, key))
return true;
errorHierarchy->addVariantHierachy(subError);
return false;
}
template <typename T>
bool JsonObject::checkArray(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<T>(errorHierarchy, value);
});
});
}
template <typename T1, typename T2, typename... Args>
bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const
{
if (!contains(key))
return true;
if (checkVariant<T1>(errorHierarchy, key))
return true;
if (checkVariant<T2, Args...>(errorHierarchy, key)) {
if (errorHierarchy)
errorHierarchy->clear();
return true;
}
errorHierarchy->setError(
QCoreApplication::translate("LanguageServerProtocol::JsonObject",
"None of the following variants could be correctly parsed:"));
return false;
}
template <typename T>
bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const
{
if (contains(key))
return check<T>(errorHierarchy, key);
return true;
}
template <typename T>
bool JsonObject::checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const
{
if (contains(key))
return checkArray<T>(errorHierarchy, key);
return true;
}
template <>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QString>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
template <>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<int>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
template <>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<double>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
template <>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<bool>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
template <>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<std::nullptr_t>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
template<>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonArray>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
template<>
LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonValue>(ErrorHierarchy *errorHierarchy,
const QJsonValue &val);
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -121,7 +121,7 @@ public:
virtual bool parametersAreValid(QString *errorMessage) const virtual bool parametersAreValid(QString *errorMessage) const
{ {
if (auto parameter = params()) if (auto parameter = params())
return parameter.value().isValid(nullptr); return parameter.value().isValid();
if (errorMessage) if (errorMessage)
*errorMessage = QCoreApplication::translate("LanguageServerProtocol::Notification", *errorMessage = QCoreApplication::translate("LanguageServerProtocol::Notification",
"No parameters in \"%1\".").arg(method()); "No parameters in \"%1\".").arg(method());
@@ -179,12 +179,7 @@ public:
void setData(const Error &data) { insert(dataKey, data); } void setData(const Error &data) { insert(dataKey, data); }
void clearData() { remove(dataKey); } void clearData() { remove(dataKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(codeKey) && contains(messageKey); }
{
return check<int>(error, codeKey)
&& check<QString>(error, messageKey)
&& checkOptional<Error>(error, dataKey);
}
QString toString() const { return errorCodesToString(code()) + ": " + message(); } QString toString() const { return errorCodesToString(code()) + ": " + message(); }
@@ -237,7 +232,7 @@ public:
MessageId id() const MessageId id() const
{ return MessageId(m_jsonObject.value(idKey)); } { return MessageId(m_jsonObject.value(idKey)); }
void setId(MessageId id) void setId(MessageId id)
{ this->m_jsonObject.insert(idKey, id.toJson()); } { this->m_jsonObject.insert(idKey, id); }
Utils::optional<Result> result() const Utils::optional<Result> result() const
{ {
@@ -277,7 +272,7 @@ public:
MessageId id() const MessageId id() const
{ return MessageId(JsonRpcMessage::m_jsonObject.value(idKey)); } { return MessageId(JsonRpcMessage::m_jsonObject.value(idKey)); }
void setId(const MessageId &id) void setId(const MessageId &id)
{ JsonRpcMessage::m_jsonObject.insert(idKey, id.toJson()); } { JsonRpcMessage::m_jsonObject.insert(idKey, id); }
using Response = LanguageServerProtocol::Response<Result, ErrorDataType>; using Response = LanguageServerProtocol::Response<Result, ErrorDataType>;
using ResponseCallback = std::function<void(Response)>; using ResponseCallback = std::function<void(Response)>;
@@ -328,17 +323,10 @@ public:
CancelParameter() = default; CancelParameter() = default;
using JsonObject::JsonObject; using JsonObject::JsonObject;
MessageId id() const { return MessageId(value(idKey)); } MessageId id() const { return typedValue<MessageId>(idKey); }
void setId(const MessageId &id) { insert(idKey, id.toJson()); } void setId(const MessageId &id) { insert(idKey, id); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(idKey); }
{
if (MessageId(value(idKey)).isValid(error))
return true;
if (error)
error->prependMember(idKey);
return false;
}
}; };
class LANGUAGESERVERPROTOCOL_EXPORT CancelRequest : public Notification<CancelParameter> class LANGUAGESERVERPROTOCOL_EXPORT CancelRequest : public Notification<CancelParameter>

View File

@@ -80,11 +80,6 @@ Utils::optional<MarkupOrString> ParameterInformation::documentation() const
return MarkupOrString(documentation); return MarkupOrString(documentation);
} }
bool SignatureHelp::isValid(ErrorHierarchy *error) const
{
return checkArray<SignatureInformation>(error, signaturesKey);
}
GotoDefinitionRequest::GotoDefinitionRequest(const TextDocumentPositionParams &params) GotoDefinitionRequest::GotoDefinitionRequest(const TextDocumentPositionParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
@@ -119,18 +114,6 @@ void CodeActionParams::CodeActionContext::setOnly(const QList<CodeActionKind> &o
insertArray(onlyKey, only); insertArray(onlyKey, only);
} }
bool CodeActionParams::CodeActionContext::isValid(ErrorHierarchy *error) const
{
return checkArray<Diagnostic>(error, diagnosticsKey);
}
bool CodeActionParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& check<Range>(error, rangeKey)
&& check<CodeActionContext>(error, contextKey);
}
CodeActionRequest::CodeActionRequest(const CodeActionParams &params) CodeActionRequest::CodeActionRequest(const CodeActionParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
@@ -155,21 +138,6 @@ DocumentColorRequest::DocumentColorRequest(const DocumentColorParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
bool Color::isValid(ErrorHierarchy *error) const
{
return check<int>(error, redKey)
&& check<int>(error, greenKey)
&& check<int>(error, blueKey)
&& check<int>(error, alphaKey);
}
bool ColorPresentationParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& check<Color>(error, colorInfoKey)
&& check<Range>(error, rangeKey);
}
ColorPresentationRequest::ColorPresentationRequest(const ColorPresentationParams &params) ColorPresentationRequest::ColorPresentationRequest(const ColorPresentationParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
@@ -202,43 +170,19 @@ void FormattingOptions::setProperty(const QString &key, const DocumentFormatting
insert(key, *val); insert(key, *val);
} }
bool FormattingOptions::isValid(ErrorHierarchy *error) const
{
return Utils::allOf(keys(), [this, &error](auto key){
return (key == tabSizeKey && this->check<int>(error, key))
|| (key == insertSpaceKey && this->check<bool>(error, key))
|| this->check<DocumentFormattingProperty>(error, key);
});
}
bool DocumentFormattingParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& check<FormattingOptions>(error, optionsKey);
}
DocumentFormattingRequest::DocumentFormattingRequest(const DocumentFormattingParams &params) DocumentFormattingRequest::DocumentFormattingRequest(const DocumentFormattingParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
bool DocumentRangeFormattingParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& check<Range>(error, rangeKey)
&& check<FormattingOptions>(error, optionsKey);
}
DocumentRangeFormattingRequest::DocumentRangeFormattingRequest( DocumentRangeFormattingRequest::DocumentRangeFormattingRequest(
const DocumentRangeFormattingParams &params) const DocumentRangeFormattingParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
bool DocumentOnTypeFormattingParams::isValid(ErrorHierarchy *error) const bool DocumentOnTypeFormattingParams::isValid() const
{ {
return check<TextDocumentIdentifier>(error, textDocumentKey) return contains(textDocumentKey) && contains(positionKey) && contains(chKey)
&& check<Position>(error, positionKey) && contains(optionsKey);
&& check<QString>(error, chKey)
&& check<FormattingOptions>(error, optionsKey);
} }
DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest( DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest(
@@ -250,11 +194,9 @@ PrepareRenameRequest::PrepareRenameRequest(const TextDocumentPositionParams &par
: Request(methodName, params) : Request(methodName, params)
{ } { }
bool RenameParams::isValid(ErrorHierarchy *error) const bool RenameParams::isValid() const
{ {
return check<TextDocumentIdentifier>(error, textDocumentKey) return contains(textDocumentKey) && contains(positionKey) && contains(newNameKey);
&& check<Position>(error, positionKey)
&& check<QString>(error, newNameKey);
} }
RenameRequest::RenameRequest(const RenameParams &params) RenameRequest::RenameRequest(const RenameParams &params)
@@ -269,6 +211,11 @@ Utils::optional<DocumentUri> DocumentLink::target() const
: Utils::nullopt; : Utils::nullopt;
} }
Utils::optional<QJsonValue> DocumentLink::data() const
{
return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt;
}
TextDocumentParams::TextDocumentParams() TextDocumentParams::TextDocumentParams()
: TextDocumentParams(TextDocumentIdentifier()) : TextDocumentParams(TextDocumentIdentifier())
{ } { }
@@ -340,13 +287,17 @@ DocumentHighlightsResult::DocumentHighlightsResult(const QJsonValue &value)
MarkedString::MarkedString(const QJsonValue &value) MarkedString::MarkedString(const QJsonValue &value)
{ {
if (value.isObject()) { if (value.isObject())
MarkedLanguageString string(value.toObject()); emplace<MarkedLanguageString>(MarkedLanguageString(value.toObject()));
if (string.isValid(nullptr)) else
emplace<MarkedLanguageString>(string);
} else if (value.isString()) {
emplace<QString>(value.toString()); emplace<QString>(value.toString());
} }
bool MarkedString::isValid() const
{
if (auto markedLanguageString = Utils::get_if<MarkedLanguageString>(this))
return markedLanguageString->isValid();
return true;
} }
LanguageServerProtocol::MarkedString::operator QJsonValue() const LanguageServerProtocol::MarkedString::operator QJsonValue() const
@@ -365,7 +316,7 @@ HoverContent::HoverContent(const QJsonValue &value)
} else if (value.isObject()) { } else if (value.isObject()) {
const QJsonObject &object = value.toObject(); const QJsonObject &object = value.toObject();
MarkedLanguageString markedLanguageString(object); MarkedLanguageString markedLanguageString(object);
if (markedLanguageString.isValid(nullptr)) if (markedLanguageString.isValid())
emplace<MarkedString>(markedLanguageString); emplace<MarkedString>(markedLanguageString);
else else
emplace<MarkupContent>(MarkupContent(object)); emplace<MarkupContent>(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<MarkedString>(*this) if (Utils::holds_alternative<MarkedString>(*this))
|| Utils::holds_alternative<MarkupContent>(*this) return Utils::get<MarkedString>(*this).isValid();
|| Utils::holds_alternative<QList<MarkedString>>(*this)) { return true;
return true;
}
if (errorHierarchy) {
errorHierarchy->setError(
QCoreApplication::translate("LanguageServerProtocol::HoverContent",
"HoverContent should be either MarkedString, "
"MarkupContent, or QList<MarkedString>."));
}
return false;
} }
DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value) DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value)
@@ -400,21 +342,6 @@ DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value)
*this = value.toString(); *this = value.toString();
} }
bool DocumentFormattingProperty::isValid(ErrorHierarchy *error) const
{
if (Utils::holds_alternative<bool>(*this)
|| Utils::holds_alternative<double>(*this)
|| Utils::holds_alternative<QString>(*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 &params) SignatureHelpRequest::SignatureHelpRequest(const TextDocumentPositionParams &params)
: Request(methodName, params) : Request(methodName, params)
{ } { }
@@ -427,7 +354,7 @@ CodeActionResult::CodeActionResult(const QJsonValue &val)
ResultArray result; ResultArray result;
for (const QJsonValue &val : array) { for (const QJsonValue &val : array) {
Command command(val); Command command(val);
if (command.isValid(nullptr)) if (command.isValid())
result << command; result << command;
else else
result << CodeAction(val); result << CodeAction(val);
@@ -438,15 +365,6 @@ CodeActionResult::CodeActionResult(const QJsonValue &val)
emplace<std::nullptr_t>(nullptr); emplace<std::nullptr_t>(nullptr);
} }
bool CodeAction::isValid(ErrorHierarchy *error) const
{
return check<QString>(error, titleKey)
&& checkOptional<CodeActionKind>(error, codeActionKindKey)
&& checkOptionalArray<Diagnostic>(error, diagnosticsKey)
&& checkOptional<WorkspaceEdit>(error, editKey)
&& checkOptional<Command>(error, commandKey);
}
Utils::optional<QList<SemanticHighlightToken>> SemanticHighlightingInformation::tokens() const Utils::optional<QList<SemanticHighlightToken>> SemanticHighlightingInformation::tokens() const
{ {
QList<SemanticHighlightToken> resultTokens; QList<SemanticHighlightToken> resultTokens;
@@ -501,19 +419,7 @@ SemanticHighlightingParams::textDocument() const
{ {
VersionedTextDocumentIdentifier textDocument = fromJsonValue<VersionedTextDocumentIdentifier>( VersionedTextDocumentIdentifier textDocument = fromJsonValue<VersionedTextDocumentIdentifier>(
value(textDocumentKey)); value(textDocumentKey));
ErrorHierarchy error; return textDocument.isValid() ? textDocument : TextDocumentIdentifier(textDocument);
if (!textDocument.isValid(&error)) {
return TextDocumentIdentifier(textDocument);
} else {
return textDocument;
}
}
bool SemanticHighlightingParams::isValid(ErrorHierarchy *error) const
{
return checkVariant<VersionedTextDocumentIdentifier, TextDocumentIdentifier>(error,
textDocumentKey)
&& checkArray<SemanticHighlightingInformation>(error, linesKey);
} }
PrepareRenameResult::PrepareRenameResult() PrepareRenameResult::PrepareRenameResult()
@@ -551,4 +457,9 @@ SemanticHighlightNotification::SemanticHighlightNotification(const SemanticHighl
: Notification(methodName, params) : Notification(methodName, params)
{} {}
Utils::optional<QJsonValue> CodeLens::data() const
{
return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt;
}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -54,8 +54,7 @@ public:
QString value() const { return typedValue<QString>(valueKey); } QString value() const { return typedValue<QString>(valueKey); }
void setValue(const QString &value) { insert(valueKey, value); } void setValue(const QString &value) { insert(valueKey, value); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(languageKey) && contains(valueKey); }
{ return check<QString>(error, languageKey) && check<QString>(error, valueKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT MarkedString class LANGUAGESERVERPROTOCOL_EXPORT MarkedString
@@ -71,6 +70,7 @@ public:
{} {}
explicit MarkedString(const QJsonValue &value); explicit MarkedString(const QJsonValue &value);
bool isValid() const;
operator QJsonValue() const; operator QJsonValue() const;
}; };
@@ -83,7 +83,7 @@ public:
explicit HoverContent(const QList<MarkedString> &other) : variant(other) {} explicit HoverContent(const QList<MarkedString> &other) : variant(other) {}
explicit HoverContent(const MarkupContent &other) : variant(other) {} explicit HoverContent(const MarkupContent &other) : variant(other) {}
explicit HoverContent(const QJsonValue &value); explicit HoverContent(const QJsonValue &value);
bool isValid(ErrorHierarchy *errorHierarchy) const; bool isValid() const;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT Hover : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT Hover : public JsonObject
@@ -98,8 +98,7 @@ public:
void setRange(const Range &range) { insert(rangeKey, range); } void setRange(const Range &range) { insert(rangeKey, range); }
void clearRange() { remove(rangeKey); } void clearRange() { remove(rangeKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(contentsKey); }
{ return check<HoverContent>(error, contentsKey) && checkOptional<Range>(error, rangeKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT HoverRequest class LANGUAGESERVERPROTOCOL_EXPORT HoverRequest
@@ -128,11 +127,7 @@ public:
{ insert(documentationKey, documentation.toJson()); } { insert(documentationKey, documentation.toJson()); }
void clearDocumentation() { remove(documentationKey); } void clearDocumentation() { remove(documentationKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(labelKey); }
{
return check<QString>(error, labelKey)
&& checkOptional<MarkupOrString>(error, documentationKey);
}
}; };
/** /**
@@ -194,7 +189,7 @@ public:
void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); } void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); }
void clearActiveParameter() { remove(activeParameterKey); } void clearActiveParameter() { remove(activeParameterKey); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(signaturesKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpRequest class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpRequest
@@ -258,17 +253,14 @@ public:
void setIncludeDeclaration(bool includeDeclaration) void setIncludeDeclaration(bool includeDeclaration)
{ insert(includeDeclarationKey, includeDeclaration); } { insert(includeDeclarationKey, includeDeclaration); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(includeDeclarationKey); }
{ return check<bool>(error, includeDeclarationKey); }
}; };
ReferenceContext context() const { return typedValue<ReferenceContext>(contextKey); } ReferenceContext context() const { return typedValue<ReferenceContext>(contextKey); }
void setContext(const ReferenceContext &context) { insert(contextKey, context); } void setContext(const ReferenceContext &context) { insert(contextKey, context); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ { return TextDocumentPositionParams::isValid() && contains(contextKey); }
return TextDocumentPositionParams::isValid(error)
&& check<ReferenceContext>(error, contextKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT FindReferencesRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT FindReferencesRequest : public Request<
@@ -298,8 +290,7 @@ public:
void setKind(int kind) { insert(kindKey, kind); } void setKind(int kind) { insert(kindKey, kind); }
void clearKind() { remove(kindKey); } void clearKind() { remove(kindKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(rangeKey); }
{ return check<Range>(error, rangeKey) && checkOptional<int>(error, kindKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DocumentHighlightsResult class LANGUAGESERVERPROTOCOL_EXPORT DocumentHighlightsResult
@@ -333,8 +324,7 @@ public:
void setTextDocument(const TextDocumentIdentifier &textDocument) void setTextDocument(const TextDocumentIdentifier &textDocument)
{ insert(textDocumentKey, textDocument); } { insert(textDocumentKey, textDocument); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(textDocumentKey); }
{ return check<TextDocumentIdentifier>(error, textDocumentKey); }
}; };
using DocumentSymbolParams = TextDocumentParams; using DocumentSymbolParams = TextDocumentParams;
@@ -417,7 +407,7 @@ public:
void setOnly(const QList<CodeActionKind> &only); void setOnly(const QList<CodeActionKind> &only);
void clearOnly() { remove(onlyKey); } void clearOnly() { remove(onlyKey); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(diagnosticsKey); }
}; };
TextDocumentIdentifier textDocument() const TextDocumentIdentifier textDocument() const
@@ -431,7 +421,8 @@ public:
CodeActionContext context() const { return typedValue<CodeActionContext>(contextKey); } CodeActionContext context() const { return typedValue<CodeActionContext>(contextKey); }
void setContext(const CodeActionContext &context) { insert(contextKey, context); } 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 class LANGUAGESERVERPROTOCOL_EXPORT CodeAction : public JsonObject
@@ -460,7 +451,7 @@ public:
void setCommand(const Command &command) { insert(commandKey, command); } void setCommand(const Command &command) { insert(commandKey, command); }
void clearCommand() { remove(commandKey); } void clearCommand() { remove(commandKey); }
bool isValid(ErrorHierarchy *) const override; bool isValid() const override { return contains(titleKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT CodeActionResult class LANGUAGESERVERPROTOCOL_EXPORT CodeActionResult
@@ -494,12 +485,11 @@ public:
void setCommand(const Command &command) { insert(commandKey, command); } void setCommand(const Command &command) { insert(commandKey, command); }
void clearCommand() { remove(commandKey); } void clearCommand() { remove(commandKey); }
Utils::optional<QJsonValue> data() const { return optionalValue<QJsonValue>(dataKey); } Utils::optional<QJsonValue> data() const;
void setData(const QJsonValue &data) { insert(dataKey, data); } void setData(const QJsonValue &data) { insert(dataKey, data); }
void clearData() { remove(dataKey); } void clearData() { remove(dataKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(rangeKey); }
{ return check<Range>(error, rangeKey) && checkOptional<Command>(error, commandKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT CodeLensRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT CodeLensRequest : public Request<
@@ -532,12 +522,11 @@ public:
void setTarget(const DocumentUri &target) { insert(targetKey, target.toString()); } void setTarget(const DocumentUri &target) { insert(targetKey, target.toString()); }
void clearTarget() { remove(targetKey); } void clearTarget() { remove(targetKey); }
Utils::optional<QJsonValue> data() const { return optionalValue<QJsonValue>(dataKey); } Utils::optional<QJsonValue> data() const;
void setData(const QJsonValue &data) { insert(dataKey, data); } void setData(const QJsonValue &data) { insert(dataKey, data); }
void clearData() { remove(dataKey); } void clearData() { remove(dataKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(rangeKey); }
{ return check<Range>(error, rangeKey) && checkOptional<QString>(error, targetKey); }
}; };
using DocumentLinkParams = TextDocumentParams; using DocumentLinkParams = TextDocumentParams;
@@ -579,7 +568,8 @@ public:
double alpha() const { return typedValue<double>(alphaKey); } double alpha() const { return typedValue<double>(alphaKey); }
void setAlpha(double alpha) { insert(alphaKey, alpha); } 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 class LANGUAGESERVERPROTOCOL_EXPORT ColorInformation : public JsonObject
@@ -593,8 +583,7 @@ public:
Color color() const { return typedValue<Color>(colorKey); } Color color() const { return typedValue<Color>(colorKey); }
void setColor(const Color &color) { insert(colorKey, color); } void setColor(const Color &color) { insert(colorKey, color); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(rangeKey) && contains(colorKey); }
{ return check<Range>(error, rangeKey) && check<Color>(error, colorKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DocumentColorRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT DocumentColorRequest : public Request<
@@ -622,7 +611,8 @@ public:
Range range() const { return typedValue<Range>(rangeKey); } Range range() const { return typedValue<Range>(rangeKey); }
void setRange(const Range &range) { insert(rangeKey, range); } 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 class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentation : public JsonObject
@@ -643,12 +633,7 @@ public:
{ insertArray(additionalTextEditsKey, additionalTextEdits); } { insertArray(additionalTextEditsKey, additionalTextEdits); }
void clearAdditionalTextEdits() { remove(additionalTextEditsKey); } void clearAdditionalTextEdits() { remove(additionalTextEditsKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(labelKey); }
{
return check<QString>(error, labelKey)
&& checkOptional<TextEdit>(error, textEditKey)
&& checkOptionalArray<TextEdit>(error, additionalTextEditsKey);
}
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentationRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentationRequest : public Request<
@@ -670,8 +655,6 @@ public:
using variant::variant; using variant::variant;
using variant::operator=; using variant::operator=;
bool isValid(ErrorHierarchy *error) const;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT FormattingOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT FormattingOptions : public JsonObject
@@ -707,7 +690,7 @@ public:
void setProperty(const QString &key, const DocumentFormattingProperty &property); void setProperty(const QString &key, const DocumentFormattingProperty &property);
void removeProperty(const QString &key) { remove(key); } 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 class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingParams : public JsonObject
@@ -723,7 +706,7 @@ public:
FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); }
void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } 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< class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingRequest : public Request<
@@ -751,7 +734,8 @@ public:
FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); }
void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } 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< class LANGUAGESERVERPROTOCOL_EXPORT DocumentRangeFormattingRequest : public Request<
@@ -782,7 +766,7 @@ public:
FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); }
void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DocumentOnTypeFormattingRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT DocumentOnTypeFormattingRequest : public Request<
@@ -805,10 +789,7 @@ public:
QString placeHolder() const { return typedValue<QString>(placeHolderKey); } QString placeHolder() const { return typedValue<QString>(placeHolderKey); }
void setPlaceHolder(const QString &placeHolder) { insert(placeHolderKey, placeHolder); } void setPlaceHolder(const QString &placeHolder) { insert(placeHolderKey, placeHolder); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(rangeKey); }
{
return check<Range>(error, rangeKey) && checkOptional<QString>(error, placeHolderKey);
}
}; };
class LANGUAGESERVERPROTOCOL_EXPORT PrepareRenameResult class LANGUAGESERVERPROTOCOL_EXPORT PrepareRenameResult
@@ -821,7 +802,7 @@ public:
explicit PrepareRenameResult(const Range &val); explicit PrepareRenameResult(const Range &val);
explicit PrepareRenameResult(const QJsonValue &val); explicit PrepareRenameResult(const QJsonValue &val);
bool isValid(ErrorHierarchy *error) const; bool isValid() const;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT PrepareRenameRequest class LANGUAGESERVERPROTOCOL_EXPORT PrepareRenameRequest
@@ -849,7 +830,7 @@ public:
QString newName() const { return typedValue<QString>(newNameKey); } QString newName() const { return typedValue<QString>(newNameKey); }
void setNewName(const QString &newName) { insert(newNameKey, newName); } void setNewName(const QString &newName) { insert(newNameKey, newName); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT RenameRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT RenameRequest : public Request<
@@ -887,8 +868,7 @@ public:
void setTokens(const QList<SemanticHighlightToken> &tokens); void setTokens(const QList<SemanticHighlightToken> &tokens);
void clearTokens() { remove(tokensKey); } void clearTokens() { remove(tokensKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(lineKey); }
{ return check<int>(error, lineKey) && checkOptional<QString>(error, tokensKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingParams : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingParams : public JsonObject
@@ -907,7 +887,7 @@ public:
void setLines(const QList<SemanticHighlightingInformation> &lines) void setLines(const QList<SemanticHighlightingInformation> &lines)
{ insertArray(linesKey, lines); } { insertArray(linesKey, lines); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(textDocumentKey) && contains(linesKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification

View File

@@ -65,15 +65,6 @@ void Diagnostic::setCode(const Diagnostic::Code &code)
insertVariant<int, QString>(codeKey, code); insertVariant<int, QString>(codeKey, code);
} }
bool Diagnostic::isValid(ErrorHierarchy *error) const
{
return check<Range>(error, rangeKey)
&& checkOptional<int>(error, severityKey)
&& (checkOptional<int>(error, codeKey) || checkOptional<QString>(error, codeKey))
&& checkOptional<QString>(error, sourceKey)
&& check<QString>(error, messageKey);
}
Utils::optional<WorkspaceEdit::Changes> WorkspaceEdit::changes() const Utils::optional<WorkspaceEdit::Changes> WorkspaceEdit::changes() const
{ {
auto it = find(changesKey); auto it = find(changesKey);
@@ -123,23 +114,11 @@ MarkupOrString::MarkupOrString(const QJsonValue &val)
emplace<QString>(val.toString()); emplace<QString>(val.toString());
} else { } else {
MarkupContent markupContent(val.toObject()); MarkupContent markupContent(val.toObject());
if (markupContent.isValid(nullptr)) if (markupContent.isValid())
emplace<MarkupContent>(MarkupContent(val.toObject())); emplace<MarkupContent>(MarkupContent(val.toObject()));
} }
} }
bool MarkupOrString::isValid(ErrorHierarchy *error) const
{
if (Utils::holds_alternative<MarkupContent>(*this) || Utils::holds_alternative<QString>(*this))
return true;
if (error) {
error->setError(
QCoreApplication::translate("LanguageServerProtocoll::MarkupOrString",
"Expected a string or MarkupContent in MarkupOrString."));
}
return false;
}
QJsonValue MarkupOrString::toJson() const QJsonValue MarkupOrString::toJson() const
{ {
if (Utils::holds_alternative<QString>(*this)) if (Utils::holds_alternative<QString>(*this))
@@ -149,28 +128,6 @@ QJsonValue MarkupOrString::toJson() const
return {}; return {};
} }
bool SymbolInformation::isValid(ErrorHierarchy *error) const
{
return check<QString>(error, nameKey)
&& check<int>(error, kindKey)
&& check<Location>(error, locationKey)
&& checkOptional<QString>(error, containerNameKey);
}
bool TextDocumentEdit::isValid(ErrorHierarchy *error) const
{
return check<VersionedTextDocumentIdentifier>(error, textDocumentKey)
&& checkArray<TextEdit>(error, editsKey);
}
bool TextDocumentItem::isValid(ErrorHierarchy *error) const
{
return check<QString>(error, uriKey)
&& check<QString>(error, languageIdKey)
&& check<int>(error, versionKey)
&& check<QString>(error, textKey);
}
static QHash<Utils::MimeType, QString> mimeTypeLanguageIdMap() static QHash<Utils::MimeType, QString> mimeTypeLanguageIdMap()
{ {
static QHash<Utils::MimeType, QString> hash; static QHash<Utils::MimeType, QString> hash;
@@ -281,6 +238,11 @@ QMap<QString, QString> languageIds()
return languages; return languages;
} }
bool TextDocumentItem::isValid() const
{
return contains(uriKey) && contains(languageIdKey) && contains(versionKey) && contains(textKey);
}
QString TextDocumentItem::mimeTypeToLanguageId(const Utils::MimeType &mimeType) QString TextDocumentItem::mimeTypeToLanguageId(const Utils::MimeType &mimeType)
{ {
return mimeTypeLanguageIdMap().value(mimeType); return mimeTypeLanguageIdMap().value(mimeType);
@@ -304,12 +266,6 @@ TextDocumentPositionParams::TextDocumentPositionParams(
setPosition(position); setPosition(position);
} }
bool TextDocumentPositionParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& check<Position>(error, positionKey);
}
Position::Position(int line, int character) Position::Position(int line, int character)
{ {
setLine(line); setLine(line);
@@ -388,16 +344,9 @@ bool DocumentFilter::applies(const Utils::FilePath &fileName, const Utils::MimeT
return !contains(schemeKey) && !contains(languageKey) && !contains(patternKey); 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<QString>(error, key);
});
}
Utils::Link Location::toLink() const Utils::Link Location::toLink() const
{ {
if (!isValid(nullptr)) if (!isValid())
return Utils::Link(); return Utils::Link();
// Ensure %xx like %20 are really decoded using fromPercentEncoding // Ensure %xx like %20 are really decoded using fromPercentEncoding

View File

@@ -83,8 +83,8 @@ public:
int character() const { return typedValue<int>(characterKey); } int character() const { return typedValue<int>(characterKey); }
void setCharacter(int character) { insert(characterKey, character); } void setCharacter(int character) { insert(characterKey, character); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ return check<int>(error, lineKey) && check<int>(error, characterKey); } { return contains(lineKey) && contains(characterKey); }
int toPositionInDocument(QTextDocument *doc) const; int toPositionInDocument(QTextDocument *doc) const;
QTextCursor toTextCursor(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 contains(const Position &pos) const { return start() <= pos && pos <= end(); }
bool overlaps(const Range &range) const; bool overlaps(const Range &range) const;
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ return check<Position>(error, startKey) && check<Position>(error, endKey); } { return JsonObject::contains(startKey) && JsonObject::contains(endKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT Location : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT Location : public JsonObject
@@ -133,8 +133,7 @@ public:
Utils::Link toLink() const; Utils::Link toLink() const;
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(uriKey) && contains(rangeKey); }
{ return check<QString>(error, uriKey) && check<Range>(error, rangeKey); }
}; };
enum class DiagnosticSeverity enum class DiagnosticSeverity
@@ -180,7 +179,7 @@ public:
{ return typedValue<QString>(messageKey); } { return typedValue<QString>(messageKey); }
void setMessage(const QString &message) { insert(messageKey, message); } 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 class LANGUAGESERVERPROTOCOL_EXPORT Command : public JsonObject
@@ -203,10 +202,7 @@ public:
void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); }
void clearArguments() { remove(argumentsKey); } void clearArguments() { remove(argumentsKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(titleKey) && contains(commandKey); }
{ return check<QString>(error, titleKey)
&& check<QString>(error, commandKey)
&& checkOptional<QJsonArray>(error, argumentsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT TextEdit : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT TextEdit : public JsonObject
@@ -225,8 +221,8 @@ public:
Utils::Text::Replacement toReplacement(QTextDocument *document) const; Utils::Text::Replacement toReplacement(QTextDocument *document) const;
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ return check<Range>(error, rangeKey) && check<QString>(error, newTextKey); } { return contains(rangeKey) && contains(newTextKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentIdentifier : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentIdentifier : public JsonObject
@@ -240,7 +236,7 @@ public:
DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue<QString>(uriKey)); } DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue<QString>(uriKey)); }
void setUri(const DocumentUri &uri) { insert(uriKey, uri); } void setUri(const DocumentUri &uri) { insert(uriKey, uri); }
bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey); } bool isValid() const override { return contains(uriKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT VersionedTextDocumentIdentifier : public TextDocumentIdentifier class LANGUAGESERVERPROTOCOL_EXPORT VersionedTextDocumentIdentifier : public TextDocumentIdentifier
@@ -258,10 +254,9 @@ public:
LanguageClientValue<int> version() const { return clientValue<int>(versionKey); } LanguageClientValue<int> version() const { return clientValue<int>(versionKey); }
void setVersion(LanguageClientValue<int> version) { insert(versionKey, version); } void setVersion(LanguageClientValue<int> version) { insert(versionKey, version); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ {
return TextDocumentIdentifier::isValid(error) return TextDocumentIdentifier::isValid() && contains(versionKey);
&& checkVariant<int, std::nullptr_t>(error, versionKey);
} }
}; };
@@ -280,7 +275,7 @@ public:
QList<TextEdit> edits() const { return array<TextEdit>(editsKey); } QList<TextEdit> edits() const { return array<TextEdit>(editsKey); }
void setEdits(const QList<TextEdit> edits) { insertArray(editsKey, edits); } void setEdits(const QList<TextEdit> 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 class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceEdit : public JsonObject
@@ -306,9 +301,6 @@ public:
{ return optionalArray<TextDocumentEdit>(documentChangesKey); } { return optionalArray<TextDocumentEdit>(documentChangesKey); }
void setDocumentChanges(const QList<TextDocumentEdit> &changes) void setDocumentChanges(const QList<TextDocumentEdit> &changes)
{ insertArray(documentChangesKey, changes); } { insertArray(documentChangesKey, changes); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptionalArray<TextDocumentEdit>(error, documentChangesKey); }
}; };
LANGUAGESERVERPROTOCOL_EXPORT QMap<QString, QString> languageIds(); LANGUAGESERVERPROTOCOL_EXPORT QMap<QString, QString> languageIds();
@@ -334,7 +326,7 @@ public:
QString text() const { return typedValue<QString>(textKey); } QString text() const { return typedValue<QString>(textKey); }
void setText(const QString &text) { insert(textKey, text); } 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 Utils::MimeType &mimeType);
static QString mimeTypeToLanguageId(const QString &mimeTypeName); static QString mimeTypeToLanguageId(const QString &mimeTypeName);
@@ -356,7 +348,7 @@ public:
Position position() const { return typedValue<Position>(positionKey); } Position position() const { return typedValue<Position>(positionKey); }
void setPosition(const Position &position) { insert(positionKey, position); } 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 class LANGUAGESERVERPROTOCOL_EXPORT DocumentFilter : public JsonObject
@@ -381,8 +373,6 @@ public:
bool applies(const Utils::FilePath &fileName, bool applies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType = Utils::MimeType()) const; const Utils::MimeType &mimeType = Utils::MimeType()) const;
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT MarkupKind class LANGUAGESERVERPROTOCOL_EXPORT MarkupKind
@@ -400,7 +390,7 @@ public:
bool operator==(const Value &value) const { return m_value == value; } bool operator==(const Value &value) const { return m_value == value; }
bool isValid(void *) const { return true; } bool isValid() const { return true; }
private: private:
Value m_value = plaintext; Value m_value = plaintext;
}; };
@@ -420,8 +410,8 @@ public:
QString content() const { return typedValue<QString>(contentKey); } QString content() const { return typedValue<QString>(contentKey); }
void setContent(const QString &content) { insert(contentKey, content); } void setContent(const QString &content) { insert(contentKey, content); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ return check<MarkupKind>(error, kindKey) && check<QString>(error, contentKey); } { return contains(kindKey) && contains(contentKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT MarkupOrString : public Utils::variant<QString, MarkupContent> class LANGUAGESERVERPROTOCOL_EXPORT MarkupOrString : public Utils::variant<QString, MarkupContent>
@@ -433,7 +423,7 @@ public:
explicit MarkupOrString(const MarkupContent &val); explicit MarkupOrString(const MarkupContent &val);
MarkupOrString(const QJsonValue &val); MarkupOrString(const QJsonValue &val);
bool isValid(ErrorHierarchy *error) const; bool isValid() const { return true; }
QJsonValue toJson() const; QJsonValue toJson() const;
}; };
@@ -453,8 +443,8 @@ public:
QString name() const { return typedValue<QString>(nameKey); } QString name() const { return typedValue<QString>(nameKey); }
void setName(const QString &name) { insert(nameKey, name); } void setName(const QString &name) { insert(nameKey, name); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ return check<QString>(error, uriKey) && check<QString>(error, nameKey); } { return contains(uriKey) && contains(nameKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SymbolInformation : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT SymbolInformation : public JsonObject
@@ -480,7 +470,8 @@ public:
void setContainerName(const QString &containerName) { insert(containerNameKey, containerName); } void setContainerName(const QString &containerName) { insert(containerNameKey, containerName); }
void clearContainerName() { remove(containerNameKey); } 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 class LANGUAGESERVERPROTOCOL_EXPORT DocumentSymbol : public JsonObject

View File

@@ -75,34 +75,18 @@ QJsonArray fromJsonValue<QJsonArray>(const QJsonValue &value)
return value.toArray(); return value.toArray();
} }
void ErrorHierarchy::clear() template<>
QJsonObject fromJsonValue<QJsonObject>(const QJsonValue &value)
{ {
m_hierarchy.clear(); if (conversionLog().isDebugEnabled() && !value.isObject())
m_children.clear(); qCDebug(conversionLog) << "Expected Object in json value but got: " << value;
m_error.clear(); return value.toObject();
} }
bool ErrorHierarchy::isEmpty() const template<>
QJsonValue fromJsonValue<QJsonValue>(const QJsonValue &value)
{ {
return m_hierarchy.isEmpty() && m_children.isEmpty() && m_error.isEmpty(); return value;
}
QString ErrorHierarchy::toString() const
{
if (m_error.isEmpty() && m_hierarchy.isEmpty())
return {};
QString error = m_hierarchy.join(" > ") + ": " + m_error;
if (!m_children.isEmpty()) {
error.append("\n\t");
error.append(Utils::transform(m_children, &ErrorHierarchy::toString).join("\n\t"));
}
return error;
}
bool ErrorHierarchy::operator==(const ErrorHierarchy &other) const
{
return m_hierarchy == other.m_hierarchy && m_children == other.m_children
&& m_error == other.m_error;
} }
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -46,7 +46,10 @@ T fromJsonValue(const QJsonValue &value)
{ {
if (conversionLog().isDebugEnabled() && !value.isObject()) if (conversionLog().isDebugEnabled() && !value.isObject())
qCDebug(conversionLog) << "Expected Object in json value but got: " << value; 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<> template<>
@@ -61,9 +64,15 @@ LANGUAGESERVERPROTOCOL_EXPORT double fromJsonValue<double>(const QJsonValue &val
template<> template<>
LANGUAGESERVERPROTOCOL_EXPORT bool fromJsonValue<bool>(const QJsonValue &value); LANGUAGESERVERPROTOCOL_EXPORT bool fromJsonValue<bool>(const QJsonValue &value);
template<>
LANGUAGESERVERPROTOCOL_EXPORT QJsonObject fromJsonValue<QJsonObject>(const QJsonValue &value);
template<> template<>
LANGUAGESERVERPROTOCOL_EXPORT QJsonArray fromJsonValue<QJsonArray>(const QJsonValue &value); LANGUAGESERVERPROTOCOL_EXPORT QJsonArray fromJsonValue<QJsonArray>(const QJsonValue &value);
template<>
LANGUAGESERVERPROTOCOL_EXPORT QJsonValue fromJsonValue<QJsonValue>(const QJsonValue &value);
template <typename T> template <typename T>
class LanguageClientArray : public Utils::variant<QList<T>, std::nullptr_t> class LanguageClientArray : public Utils::variant<QList<T>, std::nullptr_t>
{ {
@@ -165,24 +174,4 @@ QList<T> jsonArrayToList(const QJsonArray &array)
return list; return list;
} }
class LANGUAGESERVERPROTOCOL_EXPORT ErrorHierarchy } // namespace LanguageServerProtocol
{
public:
ErrorHierarchy() = default;
void setError(const QString &error) { m_error = error; }
void prependMember(const QString &member) { m_hierarchy.prepend(member); }
void addVariantHierachy(const ErrorHierarchy &subError) { m_children.append(subError); }
void clear();
bool isEmpty() const;
QString toString() const;
bool operator==(const ErrorHierarchy &other) const;
private:
QStringList m_hierarchy;
QList<ErrorHierarchy> m_children;
QString m_error;
};
} // namespace LanguageClient

View File

@@ -50,12 +50,6 @@ TelemetryNotification::TelemetryNotification(const JsonObject &params)
: Notification(methodName, params) : Notification(methodName, params)
{ } { }
bool ShowMessageRequestParams::isValid(ErrorHierarchy *error) const
{
return ShowMessageParams::isValid(error)
&& checkOptionalArray<MessageActionItem>(error, actionsKey);
}
static QString messageTypeName(int messageType) static QString messageTypeName(int messageType)
{ {
switch (messageType) { switch (messageType) {

View File

@@ -49,8 +49,8 @@ public:
QString toString() const; QString toString() const;
bool isValid(ErrorHierarchy *error) const override bool isValid() const override
{ return check<int>(error, typeKey) && check<QString>(error, messageKey); } { return contains(typeKey) && contains(messageKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageNotification : public Notification<ShowMessageParams> class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageNotification : public Notification<ShowMessageParams>
@@ -70,7 +70,7 @@ public:
QString title() const { return typedValue<QString>(titleKey); } QString title() const { return typedValue<QString>(titleKey); }
void setTitle(QString title) { insert(titleKey, title); } void setTitle(QString title) { insert(titleKey, title); }
bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, titleKey); } bool isValid() const override { return contains(titleKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequestParams : public ShowMessageParams class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequestParams : public ShowMessageParams
@@ -82,8 +82,6 @@ public:
{ return optionalArray<MessageActionItem>(actionsKey); } { return optionalArray<MessageActionItem>(actionsKey); }
void setActions(const QList<MessageActionItem> &actions) { insertArray(actionsKey, actions); } void setActions(const QList<MessageActionItem> &actions) { insertArray(actionsKey, actions); }
void clearActions() { remove(actionsKey); } void clearActions() { remove(actionsKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequest : public Request<

View File

@@ -191,7 +191,7 @@ Utils::optional<Utils::variant<bool, CodeActionOptions>> ServerCapabilities::cod
return Utils::make_optional(Utils::variant<bool, CodeActionOptions>(provider.toBool())); return Utils::make_optional(Utils::variant<bool, CodeActionOptions>(provider.toBool()));
if (provider.isObject()) { if (provider.isObject()) {
CodeActionOptions options(provider); CodeActionOptions options(provider);
if (options.isValid(nullptr)) if (options.isValid())
return Utils::make_optional(Utils::variant<bool, CodeActionOptions>(options)); return Utils::make_optional(Utils::variant<bool, CodeActionOptions>(options));
} }
return Utils::nullopt; return Utils::nullopt;
@@ -267,31 +267,6 @@ void ServerCapabilities::setColorProvider(Utils::variant<bool, JsonObject> color
insertVariant<bool, JsonObject>(renameProviderKey, colorProvider); insertVariant<bool, JsonObject>(renameProviderKey, colorProvider);
} }
bool ServerCapabilities::isValid(ErrorHierarchy *error) const
{
return checkOptional<TextDocumentSyncOptions, int>(error, textDocumentSyncKey)
&& checkOptional<bool>(error, hoverProviderKey)
&& checkOptional<CompletionOptions>(error, completionProviderKey)
&& checkOptional<SignatureHelpOptions>(error, signatureHelpProviderKey)
&& checkOptional<bool>(error, definitionProviderKey)
&& checkOptional<bool, RegistrationOptions>(error, typeDefinitionProviderKey)
&& checkOptional<bool, RegistrationOptions>(error, implementationProviderKey)
&& checkOptional<bool>(error, referencesProviderKey)
&& checkOptional<bool>(error, documentHighlightProviderKey)
&& checkOptional<bool>(error, documentSymbolProviderKey)
&& checkOptional<bool>(error, workspaceSymbolProviderKey)
&& checkOptional<bool, CodeActionOptions>(error, codeActionProviderKey)
&& checkOptional<CodeLensOptions>(error, codeLensProviderKey)
&& checkOptional<bool>(error, documentFormattingProviderKey)
&& checkOptional<bool>(error, documentRangeFormattingProviderKey)
&& checkOptional<bool, RenameOptions>(error, renameProviderKey)
&& checkOptional<DocumentLinkOptions>(error, documentLinkProviderKey)
&& checkOptional<bool, JsonObject>(error, colorProviderKey)
&& checkOptional<ExecuteCommandOptions>(error, executeCommandProviderKey)
&& checkOptional<WorkspaceServerCapabilities>(error, workspaceKey)
&& checkOptional<SemanticHighlightingServerCapabilities>(error, semanticHighlightingKey);
}
Utils::optional<Utils::variant<QString, bool> > Utils::optional<Utils::variant<QString, bool> >
ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const
{ {
@@ -309,12 +284,6 @@ void ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabiliti
insertVariant<QString, bool>(changeNotificationsKey, changeNotifications); insertVariant<QString, bool>(changeNotificationsKey, changeNotifications);
} }
bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::isValid(ErrorHierarchy *error) const
{
return checkOptional<bool>(error, supportedKey)
&& checkOptional<QString, bool>(error, changeNotificationsKey);
}
bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileName, bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType) const const Utils::MimeType &mimeType) const
{ {
@@ -326,15 +295,6 @@ bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileN
}); });
} }
bool TextDocumentSyncOptions::isValid(ErrorHierarchy *error) const
{
return checkOptional<bool>(error, openCloseKey)
&& checkOptional<int>(error, changeKey)
&& checkOptional<bool>(error, willSaveKey)
&& checkOptional<bool>(error, willSaveWaitUntilKey)
&& checkOptional<SaveOptions>(error, saveKey);
}
Utils::optional<QList<QList<QString>>> ServerCapabilities::SemanticHighlightingServerCapabilities::scopes() const Utils::optional<QList<QList<QString>>> ServerCapabilities::SemanticHighlightingServerCapabilities::scopes() const
{ {
QList<QList<QString>> scopes; QList<QList<QString>> scopes;
@@ -367,7 +327,7 @@ void ServerCapabilities::SemanticHighlightingServerCapabilities::setScopes(
insert(scopesKey, jsonScopes); insert(scopesKey, jsonScopes);
} }
bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(ErrorHierarchy *) const bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid() const
{ {
return contains(scopesKey) && value(scopesKey).isArray() return contains(scopesKey) && value(scopesKey).isArray()
&& Utils::allOf(value(scopesKey).toArray(), [](const QJsonValue &array) { && 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<QString>(error, commandsKey); return WorkDoneProgressOptions::isValid() && contains(commandsKey);
} }
bool ServerCapabilities::CompletionOptions::isValid(ErrorHierarchy *error) const bool CodeActionOptions::isValid() const
{ {
return WorkDoneProgressOptions::isValid(error) return WorkDoneProgressOptions::isValid() && contains(codeActionKindsKey);
&& checkOptionalArray<QString>(error, triggerCharactersKey)
&& checkOptional<bool>(error, resolveProviderKey);
}
bool ServerCapabilities::SignatureHelpOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkOptionalArray<QString>(error, triggerCharactersKey);
}
bool CodeActionOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkArray<QString>(error, codeActionKindsKey);
}
bool ServerCapabilities::RenameOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkOptional<bool>(error, prepareProviderKey);
} }
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -37,9 +37,6 @@ public:
Utils::optional<bool> workDoneProgress() const { return optionalValue<bool>(workDoneProgressKey); } Utils::optional<bool> workDoneProgress() const { return optionalValue<bool>(workDoneProgressKey); }
void setWorkDoneProgress(bool workDoneProgress) { insert(workDoneProgressKey, workDoneProgress); } void setWorkDoneProgress(bool workDoneProgress) { insert(workDoneProgressKey, workDoneProgress); }
void clearWorkDoneProgress() { remove(workDoneProgressKey); } void clearWorkDoneProgress() { remove(workDoneProgressKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<bool>(error, workDoneProgressKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ResolveProviderOption : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ResolveProviderOption : public JsonObject
@@ -50,9 +47,6 @@ public:
Utils::optional<bool> resolveProvider() const { return optionalValue<bool>(resolveProviderKey); } Utils::optional<bool> resolveProvider() const { return optionalValue<bool>(resolveProviderKey); }
void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); } void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); }
void clearResolveProvider() { remove(resolveProviderKey); } void clearResolveProvider() { remove(resolveProviderKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<bool>(error, resolveProviderKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentRegistrationOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentRegistrationOptions : public JsonObject
@@ -68,8 +62,7 @@ public:
bool filterApplies(const Utils::FilePath &fileName, bool filterApplies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType = Utils::MimeType()) const; const Utils::MimeType &mimeType = Utils::MimeType()) const;
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(documentSelectorKey); }
{ return checkArray<DocumentFilter>(error, documentSelectorKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SaveOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT SaveOptions : public JsonObject
@@ -81,9 +74,6 @@ public:
Utils::optional<bool> includeText() const { return optionalValue<bool>(includeTextKey); } Utils::optional<bool> includeText() const { return optionalValue<bool>(includeTextKey); }
void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void setIncludeText(bool includeText) { insert(includeTextKey, includeText); }
void clearIncludeText() { remove(includeTextKey); } void clearIncludeText() { remove(includeTextKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<bool>(error, includeTextKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentSyncOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentSyncOptions : public JsonObject
@@ -118,8 +108,6 @@ public:
Utils::optional<SaveOptions> save() const { return optionalValue<SaveOptions>(saveKey); } Utils::optional<SaveOptions> save() const { return optionalValue<SaveOptions>(saveKey); }
void setSave(const SaveOptions &save) { insert(saveKey, save); } void setSave(const SaveOptions &save) { insert(saveKey, save); }
void clearSave() { remove(saveKey); } void clearSave() { remove(saveKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
enum class TextDocumentSyncKind enum class TextDocumentSyncKind
@@ -142,7 +130,7 @@ public:
void setCodeActionKinds(const QList<QString> &codeActionKinds) void setCodeActionKinds(const QList<QString> &codeActionKinds)
{ insertArray(codeActionKindsKey, codeActionKinds); } { insertArray(codeActionKindsKey, codeActionKinds); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ServerCapabilities : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ServerCapabilities : public JsonObject
@@ -167,8 +155,6 @@ public:
Utils::optional<bool> resolveProvider() const { return optionalValue<bool>(resolveProviderKey); } Utils::optional<bool> resolveProvider() const { return optionalValue<bool>(resolveProviderKey); }
void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); } void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); }
void clearResolveProvider() { remove(resolveProviderKey); } void clearResolveProvider() { remove(resolveProviderKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpOptions : public WorkDoneProgressOptions class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpOptions : public WorkDoneProgressOptions
@@ -182,8 +168,6 @@ public:
void setTriggerCharacters(const QList<QString> &triggerCharacters) void setTriggerCharacters(const QList<QString> &triggerCharacters)
{ insertArray(triggerCharactersKey, triggerCharacters); } { insertArray(triggerCharactersKey, triggerCharacters); }
void clearTriggerCharacters() { remove(triggerCharactersKey); } void clearTriggerCharacters() { remove(triggerCharactersKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
using CodeLensOptions = ResolveProviderOption; using CodeLensOptions = ResolveProviderOption;
@@ -205,11 +189,7 @@ public:
{ insertArray(moreTriggerCharacterKey, moreTriggerCharacter); } { insertArray(moreTriggerCharacterKey, moreTriggerCharacter); }
void clearMoreTriggerCharacter() { remove(moreTriggerCharacterKey); } void clearMoreTriggerCharacter() { remove(moreTriggerCharacterKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(firstTriggerCharacterKey); }
{
return check<QString>(error, firstTriggerCharacterKey)
&& checkOptionalArray<QString>(error, moreTriggerCharacterKey);
}
}; };
using DocumentLinkOptions = ResolveProviderOption; using DocumentLinkOptions = ResolveProviderOption;
@@ -222,7 +202,7 @@ public:
QList<QString> commands() const { return array<QString>(commandsKey); } QList<QString> commands() const { return array<QString>(commandsKey); }
void setCommands(const QList<QString> &commands) { insertArray(commandsKey, commands); } void setCommands(const QList<QString> &commands) { insertArray(commandsKey, commands); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override;
}; };
using ColorProviderOptions = JsonObject; using ColorProviderOptions = JsonObject;
@@ -247,7 +227,7 @@ public:
Utils::optional<QList<QList<QString>>> scopes() const; Utils::optional<QList<QList<QString>>> scopes() const;
void setScopes(const QList<QList<QString>> &scopes); void setScopes(const QList<QList<QString>> &scopes);
bool isValid(ErrorHierarchy *) const override; bool isValid() const override;
}; };
// Defines how text documents are synced. Is either a detailed structure defining each // 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 setId(const QString &id) { insert(idKey, id); }
void clearId() { remove(idKey); } void clearId() { remove(idKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(documentSelectorKey); }
{ return checkArray<DocumentFilter>(error, documentSelectorKey) && checkOptional<bool>(error, idKey); }
}; };
// The server provides Goto Type Definition support. // The server provides Goto Type Definition support.
@@ -374,8 +353,6 @@ public:
Utils::optional<bool> prepareProvider() const { return optionalValue<bool>(prepareProviderKey); } Utils::optional<bool> prepareProvider() const { return optionalValue<bool>(prepareProviderKey); }
void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); } void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); }
void clearPrepareProvider() { remove(prepareProviderKey); } void clearPrepareProvider() { remove(prepareProviderKey); }
bool isValid(ErrorHierarchy * error) const override;
}; };
// The server provides rename support. // The server provides rename support.
@@ -420,8 +397,6 @@ public:
Utils::optional<Utils::variant<QString, bool>> changeNotifications() const; Utils::optional<Utils::variant<QString, bool>> changeNotifications() const;
void setChangeNotifications(Utils::variant<QString, bool> changeNotifications); void setChangeNotifications(Utils::variant<QString, bool> changeNotifications);
void clearChangeNotifications() { remove(changeNotificationsKey); } void clearChangeNotifications() { remove(changeNotificationsKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
Utils::optional<WorkspaceFoldersCapabilities> workspaceFolders() const Utils::optional<WorkspaceFoldersCapabilities> workspaceFolders() const
@@ -446,8 +421,6 @@ public:
void setSemanticHighlighting(const SemanticHighlightingServerCapabilities &semanticHighlighting) void setSemanticHighlighting(const SemanticHighlightingServerCapabilities &semanticHighlighting)
{ insert(semanticHighlightingKey, semanticHighlighting); } { insert(semanticHighlightingKey, semanticHighlighting); }
void clearSemanticHighlighting() { remove(semanticHighlightingKey); } void clearSemanticHighlighting() { remove(semanticHighlightingKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
} // namespace LanguageClient } // namespace LanguageClient

View File

@@ -74,12 +74,6 @@ DidChangeTextDocumentParams::DidChangeTextDocumentParams(
setContentChanges({TextDocumentContentChangeEvent(text)}); setContentChanges({TextDocumentContentChangeEvent(text)});
} }
bool DidChangeTextDocumentParams::isValid(ErrorHierarchy *error) const
{
return check<VersionedTextDocumentIdentifier>(error, textDocumentKey)
&& checkArray<TextDocumentContentChangeEvent>(error, contentChangesKey);
}
DidOpenTextDocumentParams::DidOpenTextDocumentParams(const TextDocumentItem &document) DidOpenTextDocumentParams::DidOpenTextDocumentParams(const TextDocumentItem &document)
{ {
setTextDocument(document); setTextDocument(document);
@@ -96,24 +90,11 @@ DidChangeTextDocumentParams::TextDocumentContentChangeEvent::TextDocumentContent
setText(text); setText(text);
} }
bool DidChangeTextDocumentParams::TextDocumentContentChangeEvent::isValid(ErrorHierarchy *error) const
{
return checkOptional<Range>(error, rangeKey)
&& checkOptional<int>(error, rangeLengthKey)
&& check<QString>(error, textKey);
}
DidSaveTextDocumentParams::DidSaveTextDocumentParams(const TextDocumentIdentifier &document) DidSaveTextDocumentParams::DidSaveTextDocumentParams(const TextDocumentIdentifier &document)
{ {
setTextDocument(document); setTextDocument(document);
} }
bool DidSaveTextDocumentParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& checkOptional<QString>(error, textKey);
}
WillSaveTextDocumentParams::WillSaveTextDocumentParams( WillSaveTextDocumentParams::WillSaveTextDocumentParams(
const TextDocumentIdentifier &document, const TextDocumentIdentifier &document,
const WillSaveTextDocumentParams::TextDocumentSaveReason &reason) const WillSaveTextDocumentParams::TextDocumentSaveReason &reason)
@@ -122,16 +103,4 @@ WillSaveTextDocumentParams::WillSaveTextDocumentParams(
setReason(reason); setReason(reason);
} }
bool WillSaveTextDocumentParams::isValid(ErrorHierarchy *error) const
{
return check<TextDocumentIdentifier>(error, textDocumentKey)
&& check<int>(error, reasonKey);
}
bool TextDocumentSaveRegistrationOptions::isValid(ErrorHierarchy *error) const
{
return TextDocumentRegistrationOptions::isValid(error)
&& checkOptional<bool>(error, includeTextKey);
}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -40,11 +40,9 @@ public:
TextDocumentItem textDocument() const { return typedValue<TextDocumentItem>(textDocumentKey); } TextDocumentItem textDocument() const { return typedValue<TextDocumentItem>(textDocumentKey); }
void setTextDocument(TextDocumentItem textDocument) { insert(textDocumentKey, textDocument); } void setTextDocument(TextDocumentItem textDocument) { insert(textDocumentKey, textDocument); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(textDocumentKey); }
{ return check<TextDocumentItem>(error, textDocumentKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidOpenTextDocumentNotification : public Notification< class LANGUAGESERVERPROTOCOL_EXPORT DidOpenTextDocumentNotification : public Notification<
DidOpenTextDocumentParams> DidOpenTextDocumentParams>
{ {
@@ -66,7 +64,7 @@ public:
void setSyncKind(TextDocumentSyncKind syncKind) void setSyncKind(TextDocumentSyncKind syncKind)
{ insert(syncKindKey, static_cast<int>(syncKind)); } { insert(syncKindKey, static_cast<int>(syncKind)); }
bool isValid(ErrorHierarchy *error) const override { return check<int>(error, syncKindKey); } bool isValid() const override { return contains(syncKindKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentParams : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentParams : public JsonObject
@@ -107,7 +105,7 @@ public:
QString text() const { return typedValue<QString>(textKey); } QString text() const { return typedValue<QString>(textKey); }
void setText(const QString &text) { insert(textKey, text); } void setText(const QString &text) { insert(textKey, text); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(textKey); }
}; };
QList<TextDocumentContentChangeEvent> contentChanges() const QList<TextDocumentContentChangeEvent> contentChanges() const
@@ -115,7 +113,8 @@ public:
void setContentChanges(const QList<TextDocumentContentChangeEvent> &contentChanges) void setContentChanges(const QList<TextDocumentContentChangeEvent> &contentChanges)
{ insertArray(contentChangesKey, 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< class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentNotification : public Notification<
@@ -151,7 +150,7 @@ public:
{ return static_cast<TextDocumentSaveReason>(typedValue<int>(reasonKey)); } { return static_cast<TextDocumentSaveReason>(typedValue<int>(reasonKey)); }
void setReason(TextDocumentSaveReason reason) { insert(reasonKey, static_cast<int>(reason)); } void setReason(TextDocumentSaveReason reason) { insert(reasonKey, static_cast<int>(reason)); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(textDocumentKey) && contains(reasonKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT WillSaveTextDocumentNotification : public Notification< class LANGUAGESERVERPROTOCOL_EXPORT WillSaveTextDocumentNotification : public Notification<
@@ -181,8 +180,6 @@ public:
Utils::optional<bool> includeText() const { return optionalValue<bool>(includeTextKey); } Utils::optional<bool> includeText() const { return optionalValue<bool>(includeTextKey); }
void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void setIncludeText(bool includeText) { insert(includeTextKey, includeText); }
void clearIncludeText() { remove(includeTextKey); } void clearIncludeText() { remove(includeTextKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentParams : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentParams : public JsonObject
@@ -201,7 +198,7 @@ public:
void setText(const QString &text) { insert(textKey, text); } void setText(const QString &text) { insert(textKey, text); }
void clearText() { remove(textKey); } void clearText() { remove(textKey); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(textDocumentKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentNotification : public Notification< class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentNotification : public Notification<
@@ -225,8 +222,7 @@ public:
void setTextDocument(const TextDocumentIdentifier &textDocument) void setTextDocument(const TextDocumentIdentifier &textDocument)
{ insert(textDocumentKey, textDocument); } { insert(textDocumentKey, textDocument); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(textDocumentKey); }
{ return check<TextDocumentIdentifier>(error, textDocumentKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidCloseTextDocumentNotification : public Notification< class LANGUAGESERVERPROTOCOL_EXPORT DidCloseTextDocumentNotification : public Notification<

View File

@@ -72,27 +72,6 @@ WorkspaceFoldersChangeEvent::WorkspaceFoldersChangeEvent()
insert(removedKey, QJsonArray()); insert(removedKey, QJsonArray());
} }
bool WorkspaceFoldersChangeEvent::isValid(ErrorHierarchy *error) const
{
return checkArray<WorkSpaceFolder>(error, addedKey)
&& checkArray<WorkSpaceFolder>(error, removedKey);
}
bool ConfigurationParams::ConfigureationItem::isValid(ErrorHierarchy *error) const
{
return checkOptional<QString>(error, scopeUriKey)
&& checkOptional<QString>(error, sectionKey);
}
bool DidChangeConfigurationParams::isValid(ErrorHierarchy *error) const
{
if (contains(settingsKey))
return true;
if (error)
error->prependMember(settingsKey);
return false;
}
DidChangeWatchedFilesNotification::DidChangeWatchedFilesNotification( DidChangeWatchedFilesNotification::DidChangeWatchedFilesNotification(
const DidChangeWatchedFilesParams &params) const DidChangeWatchedFilesParams &params)
: Notification(methodName, params) : Notification(methodName, params)

View File

@@ -61,7 +61,7 @@ public:
QList<WorkSpaceFolder> removed() const { return array<WorkSpaceFolder>(removedKey); } QList<WorkSpaceFolder> removed() const { return array<WorkSpaceFolder>(removedKey); }
void setRemoved(const QList<WorkSpaceFolder> &removed) { insertArray(removedKey, removed); } void setRemoved(const QList<WorkSpaceFolder> &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 class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersParams : public JsonObject
@@ -73,8 +73,7 @@ public:
{ return typedValue<WorkspaceFoldersChangeEvent>(eventKey); } { return typedValue<WorkspaceFoldersChangeEvent>(eventKey); }
void setEvent(const WorkspaceFoldersChangeEvent &event) { insert(eventKey, event); } void setEvent(const WorkspaceFoldersChangeEvent &event) { insert(eventKey, event); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(eventKey); }
{ return check<WorkspaceFoldersChangeEvent>(error, eventKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersNotification : public Notification< class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersNotification : public Notification<
@@ -91,10 +90,10 @@ class LANGUAGESERVERPROTOCOL_EXPORT DidChangeConfigurationParams : public JsonOb
public: public:
using JsonObject::JsonObject; using JsonObject::JsonObject;
QJsonValue settings() const { return typedValue<QJsonValue>(settingsKey); } QJsonValue settings() const { return value(settingsKey); }
void setSettings(QJsonValue settings) { insert(settingsKey, settings); } 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< class LANGUAGESERVERPROTOCOL_EXPORT DidChangeConfigurationNotification : public Notification<
@@ -123,14 +122,13 @@ public:
void setSection(const QString &section) { insert(sectionKey, section); } void setSection(const QString &section) { insert(sectionKey, section); }
void clearSection() { remove(sectionKey); } void clearSection() { remove(sectionKey); }
bool isValid(ErrorHierarchy *error) const override; bool isValid() const override { return contains(scopeUriKey); }
}; };
QList<ConfigureationItem> items() const { return array<ConfigureationItem>(itemsKey); } QList<ConfigureationItem> items() const { return array<ConfigureationItem>(itemsKey); }
void setItems(const QList<ConfigureationItem> &items) { insertArray(itemsKey, items); } void setItems(const QList<ConfigureationItem> &items) { insertArray(itemsKey, items); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(itemsKey); }
{ return checkArray<ConfigureationItem>(error, itemsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ConfigurationRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT ConfigurationRequest : public Request<
@@ -164,15 +162,13 @@ public:
Deleted = 3 Deleted = 3
}; };
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(uriKey) && contains(typeKey); }
{ return check<QString>(error, uriKey) && check<int>(error, typeKey); }
}; };
QList<FileEvent> changes() const { return array<FileEvent>(changesKey); } QList<FileEvent> changes() const { return array<FileEvent>(changesKey); }
void setChanges(const QList<FileEvent> &changes) { insertArray(changesKey, changes); } void setChanges(const QList<FileEvent> &changes) { insertArray(changesKey, changes); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(changesKey); }
{ return checkArray<FileEvent>(error, changesKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWatchedFilesNotification : public Notification< class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWatchedFilesNotification : public Notification<
@@ -192,7 +188,7 @@ public:
QString query() const { return typedValue<QString>(queryKey); } QString query() const { return typedValue<QString>(queryKey); }
void setQuery(const QString &query) { insert(queryKey, query); } void setQuery(const QString &query) { insert(queryKey, query); }
bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, queryKey); } bool isValid() const override { return contains(queryKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceSymbolRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceSymbolRequest : public Request<
@@ -219,11 +215,7 @@ public:
void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); }
void clearArguments() { remove(argumentsKey); } void clearArguments() { remove(argumentsKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(commandKey); }
{
return check<QString>(error, commandKey)
&& checkOptionalArray<QJsonValue>(error, argumentsKey);
}
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ExecuteCommandRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT ExecuteCommandRequest : public Request<
@@ -247,8 +239,7 @@ public:
WorkspaceEdit edit() const { return typedValue<WorkspaceEdit>(editKey); } WorkspaceEdit edit() const { return typedValue<WorkspaceEdit>(editKey); }
void setEdit(const WorkspaceEdit &edit) { insert(editKey, edit); } void setEdit(const WorkspaceEdit &edit) { insert(editKey, edit); }
bool isValid(ErrorHierarchy *error) const override bool isValid() const override { return contains(editKey); }
{ return check<WorkspaceEdit>(error, editKey) && checkOptional<QString>(error, labelKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditResponse : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditResponse : public JsonObject
@@ -259,7 +250,7 @@ public:
bool applied() const { return typedValue<bool>(appliedKey); } bool applied() const { return typedValue<bool>(appliedKey); }
void setApplied(bool applied) { insert(appliedKey, applied); } void setApplied(bool applied) { insert(appliedKey, applied); }
bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, appliedKey); } bool isValid() const override { return contains(appliedKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditRequest : public Request< class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditRequest : public Request<

View File

@@ -221,7 +221,7 @@ void JLSClient::executeCommand(const LanguageServerProtocol::Command &command)
if (!argument.isObject()) if (!argument.isObject())
continue; continue;
LanguageServerProtocol::WorkspaceEdit edit(argument.toObject()); LanguageServerProtocol::WorkspaceEdit edit(argument.toObject());
if (edit.isValid(nullptr)) if (edit.isValid())
LanguageClient::applyWorkspaceEdit(edit); LanguageClient::applyWorkspaceEdit(edit);
} }
} else { } else {

View File

@@ -314,7 +314,7 @@ void Client::openDocument(TextEditor::TextDocument *document)
return; return;
const TextDocumentRegistrationOptions option( const TextDocumentRegistrationOptions option(
m_dynamicCapabilities.option(method).toObject()); m_dynamicCapabilities.option(method).toObject());
if (option.isValid(nullptr) if (option.isValid()
&& !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) { && !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) {
return; return;
} }
@@ -387,7 +387,7 @@ void Client::updateCompletionProvider(TextEditor::TextDocument *document)
Utils::mimeTypeForName(document->mimeType())); Utils::mimeTypeForName(document->mimeType()));
const ServerCapabilities::CompletionOptions completionOptions(options); const ServerCapabilities::CompletionOptions completionOptions(options);
if (completionOptions.isValid(nullptr)) if (completionOptions.isValid())
clientCompletionProvider->setTriggerCharacters(completionOptions.triggerCharacters()); clientCompletionProvider->setTriggerCharacters(completionOptions.triggerCharacters());
} }
@@ -415,7 +415,7 @@ void Client::updateFunctionHintProvider(TextEditor::TextDocument *document)
Utils::mimeTypeForName(document->mimeType())); Utils::mimeTypeForName(document->mimeType()));
const ServerCapabilities::SignatureHelpOptions signatureOptions(options); const ServerCapabilities::SignatureHelpOptions signatureOptions(options);
if (signatureOptions.isValid(nullptr)) if (signatureOptions.isValid())
clientFunctionHintProvider->setTriggerCharacters(signatureOptions.triggerCharacters()); clientFunctionHintProvider->setTriggerCharacters(signatureOptions.triggerCharacters());
} }
@@ -488,7 +488,7 @@ void Client::documentContentsSaved(TextEditor::TextDocument *document)
if (sendMessage) { if (sendMessage) {
const TextDocumentSaveRegistrationOptions option( const TextDocumentSaveRegistrationOptions option(
m_dynamicCapabilities.option(method).toObject()); m_dynamicCapabilities.option(method).toObject());
if (option.isValid(nullptr)) { if (option.isValid()) {
sendMessage = option.filterApplies(document->filePath(), sendMessage = option.filterApplies(document->filePath(),
Utils::mimeTypeForName(document->mimeType())); Utils::mimeTypeForName(document->mimeType()));
includeText = option.includeText().value_or(includeText); includeText = option.includeText().value_or(includeText);
@@ -522,7 +522,7 @@ void Client::documentWillSave(Core::IDocument *document)
sendMessage = registered.value(); sendMessage = registered.value();
if (sendMessage) { if (sendMessage) {
const TextDocumentRegistrationOptions option(m_dynamicCapabilities.option(method)); const TextDocumentRegistrationOptions option(m_dynamicCapabilities.option(method));
if (option.isValid(nullptr)) { if (option.isValid()) {
sendMessage = option.filterApplies(filePath, sendMessage = option.filterApplies(filePath,
Utils::mimeTypeForName(document->mimeType())); Utils::mimeTypeForName(document->mimeType()));
} }
@@ -553,7 +553,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
if (syncKind != TextDocumentSyncKind::None) { if (syncKind != TextDocumentSyncKind::None) {
const TextDocumentChangeRegistrationOptions option( const TextDocumentChangeRegistrationOptions option(
m_dynamicCapabilities.option(method).toObject()); 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<Unregistration> &unregistrations
TextEditor::HighlightingResult createHighlightingResult(const SymbolInformation &info) TextEditor::HighlightingResult createHighlightingResult(const SymbolInformation &info)
{ {
if (!info.isValid(nullptr)) if (!info.isValid())
return {}; return {};
const Position &start = info.location().range().start(); const Position &start = info.location().range().start();
return TextEditor::HighlightingResult(start.line() + 1, return TextEditor::HighlightingResult(start.line() + 1,
@@ -730,7 +730,7 @@ void Client::requestCodeActions(const CodeActionRequest &request)
return; return;
const TextDocumentRegistrationOptions option( const TextDocumentRegistrationOptions option(
m_dynamicCapabilities.option(method).toObject()); m_dynamicCapabilities.option(method).toObject());
if (option.isValid(nullptr) && !option.filterApplies(fileName)) if (option.isValid() && !option.filterApplies(fileName))
return; return;
} else { } else {
Utils::variant<bool, CodeActionOptions> provider Utils::variant<bool, CodeActionOptions> provider
@@ -965,8 +965,8 @@ void Client::showMessageBox(const ShowMessageRequestParams &message, const Messa
connect(box, &QMessageBox::finished, this, [=]{ connect(box, &QMessageBox::finished, this, [=]{
ShowMessageRequest::Response response(id); ShowMessageRequest::Response response(id);
const MessageActionItem &item = itemForButton.value(box->clickedButton()); const MessageActionItem &item = itemForButton.value(box->clickedButton());
response.setResult(item.isValid(nullptr) ? LanguageClientValue<MessageActionItem>(item) response.setResult(item.isValid() ? LanguageClientValue<MessageActionItem>(item)
: LanguageClientValue<MessageActionItem>()); : LanguageClientValue<MessageActionItem>());
sendContent(response); sendContent(response);
}); });
box->show(); 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) void Client::handleMethod(const QString &method, const MessageId &id, const IContent *content)
{ {
ErrorHierarchy error;
auto logError = [&](const JsonObject &content) { auto logError = [&](const JsonObject &content) {
log(QJsonDocument(content).toJson(QJsonDocument::Indented) + '\n' 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) { if (method == PublishDiagnosticsNotification::methodName) {
auto params = dynamic_cast<const PublishDiagnosticsNotification *>(content)->params().value_or(PublishDiagnosticsParams()); auto params = dynamic_cast<const PublishDiagnosticsNotification *>(content)->params().value_or(PublishDiagnosticsParams());
if (params.isValid(&error)) if (params.isValid())
handleDiagnostics(params); handleDiagnostics(params);
else else
logError(params); logError(params);
} else if (method == LogMessageNotification::methodName) { } else if (method == LogMessageNotification::methodName) {
auto params = dynamic_cast<const LogMessageNotification *>(content)->params().value_or(LogMessageParams()); auto params = dynamic_cast<const LogMessageNotification *>(content)->params().value_or(LogMessageParams());
if (params.isValid(&error)) if (params.isValid())
log(params); log(params);
else else
logError(params); logError(params);
} else if (method == SemanticHighlightNotification::methodName) { } else if (method == SemanticHighlightNotification::methodName) {
auto params = dynamic_cast<const SemanticHighlightNotification *>(content)->params().value_or(SemanticHighlightingParams()); auto params = dynamic_cast<const SemanticHighlightNotification *>(content)->params().value_or(SemanticHighlightingParams());
if (params.isValid(&error)) if (params.isValid())
handleSemanticHighlight(params); handleSemanticHighlight(params);
else else
logError(params); logError(params);
} else if (method == ShowMessageNotification::methodName) { } else if (method == ShowMessageNotification::methodName) {
auto params = dynamic_cast<const ShowMessageNotification *>(content)->params().value_or(ShowMessageParams()); auto params = dynamic_cast<const ShowMessageNotification *>(content)->params().value_or(ShowMessageParams());
if (params.isValid(&error)) if (params.isValid())
log(params); log(params);
else else
logError(params); logError(params);
} else if (method == ShowMessageRequest::methodName) { } else if (method == ShowMessageRequest::methodName) {
auto request = dynamic_cast<const ShowMessageRequest *>(content); auto request = dynamic_cast<const ShowMessageRequest *>(content);
auto params = request->params().value_or(ShowMessageRequestParams()); auto params = request->params().value_or(ShowMessageRequestParams());
if (params.isValid(&error)) { if (params.isValid()) {
showMessageBox(params, request->id()); showMessageBox(params, request->id());
} else { } else {
ShowMessageRequest::Response response(request->id()); 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) { } else if (method == RegisterCapabilityRequest::methodName) {
auto params = dynamic_cast<const RegisterCapabilityRequest *>(content)->params().value_or(RegistrationParams()); auto params = dynamic_cast<const RegisterCapabilityRequest *>(content)->params().value_or(RegistrationParams());
if (params.isValid(&error)) if (params.isValid())
registerCapabilities(params.registrations()); registerCapabilities(params.registrations());
else else
logError(params); logError(params);
} else if (method == UnregisterCapabilityRequest::methodName) { } else if (method == UnregisterCapabilityRequest::methodName) {
auto params = dynamic_cast<const UnregisterCapabilityRequest *>(content)->params().value_or(UnregistrationParams()); auto params = dynamic_cast<const UnregisterCapabilityRequest *>(content)->params().value_or(UnregistrationParams());
if (params.isValid(&error)) if (params.isValid())
unregisterCapabilities(params.unregistrations()); unregisterCapabilities(params.unregistrations());
else else
logError(params); logError(params);
} else if (method == ApplyWorkspaceEditRequest::methodName) { } else if (method == ApplyWorkspaceEditRequest::methodName) {
auto params = dynamic_cast<const ApplyWorkspaceEditRequest *>(content)->params().value_or(ApplyWorkspaceEditParams()); auto params = dynamic_cast<const ApplyWorkspaceEditRequest *>(content)->params().value_or(ApplyWorkspaceEditParams());
if (params.isValid(&error)) if (params.isValid())
applyWorkspaceEdit(params.edit()); applyWorkspaceEdit(params.edit());
else else
logError(params); logError(params);
@@ -1111,7 +1110,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
} }
response.setResult(result); response.setResult(result);
sendContent(response); sendContent(response);
} else if (id.isValid(&error)) { } else if (id.isValid()) {
Response<JsonObject, JsonObject> response(id); Response<JsonObject, JsonObject> response(id);
ResponseError<JsonObject> error; ResponseError<JsonObject> error;
error.setCode(ResponseError<JsonObject>::MethodNotFound); error.setCode(ResponseError<JsonObject>::MethodNotFound);
@@ -1208,10 +1207,9 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse)
log(tr("No initialize result.")); log(tr("No initialize result."));
} else { } else {
const InitializeResult &result = _result.value(); const InitializeResult &result = _result.value();
ErrorHierarchy error; if (!result.isValid()) { // continue on ill formed result
if (!result.isValid(&error)) { // continue on ill formed result
log(QJsonDocument(result).toJson(QJsonDocument::Indented) + '\n' 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()); m_serverCapabilities = result.capabilities().value_or(ServerCapabilities());

View File

@@ -184,7 +184,7 @@ bool LanguageClientCompletionItem::isSnippet() const
bool LanguageClientCompletionItem::isValid() const bool LanguageClientCompletionItem::isValid() const
{ {
return m_item.isValid(nullptr); return m_item.isValid();
} }
quint64 LanguageClientCompletionItem::hash() const quint64 LanguageClientCompletionItem::hash() const

View File

@@ -80,7 +80,7 @@ QFutureWatcher<ChangeSet> *LanguageClientFormatter::format(
if (!registered.value()) if (!registered.value())
return nullptr; return nullptr;
const TextDocumentRegistrationOptions option(dynamicCapabilities.option(method).toObject()); const TextDocumentRegistrationOptions option(dynamicCapabilities.option(method).toObject());
if (option.isValid(nullptr) if (option.isValid()
&& !option.filterApplies(filePath, Utils::mimeTypeForName(m_document->mimeType()))) { && !option.filterApplies(filePath, Utils::mimeTypeForName(m_document->mimeType()))) {
return nullptr; return nullptr;
} }

View File

@@ -85,7 +85,7 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
if (sendMessage) { if (sendMessage) {
const TextDocumentRegistrationOptions option( const TextDocumentRegistrationOptions option(
m_client->dynamicCapabilities().option(HoverRequest::methodName).toObject()); m_client->dynamicCapabilities().option(HoverRequest::methodName).toObject());
if (option.isValid(nullptr)) { if (option.isValid()) {
sendMessage = option.filterApplies(editorWidget->textDocument()->filePath(), sendMessage = option.filterApplies(editorWidget->textDocument()->filePath(),
Utils::mimeTypeForName( Utils::mimeTypeForName(
editorWidget->textDocument()->mimeType())); editorWidget->textDocument()->mimeType()));

View File

@@ -231,7 +231,7 @@ bool LanguageClientOutlineWidgetFactory::clientSupportsDocumentSymbols(
DynamicCapabilities dc = client->dynamicCapabilities(); DynamicCapabilities dc = client->dynamicCapabilities();
if (dc.isRegistered(DocumentSymbolsRequest::methodName).value_or(false)) { if (dc.isRegistered(DocumentSymbolsRequest::methodName).value_or(false)) {
TextDocumentRegistrationOptions options(dc.option(DocumentSymbolsRequest::methodName)); TextDocumentRegistrationOptions options(dc.option(DocumentSymbolsRequest::methodName));
return !options.isValid(nullptr) return !options.isValid()
|| options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType())); || options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType()));
} }
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider

View File

@@ -56,7 +56,7 @@ static void sendTextDocumentPositionParamsRequest(Client *client,
if (sendMessage) { if (sendMessage) {
const TextDocumentRegistrationOptions option( const TextDocumentRegistrationOptions option(
dynamicCapabilities.option(Request::methodName)); dynamicCapabilities.option(Request::methodName));
if (option.isValid(nullptr)) if (option.isValid())
sendMessage = option.filterApplies( sendMessage = option.filterApplies(
Utils::FilePath::fromString(QUrl(uri).adjusted(QUrl::PreferLocalFile).toString())); Utils::FilePath::fromString(QUrl(uri).adjusted(QUrl::PreferLocalFile).toString()));
else else
@@ -248,7 +248,7 @@ static bool supportsRename(Client *client,
prepareSupported = ServerCapabilities::RenameOptions(options).prepareProvider().value_or( prepareSupported = ServerCapabilities::RenameOptions(options).prepareProvider().value_or(
false); false);
const TextDocumentRegistrationOptions docOps(options); const TextDocumentRegistrationOptions docOps(options);
if (docOps.isValid(nullptr) if (docOps.isValid()
&& !docOps.filterApplies(document->filePath(), && !docOps.filterApplies(document->filePath(),
Utils::mimeTypeForName(document->mimeType()))) { Utils::mimeTypeForName(document->mimeType()))) {
return false; return false;
@@ -411,7 +411,7 @@ void SymbolSupport::applyRename(const QList<Core::SearchResultItem> &checkedItem
for (const Core::SearchResultItem &item : checkedItems) { for (const Core::SearchResultItem &item : checkedItems) {
auto uri = DocumentUri::fromFilePath(Utils::FilePath::fromString(item.path().value(0))); auto uri = DocumentUri::fromFilePath(Utils::FilePath::fromString(item.path().value(0)));
TextEdit edit(item.userData().toJsonObject()); TextEdit edit(item.userData().toJsonObject());
if (edit.isValid(nullptr)) if (edit.isValid())
editsForDocuments[uri] << edit; editsForDocuments[uri] << edit;
} }

View File

@@ -152,7 +152,7 @@ void updateCodeActionRefactoringMarker(Client *client,
RefactorMarkers markers; RefactorMarkers markers;
RefactorMarker marker; RefactorMarker marker;
marker.type = client->id(); marker.type = client->id();
if (action.isValid(nullptr)) if (action.isValid())
marker.tooltip = action.title(); marker.tooltip = action.title();
if (action.edit().has_value()) { if (action.edit().has_value()) {
WorkspaceEdit edit = action.edit().value(); WorkspaceEdit edit = action.edit().value();

View File

@@ -60,8 +60,6 @@ private slots:
void jsonMessageToBaseMessage_data(); void jsonMessageToBaseMessage_data();
void jsonMessageToBaseMessage(); void jsonMessageToBaseMessage();
void jsonObject();
void documentUri_data(); void documentUri_data();
void documentUri(); void documentUri();
@@ -478,127 +476,6 @@ void tst_LanguageServerProtocol::jsonMessageToBaseMessage()
QCOMPARE(jsonMessage.toBaseMessage(), baseMessage); 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<int>("integer"), 42);
QCOMPARE(obj.typedValue<double>("double"), 42.42);
QCOMPARE(obj.typedValue<bool>("bool"), false);
QCOMPARE(obj.typedValue<QString>("string"), QString("foobar"));
QCOMPARE(obj.typedValue<JsonTestObject>("object"), innerObj);
QVERIFY(!obj.optionalValue<int>("doesNotExist").has_value());
QVERIFY(obj.optionalValue<int>("integer").has_value());
QCOMPARE(obj.optionalValue<int>("integer").value_or(0), 42);
QVERIFY(obj.clientValue<int>("null").isNull());
QVERIFY(!obj.clientValue<int>("integer").isNull());
QCOMPARE(obj.clientValue<int>("integer").value(), 42);
QVERIFY(!obj.optionalClientValue<int>("doesNotExist").has_value());
QVERIFY(obj.optionalClientValue<int>("null").has_value());
QVERIFY(obj.optionalClientValue<int>("null").value().isNull());
QVERIFY(obj.optionalClientValue<int>("integer").has_value());
QVERIFY(!obj.optionalClientValue<int>("integer").value().isNull());
QCOMPARE(obj.optionalClientValue<int>("integer").value().value(0), 42);
QCOMPARE(obj.array<QString>("strings"), QList<QString>({"foo", "bar"}));
QVERIFY(!obj.optionalArray<QString>("doesNotExist").has_value());
QVERIFY(obj.optionalArray<QString>("strings").has_value());
QCOMPARE(obj.optionalArray<QString>("strings").value_or(QList<QString>()),
QList<QString>({"foo", "bar"}));
QVERIFY(obj.clientArray<QString>("null").isNull());
QVERIFY(!obj.clientArray<QString>("strings").isNull());
QCOMPARE(obj.clientArray<QString>("strings").toList(), QList<QString>({"foo", "bar"}));
QVERIFY(!obj.optionalClientArray<QString>("doesNotExist").has_value());
QVERIFY(obj.optionalClientArray<QString>("null").has_value());
QVERIFY(obj.optionalClientArray<QString>("null").value().isNull());
QVERIFY(obj.optionalClientArray<QString>("strings").has_value());
QVERIFY(!obj.optionalClientArray<QString>("strings").value().isNull());
QCOMPARE(obj.optionalClientArray<QString>("strings").value().toList(),
QList<QString>({"foo", "bar"}));
ErrorHierarchy errorHierarchy;
QVERIFY(!obj.check<int>(&errorHierarchy, "doesNotExist"));
ErrorHierarchy errorDoesNotExists;
errorDoesNotExists.setError(
JsonTestObject::errorString(QJsonValue::Double, QJsonValue::Undefined));
errorDoesNotExists.prependMember("doesNotExist");
QCOMPARE(errorHierarchy, errorDoesNotExists);
errorHierarchy.clear();
QVERIFY(!obj.check<int>(&errorHierarchy, "bool"));
ErrorHierarchy errorWrongType;
errorWrongType.setError(JsonTestObject::errorString(QJsonValue::Double, QJsonValue::Bool));
errorWrongType.prependMember("bool");
QCOMPARE(errorHierarchy, errorWrongType);
errorHierarchy.clear();
QVERIFY(obj.check<int>(&errorHierarchy, "integer"));
QVERIFY(errorHierarchy.isEmpty());
QVERIFY(obj.check<double>(&errorHierarchy, "double"));
QVERIFY(errorHierarchy.isEmpty());
QVERIFY(obj.check<bool>(&errorHierarchy, "bool"));
QVERIFY(errorHierarchy.isEmpty());
QVERIFY(obj.check<std::nullptr_t>(&errorHierarchy, "null"));
QVERIFY(errorHierarchy.isEmpty());
QVERIFY(obj.check<QString>(&errorHierarchy, "string"));
QVERIFY(errorHierarchy.isEmpty());
}
void tst_LanguageServerProtocol::documentUri_data() void tst_LanguageServerProtocol::documentUri_data()
{ {
QTest::addColumn<DocumentUri>("uri"); QTest::addColumn<DocumentUri>("uri");