Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clangd] Dont require confirmation for include-cleaner batch-fixes #76826

Merged
merged 2 commits into from
Jan 4, 2024

Conversation

kadircet
Copy link
Member

@kadircet kadircet commented Jan 3, 2024

False negative/positive rate has decreased to the degree that these
extra confirmations no longer provide any value, but only create
friction in the happy case.

When we have false analysis, people usually need to apply the fixes and
run the builds to discover the failure. At that point they can add
relevant IWYU pragmas to guide analysis, and will be more likely to
create bug reports due to extra annoyance :)

False negative/positive rate has decreased to the degree that these
extra confirmations no longer provide any value, but only create
friction in the happy case.

When we have false analysis, people usually need to apply the fixes and
run the builds to discover the failure. At that point they can add
relevant IWYU pragmas to guide analysis, and will be more likely to
create bug reports due to extra annoyance :)
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 3, 2024

@llvm/pr-subscribers-clangd

Author: kadir çetinkaya (kadircet)

Changes

False negative/positive rate has decreased to the degree that these
extra confirmations no longer provide any value, but only create
friction in the happy case.

When we have false analysis, people usually need to apply the fixes and
run the builds to discover the failure. At that point they can add
relevant IWYU pragmas to guide analysis, and will be more likely to
create bug reports due to extra annoyance :)


Full diff: https://github.com/llvm/llvm-project/pull/76826.diff

2 Files Affected:

  • (modified) clang-tools-extra/clangd/IncludeCleaner.cpp (+1-26)
  • (modified) clang-tools-extra/clangd/test/include-cleaner-batch-fix.test (-68)
diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 563a1f5d22f5b5..672140a6f2b4d8 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -48,7 +48,6 @@
 #include <cassert>
 #include <iterator>
 #include <map>
-#include <memory>
 #include <optional>
 #include <string>
 #include <utility>
@@ -237,18 +236,6 @@ removeAllUnusedIncludes(llvm::ArrayRef<Diag> UnusedIncludes) {
                            Diag.Fixes.front().Edits.begin(),
                            Diag.Fixes.front().Edits.end());
   }
-
-  // TODO(hokein): emit a suitable text for the label.
-  ChangeAnnotation Annotation = {/*label=*/"",
-                                 /*needsConfirmation=*/true,
-                                 /*description=*/""};
-  static const ChangeAnnotationIdentifier RemoveAllUnusedID =
-      "RemoveAllUnusedIncludes";
-  for (unsigned I = 0; I < RemoveAll.Edits.size(); ++I) {
-    ChangeAnnotationIdentifier ID = RemoveAllUnusedID + std::to_string(I);
-    RemoveAll.Edits[I].annotationId = ID;
-    RemoveAll.Annotations.push_back({ID, Annotation});
-  }
   return RemoveAll;
 }
 
@@ -268,20 +255,8 @@ addAllMissingIncludes(llvm::ArrayRef<Diag> MissingIncludeDiags) {
       Edits.try_emplace(Edit.newText, Edit);
     }
   }
