kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added subscribers: usaxena95, arphaman.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98505

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp
  clang-tools-extra/clangd/Compiler.h
  clang-tools-extra/clangd/Diagnostics.cpp
  clang-tools-extra/clangd/Diagnostics.h
  clang-tools-extra/clangd/Protocol.cpp
  clang-tools-extra/clangd/Protocol.h
  clang-tools-extra/clangd/refactor/Tweak.h

Index: clang-tools-extra/clangd/refactor/Tweak.h
===================================================================
--- clang-tools-extra/clangd/refactor/Tweak.h
+++ clang-tools-extra/clangd/refactor/Tweak.h
@@ -26,6 +26,7 @@
 #include "index/Index.h"
 #include "support/Path.h"
 #include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -64,6 +65,8 @@
     unsigned SelectionEnd;
     /// The AST nodes that were selected.
     SelectionTree ASTSelection;
+    /// Diagnostics related to this selection.
+    llvm::ArrayRef<clangd::Diagnostic> Diags;
     // FIXME: provide a way to get sources and ASTs for other files.
   };
 
Index: clang-tools-extra/clangd/Protocol.h
===================================================================
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -406,6 +406,12 @@
   /// textDocument.publishDiagnostics.relatedInformation.
   bool DiagnosticRelatedInformation = false;
 
+  /// Whether the client supports the `data` property which is preserved between
+  /// a `textDocument/publishDiagnostics` and * `textDocument/codeAction`
+  /// request.
+  /// textDocument.publishDiagnostics.dataSupport
+  bool DiagnosticDataSupport = false;
+
   /// Whether the client accepts diagnostics with category attached to it
   /// using the "category" extension.
   /// textDocument.publishDiagnostics.categorySupport
@@ -840,6 +846,12 @@
   /// Only with capability textDocument.publishDiagnostics.codeActionsInline.
   /// (These actions can also be obtained using textDocument/codeAction).
   llvm::Optional<std::vector<CodeAction>> codeActions;
+
+  /// A data entry field that is preserved between a
+  /// `textDocument/publishDiagnostics` notification
+  /// and`textDocument/codeAction` request.
+  /// For clangd, this is always an array, with possibly zero elements.
+  llvm::json::Array data;
 };
 llvm::json::Value toJSON(const Diagnostic &);
 
Index: clang-tools-extra/clangd/Protocol.cpp
===================================================================
--- clang-tools-extra/clangd/Protocol.cpp
+++ clang-tools-extra/clangd/Protocol.cpp
@@ -331,6 +331,8 @@
         R.DiagnosticFixes = *CodeActions;
       if (auto RelatedInfo = Diagnostics->getBoolean("relatedInformation"))
         R.DiagnosticRelatedInformation = *RelatedInfo;
+      if (auto DataSupport = Diagnostics->getBoolean("dataSupport"))
+        R.DiagnosticDataSupport = *DataSupport;
     }
     if (auto *Completion = TextDocument->getObject("completion")) {
       if (auto *Item = Completion->getObject("completionItem")) {
@@ -593,6 +595,8 @@
     Diag["source"] = D.source;
   if (D.relatedInformation)
     Diag["relatedInformation"] = *D.relatedInformation;
+  if (!D.data.empty())
+    Diag["data"] = llvm::json::Array(D.data);
   // FIXME: workaround for older gcc/clang
   return std::move(Diag);
 }
@@ -600,7 +604,11 @@
 bool fromJSON(const llvm::json::Value &Params, Diagnostic &R,
               llvm::json::Path P) {
   llvm::json::ObjectMapper O(Params, P);
-  return O && O.map("range", R.range) && O.map("message", R.message) &&
+  if (!O)
+    return false;
+  if (auto *Data = Params.getAsObject()->getArray("data"))
+    R.data = *Data;
+  return O.map("range", R.range) && O.map("message", R.message) &&
          mapOptOrNull(Params, "severity", R.severity, P) &&
          mapOptOrNull(Params, "category", R.category, P) &&
          mapOptOrNull(Params, "code", R.code, P) &&
Index: clang-tools-extra/clangd/Diagnostics.h
===================================================================
--- clang-tools-extra/clangd/Diagnostics.h
+++ clang-tools-extra/clangd/Diagnostics.h
@@ -21,10 +21,12 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/SourceMgr.h"
 #include <cassert>
 #include <memory>
 #include <string>
+#include <vector>
 
 namespace clang {
 namespace tidy {
@@ -51,6 +53,11 @@
   /// If true, Clangd will add a number of available fixes to the diagnostic's
   /// message.
   bool DisplayFixesCount = true;
+
+  /// If true, Clangd will populate the data field in LSP diagnostic
+  /// representation. This is used to prevent extra data transfer with old
+  /// clients that doesn't support data field.
+  bool PreserveData = true;
 };
 
 /// Contains basic information about a diagnostic.
@@ -69,6 +76,10 @@
   // diags from the main file.
   bool InsideMainFile = false;
   unsigned ID; // e.g. member of clang::diag, or clang-tidy assigned ID.
+  // Feature modules can make use of this field to propagate data from a
+  // diagnostic to a CodeAction request. Each module should only append to the
+  // list.
+  std::vector<llvm::json::Value> FeatureModuleData;
 };
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DiagBase &D);
 
Index: clang-tools-extra/clangd/Diagnostics.cpp
===================================================================
--- clang-tools-extra/clangd/Diagnostics.cpp
+++ clang-tools-extra/clangd/Diagnostics.cpp
@@ -476,6 +476,12 @@
       Res.message = noteMessage(D, Note, Opts);
       OutFn(std::move(Res), llvm::ArrayRef<Fix>());
     }
+
+  if (Opts.PreserveData) {
+    // FIXME: Get rid of the copies here by taking in a mutable clangd::Diag.
+    for (auto &D : D.FeatureModuleData)
+      Main.data.push_back(D);
+  }
 }
 
 int getSeverity(DiagnosticsEngine::Level L) {
Index: clang-tools-extra/clangd/Compiler.h
===================================================================
--- clang-tools-extra/clangd/Compiler.h
+++ clang-tools-extra/clangd/Compiler.h
@@ -57,7 +57,7 @@
   const SymbolIndex *Index = nullptr;
   ParseOptions Opts = ParseOptions();
   TidyProviderRef ClangTidyProvider = {};
-  llvm::ArrayRef<std::unique_ptr<FeatureModule::ParseASTHooks>> ASTHooks;
+  llvm::ArrayRef<std::unique_ptr<FeatureModule::ParseASTHooks>> ASTHooks = {};
 };
 
 /// Builds compiler invocation that could be used to build AST or preamble.
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -505,6 +505,7 @@
   DiagOpts.SendDiagnosticCategory = Params.capabilities.DiagnosticCategory;
   DiagOpts.EmitRelatedLocations =
       Params.capabilities.DiagnosticRelatedInformation;
+  DiagOpts.PreserveData = Params.capabilities.DiagnosticDataSupport;
   if (Params.capabilities.WorkspaceSymbolKinds)
     SupportedSymbolKinds |= *Params.capabilities.WorkspaceSymbolKinds;
   if (Params.capabilities.CompletionItemKinds)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to