[clang-tools-extra] r319159 - [clangd] Switch from YAMLParser to JSONExpr
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 28 01:37:43 PST 2017
Author: sammccall
Date: Tue Nov 28 01:37:43 2017
New Revision: 319159
URL: http://llvm.org/viewvc/llvm-project?rev=319159&view=rev
Log:
[clangd] Switch from YAMLParser to JSONExpr
Summary:
- Converted Protocol.h parse() functions to take JSON::Expr.
These no longer detect and log unknown fields, as this is not that
useful and no longer free.
I haven't changed the error handling too much: fields that were
treated as optional before are still optional, even when it's wrong.
Exception: object properties with the wrong type are now ignored.
- Made JSONRPCDispatcher parse using json::parse
- The bug where 'method' must come before 'params' in the stream is
fixed as a side-effect. (And the same bug in executeCommand).
- Some parser crashers fixed as a side effect.
e.g. https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3890
- The debug stream now prettyprints the input messages with --pretty.
- Request params are attached to traces when tracing is enabled.
- Fixed some bugs in tests (errors tolerated by YAMLParser, and
off-by-ones in Content-Length that our null-termination was masking)
- Fixed a random double-escape bug in ClangdLSPServer (it was our last
use of YAMLParser!)
Reviewers: ilya-biryukov
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D40406
Removed:
clang-tools-extra/trunk/test/clangd/did-change-watch-files.test
Modified:
clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
clang-tools-extra/trunk/clangd/JSONExpr.h
clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
clang-tools-extra/trunk/clangd/Protocol.cpp
clang-tools-extra/trunk/clangd/Protocol.h
clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
clang-tools-extra/trunk/clangd/Trace.cpp
clang-tools-extra/trunk/test/clangd/authority-less-uri.test
clang-tools-extra/trunk/test/clangd/definitions.test
clang-tools-extra/trunk/test/clangd/diagnostics.test
clang-tools-extra/trunk/test/clangd/protocol.test
clang-tools-extra/trunk/unittests/clangd/JSONExprTests.cpp
Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Nov 28 01:37:43 2017
@@ -139,7 +139,7 @@ void ClangdLSPServer::onRename(Ctx C, Re
std::string Code = Server.getDocument(File);
std::vector<TextEdit> Edits = replacementsToEdits(Code, *Replacements);
WorkspaceEdit WE;
- WE.changes = {{llvm::yaml::escape(Params.textDocument.uri.uri), Edits}};
+ WE.changes = {{Params.textDocument.uri.uri, Edits}};
C.reply(WorkspaceEdit::unparse(WE));
}
@@ -249,7 +249,7 @@ bool ClangdLSPServer::run(std::istream &
// Set up JSONRPCDispatcher.
JSONRPCDispatcher Dispatcher(
- [](RequestContext Ctx, llvm::yaml::MappingNode *Params) {
+ [](RequestContext Ctx, const json::Expr &Params) {
Ctx.replyError(ErrorCode::MethodNotFound, "method not found");
});
registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this);
Modified: clang-tools-extra/trunk/clangd/JSONExpr.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONExpr.h?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONExpr.h (original)
+++ clang-tools-extra/trunk/clangd/JSONExpr.h Tue Nov 28 01:37:43 2017
@@ -181,6 +181,16 @@ public:
return as<double>();
return llvm::None;
}
+ llvm::Optional<int64_t> asInteger() const {
+ if (LLVM_LIKELY(Type == T_Number)) {
+ double D = as<double>();
+ if (LLVM_LIKELY(std::modf(D, &D) == 0 &&
+ D >= std::numeric_limits<int64_t>::min() &&
+ D <= std::numeric_limits<int64_t>::max()))
+ return D;
+ }
+ return llvm::None;
+ }
llvm::Optional<llvm::StringRef> asString() const {
if (Type == T_String)
return llvm::StringRef(as<std::string>());
@@ -324,6 +334,11 @@ public:
return V->asNumber();
return llvm::None;
}
+ llvm::Optional<int64_t> getInteger(const ObjectKey &K) const {
+ if (auto *V = get(K))
+ return V->asInteger();
+ return llvm::None;
+ }
llvm::Optional<llvm::StringRef> getString(const ObjectKey &K) const {
if (auto *V = get(K))
return V->asString();
@@ -374,6 +389,9 @@ public:
llvm::Optional<double> getNumber(size_t I) const {
return (*this)[I].asNumber();
}
+ llvm::Optional<int64_t> getInteger(size_t I) const {
+ return (*this)[I].asInteger();
+ }
llvm::Optional<llvm::StringRef> getString(size_t I) const {
return (*this)[I].asString();
}
Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp Tue Nov 28 01:37:43 2017
@@ -14,7 +14,6 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/YAMLParser.h"
#include <istream>
using namespace clang;
@@ -101,88 +100,29 @@ void JSONRPCDispatcher::registerHandler(
Handlers[Method] = std::move(H);
}
-static void
-callHandler(const llvm::StringMap<JSONRPCDispatcher::Handler> &Handlers,
- llvm::yaml::ScalarNode *Method, llvm::Optional<json::Expr> ID,
- llvm::yaml::MappingNode *Params,
- const JSONRPCDispatcher::Handler &UnknownHandler, JSONOutput &Out) {
- llvm::SmallString<64> MethodStorage;
- llvm::StringRef MethodStr = Method->getValue(MethodStorage);
- auto I = Handlers.find(MethodStr);
- auto &Handler = I != Handlers.end() ? I->second : UnknownHandler;
- Handler(RequestContext(Out, MethodStr, std::move(ID)), Params);
-}
-
-bool JSONRPCDispatcher::call(StringRef Content, JSONOutput &Out) const {
- llvm::SourceMgr SM;
- llvm::yaml::Stream YAMLStream(Content, SM);
-
- auto Doc = YAMLStream.begin();
- if (Doc == YAMLStream.end())
+bool JSONRPCDispatcher::call(const json::Expr &Message, JSONOutput &Out) const {
+ // Message must be an object with "jsonrpc":"2.0".
+ auto *Object = Message.asObject();
+ if (!Object || Object->getString("jsonrpc") != Optional<StringRef>("2.0"))
return false;
-
- auto *Object = dyn_cast_or_null<llvm::yaml::MappingNode>(Doc->getRoot());
- if (!Object)
- return false;
-
- llvm::yaml::ScalarNode *Version = nullptr;
- llvm::yaml::ScalarNode *Method = nullptr;
- llvm::yaml::MappingNode *Params = nullptr;
+ // ID may be any JSON value. If absent, this is a notification.
llvm::Optional<json::Expr> ID;
- for (auto &NextKeyValue : *Object) {
- auto *KeyString =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return false;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- llvm::yaml::Node *Value = NextKeyValue.getValue();
- if (!Value)
- return false;
-
- if (KeyValue == "jsonrpc") {
- // This should be "2.0". Always.
- Version = dyn_cast<llvm::yaml::ScalarNode>(Value);
- if (!Version || Version->getRawValue() != "\"2.0\"")
- return false;
- } else if (KeyValue == "method") {
- Method = dyn_cast<llvm::yaml::ScalarNode>(Value);
- } else if (KeyValue == "id") {
- // ID may be either a string or a number.
- if (auto *IdNode = dyn_cast<llvm::yaml::ScalarNode>(Value)) {
- llvm::SmallString<32> S;
- llvm::StringRef V = IdNode->getValue(S);
- if (IdNode->getRawValue().startswith("\"")) {
- ID.emplace(V.str());
- } else {
- double D;
- // FIXME: this is locale-sensitive.
- if (llvm::to_float(V, D))
- ID.emplace(D);
- }
- }
- } else if (KeyValue == "params") {
- if (!Method)
- return false;
- // We have to interleave the call of the function here, otherwise the
- // YAMLParser will die because it can't go backwards. This is unfortunate
- // because it will break clients that put the id after params. A possible
- // fix would be to split the parsing and execution phases.
- Params = dyn_cast<llvm::yaml::MappingNode>(Value);
- callHandler(Handlers, Method, std::move(ID), Params, UnknownHandler, Out);
- return true;
- } else {
- return false;
- }
- }
-
- // In case there was a request with no params, call the handler on the
- // leftovers.
+ if (auto *I = Object->get("id"))
+ ID = std::move(*I);
+ // Method must be given.
+ auto Method = Object->getString("method");
if (!Method)
return false;
- callHandler(Handlers, Method, std::move(ID), nullptr, UnknownHandler, Out);
+ // Params should be given, use null if not.
+ json::Expr Params = nullptr;
+ if (auto *P = Object->get("params"))
+ Params = std::move(*P);
+ auto I = Handlers.find(*Method);
+ auto &Handler = I != Handlers.end() ? I->second : UnknownHandler;
+ RequestContext Ctx(Out, *Method, std::move(ID));
+ SPAN_ATTACH(Ctx.tracer(), "Params", Params);
+ Handler(std::move(Ctx), std::move(Params));
return true;
}
@@ -211,7 +151,7 @@ void clangd::runLanguageServerLoop(std::
llvm::StringRef LineRef(Line);
- // We allow YAML-style comments in headers. Technically this isn't part
+ // We allow comments in headers. Technically this isn't part
// of the LSP specification, but makes writing tests easier.
if (LineRef.startswith("#"))
continue;
@@ -251,11 +191,9 @@ void clangd::runLanguageServerLoop(std::
}
if (ContentLength > 0) {
- std::vector<char> JSON(ContentLength + 1, '\0');
+ std::vector<char> JSON(ContentLength);
llvm::StringRef JSONRef;
{
- // Now read the JSON. Insert a trailing null byte as required by the
- // YAML parser.
In.read(JSON.data(), ContentLength);
Out.mirrorInput(StringRef(JSON.data(), In.gcount()));
@@ -271,12 +209,18 @@ void clangd::runLanguageServerLoop(std::
JSONRef = StringRef(JSON.data(), ContentLength);
}
- // Log the message.
- Out.log("<-- " + JSONRef + "\n");
-
- // Finally, execute the action for this JSON message.
- if (!Dispatcher.call(JSONRef, Out))
- Out.log("JSON dispatch failed!\n");
+ if (auto Doc = json::parse(JSONRef)) {
+ // Log the formatted message.
+ Out.log(llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));
+ // Finally, execute the action for this JSON message.
+ if (!Dispatcher.call(*Doc, Out))
+ Out.log("JSON dispatch failed!\n");
+ } else {
+ // Parse error. Log the raw message.
+ Out.log("<-- " + JSONRef + "\n");
+ Out.log(llvm::Twine("JSON parse error: ") +
+ llvm::toString(Doc.takeError()) + "\n");
+ }
// If we're done, exit the loop.
if (IsDone)
Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h Tue Nov 28 01:37:43 2017
@@ -17,7 +17,6 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/YAMLParser.h"
#include <iosfwd>
#include <mutex>
@@ -30,7 +29,7 @@ class JSONOutput : public Logger {
public:
JSONOutput(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs,
llvm::raw_ostream *InputMirror = nullptr, bool Pretty = false)
- : Outs(Outs), Logs(Logs), InputMirror(InputMirror), Pretty(Pretty) {}
+ : Pretty(Pretty), Outs(Outs), Logs(Logs), InputMirror(InputMirror) {}
/// Emit a JSONRPC message.
void writeMessage(const json::Expr &Result);
@@ -44,11 +43,13 @@ public:
/// Unlike other methods of JSONOutput, mirrorInput is not thread-safe.
void mirrorInput(const Twine &Message);
+ // Whether output should be pretty-printed.
+ const bool Pretty;
+
private:
llvm::raw_ostream &Outs;
llvm::raw_ostream &Logs;
llvm::raw_ostream *InputMirror;
- bool Pretty;
std::mutex StreamMutex;
};
@@ -84,8 +85,7 @@ private:
class JSONRPCDispatcher {
public:
// A handler responds to requests for a particular method name.
- using Handler =
- std::function<void(RequestContext, llvm::yaml::MappingNode *)>;
+ using Handler = std::function<void(RequestContext, const json::Expr &)>;
/// Create a new JSONRPCDispatcher. UnknownHandler is called when an unknown
/// method is received.
@@ -96,7 +96,7 @@ public:
void registerHandler(StringRef Method, Handler H);
/// Parses a JSONRPC message and calls the Handler for it.
- bool call(StringRef Content, JSONOutput &Out) const;
+ bool call(const json::Expr &Message, JSONOutput &Out) const;
private:
llvm::StringMap<Handler> Handlers;
Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Tue Nov 28 01:37:43 2017
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "Protocol.h"
-#include "Logger.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallString.h"
@@ -25,12 +24,6 @@
using namespace clang;
using namespace clang::clangd;
-namespace {
-void logIgnoredField(llvm::StringRef KeyValue, clangd::Logger &Logger) {
- Logger.log(llvm::formatv("Ignored unknown field \"{0}\"\n", KeyValue));
-}
-} // namespace
-
URI URI::fromUri(llvm::StringRef uri) {
URI Result;
Result.uri = uri;
@@ -58,70 +51,31 @@ URI URI::fromFile(llvm::StringRef file)
return Result;
}
-URI URI::parse(llvm::yaml::ScalarNode *Param) {
- llvm::SmallString<10> Storage;
- return URI::fromUri(Param->getValue(Storage));
-}
-
json::Expr URI::unparse(const URI &U) { return U.uri; }
llvm::Optional<TextDocumentIdentifier>
-TextDocumentIdentifier::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+TextDocumentIdentifier::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
TextDocumentIdentifier Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- if (KeyValue == "uri") {
- Result.uri = URI::parse(Value);
- } else if (KeyValue == "version") {
- // FIXME: parse version, but only for VersionedTextDocumentIdentifiers.
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
+ if (auto U = O->getString("uri"))
+ Result.uri = URI::parse(*U);
+ // FIXME: parse 'version', but only for VersionedTextDocumentIdentifiers.
return Result;
}
-llvm::Optional<Position> Position::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+llvm::Optional<Position> Position::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
Position Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "line") {
- long long Val;
- if (llvm::getAsSignedInteger(Value->getValue(Storage), 0, Val))
- return llvm::None;
- Result.line = Val;
- } else if (KeyValue == "character") {
- long long Val;
- if (llvm::getAsSignedInteger(Value->getValue(Storage), 0, Val))
- return llvm::None;
- Result.character = Val;
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
+ if (auto L = O->getInteger("line"))
+ Result.line = *L;
+ if (auto C = O->getInteger("character"))
+ Result.character = *C;
return Result;
}
@@ -132,35 +86,23 @@ json::Expr Position::unparse(const Posit
};
}
-llvm::Optional<Range> Range::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+llvm::Optional<Range> Range::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
Range Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "start") {
- auto Parsed = Position::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
- Result.start = std::move(*Parsed);
- } else if (KeyValue == "end") {
- auto Parsed = Position::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
- Result.end = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ if (auto *S = O->get("start")) {
+ if (auto P = Position::parse(*S))
+ Result.start = std::move(*P);
+ else
+ return None;
+ }
+ if (auto *E = O->get("end")) {
+ if (auto P = Position::parse(*E))
+ Result.end = std::move(*P);
+ else
+ return None;
}
return Result;
}
@@ -180,100 +122,53 @@ json::Expr Location::unparse(const Locat
}
llvm::Optional<TextDocumentItem>
-TextDocumentItem::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+TextDocumentItem::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
TextDocumentItem Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "uri") {
- Result.uri = URI::parse(Value);
- } else if (KeyValue == "languageId") {
- Result.languageId = Value->getValue(Storage);
- } else if (KeyValue == "version") {
- long long Val;
- if (llvm::getAsSignedInteger(Value->getValue(Storage), 0, Val))
- return llvm::None;
- Result.version = Val;
- } else if (KeyValue == "text") {
- Result.text = Value->getValue(Storage);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
+ if (auto U = O->getString("uri"))
+ Result.uri = URI::parse(*U);
+ if (auto L = O->getString("languageId"))
+ Result.languageId = *L;
+ if (auto V = O->getInteger("version"))
+ Result.version = *V;
+ if (auto T = O->getString("text"))
+ Result.text = *T;
return Result;
}
-llvm::Optional<Metadata> Metadata::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- Metadata Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+llvm::Optional<Metadata> Metadata::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value = NextKeyValue.getValue();
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "extraFlags") {
- auto *Seq = dyn_cast<llvm::yaml::SequenceNode>(Value);
- if (!Seq)
+ Metadata Result;
+ if (auto *Flags = O->getArray("extraFlags"))
+ for (auto &F : *Flags) {
+ if (auto S = F.asString())
+ Result.extraFlags.push_back(*S);
+ else
return llvm::None;
- for (auto &Item : *Seq) {
- auto *Node = dyn_cast<llvm::yaml::ScalarNode>(&Item);
- if (!Node)
- return llvm::None;
- Result.extraFlags.push_back(Node->getValue(Storage));
- }
- } else {
- logIgnoredField(KeyValue, Logger);
}
- }
return Result;
}
-llvm::Optional<TextEdit> TextEdit::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- TextEdit Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+llvm::Optional<TextEdit> TextEdit::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value = NextKeyValue.getValue();
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "range") {
- auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
- if (!Map)
- return llvm::None;
- auto Parsed = Range::parse(Map, Logger);
- if (!Parsed)
- return llvm::None;
+ TextEdit Result;
+ if (auto *R = O->get("range")) {
+ if (auto Parsed = Range::parse(*R))
Result.range = std::move(*Parsed);
- } else if (KeyValue == "newText") {
- auto *Node = dyn_cast<llvm::yaml::ScalarNode>(Value);
- if (!Node)
- return llvm::None;
- Result.newText = Node->getValue(Storage);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
+ if (auto T = O->getString("newText"))
+ Result.newText = *T;
return Result;
}
@@ -285,313 +180,154 @@ json::Expr TextEdit::unparse(const TextE
}
namespace {
-TraceLevel getTraceLevel(llvm::StringRef TraceLevelStr,
- clangd::Logger &Logger) {
+TraceLevel getTraceLevel(llvm::StringRef TraceLevelStr) {
if (TraceLevelStr == "off")
return TraceLevel::Off;
else if (TraceLevelStr == "messages")
return TraceLevel::Messages;
else if (TraceLevelStr == "verbose")
return TraceLevel::Verbose;
-
- Logger.log(llvm::formatv("Unknown trace level \"{0}\"\n", TraceLevelStr));
return TraceLevel::Off;
}
} // namespace
llvm::Optional<InitializeParams>
-InitializeParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- // If we don't understand the params, proceed with default parameters.
- auto ParseFailure = [&] {
- Logger.log("Failed to decode InitializeParams\n");
- return InitializeParams();
- };
+InitializeParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
InitializeParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return ParseFailure();
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- continue;
-
- if (KeyValue == "processId") {
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return ParseFailure();
- long long Val;
- if (llvm::getAsSignedInteger(Value->getValue(KeyStorage), 0, Val))
- return ParseFailure();
- Result.processId = Val;
- } else if (KeyValue == "rootPath") {
- Result.rootPath = Value->getValue(KeyStorage);
- } else if (KeyValue == "rootUri") {
- Result.rootUri = URI::parse(Value);
- } else if (KeyValue == "initializationOptions") {
- // Not used
- } else if (KeyValue == "capabilities") {
- // Not used
- } else if (KeyValue == "trace") {
- Result.trace = getTraceLevel(Value->getValue(KeyStorage), Logger);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
+ if (auto P = O->getInteger("processId"))
+ Result.processId = *P;
+ if (auto R = O->getString("rootPath"))
+ Result.rootPath = *R;
+ if (auto R = O->getString("rootUri"))
+ Result.rootUri = URI::parse(*R);
+ if (auto T = O->getString("trace"))
+ Result.trace = getTraceLevel(*T);
+ // initializationOptions, capabilities unused
return Result;
}
llvm::Optional<DidOpenTextDocumentParams>
-DidOpenTextDocumentParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+DidOpenTextDocumentParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
DidOpenTextDocumentParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "textDocument") {
- auto Parsed = TextDocumentItem::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentItem::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "metadata") {
- auto Parsed = Metadata::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *M = O->get("metadata")) {
+ if (auto Parsed = Metadata::parse(*M))
Result.metadata = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
llvm::Optional<DidCloseTextDocumentParams>
-DidCloseTextDocumentParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- DidCloseTextDocumentParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+DidCloseTextDocumentParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value = NextKeyValue.getValue();
-
- if (KeyValue == "textDocument") {
- auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
- if (!Map)
- return llvm::None;
- auto Parsed = TextDocumentIdentifier::parse(Map, Logger);
- if (!Parsed)
- return llvm::None;
+ DidCloseTextDocumentParams Result;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
llvm::Optional<DidChangeTextDocumentParams>
-DidChangeTextDocumentParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- DidChangeTextDocumentParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+DidChangeTextDocumentParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value = NextKeyValue.getValue();
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "textDocument") {
- auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
- if (!Map)
- return llvm::None;
- auto Parsed = TextDocumentIdentifier::parse(Map, Logger);
- if (!Parsed)
- return llvm::None;
+ DidChangeTextDocumentParams Result;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "contentChanges") {
- auto *Seq = dyn_cast<llvm::yaml::SequenceNode>(Value);
- if (!Seq)
- return llvm::None;
- for (auto &Item : *Seq) {
- auto *I = dyn_cast<llvm::yaml::MappingNode>(&Item);
- if (!I)
- return llvm::None;
- auto Parsed = TextDocumentContentChangeEvent::parse(I, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *A = O->getArray("contentChanges"))
+ for (auto &E : *A) {
+ if (auto Parsed = TextDocumentContentChangeEvent::parse(E))
Result.contentChanges.push_back(std::move(*Parsed));
- }
- } else {
- logIgnoredField(KeyValue, Logger);
+ else
+ return llvm::None;
}
- }
return Result;
}
-llvm::Optional<FileEvent> FileEvent::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- llvm::Optional<FileEvent> Result = FileEvent();
- for (auto &NextKeyValue : *Params) {
- // We have to consume the whole MappingNode because it doesn't support
- // skipping and we want to be able to parse further valid events.
- if (!Result)
- continue;
-
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString) {
- Result.reset();
- continue;
- }
+llvm::Optional<FileEvent> FileEvent::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value) {
- Result.reset();
- continue;
- }
- llvm::SmallString<10> Storage;
- if (KeyValue == "uri") {
- Result->uri = URI::parse(Value);
- } else if (KeyValue == "type") {
- long long Val;
- if (llvm::getAsSignedInteger(Value->getValue(Storage), 0, Val)) {
- Result.reset();
- continue;
- }
- Result->type = static_cast<FileChangeType>(Val);
- if (Result->type < FileChangeType::Created ||
- Result->type > FileChangeType::Deleted)
- Result.reset();
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ FileEvent Result;
+ if (auto U = O->getString("uri"))
+ Result.uri = URI::parse(*U);
+ if (auto T = O->getInteger("type")) {
+ if (*T < static_cast<int>(FileChangeType::Created) ||
+ *T > static_cast<int>(FileChangeType::Deleted))
+ return llvm::None;
+ Result.type = static_cast<FileChangeType>(*T);
}
return Result;
}
llvm::Optional<DidChangeWatchedFilesParams>
-DidChangeWatchedFilesParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- DidChangeWatchedFilesParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+DidChangeWatchedFilesParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value = NextKeyValue.getValue();
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "changes") {
- auto *Seq = dyn_cast<llvm::yaml::SequenceNode>(Value);
- if (!Seq)
+ DidChangeWatchedFilesParams Result;
+ if (auto *C = O->getArray("changes"))
+ for (auto &E : *C) {
+ if (auto Parsed = FileEvent::parse(E))
+ Result.changes.push_back(std::move(*Parsed));
+ else
return llvm::None;
- for (auto &Item : *Seq) {
- auto *I = dyn_cast<llvm::yaml::MappingNode>(&Item);
- if (!I)
- return llvm::None;
- auto Parsed = FileEvent::parse(I, Logger);
- if (Parsed)
- Result.changes.push_back(std::move(*Parsed));
- else
- Logger.log("Failed to decode a FileEvent.\n");
- }
- } else {
- logIgnoredField(KeyValue, Logger);
}
- }
return Result;
}
llvm::Optional<TextDocumentContentChangeEvent>
-TextDocumentContentChangeEvent::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+TextDocumentContentChangeEvent::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
TextDocumentContentChangeEvent Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "text") {
- Result.text = Value->getValue(Storage);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
+ if (auto T = O->getString("text"))
+ Result.text = *T;
return Result;
}
llvm::Optional<FormattingOptions>
-FormattingOptions::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+FormattingOptions::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
FormattingOptions Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "tabSize") {
- long long Val;
- if (llvm::getAsSignedInteger(Value->getValue(Storage), 0, Val))
- return llvm::None;
- Result.tabSize = Val;
- } else if (KeyValue == "insertSpaces") {
- long long Val;
- StringRef Str = Value->getValue(Storage);
- if (llvm::getAsSignedInteger(Str, 0, Val)) {
- if (Str == "true")
- Val = 1;
- else if (Str == "false")
- Val = 0;
- else
- return llvm::None;
- }
- Result.insertSpaces = Val;
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
+ if (auto T = O->getInteger("tabSize"))
+ Result.tabSize = *T;
+ if (auto I = O->getBoolean("insertSpaces"))
+ Result.insertSpaces = *I;
return Result;
}
@@ -603,305 +339,182 @@ json::Expr FormattingOptions::unparse(co
}
llvm::Optional<DocumentRangeFormattingParams>
-DocumentRangeFormattingParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+DocumentRangeFormattingParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
DocumentRangeFormattingParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "textDocument") {
- auto Parsed = TextDocumentIdentifier::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "range") {
- auto Parsed = Range::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *R = O->get("range")) {
+ if (auto Parsed = Range::parse(*R))
Result.range = std::move(*Parsed);
- } else if (KeyValue == "options") {
- auto Parsed = FormattingOptions::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *F = O->get("options")) {
+ if (auto Parsed = FormattingOptions::parse(*F))
Result.options = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
llvm::Optional<DocumentOnTypeFormattingParams>
-DocumentOnTypeFormattingParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- DocumentOnTypeFormattingParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+DocumentOnTypeFormattingParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
-
- if (KeyValue == "ch") {
- auto *ScalarValue =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!ScalarValue)
- return llvm::None;
- llvm::SmallString<10> Storage;
- Result.ch = ScalarValue->getValue(Storage);
- continue;
- }
-
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
- if (KeyValue == "textDocument") {
- auto Parsed = TextDocumentIdentifier::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ DocumentOnTypeFormattingParams Result;
+ if (auto Ch = O->getString("ch"))
+ Result.ch = *Ch;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "position") {
- auto Parsed = Position::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *P = O->get("position")) {
+ if (auto Parsed = Position::parse(*P))
Result.position = std::move(*Parsed);
- } else if (KeyValue == "options") {
- auto Parsed = FormattingOptions::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *F = O->get("options")) {
+ if (auto Parsed = FormattingOptions::parse(*F))
Result.options = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
llvm::Optional<DocumentFormattingParams>
-DocumentFormattingParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+DocumentFormattingParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
DocumentFormattingParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "textDocument") {
- auto Parsed = TextDocumentIdentifier::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "options") {
- auto Parsed = FormattingOptions::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *F = O->get("options")) {
+ if (auto Parsed = FormattingOptions::parse(*F))
Result.options = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
-llvm::Optional<Diagnostic> Diagnostic::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- Diagnostic Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+llvm::Optional<Diagnostic> Diagnostic::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "range") {
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
- auto Parsed = Range::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ Diagnostic Result;
+ if (auto *R = O->get("range")) {
+ if (auto Parsed = Range::parse(*R))
Result.range = std::move(*Parsed);
- } else if (KeyValue == "severity") {
- auto *Value =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
- long long Val;
- 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());
- if (!Value)
- return llvm::None;
- Result.message = Value->getValue(Storage);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
+ if (auto S = O->getInteger("severity"))
+ Result.severity = *S;
+ if (auto M = O->getString("message"))
+ Result.message = *M;
return Result;
}
llvm::Optional<CodeActionContext>
-CodeActionContext::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- CodeActionContext Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+CodeActionContext::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value = NextKeyValue.getValue();
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "diagnostics") {
- auto *Seq = dyn_cast<llvm::yaml::SequenceNode>(Value);
- if (!Seq)
- return llvm::None;
- for (auto &Item : *Seq) {
- auto *I = dyn_cast<llvm::yaml::MappingNode>(&Item);
- if (!I)
- return llvm::None;
- auto Parsed = Diagnostic::parse(I, Logger);
- if (!Parsed)
- return llvm::None;
+ CodeActionContext Result;
+ if (auto *D = O->getArray("diagnostics"))
+ for (auto &E : *D) {
+ if (auto Parsed = Diagnostic::parse(E))
Result.diagnostics.push_back(std::move(*Parsed));
- }
- } else {
- logIgnoredField(KeyValue, Logger);
+ else
+ return llvm::None;
}
- }
return Result;
}
llvm::Optional<CodeActionParams>
-CodeActionParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+CodeActionParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
CodeActionParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "textDocument") {
- auto Parsed = TextDocumentIdentifier::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "range") {
- auto Parsed = Range::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *R = O->get("range")) {
+ if (auto Parsed = Range::parse(*R))
Result.range = std::move(*Parsed);
- } else if (KeyValue == "context") {
- auto Parsed = CodeActionContext::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *R = O->get("context")) {
+ if (auto Parsed = CodeActionContext::parse(*R))
Result.context = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
-static llvm::Optional<std::map<std::string, std::vector<TextEdit>>>
-parseWorkspaceEditChange(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+llvm::Optional<std::map<std::string, std::vector<TextEdit>>>
+parseWorkspaceEditChange(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
std::map<std::string, std::vector<TextEdit>> Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
+ for (const auto &KV : *O) {
+ auto &Values = Result[StringRef(KV.first)];
+ if (auto *Edits = KV.second.asArray())
+ for (auto &Edit : *Edits) {
+ if (auto Parsed = TextEdit::parse(Edit))
+ Values.push_back(std::move(*Parsed));
+ else
+ return llvm::None;
+ }
+ else
return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- if (Result.count(KeyValue)) {
- logIgnoredField(KeyValue, Logger);
- continue;
- }
-
- auto *Value =
- dyn_cast_or_null<llvm::yaml::SequenceNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
- for (auto &Item : *Value) {
- auto *ItemValue = dyn_cast_or_null<llvm::yaml::MappingNode>(&Item);
- if (!ItemValue)
- return llvm::None;
- auto Parsed = TextEdit::parse(ItemValue, Logger);
- if (!Parsed)
- return llvm::None;
-
- Result[KeyValue].push_back(*Parsed);
- }
}
-
return Result;
}
-llvm::Optional<WorkspaceEdit>
-WorkspaceEdit::parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger) {
- WorkspaceEdit Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+llvm::Optional<WorkspaceEdit> WorkspaceEdit::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "changes") {
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- return llvm::None;
- auto Parsed = parseWorkspaceEditChange(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ WorkspaceEdit Result;
+ if (auto *C = O->get("changes")) {
+ if (auto Parsed = parseWorkspaceEditChange(*C))
Result.changes = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
@@ -910,59 +523,25 @@ const std::string ExecuteCommandParams::
"clangd.applyFix";
llvm::Optional<ExecuteCommandParams>
-ExecuteCommandParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
- ExecuteCommandParams Result;
- // Depending on which "command" we parse, we will use this function to parse
- // the command "arguments".
- std::function<bool(llvm::yaml::MappingNode * Params)> ArgParser = nullptr;
-
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
-
- // Note that "commands" has to be parsed before "arguments" for this to
- // work properly.
- if (KeyValue == "command") {
- auto *ScalarValue =
- dyn_cast_or_null<llvm::yaml::ScalarNode>(NextKeyValue.getValue());
- if (!ScalarValue)
- return llvm::None;
- llvm::SmallString<10> Storage;
- Result.command = ScalarValue->getValue(Storage);
- if (Result.command == ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND) {
- ArgParser = [&Result, &Logger](llvm::yaml::MappingNode *Params) {
- auto WE = WorkspaceEdit::parse(Params, Logger);
- if (WE)
- Result.workspaceEdit = WE;
- return WE.hasValue();
- };
- } else {
- return llvm::None;
- }
- } else if (KeyValue == "arguments") {
- auto *Value = NextKeyValue.getValue();
- auto *Seq = dyn_cast<llvm::yaml::SequenceNode>(Value);
- if (!Seq)
- return llvm::None;
- for (auto &Item : *Seq) {
- auto *ItemValue = dyn_cast_or_null<llvm::yaml::MappingNode>(&Item);
- if (!ItemValue || !ArgParser)
- return llvm::None;
- if (!ArgParser(ItemValue))
- return llvm::None;
- }
- } else {
- logIgnoredField(KeyValue, Logger);
- }
- }
- if (Result.command.empty())
- return llvm::None;
+ExecuteCommandParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+ ExecuteCommandParams Result;
+ if (auto Command = O->getString("command"))
+ Result.command = *Command;
+ auto Args = O->getArray("arguments");
+
+ if (Result.command == ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND) {
+ if (!Args || Args->size() != 1)
+ return llvm::None;
+ if (auto Parsed = WorkspaceEdit::parse(Args->front()))
+ Result.workspaceEdit = std::move(*Parsed);
+ else
+ return llvm::None;
+ } else
+ return llvm::None; // Unrecognized command.
return Result;
}
@@ -981,35 +560,23 @@ ApplyWorkspaceEditParams::unparse(const
}
llvm::Optional<TextDocumentPositionParams>
-TextDocumentPositionParams::parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger) {
+TextDocumentPositionParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
+
TextDocumentPositionParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
-
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- continue;
-
- llvm::SmallString<10> Storage;
- if (KeyValue == "textDocument") {
- auto Parsed = TextDocumentIdentifier::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "position") {
- auto Parsed = Position::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *P = O->get("position")) {
+ if (auto Parsed = Position::parse(*P))
Result.position = std::move(*Parsed);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
return Result;
}
@@ -1081,50 +648,25 @@ json::Expr SignatureHelp::unparse(const
};
}
-llvm::Optional<RenameParams>
-RenameParams::parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger) {
- RenameParams Result;
- for (auto &NextKeyValue : *Params) {
- auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
- if (!KeyString)
- return llvm::None;
+llvm::Optional<RenameParams> RenameParams::parse(const json::Expr &Params) {
+ const json::obj *O = Params.asObject();
+ if (!O)
+ return None;
- llvm::SmallString<10> KeyStorage;
- StringRef KeyValue = KeyString->getValue(KeyStorage);
-
- if (KeyValue == "textDocument") {
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- continue;
- auto *Map = dyn_cast<llvm::yaml::MappingNode>(Value);
- if (!Map)
- return llvm::None;
- auto Parsed = TextDocumentIdentifier::parse(Map, Logger);
- if (!Parsed)
- return llvm::None;
+ RenameParams Result;
+ if (auto *D = O->get("textDocument")) {
+ if (auto Parsed = TextDocumentIdentifier::parse(*D))
Result.textDocument = std::move(*Parsed);
- } else if (KeyValue == "position") {
- auto *Value =
- dyn_cast_or_null<llvm::yaml::MappingNode>(NextKeyValue.getValue());
- if (!Value)
- continue;
- auto Parsed = Position::parse(Value, Logger);
- if (!Parsed)
- return llvm::None;
+ else
+ return llvm::None;
+ }
+ if (auto *P = O->get("position")) {
+ if (auto Parsed = Position::parse(*P))
Result.position = std::move(*Parsed);
- } else if (KeyValue == "newName") {
- auto *Value = NextKeyValue.getValue();
- if (!Value)
- continue;
- auto *Node = dyn_cast<llvm::yaml::ScalarNode>(Value);
- if (!Node)
- return llvm::None;
- llvm::SmallString<10> Storage;
- Result.newName = Node->getValue(Storage);
- } else {
- logIgnoredField(KeyValue, Logger);
- }
+ else
+ return llvm::None;
}
+ if (auto N = O->getString("newName"))
+ Result.newName = *N;
return Result;
}
Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Tue Nov 28 01:37:43 2017
@@ -23,15 +23,12 @@
#include "JSONExpr.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/YAMLParser.h"
#include <string>
#include <vector>
namespace clang {
namespace clangd {
-class Logger;
-
enum class ErrorCode {
// Defined by JSON RPC.
ParseError = -32700,
@@ -54,7 +51,7 @@ struct URI {
static URI fromUri(llvm::StringRef uri);
static URI fromFile(llvm::StringRef file);
- static URI parse(llvm::yaml::ScalarNode *Param);
+ static URI parse(llvm::StringRef U) { return fromUri(U); }
static json::Expr unparse(const URI &U);
friend bool operator==(const URI &LHS, const URI &RHS) {
@@ -74,8 +71,7 @@ struct TextDocumentIdentifier {
/// The text document's URI.
URI uri;
- static llvm::Optional<TextDocumentIdentifier>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ static llvm::Optional<TextDocumentIdentifier> parse(const json::Expr &Params);
};
struct Position {
@@ -94,8 +90,7 @@ struct Position {
std::tie(RHS.line, RHS.character);
}
- static llvm::Optional<Position> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<Position> parse(const json::Expr &Params);
static json::Expr unparse(const Position &P);
};
@@ -113,8 +108,7 @@ struct Range {
return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end);
}
- static llvm::Optional<Range> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<Range> parse(const json::Expr &Params);
static json::Expr unparse(const Range &P);
};
@@ -141,8 +135,7 @@ struct Location {
struct Metadata {
std::vector<std::string> extraFlags;
- static llvm::Optional<Metadata> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<Metadata> parse(const json::Expr &Params);
};
struct TextEdit {
@@ -154,8 +147,7 @@ struct TextEdit {
/// empty string.
std::string newText;
- static llvm::Optional<TextEdit> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<TextEdit> parse(const json::Expr &Params);
static json::Expr unparse(const TextEdit &P);
};
@@ -172,8 +164,7 @@ struct TextDocumentItem {
/// The content of the opened text document.
std::string text;
- static llvm::Optional<TextDocumentItem> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<TextDocumentItem> parse(const json::Expr &Params);
};
enum class TraceLevel {
@@ -183,8 +174,7 @@ enum class TraceLevel {
};
struct NoParams {
- static llvm::Optional<NoParams> parse(llvm::yaml::MappingNode *Params,
- Logger &Logger) {
+ static llvm::Optional<NoParams> parse(const json::Expr &Params) {
return NoParams{};
}
};
@@ -218,8 +208,7 @@ struct InitializeParams {
/// The initial trace setting. If omitted trace is disabled ('off').
llvm::Optional<TraceLevel> trace;
- static llvm::Optional<InitializeParams> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<InitializeParams> parse(const json::Expr &Params);
};
struct DidOpenTextDocumentParams {
@@ -230,7 +219,7 @@ struct DidOpenTextDocumentParams {
llvm::Optional<Metadata> metadata;
static llvm::Optional<DidOpenTextDocumentParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct DidCloseTextDocumentParams {
@@ -238,7 +227,7 @@ struct DidCloseTextDocumentParams {
TextDocumentIdentifier textDocument;
static llvm::Optional<DidCloseTextDocumentParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct TextDocumentContentChangeEvent {
@@ -246,7 +235,7 @@ struct TextDocumentContentChangeEvent {
std::string text;
static llvm::Optional<TextDocumentContentChangeEvent>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct DidChangeTextDocumentParams {
@@ -259,7 +248,7 @@ struct DidChangeTextDocumentParams {
std::vector<TextDocumentContentChangeEvent> contentChanges;
static llvm::Optional<DidChangeTextDocumentParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
enum class FileChangeType {
@@ -277,8 +266,7 @@ struct FileEvent {
/// The change type.
FileChangeType type;
- static llvm::Optional<FileEvent> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<FileEvent> parse(const json::Expr &Params);
};
struct DidChangeWatchedFilesParams {
@@ -286,7 +274,7 @@ struct DidChangeWatchedFilesParams {
std::vector<FileEvent> changes;
static llvm::Optional<DidChangeWatchedFilesParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct FormattingOptions {
@@ -296,8 +284,7 @@ struct FormattingOptions {
/// Prefer spaces over tabs.
bool insertSpaces;
- static llvm::Optional<FormattingOptions>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ static llvm::Optional<FormattingOptions> parse(const json::Expr &Params);
static json::Expr unparse(const FormattingOptions &P);
};
@@ -312,7 +299,7 @@ struct DocumentRangeFormattingParams {
FormattingOptions options;
static llvm::Optional<DocumentRangeFormattingParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct DocumentOnTypeFormattingParams {
@@ -329,7 +316,7 @@ struct DocumentOnTypeFormattingParams {
FormattingOptions options;
static llvm::Optional<DocumentOnTypeFormattingParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct DocumentFormattingParams {
@@ -340,7 +327,7 @@ struct DocumentFormattingParams {
FormattingOptions options;
static llvm::Optional<DocumentFormattingParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
struct Diagnostic {
@@ -372,16 +359,14 @@ struct Diagnostic {
std::tie(RHS.range, RHS.severity, RHS.message);
}
- static llvm::Optional<Diagnostic> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<Diagnostic> parse(const json::Expr &Params);
};
struct CodeActionContext {
/// An array of diagnostics.
std::vector<Diagnostic> diagnostics;
- static llvm::Optional<CodeActionContext>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ static llvm::Optional<CodeActionContext> parse(const json::Expr &Params);
};
struct CodeActionParams {
@@ -394,8 +379,7 @@ struct CodeActionParams {
/// Context carrying additional information.
CodeActionContext context;
- static llvm::Optional<CodeActionParams> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<CodeActionParams> parse(const json::Expr &Params);
};
struct WorkspaceEdit {
@@ -405,8 +389,7 @@ struct WorkspaceEdit {
/// Note: "documentChanges" is not currently used because currently there is
/// no support for versioned edits.
- static llvm::Optional<WorkspaceEdit> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<WorkspaceEdit> parse(const json::Expr &Params);
static json::Expr unparse(const WorkspaceEdit &WE);
};
@@ -429,8 +412,7 @@ struct ExecuteCommandParams {
llvm::Optional<WorkspaceEdit> workspaceEdit;
- static llvm::Optional<ExecuteCommandParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ static llvm::Optional<ExecuteCommandParams> parse(const json::Expr &Params);
};
struct ApplyWorkspaceEditParams {
@@ -446,7 +428,7 @@ struct TextDocumentPositionParams {
Position position;
static llvm::Optional<TextDocumentPositionParams>
- parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger);
+ parse(const json::Expr &Params);
};
/// The kind of a completion entry.
@@ -611,8 +593,7 @@ struct RenameParams {
/// The new name of the symbol.
std::string newName;
- static llvm::Optional<RenameParams> parse(llvm::yaml::MappingNode *Params,
- clangd::Logger &Logger);
+ static llvm::Optional<RenameParams> parse(const json::Expr &Params);
};
} // namespace clangd
Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp Tue Nov 28 01:37:43 2017
@@ -21,7 +21,7 @@ namespace {
// Helper for attaching ProtocolCallbacks methods to a JSONRPCDispatcher.
// Invoke like: Registerer("foo", &ProtocolCallbacks::onFoo)
// onFoo should be: void onFoo(Ctx &C, FooParams &Params)
-// FooParams should have a static factory method: parse(yaml::MappingNode*).
+// FooParams should have a static factory method: parse(const json::Expr&).
struct HandlerRegisterer {
template <typename Param>
void operator()(StringRef Method,
@@ -30,10 +30,10 @@ struct HandlerRegisterer {
auto *Out = this->Out;
auto *Callbacks = this->Callbacks;
Dispatcher.registerHandler(
- Method, [=](RequestContext C, llvm::yaml::MappingNode *RawParams) {
+ Method, [=](RequestContext C, const json::Expr &RawParams) {
if (auto P = [&] {
trace::Span Tracer("Parse");
- return std::decay<Param>::type::parse(RawParams, *Out);
+ return std::decay<Param>::type::parse(RawParams);
}()) {
(Callbacks->*Handler)(std::move(C), *P);
} else {
Modified: clang-tools-extra/trunk/clangd/Trace.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.cpp?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Trace.cpp (original)
+++ clang-tools-extra/trunk/clangd/Trace.cpp Tue Nov 28 01:37:43 2017
@@ -14,7 +14,6 @@
#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Threading.h"
-#include "llvm/Support/YAMLParser.h"
#include <mutex>
namespace clang {
Modified: clang-tools-extra/trunk/test/clangd/authority-less-uri.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/authority-less-uri.test?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/authority-less-uri.test (original)
+++ clang-tools-extra/trunk/test/clangd/authority-less-uri.test Tue Nov 28 01:37:43 2017
@@ -28,7 +28,7 @@ Content-Length: 146
# CHECK-NEXT: "sortText": "{{.*}}fake"
# CHECK: ]
# CHECK-NEXT: }
-Content-Length: 172
+Content-Length: 173
{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"uri":"file:///main.cpp","position":{"line":3,"character":5}}}
# Test params parsing in the presence of a 1.x-compatible client (inlined "uri")
@@ -51,4 +51,4 @@ Content-Length: 44
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Content-Length: 33
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Modified: clang-tools-extra/trunk/test/clangd/definitions.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/definitions.test?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/definitions.test (original)
+++ clang-tools-extra/trunk/test/clangd/definitions.test Tue Nov 28 01:37:43 2017
@@ -101,7 +101,7 @@ Content-Length: 149
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 187
+Content-Length: 188
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":4},"contentChanges":[{"text":"int main() {\n main();\n return 0;\n}"}]}}
@@ -126,7 +126,7 @@ Content-Length: 148
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 208
+Content-Length: 209
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":5},"contentChanges":[{"text":"struct Foo {\n};\nint main() {\n Foo bar;\n return 0;\n}\n"}]}}
@@ -151,7 +151,7 @@ Content-Length: 148
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 231
+Content-Length: 232
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":5},"contentChanges":[{"text":"namespace n1 {\nstruct Foo {\n};\n}\nint main() {\n n1::Foo bar;\n return 0;\n}\n"}]}}
@@ -176,7 +176,7 @@ Content-Length: 148
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 215
+Content-Length: 216
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":6},"contentChanges":[{"text":"struct Foo {\n int x;\n};\nint main() {\n Foo bar;\n bar.x;\n}\n"}]}}
@@ -201,7 +201,7 @@ Content-Length: 148
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 220
+Content-Length: 221
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":7},"contentChanges":[{"text":"struct Foo {\n void x();\n};\nint main() {\n Foo bar;\n bar.x();\n}\n"}]}}
@@ -226,7 +226,7 @@ Content-Length: 148
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 240
+Content-Length: 241
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":7},"contentChanges":[{"text":"struct Foo {\n};\ntypedef Foo TypedefFoo;\nint main() {\n TypedefFoo bar;\n return 0;\n}\n"}]}}
@@ -251,7 +251,7 @@ Content-Length: 149
# CHECK-NEXT: "uri": "file:///{{([A-Z]:/)?}}main.cpp"
# CHECK-NEXT: }
# CHECK-NEXT: ]
-Content-Length: 254
+Content-Length: 253
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":7},"contentChanges":[{"text":"template <typename MyTemplateParam>\nvoid foo() {\n MyTemplateParam a;\n}\nint main() {\n return 0;\n}\n"}]}}
@@ -262,7 +262,7 @@ Content-Length: 149
# CHECK: "id": 1,
# CHECK-NEXT: "jsonrpc": "2.0",
# CHECK-NEXT: "result": []
-Content-Length: 256
+Content-Length: 257
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":7},"contentChanges":[{"text":"namespace ns {\nstruct Foo {\nstatic void bar() {}\n};\n}\nint main() {\n ns::Foo::bar();\n return 0;\n}\n"}]}}
@@ -418,4 +418,4 @@ Content-Length: 48
{"jsonrpc":"2.0","id":10000,"method":"shutdown"}
Content-Length: 33
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Modified: clang-tools-extra/trunk/test/clangd/diagnostics.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/diagnostics.test?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/diagnostics.test (original)
+++ clang-tools-extra/trunk/test/clangd/diagnostics.test Tue Nov 28 01:37:43 2017
@@ -47,4 +47,4 @@ Content-Length: 44
{"jsonrpc":"2.0","id":5,"method":"shutdown"}
Content-Length: 33
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Removed: clang-tools-extra/trunk/test/clangd/did-change-watch-files.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/did-change-watch-files.test?rev=319158&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clangd/did-change-watch-files.test (original)
+++ clang-tools-extra/trunk/test/clangd/did-change-watch-files.test (removed)
@@ -1,53 +0,0 @@
-# RUN: clangd -run-synchronously < %s 2>&1 | FileCheck -check-prefix=STDERR %s
-# It is absolutely vital that this file has CRLF line endings.
-#
-# Test initialize request parameters with rootUri
-Content-Length: 143
-
-{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# Normal case.
-Content-Length: 217
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[{"uri":"file:///path/to/file.cpp","type":1},{"uri":"file:///path/to/file2.cpp","type":2},{"uri":"file:///path/to/file3.cpp","type":3}]}}
-
-# Wrong event type, integer
-Content-Length: 173
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[{"uri":"file:///path/to/file2.cpp","type":0},{"uri":"file:///path/to/file3.cpp","type":4}]}}
-# STDERR: Failed to decode a FileEvent.
-# Wrong event type, string
-Content-Length: 132
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[{"uri":"file:///path/to/file2.cpp","type":"foo"}]}}
-# STDERR: Failed to decode a FileEvent.
-#Custom event field
-Content-Length: 143
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[{"uri":"file:///path/to/file2.cpp","type":1,"custom":"foo"}]}}
-# STDERR: Failed to decode a FileEvent.
-#Event field with object
-Content-Length: 140
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[{"uri":"file:///path/to/file2.cpp","type":{"foo":"bar"}}]}}
-# STDERR: Failed to decode a FileEvent.
-# Changes field with sequence but no object
-Content-Length: 86
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[""]}}
-# STDERR: Failed to decode workspace/didChangeWatchedFiles request.
-# Changes field with no sequence
-Content-Length: 84
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":""}}
-# STDERR: Failed to decode workspace/didChangeWatchedFiles request.
-# Custom field
-Content-Length: 86
-
-{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"custom":"foo"}}
-# STDERR: Ignored unknown field "custom"
-Content-Length: 44
-
-{"jsonrpc":"2.0","id":3,"method":"shutdown"}
-Content-Length: 33
-
-{"jsonrpc":"2.0":"method":"exit"}
Modified: clang-tools-extra/trunk/test/clangd/protocol.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/protocol.test?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/protocol.test (original)
+++ clang-tools-extra/trunk/test/clangd/protocol.test Tue Nov 28 01:37:43 2017
@@ -79,7 +79,7 @@ Content-Length: 10
{"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:/main.cpp"},"position":{"line":3,"character":5}}}
# Test message with malformed Content-Length
#
-# STDERR: JSON dispatch failed!
+# STDERR: JSON parse error
# Ensure we recover by sending another (valid) message
Content-Length: 146
Modified: clang-tools-extra/trunk/unittests/clangd/JSONExprTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/JSONExprTests.cpp?rev=319159&r1=319158&r2=319159&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/JSONExprTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/JSONExprTests.cpp Tue Nov 28 01:37:43 2017
@@ -205,6 +205,7 @@ TEST(JSONTest, Inspection) {
EXPECT_TRUE(O->getNull("null"));
EXPECT_EQ(O->getNumber("number"), llvm::Optional<double>(2.78));
+ EXPECT_FALSE(O->getInteger("number"));
EXPECT_EQ(O->getString("string"), llvm::Optional<llvm::StringRef>("json"));
ASSERT_FALSE(O->getObject("missing"));
ASSERT_FALSE(O->getObject("array"));
@@ -216,6 +217,7 @@ TEST(JSONTest, Inspection) {
EXPECT_EQ(A->getBoolean(1), llvm::Optional<bool>(true));
ASSERT_TRUE(A->getArray(4));
EXPECT_EQ(*A->getArray(4), (ary{1, 2, 3}));
+ EXPECT_EQ(A->getArray(4)->getInteger(1), llvm::Optional<int64_t>(2));
int I = 0;
for (Expr &E : *A) {
if (I++ == 5) {
More information about the cfe-commits
mailing list