courbet updated this revision to Diff 440948.
courbet added a comment.

Format patch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128807/new/

https://reviews.llvm.org/D128807

Files:
  clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
  clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
  clang/include/clang/Tooling/Transformer/RewriteRule.h
  clang/lib/Tooling/Transformer/RewriteRule.cpp

Index: clang/lib/Tooling/Transformer/RewriteRule.cpp
===================================================================
--- clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -50,17 +50,26 @@
     // produces a bad range, whereas the latter will simply ignore A.
     if (!EditRange)
       return SmallVector<Edit, 0>();
-    auto Replacement = E.Replacement->eval(Result);
-    if (!Replacement)
-      return Replacement.takeError();
-    auto Metadata = E.Metadata(Result);
-    if (!Metadata)
-      return Metadata.takeError();
     transformer::Edit T;
     T.Kind = E.Kind;
     T.Range = *EditRange;
-    T.Replacement = std::move(*Replacement);
-    T.Metadata = std::move(*Metadata);
+    if (E.Replacement) {
+      auto Replacement = E.Replacement->eval(Result);
+      if (!Replacement)
+        return Replacement.takeError();
+      T.Replacement = std::move(*Replacement);
+    }
+    if (E.Note) {
+      auto Note = E.Note->eval(Result);
+      if (!Note)
+        return Note.takeError();
+      T.Note = std::move(*Note);
+    }
+    if (auto Metadata = E.Metadata(Result)) {
+      if (!Metadata)
+        return Metadata.takeError();
+      T.Metadata = std::move(*Metadata);
+    }
     Edits.push_back(std::move(T));
   }
   return Edits;
@@ -121,6 +130,29 @@
   return E;
 }
 
+ASTEdit transformer::withNote(ASTEdit Edit, TextGenerator Note) {
+  Edit.Note = std::move(Note);
+  return Edit;
+}
+
+EditGenerator transformer::withNote(EditGenerator Generator,
+                                    TextGenerator Note) {
+  return
+      [G = std::move(Generator), N = std::move(Note)](
+          const MatchResult &Result) -> llvm::Expected<SmallVector<Edit, 1>> {
+        llvm::Expected<SmallVector<Edit, 1>> Edits = G(Result);
+        if (!Edits)
+          return Edits.takeError();
+        llvm::Expected<std::string> Note = N->eval(Result);
+        if (!Note)
+          return Note.takeError();
+        for (Edit &E : *Edits) {
+          E.Note = *Note;
+        }
+        return Edits;
+      };
+}
+
 namespace {
 /// A \c TextGenerator that always returns a fixed string.
 class SimpleTextGenerator : public MatchComputation<std::string> {
Index: clang/include/clang/Tooling/Transformer/RewriteRule.h
===================================================================
--- clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -46,6 +46,7 @@
   EditKind Kind = EditKind::Range;
   CharSourceRange Range;
   std::string Replacement;
+  std::string Note;
   llvm::Any Metadata;
 };
 
@@ -246,6 +247,14 @@
   return Edit;
 }
 
+// Adds a note to the given edit or edits. If there are several edits, the note
+// is added to each one of them.
+// \code
+//   withNote(noopEdit(), cat("some note"))
+// \endcode
+EditGenerator withNote(EditGenerator Generator, TextGenerator Note);
+ASTEdit withNote(ASTEdit Edit, TextGenerator Note);
+
 /// Assuming that the inner range is enclosed by the outer range, creates
 /// precision edits to remove the parts of the outer range that are not included
 /// in the inner range.
Index: clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
===================================================================
--- clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
@@ -31,6 +31,7 @@
 using transformer::RewriteRuleWith;
 using transformer::RootID;
 using transformer::statement;
+using transformer::withNote;
 
 // Invert the code of an if-statement, while maintaining its semantics.
 RewriteRuleWith<std::string> invertIf() {
@@ -85,11 +86,33 @@
   EXPECT_EQ(Errors.size(), 1U);
   EXPECT_EQ(Errors[0].Message.Message, "message");
   EXPECT_THAT(Errors[0].Message.Ranges, testing::IsEmpty());
+  EXPECT_THAT(Errors[0].Notes, testing::IsEmpty());
 
   // The diagnostic is anchored to the match, "return 5".
   EXPECT_EQ(Errors[0].Message.FileOffset, 10U);
 }
 
+TEST(TransformerClangTidyCheckTest, NotesCorrectlyGenerated) {
+  class DiagAndNoteCheck : public TransformerClangTidyCheck {
+  public:
+    DiagAndNoteCheck(StringRef Name, ClangTidyContext *Context)
+        : TransformerClangTidyCheck(
+              makeRule(returnStmt(),
+                       withNote(noopEdit(node(RootID)), cat("some note")),
+                       cat("message")),
+              Name, Context) {}
+  };
+  std::string Input = "int h() { return 5; }";
+  std::vector<ClangTidyError> Errors;
+  EXPECT_EQ(Input, test::runCheckOnCode<DiagAndNoteCheck>(Input, &Errors));
+  EXPECT_EQ(Errors.size(), 1U);
+  EXPECT_EQ(Errors[0].Notes.size(), 1U);
+  EXPECT_EQ(Errors[0].Notes[0].Message, "some note");
+
+  // The note is anchored to the match, "return 5".
+  EXPECT_EQ(Errors[0].Notes[0].FileOffset, 10U);
+}
+
 TEST(TransformerClangTidyCheckTest, DiagnosticMessageEscaped) {
   class GiveDiagWithPercentSymbol : public TransformerClangTidyCheck {
   public:
Index: clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "TransformerClangTidyCheck.h"
+#include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/STLExtras.h"
 
@@ -126,18 +127,28 @@
   }
 
   // Associate the diagnostic with the location of the first change.
-  DiagnosticBuilder Diag =
-      diag((*Edits)[0].Range.getBegin(), escapeForDiagnostic(*Explanation));
-  for (const auto &T : *Edits)
-    switch (T.Kind) {
-    case transformer::EditKind::Range:
-      Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
-      break;
-    case transformer::EditKind::AddInclude:
-      Diag << Inserter.createIncludeInsertion(
-          Result.SourceManager->getFileID(T.Range.getBegin()), T.Replacement);
-      break;
+  {
+    DiagnosticBuilder Diag =
+        diag((*Edits)[0].Range.getBegin(), escapeForDiagnostic(*Explanation));
+    for (const auto &T : *Edits) {
+      switch (T.Kind) {
+      case transformer::EditKind::Range:
+        Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
+        break;
+      case transformer::EditKind::AddInclude:
+        Diag << Inserter.createIncludeInsertion(
+            Result.SourceManager->getFileID(T.Range.getBegin()), T.Replacement);
+        break;
+      }
     }
+  }
+  // Emit potential notes.
+  for (const auto &T : *Edits) {
+    if (!T.Note.empty()) {
+      diag(T.Range.getBegin(), escapeForDiagnostic(T.Note),
+           DiagnosticIDs::Note);
+    }
+  }
 }
 
 void TransformerClangTidyCheck::storeOptions(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to