[clang-tools-extra] 5627ae6 - [clangd] Support CodeActionParams.only
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 29 01:58:16 PDT 2020
Author: Sam McCall
Date: 2020-10-29T09:44:08+01:00
New Revision: 5627ae6c507d62ef52d30fe80a0120f2ee033123
URL: https://github.com/llvm/llvm-project/commit/5627ae6c507d62ef52d30fe80a0120f2ee033123
DIFF: https://github.com/llvm/llvm-project/commit/5627ae6c507d62ef52d30fe80a0120f2ee033123.diff
LOG: [clangd] Support CodeActionParams.only
Differential Revision: https://reviews.llvm.org/D89126
Added:
Modified:
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/test/code-action-request.test
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 99c2465a579c..3164b6cbfb14 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -993,12 +993,24 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
if (!Code)
return Reply(llvm::make_error<LSPError>(
"onCodeAction called for non-added file", ErrorCode::InvalidParams));
+
+ // Checks whether a particular CodeActionKind is included in the response.
+ auto KindAllowed = [Only(Params.context.only)](llvm::StringRef Kind) {
+ if (Only.empty())
+ return true;
+ return llvm::any_of(Only, [&](llvm::StringRef Base) {
+ return Kind.consume_front(Base) && (Kind.empty() || Kind.startswith("."));
+ });
+ };
+
// We provide a code action for Fixes on the specified diagnostics.
std::vector<CodeAction> FixIts;
- for (const Diagnostic &D : Params.context.diagnostics) {
- for (auto &F : getFixes(File.file(), D)) {
- FixIts.push_back(toCodeAction(F, Params.textDocument.uri));
- FixIts.back().diagnostics = {D};
+ if (KindAllowed(CodeAction::QUICKFIX_KIND)) {
+ for (const Diagnostic &D : Params.context.diagnostics) {
+ for (auto &F : getFixes(File.file(), D)) {
+ FixIts.push_back(toCodeAction(F, Params.textDocument.uri));
+ FixIts.back().diagnostics = {D};
+ }
}
}
@@ -1038,14 +1050,10 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
}
return Reply(llvm::json::Array(Commands));
};
-
Server->enumerateTweaks(
File.file(), Params.range,
- [&](const Tweak &T) {
- if (!Opts.TweakFilter(T))
- return false;
- // FIXME: also consider CodeActionContext.only
- return true;
+ [this, KindAllowed(std::move(KindAllowed))](const Tweak &T) {
+ return Opts.TweakFilter(T) && KindAllowed(T.kind());
},
std::move(ConsumeActions));
}
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 0103a06ff951..d11307d04cee 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -599,7 +599,10 @@ llvm::json::Value toJSON(const PublishDiagnosticsParams &PDP) {
bool fromJSON(const llvm::json::Value &Params, CodeActionContext &R,
llvm::json::Path P) {
llvm::json::ObjectMapper O(Params, P);
- return O && O.map("diagnostics", R.diagnostics);
+ if (!O || !O.map("diagnostics", R.diagnostics))
+ return false;
+ O.map("only", R.only);
+ return true;
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diagnostic &D) {
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index 165a4a89e1cd..f846accbdde7 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -863,8 +863,19 @@ struct PublishDiagnosticsParams {
llvm::json::Value toJSON(const PublishDiagnosticsParams &);
struct CodeActionContext {
- /// An array of diagnostics.
+ /// An array of diagnostics known on the client side overlapping the range
+ /// provided to the `textDocument/codeAction` request. They are provided so
+ /// that the server knows which errors are currently presented to the user for
+ /// the given range. There is no guarantee that these accurately reflect the
+ /// error state of the resource. The primary parameter to compute code actions
+ /// is the provided range.
std::vector<Diagnostic> diagnostics;
+
+ /// Requested kind of actions to return.
+ ///
+ /// Actions not of this kind are filtered out by the client before being
+ /// shown. So servers can omit computing them.
+ std::vector<std::string> only;
};
bool fromJSON(const llvm::json::Value &, CodeActionContext &, llvm::json::Path);
diff --git a/clang-tools-extra/clangd/test/code-action-request.test b/clang-tools-extra/clangd/test/code-action-request.test
index 78e90ce6c423..f16f77989b47 100644
--- a/clang-tools-extra/clangd/test/code-action-request.test
+++ b/clang-tools-extra/clangd/test/code-action-request.test
@@ -51,6 +51,47 @@
# CHECK-NEXT: }
# CHECK-NEXT: ]
---
+{
+ "jsonrpc": "2.0",
+ "id": 2,
+ "method": "textDocument/codeAction",
+ "params": {
+ "textDocument": { "uri": "test:///main.cpp" },
+ "range": {
+ "start": {"line": 0, "character": 0},
+ "end": {"line": 0, "character": 4}
+ },
+ "context": {
+ "diagnostics": [],
+ "only": ["quickfix"]
+ }
+ }
+}
+# CHECK: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": []
+---
+{
+ "jsonrpc": "2.0",
+ "id": 3,
+ "method": "textDocument/codeAction",
+ "params": {
+ "textDocument": { "uri": "test:///main.cpp" },
+ "range": {
+ "start": {"line": 0, "character": 0},
+ "end": {"line": 0, "character": 4}
+ },
+ "context": {
+ "diagnostics": [],
+ "only": ["refactor"]
+ }
+ }
+}
+# CHECK: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+---
{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command":"clangd.applyTweak","arguments":[{"file":"test:///main.cpp","selection":{"end":{"character":4,"line":0},"start":{"character":0,"line":0}},"tweakID":"ExpandAutoType"}]}}
# CHECK: "newText": "int",
# CHECK-NEXT: "range": {
@@ -64,7 +105,7 @@
# CHECK-NEXT: }
# CHECK-NEXT: }
---
-{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
---
{"jsonrpc":"2.0","method":"exit"}
---
More information about the cfe-commits
mailing list