-  // FIXME(hokein): emit used symbol reference in the annotation.
-  ChangeAnnotation Annotation = {/*label=*/"",
-                                 /*needsConfirmation=*/true,
-                                 /*description=*/""};
-  static const ChangeAnnotationIdentifier AddAllMissingID =
-      "AddAllMissingIncludes";
-  unsigned I = 0;
-  for (auto &It : Edits) {
-    ChangeAnnotationIdentifier ID = AddAllMissingID + std::to_string(I++);
+  for (auto &It : Edits)
     AddAllMissing.Edits.push_back(std::move(It.second));
-    AddAllMissing.Edits.back().annotationId = ID;
-
-    AddAllMissing.Annotations.push_back({ID, Annotation});
-  }
   return AddAllMissing;
 }
 Fix fixAll(const Fix &RemoveAllUnused, const Fix &AddAllMissing) {
diff --git a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
index af7cdba5b05f43..07ebe1009a78f6 100644
--- a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
+++ b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
@@ -157,21 +157,10 @@
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "arguments": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "changeAnnotations": {
-# CHECK-NEXT:            "AddAllMissingIncludes0": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "AddAllMissingIncludes1": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            }
-# CHECK-NEXT:          },
 # CHECK-NEXT:          "documentChanges": [
 # CHECK-NEXT:            {
 # CHECK-NEXT:              "edits": [
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "AddAllMissingIncludes0",
 # CHECK-NEXT:                  "newText": "#include {{.*}}bar.h{{.*}}",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -185,7 +174,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "AddAllMissingIncludes1",
 # CHECK-NEXT:                  "newText": "#include {{.*}}foo.h{{.*}}",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -213,29 +201,10 @@
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "arguments": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "changeAnnotations": {
-# CHECK-NEXT:            "AddAllMissingIncludes0": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "AddAllMissingIncludes1": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "RemoveAllUnusedIncludes0": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "RemoveAllUnusedIncludes1": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            }
-# CHECK-NEXT:          },
 # CHECK-NEXT:          "documentChanges": [
 # CHECK-NEXT:            {
 # CHECK-NEXT:              "edits": [
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "RemoveAllUnusedIncludes0",
 # CHECK-NEXT:                  "newText": "",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -249,7 +218,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "RemoveAllUnusedIncludes1",
 # CHECK-NEXT:                  "newText": "",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -263,7 +231,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "AddAllMissingIncludes0",
 # CHECK-NEXT:                  "newText": "#include {{.*}}bar.h{{.*}}",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -277,7 +244,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "AddAllMissingIncludes1",
 # CHECK-NEXT:                  "newText": "#include {{.*}}foo.h{{.*}}",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -342,21 +308,10 @@
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "arguments": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "changeAnnotations": {
-# CHECK-NEXT:            "RemoveAllUnusedIncludes0": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "RemoveAllUnusedIncludes1": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            }
-# CHECK-NEXT:          },
 # CHECK-NEXT:          "documentChanges": [
 # CHECK-NEXT:            {
 # CHECK-NEXT:              "edits": [
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "RemoveAllUnusedIncludes0",
 # CHECK-NEXT:                  "newText": "",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -370,7 +325,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "RemoveAllUnusedIncludes1",
 # CHECK-NEXT:                  "newText": "",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -398,29 +352,10 @@
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "arguments": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "changeAnnotations": {
-# CHECK-NEXT:            "AddAllMissingIncludes0": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "AddAllMissingIncludes1": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "RemoveAllUnusedIncludes0": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            },
-# CHECK-NEXT:            "RemoveAllUnusedIncludes1": {
-# CHECK-NEXT:              "label": "",
-# CHECK-NEXT:              "needsConfirmation": true
-# CHECK-NEXT:            }
-# CHECK-NEXT:          },
 # CHECK-NEXT:          "documentChanges": [
 # CHECK-NEXT:            {
 # CHECK-NEXT:              "edits": [
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "RemoveAllUnusedIncludes0",
 # CHECK-NEXT:                  "newText": "",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -434,7 +369,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "RemoveAllUnusedIncludes1",
 # CHECK-NEXT:                  "newText": "",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -448,7 +382,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "AddAllMissingIncludes0",
 # CHECK-NEXT:                  "newText": "#include {{.*}}bar.h{{.*}}",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {
@@ -462,7 +395,6 @@
 # CHECK-NEXT:                  }
 # CHECK-NEXT:                },
 # CHECK-NEXT:                {
-# CHECK-NEXT:                  "annotationId": "AddAllMissingIncludes1",
 # CHECK-NEXT:                  "newText": "#include {{.*}}foo.h{{.*}}",
 # CHECK-NEXT:                  "range": {
 # CHECK-NEXT:                    "end": {

Copy link
Collaborator

@hokein hokein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes sense for removing all unused includes (as all these unused includes are visible in the editor). For missing includes, they are less obvious, but it is probably fine.

(I think it would be great to have a way to view all missing includes, VSCode has a feature to preview code action changes, but it seems broken with clangd.)

clang-tools-extra/clangd/IncludeCleaner.cpp Show resolved Hide resolved
@kadircet
Copy link
Member Author

kadircet commented Jan 4, 2024

This change makes sense for removing all unused includes (as all these unused includes are visible in the editor). For missing includes, they are less obvious, but it is probably fine.

The rationale for missing includes was the same, when things go wrong it's usually obscure enough that problems only raise with build systems that have visibility restrictions. Hence I am not sure if this extra step provides enough value.

(I think it would be great to have a way to view all missing includes, VSCode has a feature to preview code action changes, but it seems broken with clangd.)

Agreed, making alt+enter work in these cases would be useful, and last time I checked it is actually working. I tried with this patch, and it still gives people a way to preview and selectively apply these edits. So we're actually not taking away the functionality completely, but rather putting this behind an extra shortcut :)

Can you check if it's still broken for you ?
Screenshot 2024-01-04 at 12 52 20

@kadircet
Copy link
Member Author

kadircet commented Jan 4, 2024

oh sorry, this should ofc work with include-cleaner fixes, as we actually provide these as edits, instead of commands, as we do with our usual tweaks.

@kadircet kadircet merged commit 2336f79 into llvm:main Jan 4, 2024
3 of 4 checks passed
@kadircet kadircet deleted the no_confirmation branch January 4, 2024 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants