[clangd] Send CodeAction responses to textDocument/codeAction (LSP 3.8)

Summary:
I don't bother mirroring the full capabilities struct, just parse the
bits we care about. I'll send a new patch to use this approach elsewhere too.

Reviewers: kadircet

Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits

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

llvm-svn: 344617
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index ced7cf2..daab132 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -251,6 +251,9 @@
     return false;
   O.map("completion", R.completion);
   O.map("publishDiagnostics", R.publishDiagnostics);
+  if (auto *CodeAction = Params.getAsObject()->getObject("codeAction"))
+    if (CodeAction->getObject("codeActionLiteralSupport"))
+      R.codeActionLiteralSupport = true;
   return true;
 }
 
@@ -360,6 +363,17 @@
   return O && O.map("textDocument", R.textDocument);
 }
 
+llvm::json::Value toJSON(const Diagnostic &D) {
+  json::Object Diag{
+      {"range", D.range},
+      {"severity", D.severity},
+      {"message", D.message},
+  };
+  // FIXME: this should be used for publishDiagnostics.
+  // FIXME: send category and fixes when appropriate.
+  return std::move(Diag);
+}
+
 bool fromJSON(const json::Value &Params, Diagnostic &R) {
   json::ObjectMapper O(Params);
   if (!O || !O.map("range", R.range) || !O.map("message", R.message))
@@ -448,6 +462,21 @@
   return std::move(Cmd);
 }
 
+const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix";
+
+llvm::json::Value toJSON(const CodeAction &CA) {
+  auto CodeAction = json::Object{{"title", CA.title}};
+  if (CA.kind)
+    CodeAction["kind"] = *CA.kind;
+  if (CA.diagnostics)
+    CodeAction["diagnostics"] = json::Array(*CA.diagnostics);
+  if (CA.edit)
+    CodeAction["edit"] = *CA.edit;
+  if (CA.command)
+    CodeAction["command"] = *CA.command;
+  return std::move(CodeAction);
+}
+
 json::Value toJSON(const WorkspaceEdit &WE) {
   if (!WE.changes)
     return json::Object{};