[clang-tools-extra] [clangd] Attempt to fix https://github.com/clangd/clangd/issues/1536 (PR #79448)
Tor Shepherd via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 25 06:17:52 PST 2024
https://github.com/torshepherd created https://github.com/llvm/llvm-project/pull/79448
This PR attempts to fix [1536.](https://github.com/clangd/clangd/issues/1536). See in the unit tests, when all quick fixes are of the same `code`, `isPreferred` will be true. However, this doesn't seem to change the behavior in vscode:
![image](https://github.com/llvm/llvm-project/assets/49597791/1d8236c3-3e43-4260-b655-d33d6cac6e42)
>From 6bb871f64073132683bab2318c228a4ef7723c8e Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.shepherd at gmail.com>
Date: Wed, 24 Jan 2024 23:43:52 -0500
Subject: [PATCH 1/2] second try
---
clang-tools-extra/clangd/ClangdLSPServer.cpp | 78 ++++++++++----------
1 file changed, 41 insertions(+), 37 deletions(-)
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index a87da252b7a7e9b..5fbd09fdcfdf420 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -27,7 +27,9 @@
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Allocator.h"
@@ -117,10 +119,9 @@ CodeAction toCodeAction(const Fix &F, const URIForFile &File,
Edit.textDocument = VersionedTextDocumentIdentifier{{File}, Version};
for (const auto &E : F.Edits)
Edit.edits.push_back(
- {E.range, E.newText,
- SupportChangeAnnotation ? E.annotationId : ""});
+ {E.range, E.newText, SupportChangeAnnotation ? E.annotationId : ""});
if (SupportChangeAnnotation) {
- for (const auto &[AID, Annotation]: F.Annotations)
+ for (const auto &[AID, Annotation] : F.Annotations)
Action.edit->changeAnnotations[AID] = Annotation;
}
}
@@ -861,24 +862,24 @@ void ClangdLSPServer::onRename(const RenameParams &Params,
if (!Server->getDraft(File))
return Reply(llvm::make_error<LSPError>(
"onRename called for non-added file", ErrorCode::InvalidParams));
- Server->rename(File, Params.position, Params.newName, Opts.Rename,
- [File, Params, Reply = std::move(Reply),
- this](llvm::Expected<RenameResult> R) mutable {
- if (!R)
- return Reply(R.takeError());
- if (auto Err = validateEdits(*Server, R->GlobalChanges))
- return Reply(std::move(Err));
- WorkspaceEdit Result;
- // FIXME: use documentChanges if SupportDocumentChanges is
- // true.
- Result.changes.emplace();
- for (const auto &Rep : R->GlobalChanges) {
- (*Result
- .changes)[URI::createFile(Rep.first()).toString()] =
- Rep.second.asTextEdits();
- }
- Reply(Result);
- });
+ Server->rename(
+ File, Params.position, Params.newName, Opts.Rename,
+ [File, Params, Reply = std::move(Reply),
+ this](llvm::Expected<RenameResult> R) mutable {
+ if (!R)
+ return Reply(R.takeError());
+ if (auto Err = validateEdits(*Server, R->GlobalChanges))
+ return Reply(std::move(Err));
+ WorkspaceEdit Result;
+ // FIXME: use documentChanges if SupportDocumentChanges is
+ // true.
+ Result.changes.emplace();
+ for (const auto &Rep : R->GlobalChanges) {
+ (*Result.changes)[URI::createFile(Rep.first()).toString()] =
+ Rep.second.asTextEdits();
+ }
+ Reply(Result);
+ });
}
void ClangdLSPServer::onDocumentDidClose(
@@ -1014,7 +1015,7 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
std::map<ClangdServer::DiagRef, clangd::Diagnostic> ToLSPDiags;
ClangdServer::CodeActionInputs Inputs;
- for (const auto& LSPDiag : Params.context.diagnostics) {
+ for (const auto &LSPDiag : Params.context.diagnostics) {
if (auto DiagRef = getDiagRef(File.file(), LSPDiag)) {
ToLSPDiags[*DiagRef] = LSPDiag;
Inputs.Diagnostics.push_back(*DiagRef);
@@ -1023,13 +1024,9 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
Inputs.File = File.file();
Inputs.Selection = Params.range;
Inputs.RequestedActionKinds = Params.context.only;
- Inputs.TweakFilter = [this](const Tweak &T) {
- return Opts.TweakFilter(T);
- };
- auto CB = [this,
- Reply = std::move(Reply),
- ToLSPDiags = std::move(ToLSPDiags), File,
- Selection = Params.range](
+ Inputs.TweakFilter = [this](const Tweak &T) { return Opts.TweakFilter(T); };
+ auto CB = [this, Reply = std::move(Reply), ToLSPDiags = std::move(ToLSPDiags),
+ File, Selection = Params.range](
llvm::Expected<ClangdServer::CodeActionResult> Fixits) mutable {
if (!Fixits)
return Reply(Fixits.takeError());
@@ -1038,27 +1035,34 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
for (const auto &QF : Fixits->QuickFixes) {
CAs.push_back(toCodeAction(QF.F, File, Version, SupportsDocumentChanges,
SupportsChangeAnnotation));
- if (auto It = ToLSPDiags.find(QF.Diag);
- It != ToLSPDiags.end()) {
+ if (auto It = ToLSPDiags.find(QF.Diag); It != ToLSPDiags.end()) {
CAs.back().diagnostics = {It->second};
}
}
for (const auto &TR : Fixits->TweakRefs)
CAs.push_back(toCodeAction(TR, File, Selection));
- // If there's exactly one quick-fix, call it "preferred".
+ // If there's exactly one quick-fix category, call it "preferred".
// We never consider refactorings etc as preferred.
- CodeAction *OnlyFix = nullptr;
+ llvm::SmallVector<CodeAction *, 1> OnlyFixes;
+ std::optional<std::string> OnlyFixCategory;
for (auto &Action : CAs) {
+ std::string Code =
+ Action.diagnostics.has_value() && !Action.diagnostics->empty()
+ ? Action.diagnostics->front().code
+ : "";
if (Action.kind && *Action.kind == CodeAction::QUICKFIX_KIND) {
- if (OnlyFix) {
- OnlyFix = nullptr;
+ if (OnlyFixCategory && *OnlyFixCategory != Code) {
+ OnlyFixCategory = std::nullopt;
break;
}
- OnlyFix = &Action;
+ if (!OnlyFixCategory) {
+ OnlyFixCategory = Code;
+ }
+ OnlyFixes.emplace_back(&Action);
}
}
- if (OnlyFix) {
+ for (const auto &OnlyFix : OnlyFixes) {
OnlyFix->isPreferred = true;
if (ToLSPDiags.size() == 1 &&
ToLSPDiags.begin()->second.range == Selection)
>From 70e33931b2a15e515538f64e48ef0c57490b1245 Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.shepherd at gmail.com>
Date: Thu, 25 Jan 2024 09:17:32 -0500
Subject: [PATCH 2/2] fix tests
---
.../clangd/test/fixits-codeaction-documentchanges.test | 2 ++
clang-tools-extra/clangd/test/fixits-codeaction.test | 2 ++
2 files changed, 4 insertions(+)
diff --git a/clang-tools-extra/clangd/test/fixits-codeaction-documentchanges.test b/clang-tools-extra/clangd/test/fixits-codeaction-documentchanges.test
index 7a591319a740547..d796453679a4cbd 100644
--- a/clang-tools-extra/clangd/test/fixits-codeaction-documentchanges.test
+++ b/clang-tools-extra/clangd/test/fixits-codeaction-documentchanges.test
@@ -87,6 +87,7 @@
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: },
+# CHECK-NEXT: "isPreferred": true,
# CHECK-NEXT: "kind": "quickfix",
# CHECK-NEXT: "title": "place parentheses around the assignment to silence this warning"
# CHECK-NEXT: },
@@ -134,6 +135,7 @@
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: },
+# CHECK-NEXT: "isPreferred": true,
# CHECK-NEXT: "kind": "quickfix",
# CHECK-NEXT: "title": "use '==' to turn this assignment into an equality comparison"
# CHECK-NEXT: }
diff --git a/clang-tools-extra/clangd/test/fixits-codeaction.test b/clang-tools-extra/clangd/test/fixits-codeaction.test
index 75d0fb012ffc814..09e2e22aefe57f1 100644
--- a/clang-tools-extra/clangd/test/fixits-codeaction.test
+++ b/clang-tools-extra/clangd/test/fixits-codeaction.test
@@ -81,6 +81,7 @@
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: },
+# CHECK-NEXT: "isPreferred": true,
# CHECK-NEXT: "kind": "quickfix",
# CHECK-NEXT: "title": "place parentheses around the assignment to silence this warning"
# CHECK-NEXT: },
@@ -122,6 +123,7 @@
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: },
+# CHECK-NEXT: "isPreferred": true,
# CHECK-NEXT: "kind": "quickfix",
# CHECK-NEXT: "title": "use '==' to turn this assignment into an equality comparison"
# CHECK-NEXT: }
More information about the cfe-commits
mailing list