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.

A module interface to enable custom contributions for diagnostic fixes.
Interface also allows contributors to return a Command which can be
computed outside of the latency sensitive diagnostic release cycle.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96439

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp
  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/test/initialize-params.test

Index: clang-tools-extra/clangd/test/initialize-params.test
===================================================================
--- clang-tools-extra/clangd/test/initialize-params.test
+++ clang-tools-extra/clangd/test/initialize-params.test
@@ -67,7 +67,8 @@
 # CHECK-NEXT:      "executeCommandProvider": {
 # CHECK-NEXT:        "commands": [
 # CHECK-NEXT:          "clangd.applyFix",
-# CHECK-NEXT:          "clangd.applyTweak"
+# CHECK-NEXT:          "clangd.applyTweak",
+# CHECK-NEXT:          "clangd.applyAugmentedFix"
 # CHECK-NEXT:        ]
 # CHECK-NEXT:      },
 # CHECK-NEXT:      "hoverProvider": true,
Index: clang-tools-extra/clangd/Protocol.h
===================================================================
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -914,6 +914,15 @@
 bool fromJSON(const llvm::json::Value &, TweakArgs &, llvm::json::Path);
 llvm::json::Value toJSON(const TweakArgs &A);
 
+/// Arguments for applyAugmentedFix command. These are send as code actions from
+/// the server in response to diagnostics.
+struct AugmentedDiagArgs {
+  /// ID of the module that generated the action.
+  std::string moduleID;
+  /// Augmenters arguments are opaque and should be parsed by them.
+  llvm::json::Value args;
+};
+
 /// Exact commands are not specified in the protocol so we define the
 /// ones supported by Clangd here. The protocol specifies the command arguments
 /// to be "any[]" but to make this safer and more manageable, each command we
@@ -927,6 +936,9 @@
   const static llvm::StringLiteral CLANGD_APPLY_FIX_COMMAND;
   // Command to apply the code action. Uses TweakArgs as argument.
   const static llvm::StringLiteral CLANGD_APPLY_TWEAK;
+  // Command to apply a fix generated by a DiagnosticsAugmentationModule. Uses
+  // AugmentedDiagArgs as argument.
+  const static llvm::StringLiteral CLANGD_APPLY_AUGMENTED_FIX;
 
   /// The command identifier, e.g. CLANGD_APPLY_FIX_COMMAND
   std::string command;
@@ -934,6 +946,7 @@
   // Arguments
   llvm::Optional<WorkspaceEdit> workspaceEdit;
   llvm::Optional<TweakArgs> tweakArgs;
+  llvm::Optional<AugmentedDiagArgs> augmentDiagArgs;
 };
 bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &,
               llvm::json::Path);
Index: clang-tools-extra/clangd/Protocol.cpp
===================================================================
--- clang-tools-extra/clangd/Protocol.cpp
+++ clang-tools-extra/clangd/Protocol.cpp
@@ -659,6 +659,8 @@
     "clangd.applyFix";
 const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_TWEAK =
     "clangd.applyTweak";
+const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_AUGMENTED_FIX =
+    "clangd.applyAugmentedFix";
 
 bool fromJSON(const llvm::json::Value &Params, ExecuteCommandParams &R,
               llvm::json::Path P) {
Index: clang-tools-extra/clangd/Diagnostics.h
===================================================================
--- clang-tools-extra/clangd/Diagnostics.h
+++ clang-tools-extra/clangd/Diagnostics.h
@@ -9,7 +9,9 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H
 
+#include "Module.h"
 #include "Protocol.h"
+#include "SourceCode.h"
 #include "support/Path.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
@@ -30,6 +32,20 @@
 } // namespace tidy
 namespace clangd {
 
+/// Can be used to provide additional fixes to diagnostics.
+/// Returned codeaction might just contain a command instead to postpone
+/// computation of expensive edits or calculate them outside the critical path.
+/// This command will be invoked via executeCommand later on, if user requests.
+class DiagnosticsAugmentationModule : public Module {
+public:
+  /// Returns an action that can be invoked to fix the diagnostic.
+  virtual llvm::Optional<CodeAction>
+  augmentDiag(DiagnosticsEngine::Level L, const clang::Diagnostic &Diag) = 0;
+
+  // FIXME: Lift Tweak::Effect out of Tweak.h and use it here.
+  virtual llvm::Expected<FileEdits> executeCommand(llvm::json::Value Args) = 0;
+};
+
 struct ClangdDiagnosticOptions {
   /// If true, Clangd uses an LSP extension to embed the fixes with the
   /// diagnostics that are sent to the client.
@@ -145,12 +161,16 @@
   /// diagnostics, such as promoting warnings to errors, or ignoring
   /// diagnostics.
   void setLevelAdjuster(LevelAdjuster Adjuster) { this->Adjuster = Adjuster; }
+  void setAugmenters(llvm::ArrayRef<DiagnosticsAugmentationModule *> Modules) {
+    this->Modules = Modules;
+  }
 
 private:
   void flushLastDiag();
 
   DiagFixer Fixer = nullptr;
   LevelAdjuster Adjuster = nullptr;
+  llvm::ArrayRef<DiagnosticsAugmentationModule *> Modules = {};
   std::vector<Diag> Output;
   llvm::Optional<LangOptions> LangOpts;
   llvm::Optional<Diag> LastDiag;
Index: clang-tools-extra/clangd/Diagnostics.cpp
===================================================================
--- clang-tools-extra/clangd/Diagnostics.cpp
+++ clang-tools-extra/clangd/Diagnostics.cpp
@@ -746,6 +746,10 @@
       LastDiag->Fixes.insert(LastDiag->Fixes.end(), ExtraFixes.begin(),
                              ExtraFixes.end());
     }
+    for (auto *Module : Modules) {
+      if (auto Action = Module->augmentDiag(DiagLevel, Info))
+        LastDiag->Actions.emplace_back(std::move(*Action));
+    }
   } else {
     // Handle a note to an existing diagnostic.
 
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -654,8 +654,11 @@
             {"executeCommandProvider",
              llvm::json::Object{
                  {"commands",
-                  {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND,
-                   ExecuteCommandParams::CLANGD_APPLY_TWEAK}},
+                  {
+                      ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND,
+                      ExecuteCommandParams::CLANGD_APPLY_TWEAK,
+                      ExecuteCommandParams::CLANGD_APPLY_AUGMENTED_FIX,
+                  }},
              }},
             {"typeHierarchyProvider", true},
             {"memoryUsageProvider", true}, // clangd extension
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to