ymandel created this revision.
ymandel added a reviewer: gribozavr.
Herald added a project: clang.

This revision generalizes the (deprecated) `clang::tooling::text` combinator to
a `value` combinator, which works for any type. Aside from being more general,
it resolves the naming confict between `clang::tooling::text` and
`clang::transformer::text`, which has a subtly different meaning.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69184

Files:
  clang/include/clang/Tooling/Transformer/MatchConsumer.h
  clang/unittests/Tooling/TransformerTest.cpp

Index: clang/unittests/Tooling/TransformerTest.cpp
===================================================================
--- clang/unittests/Tooling/TransformerTest.cpp
+++ clang/unittests/Tooling/TransformerTest.cpp
@@ -21,6 +21,7 @@
 namespace {
 using ::testing::IsEmpty;
 using transformer::RewriteRule;
+using transformer::value;
 
 constexpr char KHeaderContents[] = R"cc(
   struct string {
@@ -147,7 +148,8 @@
                                   on(expr(hasType(isOrPointsTo(StringType)))
                                          .bind(StringExpr)),
                                   callee(cxxMethodDecl(hasName("c_str")))))),
-      change(text("REPLACED")), text("Use size() method directly on string."));
+      change(value("REPLACED")),
+      value("Use size() method directly on string."));
   return R;
 }
 
@@ -171,7 +173,7 @@
                                     hasName("proto::ProtoCommandLineFlag"))))
                                .bind(Flag)),
                         unless(callee(cxxMethodDecl(hasName("GetProto"))))),
-      change(node(Flag), text("EXPR")));
+      change(node(Flag), value("EXPR")));
 
   std::string Input = R"cc(
     proto::ProtoCommandLineFlag flag;
@@ -189,7 +191,7 @@
 
 TEST_F(TransformerTest, AddIncludeQuoted) {
   RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f")))),
-                              change(text("other()")));
+                              change(value("other()")));
   addInclude(Rule, "clang/OtherLib.h");
 
   std::string Input = R"cc(
@@ -207,7 +209,7 @@
 
 TEST_F(TransformerTest, AddIncludeAngled) {
   RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f")))),
-                              change(text("other()")));
+                              change(value("other()")));
   addInclude(Rule, "clang/OtherLib.h", transformer::IncludeFormat::Angled);
 
   std::string Input = R"cc(
@@ -226,7 +228,7 @@
 TEST_F(TransformerTest, NodePartNameNamedDecl) {
   StringRef Fun = "fun";
   RewriteRule Rule = makeRule(functionDecl(hasName("bad")).bind(Fun),
-                              change(name(Fun), text("good")));
+                              change(name(Fun), value("good")));
 
   std::string Input = R"cc(
     int bad(int x);
@@ -258,7 +260,7 @@
 
   StringRef Ref = "ref";
   testRule(makeRule(declRefExpr(to(functionDecl(hasName("bad")))).bind(Ref),
-                    change(name(Ref), text("good"))),
+                    change(name(Ref), value("good"))),
            Input, Expected);
 }
 
@@ -276,7 +278,7 @@
 
   StringRef Ref = "ref";
   Transformer T(makeRule(declRefExpr(to(functionDecl())).bind(Ref),
-                         change(name(Ref), text("good"))),
+                         change(name(Ref), value("good"))),
                 consumer());
   T.registerMatchers(&MatchFinder);
   EXPECT_FALSE(rewrite(Input));
@@ -285,7 +287,7 @@
 TEST_F(TransformerTest, NodePartMember) {
   StringRef E = "expr";
   RewriteRule Rule = makeRule(memberExpr(member(hasName("bad"))).bind(E),
-                              change(member(E), text("good")));
+                              change(member(E), value("good")));
 
   std::string Input = R"cc(
     struct S {
@@ -338,7 +340,7 @@
   )cc";
 
   StringRef E = "expr";
-  testRule(makeRule(memberExpr().bind(E), change(member(E), text("good"))),
+  testRule(makeRule(memberExpr().bind(E), change(member(E), value("good"))),
            Input, Expected);
 }
 
@@ -370,7 +372,7 @@
 
   StringRef MemExpr = "member";
   testRule(makeRule(memberExpr().bind(MemExpr),
-                    change(member(MemExpr), text("good"))),
+                    change(member(MemExpr), value("good"))),
            Input, Expected);
 }
 
@@ -389,7 +391,7 @@
 
   StringRef Ret = "return";
   testRule(makeRule(returnStmt().bind(Ret),
-                    insertBefore(statement(Ret), text("int y = 3;"))),
+                    insertBefore(statement(Ret), value("int y = 3;"))),
            Input, Expected);
 }
 
@@ -410,7 +412,7 @@
 
   StringRef Decl = "decl";
   testRule(makeRule(declStmt().bind(Decl),
-                    insertAfter(statement(Decl), text("int y = 3;"))),
+                    insertAfter(statement(Decl), value("int y = 3;"))),
            Input, Expected);
 }
 
@@ -451,9 +453,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 */ }"))}),
+                    {change(node(C), value("true")),
+                     change(statement(T), value("{ /* then */ }")),
+                     change(statement(E), value("{ /* else */ }"))}),
            Input, Expected);
 }
 
@@ -464,7 +466,7 @@
                                     hasName("proto::ProtoCommandLineFlag"))))
                                .bind(Flag)),
                         unless(callee(cxxMethodDecl(hasName("GetProto"))))),
-      change(node(Flag), text("PROTO")));
+      change(node(Flag), value("PROTO")));
 
   std::string Input = R"cc(
     proto::ProtoCommandLineFlag flag;
