forked from qt-creator/qt-creator
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:
@@ -80,11 +80,6 @@ Utils::optional<MarkupOrString> ParameterInformation::documentation() const
|
||||
return MarkupOrString(documentation);
|
||||
}
|
||||
|
||||
bool SignatureHelp::isValid(ErrorHierarchy *error) const
|
||||
{
|
||||
return checkArray<SignatureInformation>(error, signaturesKey);
|
||||
}
|
||||
|
||||
GotoDefinitionRequest::GotoDefinitionRequest(const TextDocumentPositionParams ¶ms)
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
@@ -119,18 +114,6 @@ void CodeActionParams::CodeActionContext::setOnly(const QList<CodeActionKind> &o
|
||||
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 ¶ms)
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
@@ -155,21 +138,6 @@ DocumentColorRequest::DocumentColorRequest(const DocumentColorParams ¶ms)
|
||||
: 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 ¶ms)
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
@@ -202,43 +170,19 @@ void FormattingOptions::setProperty(const QString &key, const DocumentFormatting
|
||||
insert(key, *val);
|
||||
}
|
||||
|
||||
bool FormattingOptions::isValid(ErrorHierarchy *error) const
|
||||
{
|
||||
return Utils::allOf(keys(), [this, &error](auto key){
|
||||
return (key == tabSizeKey && this->check<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 ¶ms)
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
|
||||
bool DocumentRangeFormattingParams::isValid(ErrorHierarchy *error) const
|
||||
{
|
||||
return check<TextDocumentIdentifier>(error, textDocumentKey)
|
||||
&& check<Range>(error, rangeKey)
|
||||
&& check<FormattingOptions>(error, optionsKey);
|
||||
}
|
||||
|
||||
DocumentRangeFormattingRequest::DocumentRangeFormattingRequest(
|
||||
const DocumentRangeFormattingParams ¶ms)
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
|
||||
bool DocumentOnTypeFormattingParams::isValid(ErrorHierarchy *error) const
|
||||
bool DocumentOnTypeFormattingParams::isValid() const
|
||||
{
|
||||
return check<TextDocumentIdentifier>(error, textDocumentKey)
|
||||
&& check<Position>(error, positionKey)
|
||||
&& check<QString>(error, chKey)
|
||||
&& check<FormattingOptions>(error, optionsKey);
|
||||
return contains(textDocumentKey) && contains(positionKey) && contains(chKey)
|
||||
&& contains(optionsKey);
|
||||
}
|
||||
|
||||
DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest(
|
||||
@@ -250,11 +194,9 @@ PrepareRenameRequest::PrepareRenameRequest(const TextDocumentPositionParams &par
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
|
||||
bool RenameParams::isValid(ErrorHierarchy *error) const
|
||||
bool RenameParams::isValid() const
|
||||
{
|
||||
return check<TextDocumentIdentifier>(error, textDocumentKey)
|
||||
&& check<Position>(error, positionKey)
|
||||
&& check<QString>(error, newNameKey);
|
||||
return contains(textDocumentKey) && contains(positionKey) && contains(newNameKey);
|
||||
}
|
||||
|
||||
RenameRequest::RenameRequest(const RenameParams ¶ms)
|
||||
@@ -269,6 +211,11 @@ Utils::optional<DocumentUri> DocumentLink::target() const
|
||||
: Utils::nullopt;
|
||||
}
|
||||
|
||||
Utils::optional<QJsonValue> DocumentLink::data() const
|
||||
{
|
||||
return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt;
|
||||
}
|
||||
|
||||
TextDocumentParams::TextDocumentParams()
|
||||
: TextDocumentParams(TextDocumentIdentifier())
|
||||
{ }
|
||||
@@ -340,13 +287,17 @@ DocumentHighlightsResult::DocumentHighlightsResult(const QJsonValue &value)
|
||||
|
||||
MarkedString::MarkedString(const QJsonValue &value)
|
||||
{
|
||||
if (value.isObject()) {
|
||||
MarkedLanguageString string(value.toObject());
|
||||
if (string.isValid(nullptr))
|
||||
emplace<MarkedLanguageString>(string);
|
||||
} else if (value.isString()) {
|
||||
if (value.isObject())
|
||||
emplace<MarkedLanguageString>(MarkedLanguageString(value.toObject()));
|
||||
else
|
||||
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
|
||||
@@ -365,7 +316,7 @@ HoverContent::HoverContent(const QJsonValue &value)
|
||||
} else if (value.isObject()) {
|
||||
const QJsonObject &object = value.toObject();
|
||||
MarkedLanguageString markedLanguageString(object);
|
||||
if (markedLanguageString.isValid(nullptr))
|
||||
if (markedLanguageString.isValid())
|
||||
emplace<MarkedString>(markedLanguageString);
|
||||
else
|
||||
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)
|
||||
|| Utils::holds_alternative<MarkupContent>(*this)
|
||||
|| Utils::holds_alternative<QList<MarkedString>>(*this)) {
|
||||
return true;
|
||||
}
|
||||
if (errorHierarchy) {
|
||||
errorHierarchy->setError(
|
||||
QCoreApplication::translate("LanguageServerProtocol::HoverContent",
|
||||
"HoverContent should be either MarkedString, "
|
||||
"MarkupContent, or QList<MarkedString>."));
|
||||
}
|
||||
return false;
|
||||
if (Utils::holds_alternative<MarkedString>(*this))
|
||||
return Utils::get<MarkedString>(*this).isValid();
|
||||
return true;
|
||||
}
|
||||
|
||||
DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value)
|
||||
@@ -400,21 +342,6 @@ DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value)
|
||||
*this = value.toString();
|
||||
}
|
||||
|
||||
bool DocumentFormattingProperty::isValid(ErrorHierarchy *error) const
|
||||
{
|
||||
if (Utils::holds_alternative<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 ¶ms)
|
||||
: Request(methodName, params)
|
||||
{ }
|
||||
@@ -427,7 +354,7 @@ CodeActionResult::CodeActionResult(const QJsonValue &val)
|
||||
ResultArray result;
|
||||
for (const QJsonValue &val : array) {
|
||||
Command command(val);
|
||||
if (command.isValid(nullptr))
|
||||
if (command.isValid())
|
||||
result << command;
|
||||
else
|
||||
result << CodeAction(val);
|
||||
@@ -438,15 +365,6 @@ CodeActionResult::CodeActionResult(const QJsonValue &val)
|
||||
emplace<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
|
||||
{
|
||||
QList<SemanticHighlightToken> resultTokens;
|
||||
@@ -501,19 +419,7 @@ SemanticHighlightingParams::textDocument() const
|
||||
{
|
||||
VersionedTextDocumentIdentifier textDocument = fromJsonValue<VersionedTextDocumentIdentifier>(
|
||||
value(textDocumentKey));
|
||||
ErrorHierarchy error;
|
||||
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);
|
||||
return textDocument.isValid() ? textDocument : TextDocumentIdentifier(textDocument);
|
||||
}
|
||||
|
||||
PrepareRenameResult::PrepareRenameResult()
|
||||
@@ -551,4 +457,9 @@ SemanticHighlightNotification::SemanticHighlightNotification(const SemanticHighl
|
||||
: Notification(methodName, params)
|
||||
{}
|
||||
|
||||
Utils::optional<QJsonValue> CodeLens::data() const
|
||||
{
|
||||
return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt;
|
||||
}
|
||||
|
||||
} // namespace LanguageServerProtocol
|
||||
|
||||
Reference in New Issue
Block a user