mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-17 04:50:15 +00:00
[clangd] Fix codeAction not decoded properly when sent from some clients
Summary: Fix for bug https://bugs.llvm.org/show_bug.cgi?id=34559 Also log unknown fields instead of aborting the JSON parsing because it's common that new optional fields are added either in new versions of the protocol or extensions. Reviewers: ilya-biryukov Reviewed By: ilya-biryukov Subscribers: ilya-biryukov Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D37754 llvm-svn: 313536
This commit is contained in:
parent
3fa0ccffc6
commit
85dcce4d15
@ -13,13 +13,22 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Protocol.h"
|
||||
#include "JSONRPCDispatcher.h"
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace clang::clangd;
|
||||
|
||||
namespace {
|
||||
void logIgnoredField(llvm::StringRef KeyValue, JSONOutput &Output) {
|
||||
Output.log(llvm::formatv("Ignored unknown field \"{0}\"\n", KeyValue));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
URI URI::fromUri(llvm::StringRef uri) {
|
||||
URI Result;
|
||||
Result.uri = uri;
|
||||
@ -55,7 +64,8 @@ URI URI::parse(llvm::yaml::ScalarNode *Param) {
|
||||
std::string URI::unparse(const URI &U) { return "\"" + U.uri + "\""; }
|
||||
|
||||
llvm::Optional<TextDocumentIdentifier>
|
||||
TextDocumentIdentifier::parse(llvm::yaml::MappingNode *Params) {
|
||||
TextDocumentIdentifier::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
TextDocumentIdentifier Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -74,13 +84,14 @@ TextDocumentIdentifier::parse(llvm::yaml::MappingNode *Params) {
|
||||
} else if (KeyValue == "version") {
|
||||
// FIXME: parse version, but only for VersionedTextDocumentIdentifiers.
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<Position> Position::parse(llvm::yaml::MappingNode *Params) {
|
||||
llvm::Optional<Position> Position::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
Position Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -106,7 +117,7 @@ llvm::Optional<Position> Position::parse(llvm::yaml::MappingNode *Params) {
|
||||
return llvm::None;
|
||||
Result.character = Val;
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
@ -119,7 +130,8 @@ std::string Position::unparse(const Position &P) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<Range> Range::parse(llvm::yaml::MappingNode *Params) {
|
||||
llvm::Optional<Range> Range::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
Range Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -135,17 +147,17 @@ llvm::Optional<Range> Range::parse(llvm::yaml::MappingNode *Params) {
|
||||
|
||||
llvm::SmallString<10> Storage;
|
||||
if (KeyValue == "start") {
|
||||
auto Parsed = Position::parse(Value);
|
||||
auto Parsed = Position::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.start = std::move(*Parsed);
|
||||
} else if (KeyValue == "end") {
|
||||
auto Parsed = Position::parse(Value);
|
||||
auto Parsed = Position::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.end = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
@ -168,7 +180,7 @@ std::string Location::unparse(const Location &P) {
|
||||
}
|
||||
|
||||
llvm::Optional<TextDocumentItem>
|
||||
TextDocumentItem::parse(llvm::yaml::MappingNode *Params) {
|
||||
TextDocumentItem::parse(llvm::yaml::MappingNode *Params, JSONOutput &Output) {
|
||||
TextDocumentItem Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -195,13 +207,14 @@ TextDocumentItem::parse(llvm::yaml::MappingNode *Params) {
|
||||
} else if (KeyValue == "text") {
|
||||
Result.text = Value->getValue(Storage);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<Metadata> Metadata::parse(llvm::yaml::MappingNode *Params) {
|
||||
llvm::Optional<Metadata> Metadata::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
Metadata Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -223,12 +236,15 @@ llvm::Optional<Metadata> Metadata::parse(llvm::yaml::MappingNode *Params) {
|
||||
return llvm::None;
|
||||
Result.extraFlags.push_back(Node->getValue(Storage));
|
||||
}
|
||||
} else {
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<TextEdit> TextEdit::parse(llvm::yaml::MappingNode *Params) {
|
||||
llvm::Optional<TextEdit> TextEdit::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
TextEdit Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -244,7 +260,7 @@ llvm::Optional<TextEdit> TextEdit::parse(llvm::yaml::MappingNode *Params) {
|
||||
auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
|
||||
if (!Map)
|
||||
return llvm::None;
|
||||
auto Parsed = Range::parse(Map);
|
||||
auto Parsed = Range::parse(Map, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.range = std::move(*Parsed);
|
||||
@ -254,7 +270,7 @@ llvm::Optional<TextEdit> TextEdit::parse(llvm::yaml::MappingNode *Params) {
|
||||
return llvm::None;
|
||||
Result.newText = Node->getValue(Storage);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
@ -269,7 +285,8 @@ std::string TextEdit::unparse(const TextEdit &P) {
|
||||
}
|
||||
|
||||
llvm::Optional<DidOpenTextDocumentParams>
|
||||
DidOpenTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
DidOpenTextDocumentParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
DidOpenTextDocumentParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -285,24 +302,25 @@ DidOpenTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
|
||||
llvm::SmallString<10> Storage;
|
||||
if (KeyValue == "textDocument") {
|
||||
auto Parsed = TextDocumentItem::parse(Value);
|
||||
auto Parsed = TextDocumentItem::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else if (KeyValue == "metadata") {
|
||||
auto Parsed = Metadata::parse(Value);
|
||||
auto Parsed = Metadata::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.metadata = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<DidCloseTextDocumentParams>
|
||||
DidCloseTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
DidCloseTextDocumentParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
DidCloseTextDocumentParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -317,19 +335,20 @@ DidCloseTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
|
||||
if (!Map)
|
||||
return llvm::None;
|
||||
auto Parsed = TextDocumentIdentifier::parse(Map);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Map, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<DidChangeTextDocumentParams>
|
||||
DidChangeTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
DidChangeTextDocumentParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
DidChangeTextDocumentParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -345,7 +364,7 @@ DidChangeTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
|
||||
if (!Map)
|
||||
return llvm::None;
|
||||
auto Parsed = TextDocumentIdentifier::parse(Map);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Map, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
@ -357,20 +376,21 @@ DidChangeTextDocumentParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
auto *I = dyn_cast<llvm::yaml::MappingNode>(&Item);
|
||||
if (!I)
|
||||
return llvm::None;
|
||||
auto Parsed = TextDocumentContentChangeEvent::parse(I);
|
||||
auto Parsed = TextDocumentContentChangeEvent::parse(I, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.contentChanges.push_back(std::move(*Parsed));
|
||||
}
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<TextDocumentContentChangeEvent>
|
||||
TextDocumentContentChangeEvent::parse(llvm::yaml::MappingNode *Params) {
|
||||
TextDocumentContentChangeEvent::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
TextDocumentContentChangeEvent Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -388,14 +408,14 @@ TextDocumentContentChangeEvent::parse(llvm::yaml::MappingNode *Params) {
|
||||
if (KeyValue == "text") {
|
||||
Result.text = Value->getValue(Storage);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<FormattingOptions>
|
||||
FormattingOptions::parse(llvm::yaml::MappingNode *Params) {
|
||||
FormattingOptions::parse(llvm::yaml::MappingNode *Params, JSONOutput &Output) {
|
||||
FormattingOptions Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -428,7 +448,7 @@ FormattingOptions::parse(llvm::yaml::MappingNode *Params) {
|
||||
}
|
||||
Result.insertSpaces = Val;
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
@ -442,7 +462,8 @@ std::string FormattingOptions::unparse(const FormattingOptions &P) {
|
||||
}
|
||||
|
||||
llvm::Optional<DocumentRangeFormattingParams>
|
||||
DocumentRangeFormattingParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
DocumentRangeFormattingParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
DocumentRangeFormattingParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -458,29 +479,30 @@ DocumentRangeFormattingParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
|
||||
llvm::SmallString<10> Storage;
|
||||
if (KeyValue == "textDocument") {
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else if (KeyValue == "range") {
|
||||
auto Parsed = Range::parse(Value);
|
||||
auto Parsed = Range::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.range = std::move(*Parsed);
|
||||
} else if (KeyValue == "options") {
|
||||
auto Parsed = FormattingOptions::parse(Value);
|
||||
auto Parsed = FormattingOptions::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.options = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<DocumentOnTypeFormattingParams>
|
||||
DocumentOnTypeFormattingParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
DocumentOnTypeFormattingParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
DocumentOnTypeFormattingParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -505,29 +527,30 @@ DocumentOnTypeFormattingParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
if (!Value)
|
||||
return llvm::None;
|
||||
if (KeyValue == "textDocument") {
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else if (KeyValue == "position") {
|
||||
auto Parsed = Position::parse(Value);
|
||||
auto Parsed = Position::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.position = std::move(*Parsed);
|
||||
} else if (KeyValue == "options") {
|
||||
auto Parsed = FormattingOptions::parse(Value);
|
||||
auto Parsed = FormattingOptions::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.options = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<DocumentFormattingParams>
|
||||
DocumentFormattingParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
DocumentFormattingParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
DocumentFormattingParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -543,23 +566,24 @@ DocumentFormattingParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
|
||||
llvm::SmallString<10> Storage;
|
||||
if (KeyValue == "textDocument") {
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else if (KeyValue == "options") {
|
||||
auto Parsed = FormattingOptions::parse(Value);
|
||||
auto Parsed = FormattingOptions::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.options = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<Diagnostic> Diagnostic::parse(llvm::yaml::MappingNode *Params) {
|
||||
llvm::Optional<Diagnostic> Diagnostic::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
Diagnostic Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -575,7 +599,7 @@ llvm::Optional<Diagnostic> Diagnostic::parse(llvm::yaml::MappingNode *Params) {
|
||||
dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
|
||||
if (!Value)
|
||||
return llvm::None;
|
||||
auto Parsed = Range::parse(Value);
|
||||
auto Parsed = Range::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.range = std::move(*Parsed);
|
||||
@ -588,6 +612,10 @@ llvm::Optional<Diagnostic> Diagnostic::parse(llvm::yaml::MappingNode *Params) {
|
||||
if (llvm::getAsSignedInteger(Value->getValue(Storage), 0, Val))
|
||||
return llvm::None;
|
||||
Result.severity = Val;
|
||||
} else if (KeyValue == "code") {
|
||||
// Not currently used
|
||||
} else if (KeyValue == "source") {
|
||||
// Not currently used
|
||||
} else if (KeyValue == "message") {
|
||||
auto *Value =
|
||||
dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
|
||||
@ -595,14 +623,14 @@ llvm::Optional<Diagnostic> Diagnostic::parse(llvm::yaml::MappingNode *Params) {
|
||||
return llvm::None;
|
||||
Result.message = Value->getValue(Storage);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<CodeActionContext>
|
||||
CodeActionContext::parse(llvm::yaml::MappingNode *Params) {
|
||||
CodeActionContext::parse(llvm::yaml::MappingNode *Params, JSONOutput &Output) {
|
||||
CodeActionContext Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -622,20 +650,20 @@ CodeActionContext::parse(llvm::yaml::MappingNode *Params) {
|
||||
auto *I = dyn_cast<llvm::yaml::MappingNode>(&Item);
|
||||
if (!I)
|
||||
return llvm::None;
|
||||
auto Parsed = Diagnostic::parse(I);
|
||||
auto Parsed = Diagnostic::parse(I, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.diagnostics.push_back(std::move(*Parsed));
|
||||
}
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<CodeActionParams>
|
||||
CodeActionParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
CodeActionParams::parse(llvm::yaml::MappingNode *Params, JSONOutput &Output) {
|
||||
CodeActionParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -651,29 +679,30 @@ CodeActionParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
|
||||
llvm::SmallString<10> Storage;
|
||||
if (KeyValue == "textDocument") {
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else if (KeyValue == "range") {
|
||||
auto Parsed = Range::parse(Value);
|
||||
auto Parsed = Range::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.range = std::move(*Parsed);
|
||||
} else if (KeyValue == "context") {
|
||||
auto Parsed = CodeActionContext::parse(Value);
|
||||
auto Parsed = CodeActionContext::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.context = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Optional<TextDocumentPositionParams>
|
||||
TextDocumentPositionParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
TextDocumentPositionParams::parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output) {
|
||||
TextDocumentPositionParams Result;
|
||||
for (auto &NextKeyValue : *Params) {
|
||||
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
|
||||
@ -689,17 +718,17 @@ TextDocumentPositionParams::parse(llvm::yaml::MappingNode *Params) {
|
||||
|
||||
llvm::SmallString<10> Storage;
|
||||
if (KeyValue == "textDocument") {
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value);
|
||||
auto Parsed = TextDocumentIdentifier::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.textDocument = std::move(*Parsed);
|
||||
} else if (KeyValue == "position") {
|
||||
auto Parsed = Position::parse(Value);
|
||||
auto Parsed = Position::parse(Value, Output);
|
||||
if (!Parsed)
|
||||
return llvm::None;
|
||||
Result.position = std::move(*Parsed);
|
||||
} else {
|
||||
return llvm::None;
|
||||
logIgnoredField(KeyValue, Output);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
|
@ -29,6 +29,8 @@
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
||||
class JSONOutput;
|
||||
|
||||
struct URI {
|
||||
std::string uri;
|
||||
std::string file;
|
||||
@ -57,7 +59,7 @@ struct TextDocumentIdentifier {
|
||||
URI uri;
|
||||
|
||||
static llvm::Optional<TextDocumentIdentifier>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct Position {
|
||||
@ -76,7 +78,8 @@ struct Position {
|
||||
std::tie(RHS.line, RHS.character);
|
||||
}
|
||||
|
||||
static llvm::Optional<Position> parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<Position> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
static std::string unparse(const Position &P);
|
||||
};
|
||||
|
||||
@ -94,7 +97,8 @@ struct Range {
|
||||
return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end);
|
||||
}
|
||||
|
||||
static llvm::Optional<Range> parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<Range> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
static std::string unparse(const Range &P);
|
||||
};
|
||||
|
||||
@ -121,7 +125,8 @@ struct Location {
|
||||
struct Metadata {
|
||||
std::vector<std::string> extraFlags;
|
||||
|
||||
static llvm::Optional<Metadata> parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<Metadata> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct TextEdit {
|
||||
@ -133,7 +138,8 @@ struct TextEdit {
|
||||
/// empty string.
|
||||
std::string newText;
|
||||
|
||||
static llvm::Optional<TextEdit> parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<TextEdit> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
static std::string unparse(const TextEdit &P);
|
||||
};
|
||||
|
||||
@ -150,8 +156,8 @@ struct TextDocumentItem {
|
||||
/// The content of the opened text document.
|
||||
std::string text;
|
||||
|
||||
static llvm::Optional<TextDocumentItem>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<TextDocumentItem> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct DidOpenTextDocumentParams {
|
||||
@ -162,7 +168,7 @@ struct DidOpenTextDocumentParams {
|
||||
llvm::Optional<Metadata> metadata;
|
||||
|
||||
static llvm::Optional<DidOpenTextDocumentParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct DidCloseTextDocumentParams {
|
||||
@ -170,7 +176,7 @@ struct DidCloseTextDocumentParams {
|
||||
TextDocumentIdentifier textDocument;
|
||||
|
||||
static llvm::Optional<DidCloseTextDocumentParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct TextDocumentContentChangeEvent {
|
||||
@ -178,7 +184,7 @@ struct TextDocumentContentChangeEvent {
|
||||
std::string text;
|
||||
|
||||
static llvm::Optional<TextDocumentContentChangeEvent>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct DidChangeTextDocumentParams {
|
||||
@ -191,7 +197,7 @@ struct DidChangeTextDocumentParams {
|
||||
std::vector<TextDocumentContentChangeEvent> contentChanges;
|
||||
|
||||
static llvm::Optional<DidChangeTextDocumentParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct FormattingOptions {
|
||||
@ -202,7 +208,7 @@ struct FormattingOptions {
|
||||
bool insertSpaces;
|
||||
|
||||
static llvm::Optional<FormattingOptions>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
static std::string unparse(const FormattingOptions &P);
|
||||
};
|
||||
|
||||
@ -217,7 +223,7 @@ struct DocumentRangeFormattingParams {
|
||||
FormattingOptions options;
|
||||
|
||||
static llvm::Optional<DocumentRangeFormattingParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct DocumentOnTypeFormattingParams {
|
||||
@ -234,7 +240,7 @@ struct DocumentOnTypeFormattingParams {
|
||||
FormattingOptions options;
|
||||
|
||||
static llvm::Optional<DocumentOnTypeFormattingParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct DocumentFormattingParams {
|
||||
@ -245,7 +251,7 @@ struct DocumentFormattingParams {
|
||||
FormattingOptions options;
|
||||
|
||||
static llvm::Optional<DocumentFormattingParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct Diagnostic {
|
||||
@ -256,6 +262,15 @@ struct Diagnostic {
|
||||
/// client to interpret diagnostics as error, warning, info or hint.
|
||||
int severity;
|
||||
|
||||
/// The diagnostic's code. Can be omitted.
|
||||
/// Note: Not currently used by clangd
|
||||
// std::string code;
|
||||
|
||||
/// A human-readable string describing the source of this
|
||||
/// diagnostic, e.g. 'typescript' or 'super lint'.
|
||||
/// Note: Not currently used by clangd
|
||||
// std::string source;
|
||||
|
||||
/// The diagnostic's message.
|
||||
std::string message;
|
||||
|
||||
@ -268,7 +283,8 @@ struct Diagnostic {
|
||||
std::tie(RHS.range, RHS.severity, RHS.message);
|
||||
}
|
||||
|
||||
static llvm::Optional<Diagnostic> parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<Diagnostic> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct CodeActionContext {
|
||||
@ -276,7 +292,7 @@ struct CodeActionContext {
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
|
||||
static llvm::Optional<CodeActionContext>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct CodeActionParams {
|
||||
@ -289,8 +305,8 @@ struct CodeActionParams {
|
||||
/// Context carrying additional information.
|
||||
CodeActionContext context;
|
||||
|
||||
static llvm::Optional<CodeActionParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
static llvm::Optional<CodeActionParams> parse(llvm::yaml::MappingNode *Params,
|
||||
JSONOutput &Output);
|
||||
};
|
||||
|
||||
struct TextDocumentPositionParams {
|
||||
@ -301,7 +317,7 @@ struct TextDocumentPositionParams {
|
||||
Position position;
|
||||
|
||||
static llvm::Optional<TextDocumentPositionParams>
|
||||
parse(llvm::yaml::MappingNode *Params);
|
||||
parse(llvm::yaml::MappingNode *Params, JSONOutput &Output);
|
||||
};
|
||||
|
||||
/// The kind of a completion entry.
|
||||
|
@ -45,7 +45,7 @@ struct TextDocumentDidOpenHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleNotification(llvm::yaml::MappingNode *Params) override {
|
||||
auto DOTDP = DidOpenTextDocumentParams::parse(Params);
|
||||
auto DOTDP = DidOpenTextDocumentParams::parse(Params, Output);
|
||||
if (!DOTDP) {
|
||||
Output.log("Failed to decode DidOpenTextDocumentParams!\n");
|
||||
return;
|
||||
@ -62,7 +62,7 @@ struct TextDocumentDidChangeHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleNotification(llvm::yaml::MappingNode *Params) override {
|
||||
auto DCTDP = DidChangeTextDocumentParams::parse(Params);
|
||||
auto DCTDP = DidChangeTextDocumentParams::parse(Params, Output);
|
||||
if (!DCTDP || DCTDP->contentChanges.size() != 1) {
|
||||
Output.log("Failed to decode DidChangeTextDocumentParams!\n");
|
||||
return;
|
||||
@ -80,7 +80,7 @@ struct TextDocumentDidCloseHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleNotification(llvm::yaml::MappingNode *Params) override {
|
||||
auto DCTDP = DidCloseTextDocumentParams::parse(Params);
|
||||
auto DCTDP = DidCloseTextDocumentParams::parse(Params, Output);
|
||||
if (!DCTDP) {
|
||||
Output.log("Failed to decode DidCloseTextDocumentParams!\n");
|
||||
return;
|
||||
@ -99,7 +99,7 @@ struct TextDocumentOnTypeFormattingHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
|
||||
auto DOTFP = DocumentOnTypeFormattingParams::parse(Params);
|
||||
auto DOTFP = DocumentOnTypeFormattingParams::parse(Params, Output);
|
||||
if (!DOTFP) {
|
||||
Output.log("Failed to decode DocumentOnTypeFormattingParams!\n");
|
||||
return;
|
||||
@ -118,7 +118,7 @@ struct TextDocumentRangeFormattingHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
|
||||
auto DRFP = DocumentRangeFormattingParams::parse(Params);
|
||||
auto DRFP = DocumentRangeFormattingParams::parse(Params, Output);
|
||||
if (!DRFP) {
|
||||
Output.log("Failed to decode DocumentRangeFormattingParams!\n");
|
||||
return;
|
||||
@ -137,7 +137,7 @@ struct TextDocumentFormattingHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
|
||||
auto DFP = DocumentFormattingParams::parse(Params);
|
||||
auto DFP = DocumentFormattingParams::parse(Params, Output);
|
||||
if (!DFP) {
|
||||
Output.log("Failed to decode DocumentFormattingParams!\n");
|
||||
return;
|
||||
@ -155,7 +155,7 @@ struct CodeActionHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
|
||||
auto CAP = CodeActionParams::parse(Params);
|
||||
auto CAP = CodeActionParams::parse(Params, Output);
|
||||
if (!CAP) {
|
||||
Output.log("Failed to decode CodeActionParams!\n");
|
||||
return;
|
||||
@ -173,7 +173,7 @@ struct CompletionHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
|
||||
auto TDPP = TextDocumentPositionParams::parse(Params);
|
||||
auto TDPP = TextDocumentPositionParams::parse(Params, Output);
|
||||
if (!TDPP) {
|
||||
Output.log("Failed to decode TextDocumentPositionParams!\n");
|
||||
return;
|
||||
@ -191,7 +191,7 @@ struct GotoDefinitionHandler : Handler {
|
||||
: Handler(Output), Callbacks(Callbacks) {}
|
||||
|
||||
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
|
||||
auto TDPP = TextDocumentPositionParams::parse(Params);
|
||||
auto TDPP = TextDocumentPositionParams::parse(Params, Output);
|
||||
if (!TDPP) {
|
||||
Output.log("Failed to decode TextDocumentPositionParams!\n");
|
||||
return;
|
||||
|
@ -17,6 +17,12 @@ Content-Length: 746
|
||||
#
|
||||
# CHECK: {"jsonrpc":"2.0","id":2, "result": [{"title":"Apply FixIt 'place parentheses around the assignment to silence this warning'", "command": "clangd.applyFix", "arguments": ["file:///foo.c", [{"range": {"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 32}}, "newText": "("},{"range": {"start": {"line": 0, "character": 37}, "end": {"line": 0, "character": 37}}, "newText": ")"}]]},{"title":"Apply FixIt 'use '==' to turn this assignment into an equality comparison'", "command": "clangd.applyFix", "arguments": ["file:///foo.c", [{"range": {"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}}, "newText": "=="}]]}]
|
||||
#
|
||||
Content-Length: 771
|
||||
|
||||
{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 35}, "end": {"line": 0, "character": 35}},"severity":2,"code":"1","source":"foo","message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 35}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 35}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}}
|
||||
# Make sure unused "code" and "source" fields ignored gracefully
|
||||
# CHECK: {"jsonrpc":"2.0","id":2, "result": [{"title":"Apply FixIt 'place parentheses around the assignment to silence this warning'", "command": "clangd.applyFix", "arguments": ["file:///foo.c", [{"range": {"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 32}}, "newText": "("},{"range": {"start": {"line": 0, "character": 37}, "end": {"line": 0, "character": 37}}, "newText": ")"}]]},{"title":"Apply FixIt 'use '==' to turn this assignment into an equality comparison'", "command": "clangd.applyFix", "arguments": ["file:///foo.c", [{"range": {"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}}, "newText": "=="}]]}]
|
||||
#
|
||||
Content-Length: 44
|
||||
|
||||
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
|
||||
|
Loading…
Reference in New Issue
Block a user