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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits