[clangd] Initial cancellation mechanism for LSP requests.

Reviewers: ilya-biryukov, ioeric, hokein

Reviewed By: ilya-biryukov

Subscribers: mgorny, ioeric, MaskRay, jkorous, arphaman, jfb, cfe-commits

Differential Revision: https://reviews.llvm.org/D50502

llvm-svn: 340607
diff --git a/clang-tools-extra/clangd/JSONRPCDispatcher.cpp b/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
index 2741c66..9dea83a 100644
--- a/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
+++ b/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "JSONRPCDispatcher.h"
+#include "Cancellation.h"
 #include "ProtocolHandlers.h"
 #include "Trace.h"
 #include "llvm/ADT/SmallString.h"
@@ -93,7 +94,7 @@
 }
 
 void clangd::reply(json::Value &&Result) {
-  auto ID = Context::current().get(RequestID);
+  auto ID = getRequestId();
   if (!ID) {
     elog("Attempted to reply to a notification!");
     return;
@@ -116,7 +117,7 @@
                                  {"message", Message.str()}};
   });
 
-  if (auto ID = Context::current().get(RequestID)) {
+  if (auto ID = getRequestId()) {
     log("--> reply({0}) error: {1}", *ID, Message);
     Context::current()
         .getExisting(RequestOut)
@@ -129,6 +130,16 @@
   }
 }
 
+void clangd::replyError(Error E) {
+  handleAllErrors(std::move(E),
+                  [](const CancelledError &TCE) {
+                    replyError(ErrorCode::RequestCancelled, TCE.message());
+                  },
+                  [](const ErrorInfoBase &EIB) {
+                    replyError(ErrorCode::InvalidParams, EIB.message());
+                  });
+}
+
 void clangd::call(StringRef Method, json::Value &&Params) {
   RequestSpan::attach([&](json::Object &Args) {
     Args["Call"] = json::Object{{"method", Method.str()}, {"params", Params}};
@@ -366,3 +377,7 @@
     }
   }
 }
+
+const json::Value *clangd::getRequestId() {
+  return Context::current().get(RequestID);
+}