@@ -498,10 +500,10 @@
 
   RewriteRule ReplaceF1 =
       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
-               change(text("REPLACE_F1")));
+               change(value("REPLACE_F1")));
   RewriteRule ReplaceF1OrF2 =
       makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))),
-               change(text("REPLACE_F1_OR_F2")));
+               change(value("REPLACE_F1_OR_F2")));
   testRule(applyFirst({ReplaceF1, ReplaceF1OrF2}), Input, Expected);
 }
 
@@ -523,10 +525,10 @@
 
   RewriteRule ReplaceF1 =
       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
-               change(text("REPLACE_F1")));
+               change(value("REPLACE_F1")));
   RewriteRule ReplaceF1OrF2 =
       makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))),
-               change(text("REPLACE_F1_OR_F2")));
+               change(value("REPLACE_F1_OR_F2")));
   testRule(applyFirst({ReplaceF1OrF2, ReplaceF1}), Input, Expected);
 }
 
@@ -551,12 +553,12 @@
 
   RewriteRule ReplaceF1 =
       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
-               change(text("REPLACE_F1")));
+               change(value("REPLACE_F1")));
   RewriteRule ReplaceF1OrF2 =
       makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))),
-               change(text("REPLACE_F1_OR_F2")));
+               change(value("REPLACE_F1_OR_F2")));
   RewriteRule DeclRule = makeRule(functionDecl(hasName("f2")).bind("fun"),
-                                  change(name("fun"), text("DECL_RULE")));
+                                  change(name("fun"), value("DECL_RULE")));
 
   RewriteRule Rule = applyFirst({ReplaceF1, DeclRule, ReplaceF1OrF2});
   EXPECT_EQ(transformer::detail::buildMatchers(Rule).size(), 2UL);
@@ -590,8 +592,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"))}),
+                         {change(node(O), value("DELETE_OP")),
+                          change(node(L), value("DELETE_LHS"))}),
                 consumer());
   T.registerMatchers(&MatchFinder);
   EXPECT_FALSE(rewrite(Input));
@@ -604,7 +606,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), change(node(E), value("DELETE_EXPR"))),
                 consumer());
   T.registerMatchers(&MatchFinder);
   // The rewrite process fails because the changes conflict with each other...
@@ -618,7 +620,7 @@
   // Syntax error in the function body:
   std::string Input = "void errorOccurred() { 3 }";
   Transformer T(makeRule(functionDecl(hasName("errorOccurred")),
-                         change(text("DELETED;"))),
+                         change(value("DELETED;"))),
                 consumer());
   T.registerMatchers(&MatchFinder);
   // The rewrite process itself fails...
@@ -642,7 +644,7 @@
 
   StringRef zero = "zero";
   RewriteRule R = makeRule(integerLiteral(equals(0)).bind(zero),
-                           change(node(zero), text("999")));
+                           change(node(zero), value("999")));
   testRule(R, Input, Expected);
 }
 
@@ -722,7 +724,7 @@
     int f() { return PLUS(LIT, LIT); }
   )cc";
 
-  testRule(makeRule(integerLiteral(), change(text("LIT"))), Input, Expected);
+  testRule(makeRule(integerLiteral(), change(value("LIT"))), Input, Expected);
 }
 
 // Tests case where the rule's match spans both source from the macro and its
@@ -739,7 +741,7 @@
 
   StringRef E = "expr";
   testRule(makeRule(binaryOperator(hasLHS(expr().bind(E))),
-                    change(node(E), text("LIT"))),
+                    change(node(E), value("LIT"))),
            Input, Expected);
 }
 
@@ -757,7 +759,7 @@
 
   StringRef E = "expr";
   testRule(makeRule(binaryOperator(hasRHS(expr().bind(E))),
-                    change(node(E), text("LIT"))),
+                    change(node(E), value("LIT"))),
            Input, Expected);
 }
 
@@ -772,7 +774,7 @@
 
   StringRef zero = "zero";
   RewriteRule R = makeRule(integerLiteral(equals(0)).bind(zero),
-                           change(node(zero), text("0")));
+                           change(node(zero), value("0")));
   testRule(R, Input, Input);
 }
 
@@ -794,11 +796,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(), change(value("Q")));
   EXPECT_DEATH(transformer::detail::buildMatchers(QualTypeRule),
                "Matcher must be.*node matcher");
 
-  RewriteRule TypeRule = makeRule(arrayType(), change(text("T")));
+  RewriteRule TypeRule = makeRule(arrayType(), change(value("T")));
   EXPECT_DEATH(transformer::detail::buildMatchers(TypeRule),
                "Matcher must be.*node matcher");
 }
Index: clang/include/clang/Tooling/Transformer/MatchConsumer.h
===================================================================
--- clang/include/clang/Tooling/Transformer/MatchConsumer.h
+++ clang/include/clang/Tooling/Transformer/MatchConsumer.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
+#include <type_traits>
 
 namespace clang {
 namespace transformer {
@@ -41,6 +42,13 @@
                                              "Id not bound: " + Id);
 }
 
+/// Constructs a consumer that always returns the fixed value `V`.
+template <typename T> MatchConsumer<typename std::decay<T>::type> value(T V) {
+  return [V](const ast_matchers::MatchFinder::MatchResult &) {
+    return Expected<T>(V);
+  };
+}
+
 /// Chooses between the two consumers, based on whether \p ID is bound in the
 /// match.
 template <typename T>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to