diff --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h b/clang/include/clang/Tooling/Transformer/RewriteRule.h --- a/clang/include/clang/Tooling/Transformer/RewriteRule.h +++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -55,18 +55,18 @@ // `ASTEdit` should be built using the `change` convenience functions. For // example, // \code -// change(name(fun), text("Frodo")) +// changeTo(name(fun), cat("Frodo")) // \endcode // Or, if we use Stencil for the TextGenerator: // \code // using stencil::cat; -// change(statement(thenNode), cat("{", thenNode, "}")) -// change(callArgs(call), cat(x, ",", y)) +// changeTo(statement(thenNode), cat("{", thenNode, "}")) +// changeTo(callArgs(call), cat(x, ",", y)) // \endcode // Or, if you are changing the node corresponding to the rule's matcher, you can // use the single-argument override of \c change: // \code -// change(cat("different_expr")) +// changeTo(cat("different_expr")) // \endcode struct ASTEdit { RangeSelector TargetRange; @@ -141,7 +141,7 @@ /// could write: /// \code /// auto R = makeRule(callExpr(callee(functionDecl(hasName("foo")))), -/// change(text("bar()"))); +/// changeTo(cat("bar()"))); /// AddInclude(R, "path/to/bar_header.h"); /// AddInclude(R, "vector", IncludeFormat::Angled); /// \endcode @@ -190,28 +190,36 @@ RewriteRule applyFirst(ArrayRef Rules); /// Replaces a portion of the source text with \p Replacement. -ASTEdit change(RangeSelector Target, TextGenerator Replacement); +ASTEdit changeTo(RangeSelector Target, TextGenerator Replacement); +/// DEPRECATED: use \c changeTo. +inline ASTEdit change(RangeSelector Target, TextGenerator Replacement) { + return changeTo(std::move(Target), std::move(Replacement)); +} /// Replaces the entirety of a RewriteRule's match with \p Replacement. For /// example, to replace a function call, one could write: /// \code /// makeRule(callExpr(callee(functionDecl(hasName("foo")))), -/// change(text("bar()"))) +/// changeTo(cat("bar()"))) /// \endcode +inline ASTEdit changeTo(TextGenerator Replacement) { + return changeTo(node(RewriteRule::RootID), std::move(Replacement)); +} +/// DEPRECATED: use \c changeTo. inline ASTEdit change(TextGenerator Replacement) { - return change(node(RewriteRule::RootID), std::move(Replacement)); + return changeTo(std::move(Replacement)); } /// Inserts \p Replacement before \p S, leaving the source selected by \S /// unchanged. inline ASTEdit insertBefore(RangeSelector S, TextGenerator Replacement) { - return change(before(std::move(S)), std::move(Replacement)); + return changeTo(before(std::move(S)), std::move(Replacement)); } /// Inserts \p Replacement after \p S, leaving the source selected by \S /// unchanged. inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) { - return change(after(std::move(S)), std::move(Replacement)); + return changeTo(after(std::move(S)), std::move(Replacement)); } /// Removes the source selected by \p S. diff --git a/clang/include/clang/Tooling/Transformer/Stencil.h b/clang/include/clang/Tooling/Transformer/Stencil.h --- a/clang/include/clang/Tooling/Transformer/Stencil.h +++ b/clang/include/clang/Tooling/Transformer/Stencil.h @@ -108,9 +108,11 @@ // Functions for conveniently building stencils. // +/// DEPRECATED: Use `cat` instead. /// \returns exactly the text provided. Stencil text(llvm::StringRef Text); +/// DEPRECATED: Use `cat` instead. /// \returns the source corresponding to the selected range. Stencil selection(RangeSelector Selector); diff --git a/clang/unittests/Tooling/TransformerTest.cpp b/clang/unittests/Tooling/TransformerTest.cpp --- a/clang/unittests/Tooling/TransformerTest.cpp +++ b/clang/unittests/Tooling/TransformerTest.cpp @@ -147,7 +147,7 @@ on(expr(hasType(isOrPointsTo(StringType))) .bind(StringExpr)), callee(cxxMethodDecl(hasName("c_str")))))), - change(text("REPLACED")), text("Use size() method directly on string.")); + changeTo(cat("REPLACED")), cat("Use size() method directly on string.")); return R; } @@ -171,7 +171,7 @@ hasName("proto::ProtoCommandLineFlag")))) .bind(Flag)), unless(callee(cxxMethodDecl(hasName("GetProto"))))), - change(node(Flag), text("EXPR"))); + changeTo(node(Flag), cat("EXPR"))); std::string Input = R"cc( proto::ProtoCommandLineFlag flag; @@ -189,7 +189,7 @@ TEST_F(TransformerTest, AddIncludeQuoted) { RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f")))), - change(text("other()"))); + changeTo(cat("other()"))); addInclude(Rule, "clang/OtherLib.h"); std::string Input = R"cc( @@ -207,7 +207,7 @@ TEST_F(TransformerTest, AddIncludeAngled) { RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f")))), - change(text("other()"))); + changeTo(cat("other()"))); addInclude(Rule, "clang/OtherLib.h", transformer::IncludeFormat::Angled); std::string Input = R"cc( @@ -226,7 +226,7 @@ TEST_F(TransformerTest, NodePartNameNamedDecl) { StringRef Fun = "fun"; RewriteRule Rule = makeRule(functionDecl(hasName("bad")).bind(Fun), - change(name(Fun), text("good"))); + changeTo(name(Fun), cat("good"))); std::string Input = R"cc( int bad(int x); @@ -258,7 +258,7 @@ StringRef Ref = "ref"; testRule(makeRule(declRefExpr(to(functionDecl(hasName("bad")))).bind(Ref), - change(name(Ref), text("good"))), + changeTo(name(Ref), cat("good"))), Input, Expected); } @@ -276,7 +276,7 @@ StringRef Ref = "ref"; Transformer T(makeRule(declRefExpr(to(functionDecl())).bind(Ref), - change(name(Ref), text("good"))), + changeTo(name(Ref), cat("good"))), consumer()); T.registerMatchers(&MatchFinder); EXPECT_FALSE(rewrite(Input)); @@ -285,7 +285,7 @@ TEST_F(TransformerTest, NodePartMember) { StringRef E = "expr"; RewriteRule Rule = makeRule(memberExpr(member(hasName("bad"))).bind(E), - change(member(E), text("good"))); + changeTo(member(E), cat("good"))); std::string Input = R"cc( struct S { @@ -338,7 +338,7 @@ )cc"; StringRef E = "expr"; - testRule(makeRule(memberExpr().bind(E), change(member(E), text("good"))), + testRule(makeRule(memberExpr().bind(E), changeTo(member(E), cat("good"))), Input, Expected); } @@ -370,7 +370,7 @@ StringRef MemExpr = "member"; testRule(makeRule(memberExpr().bind(MemExpr), - change(member(MemExpr), text("good"))), + changeTo(member(MemExpr), cat("good"))), Input, Expected); } @@ -389,7 +389,7 @@ StringRef Ret = "return"; testRule(makeRule(returnStmt().bind(Ret), - insertBefore(statement(Ret), text("int y = 3;"))), + insertBefore(statement(Ret), cat("int y = 3;"))), Input, Expected); } @@ -410,7 +410,7 @@ StringRef Decl = "decl"; testRule(makeRule(declStmt().bind(Decl), - insertAfter(statement(Decl), text("int y = 3;"))), + insertAfter(statement(Decl), cat("int y = 3;"))), Input, Expected); } @@ -451,9 +451,9 @@ StringRef C = "C", T = "T", E = "E"; testRule(makeRule(ifStmt(hasCondition(expr().bind(C)), hasThen(stmt().bind(T)), hasElse(stmt().bind(E))), - {change(node(C), text("true")), - change(statement(T), text("{ /* then */ }")), - change(statement(E), text("{ /* else */ }"))}), + {changeTo(node(C), cat("true")), + changeTo(statement(T), cat("{ /* then */ }")), + changeTo(statement(E), cat("{ /* else */ }"))}), Input, Expected); } @@ -464,7 +464,7 @@ hasName("proto::ProtoCommandLineFlag")))) .bind(Flag)), unless(callee(cxxMethodDecl(hasName("GetProto"))))), - change(node(Flag), text("PROTO"))); + changeTo(node(Flag), cat("PROTO"))); std::string Input = R"cc( proto::ProtoCommandLineFlag flag; @@ -498,10 +498,10 @@ RewriteRule ReplaceF1 = makeRule(callExpr(callee(functionDecl(hasName("f1")))), - change(text("REPLACE_F1"))); + changeTo(cat("REPLACE_F1"))); RewriteRule ReplaceF1OrF2 = makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))), - change(text("REPLACE_F1_OR_F2"))); + changeTo(cat("REPLACE_F1_OR_F2"))); testRule(applyFirst({ReplaceF1, ReplaceF1OrF2}), Input, Expected); } @@ -523,10 +523,10 @@ RewriteRule ReplaceF1 = makeRule(callExpr(callee(functionDecl(hasName("f1")))), - change(text("REPLACE_F1"))); + changeTo(cat("REPLACE_F1"))); RewriteRule ReplaceF1OrF2 = makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))), - change(text("REPLACE_F1_OR_F2"))); + changeTo(cat("REPLACE_F1_OR_F2"))); testRule(applyFirst({ReplaceF1OrF2, ReplaceF1}), Input, Expected); } @@ -551,12 +551,12 @@ RewriteRule ReplaceF1 = makeRule(callExpr(callee(functionDecl(hasName("f1")))), - change(text("REPLACE_F1"))); + changeTo(cat("REPLACE_F1"))); RewriteRule ReplaceF1OrF2 = makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))), - change(text("REPLACE_F1_OR_F2"))); + changeTo(cat("REPLACE_F1_OR_F2"))); RewriteRule DeclRule = makeRule(functionDecl(hasName("f2")).bind("fun"), - change(name("fun"), text("DECL_RULE"))); + changeTo(name("fun"), cat("DECL_RULE"))); RewriteRule Rule = applyFirst({ReplaceF1, DeclRule, ReplaceF1OrF2}); EXPECT_EQ(transformer::detail::buildMatchers(Rule).size(), 2UL); @@ -576,8 +576,9 @@ -> llvm::Expected { return llvm::createStringError(llvm::errc::invalid_argument, "ERROR"); }; - Transformer T(makeRule(binaryOperator().bind(O), change(node(O), AlwaysFail)), - consumer()); + Transformer T( + makeRule(binaryOperator().bind(O), changeTo(node(O), AlwaysFail)), + consumer()); T.registerMatchers(&MatchFinder); EXPECT_FALSE(rewrite(Input)); EXPECT_THAT(Changes, IsEmpty()); @@ -590,8 +591,8 @@ // Try to change the whole binary-operator expression AND one its operands: StringRef O = "O", L = "L"; Transformer T(makeRule(binaryOperator(hasLHS(expr().bind(L))).bind(O), - {change(node(O), text("DELETE_OP")), - change(node(L), text("DELETE_LHS"))}), + {changeTo(node(O), cat("DELETE_OP")), + changeTo(node(L), cat("DELETE_LHS"))}), consumer()); T.registerMatchers(&MatchFinder); EXPECT_FALSE(rewrite(Input)); @@ -604,7 +605,7 @@ std::string Input = "int conflictOneRule() { return -7; }"; // Try to change the whole binary-operator expression AND one its operands: StringRef E = "E"; - Transformer T(makeRule(expr().bind(E), change(node(E), text("DELETE_EXPR"))), + Transformer T(makeRule(expr().bind(E), changeTo(node(E), cat("DELETE_EXPR"))), consumer()); T.registerMatchers(&MatchFinder); // The rewrite process fails because the changes conflict with each other... @@ -618,7 +619,7 @@ // Syntax error in the function body: std::string Input = "void errorOccurred() { 3 }"; Transformer T(makeRule(functionDecl(hasName("errorOccurred")), - change(text("DELETED;"))), + changeTo(cat("DELETED;"))), consumer()); T.registerMatchers(&MatchFinder); // The rewrite process itself fails... @@ -642,7 +643,7 @@ StringRef zero = "zero"; RewriteRule R = makeRule(integerLiteral(equals(0)).bind(zero), - change(node(zero), text("999"))); + changeTo(node(zero), cat("999"))); testRule(R, Input, Expected); } @@ -722,7 +723,7 @@ int f() { return PLUS(LIT, LIT); } )cc"; - testRule(makeRule(integerLiteral(), change(text("LIT"))), Input, Expected); + testRule(makeRule(integerLiteral(), changeTo(cat("LIT"))), Input, Expected); } // Tests case where the rule's match spans both source from the macro and its @@ -739,7 +740,7 @@ StringRef E = "expr"; testRule(makeRule(binaryOperator(hasLHS(expr().bind(E))), - change(node(E), text("LIT"))), + changeTo(node(E), cat("LIT"))), Input, Expected); } @@ -757,7 +758,7 @@ StringRef E = "expr"; testRule(makeRule(binaryOperator(hasRHS(expr().bind(E))), - change(node(E), text("LIT"))), + changeTo(node(E), cat("LIT"))), Input, Expected); } @@ -772,7 +773,7 @@ StringRef zero = "zero"; RewriteRule R = makeRule(integerLiteral(equals(0)).bind(zero), - change(node(zero), text("0"))); + changeTo(node(zero), cat("0"))); testRule(R, Input, Input); } @@ -794,11 +795,11 @@ // Verifies that `Type` and `QualType` are not allowed as top-level matchers in // rules. TEST(TransformerDeathTest, OrderedRuleTypes) { - RewriteRule QualTypeRule = makeRule(qualType(), change(text("Q"))); + RewriteRule QualTypeRule = makeRule(qualType(), changeTo(cat("Q"))); EXPECT_DEATH(transformer::detail::buildMatchers(QualTypeRule), "Matcher must be.*node matcher"); - RewriteRule TypeRule = makeRule(arrayType(), change(text("T"))); + RewriteRule TypeRule = makeRule(arrayType(), changeTo(cat("T"))); EXPECT_DEATH(transformer::detail::buildMatchers(TypeRule), "Matcher must be.*node matcher"); }