ymandel created this revision. ymandel added reviewers: tdl-g, gribozavr2. Herald added a project: clang. ymandel requested review of this revision.
This functionality is commonly needed in clang tidy checks (based on transformer) that only print warnings, without suggesting any edits. The no-op edit allows the user to associate a diagnostic message with a source location. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D89961 Files: clang/include/clang/Tooling/Transformer/RewriteRule.h clang/lib/Tooling/Transformer/RewriteRule.cpp clang/unittests/Tooling/TransformerTest.cpp Index: clang/unittests/Tooling/TransformerTest.cpp =================================================================== --- clang/unittests/Tooling/TransformerTest.cpp +++ clang/unittests/Tooling/TransformerTest.cpp @@ -426,6 +426,14 @@ testRule(makeRule(returnStmt().bind("return"), noEdits()), Input, Input); } +TEST_F(TransformerTest, NoopEdit) { + using transformer::node; + using transformer::noopEdit; + std::string Input = "int f(int x) { return x; }"; + testRule(makeRule(returnStmt().bind("return"), noopEdit(node("return"))), + Input, Input); +} + TEST_F(TransformerTest, IfBound2Args) { using transformer::ifBound; std::string Input = "int f(int x) { return x; }"; Index: clang/lib/Tooling/Transformer/RewriteRule.cpp =================================================================== --- clang/lib/Tooling/Transformer/RewriteRule.cpp +++ clang/lib/Tooling/Transformer/RewriteRule.cpp @@ -73,6 +73,24 @@ }; } +EditGenerator transformer::noopEdit(RangeSelector Anchor) { + return [Anchor = std::move(Anchor)](const MatchResult &Result) + -> Expected<SmallVector<transformer::Edit, 1>> { + Expected<CharSourceRange> Range = Anchor(Result); + if (!Range) + return Range.takeError(); + // In case the range is inside a macro expansion, map the location back to a + // "real" source location. + SourceLocation Begin = + Result.SourceManager->getSpellingLoc(Range->getBegin()); + Edit E; + // Implicitly, leave `E.Replacement` as the empty string. + E.Kind = EditKind::Range; + E.Range = CharSourceRange::getCharRange(Begin, Begin); + return SmallVector<Edit, 1>{E}; + }; +} + EditGenerator transformer::flattenVector(SmallVector<EditGenerator, 2> Generators) { if (Generators.size() == 1) Index: clang/include/clang/Tooling/Transformer/RewriteRule.h =================================================================== --- clang/include/clang/Tooling/Transformer/RewriteRule.h +++ clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -107,7 +107,7 @@ TextGenerator Replacement; TextGenerator Note; // Not all transformations will want or need to attach metadata and therefore - // should not be requierd to do so. + // should not be required to do so. AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &) -> llvm::Expected<llvm::Any> { return llvm::Expected<llvm::Any>(llvm::Any()); @@ -131,6 +131,11 @@ /// Generates no edits. inline EditGenerator noEdits() { return editList({}); } +/// Generates a single, no-op edit anchored at the start location of the +/// specified range. A `noopEdit` may be preferred over `noEdits` to associate a +/// diagnostic `Explanation` with the rule. +EditGenerator noopEdit(RangeSelector Anchor); + /// Version of `ifBound` specialized to `ASTEdit`. inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit, ASTEdit FalseEdit) {
Index: clang/unittests/Tooling/TransformerTest.cpp =================================================================== --- clang/unittests/Tooling/TransformerTest.cpp +++ clang/unittests/Tooling/TransformerTest.cpp @@ -426,6 +426,14 @@ testRule(makeRule(returnStmt().bind("return"), noEdits()), Input, Input); } +TEST_F(TransformerTest, NoopEdit) { + using transformer::node; + using transformer::noopEdit; + std::string Input = "int f(int x) { return x; }"; + testRule(makeRule(returnStmt().bind("return"), noopEdit(node("return"))), + Input, Input); +} + TEST_F(TransformerTest, IfBound2Args) { using transformer::ifBound; std::string Input = "int f(int x) { return x; }"; Index: clang/lib/Tooling/Transformer/RewriteRule.cpp =================================================================== --- clang/lib/Tooling/Transformer/RewriteRule.cpp +++ clang/lib/Tooling/Transformer/RewriteRule.cpp @@ -73,6 +73,24 @@ }; } +EditGenerator transformer::noopEdit(RangeSelector Anchor) { + return [Anchor = std::move(Anchor)](const MatchResult &Result) + -> Expected<SmallVector<transformer::Edit, 1>> { + Expected<CharSourceRange> Range = Anchor(Result); + if (!Range) + return Range.takeError(); + // In case the range is inside a macro expansion, map the location back to a + // "real" source location. + SourceLocation Begin = + Result.SourceManager->getSpellingLoc(Range->getBegin()); + Edit E; + // Implicitly, leave `E.Replacement` as the empty string. + E.Kind = EditKind::Range; + E.Range = CharSourceRange::getCharRange(Begin, Begin); + return SmallVector<Edit, 1>{E}; + }; +} + EditGenerator transformer::flattenVector(SmallVector<EditGenerator, 2> Generators) { if (Generators.size() == 1) Index: clang/include/clang/Tooling/Transformer/RewriteRule.h =================================================================== --- clang/include/clang/Tooling/Transformer/RewriteRule.h +++ clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -107,7 +107,7 @@ TextGenerator Replacement; TextGenerator Note; // Not all transformations will want or need to attach metadata and therefore - // should not be requierd to do so. + // should not be required to do so. AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &) -> llvm::Expected<llvm::Any> { return llvm::Expected<llvm::Any>(llvm::Any()); @@ -131,6 +131,11 @@ /// Generates no edits. inline EditGenerator noEdits() { return editList({}); } +/// Generates a single, no-op edit anchored at the start location of the +/// specified range. A `noopEdit` may be preferred over `noEdits` to associate a +/// diagnostic `Explanation` with the rule. +EditGenerator noopEdit(RangeSelector Anchor); + /// Version of `ifBound` specialized to `ASTEdit`. inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit, ASTEdit FalseEdit) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits