1 //===- unittest/Tooling/TransformerTest.cpp -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "clang/Tooling/Transformer/Transformer.h"
10 #include "clang/ASTMatchers/ASTMatchers.h"
11 #include "clang/Tooling/Tooling.h"
12 #include "clang/Tooling/Transformer/RangeSelector.h"
13 #include "clang/Tooling/Transformer/RewriteRule.h"
14 #include "clang/Tooling/Transformer/Stencil.h"
15 #include "llvm/Support/Errc.h"
16 #include "llvm/Support/Error.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19 
20 using namespace clang;
21 using namespace tooling;
22 using namespace ast_matchers;
23 namespace {
24 using ::clang::transformer::addInclude;
25 using ::clang::transformer::applyFirst;
26 using ::clang::transformer::before;
27 using ::clang::transformer::cat;
28 using ::clang::transformer::changeTo;
29 using ::clang::transformer::editList;
30 using ::clang::transformer::makeRule;
31 using ::clang::transformer::member;
32 using ::clang::transformer::name;
33 using ::clang::transformer::node;
34 using ::clang::transformer::remove;
35 using ::clang::transformer::rewriteDescendants;
36 using ::clang::transformer::RewriteRule;
37 using ::clang::transformer::statement;
38 using ::testing::ElementsAre;
39 using ::testing::IsEmpty;
40 using ::testing::ResultOf;
41 using ::testing::UnorderedElementsAre;
42 
43 constexpr char KHeaderContents[] = R"cc(
44   struct string {
45     string(const char*);
46     char* c_str();
47     int size();
48   };
49   int strlen(const char*);
50 
51   namespace proto {
52   struct PCFProto {
53     int foo();
54   };
55   struct ProtoCommandLineFlag : PCFProto {
56     PCFProto& GetProto();
57   };
58   }  // namespace proto
59   class Logger {};
60   void operator<<(Logger& l, string msg);
61   Logger& log(int level);
62 )cc";
63 
64 static ast_matchers::internal::Matcher<clang::QualType>
65 isOrPointsTo(const clang::ast_matchers::DeclarationMatcher &TypeMatcher) {
66   return anyOf(hasDeclaration(TypeMatcher), pointsTo(TypeMatcher));
67 }
68 
69 static std::string format(StringRef Code) {
70   const std::vector<Range> Ranges(1, Range(0, Code.size()));
71   auto Style = format::getLLVMStyle();
72   const auto Replacements = format::reformat(Style, Code, Ranges);
73   auto Formatted = applyAllReplacements(Code, Replacements);
74   if (!Formatted) {
75     ADD_FAILURE() << "Could not format code: "
76                   << llvm::toString(Formatted.takeError());
77     return std::string();
78   }
79   return *Formatted;
80 }
81 
82 static void compareSnippets(StringRef Expected,
83                      const llvm::Optional<std::string> &MaybeActual) {
84   ASSERT_TRUE(MaybeActual) << "Rewrite failed. Expecting: " << Expected;
85   auto Actual = *MaybeActual;
86   std::string HL = "#include \"header.h\"\n";
87   auto I = Actual.find(HL);
88   if (I != std::string::npos)
89     Actual.erase(I, HL.size());
90   EXPECT_EQ(format(Expected), format(Actual));
91 }
92 
93 // FIXME: consider separating this class into its own file(s).
94 class ClangRefactoringTestBase : public testing::Test {
95 protected:
96   void appendToHeader(StringRef S) { FileContents[0].second += S; }
97 
98   void addFile(StringRef Filename, StringRef Content) {
99     FileContents.emplace_back(std::string(Filename), std::string(Content));
100   }
101 
102   llvm::Optional<std::string> rewrite(StringRef Input) {
103     std::string Code = ("#include \"header.h\"\n" + Input).str();
104     auto Factory = newFrontendActionFactory(&MatchFinder);
105     if (!runToolOnCodeWithArgs(
106             Factory->create(), Code, std::vector<std::string>(), "input.cc",
107             "clang-tool", std::make_shared<PCHContainerOperations>(),
108             FileContents)) {
109       llvm::errs() << "Running tool failed.\n";
110       return None;
111     }
112     if (ErrorCount != 0) {
113       llvm::errs() << "Generating changes failed.\n";
114       return None;
115     }
116     auto ChangedCode =
117         applyAtomicChanges("input.cc", Code, Changes, ApplyChangesSpec());
118     if (!ChangedCode) {
119       llvm::errs() << "Applying changes failed: "
120                    << llvm::toString(ChangedCode.takeError()) << "\n";
121       return None;
122     }
123     return *ChangedCode;
124   }
125 
126   Transformer::ChangeSetConsumer consumer() {
127     return [this](Expected<MutableArrayRef<AtomicChange>> C) {
128       if (C) {
129         Changes.insert(Changes.end(), std::make_move_iterator(C->begin()),
130                        std::make_move_iterator(C->end()));
131       } else {
132         // FIXME: stash this error rather then printing.
133         llvm::errs() << "Error generating changes: "
134                      << llvm::toString(C.takeError()) << "\n";
135         ++ErrorCount;
136       }
137     };
138   }
139 
140   template <typename R>
141   void testRule(R Rule, StringRef Input, StringRef Expected) {
142     Transformers.push_back(
143         std::make_unique<Transformer>(std::move(Rule), consumer()));
144     Transformers.back()->registerMatchers(&MatchFinder);
145     compareSnippets(Expected, rewrite(Input));
146   }
147 
148   template <typename R> void testRuleFailure(R Rule, StringRef Input) {
149     Transformers.push_back(
150         std::make_unique<Transformer>(std::move(Rule), consumer()));
151     Transformers.back()->registerMatchers(&MatchFinder);
152     ASSERT_FALSE(rewrite(Input)) << "Expected failure to rewrite code";
153   }
154 
155   // Transformers are referenced by MatchFinder.
156   std::vector<std::unique_ptr<Transformer>> Transformers;
157   clang::ast_matchers::MatchFinder MatchFinder;
158   // Records whether any errors occurred in individual changes.
159   int ErrorCount = 0;
160   AtomicChanges Changes;
161 
162 private:
163   FileContentMappings FileContents = {{"header.h", ""}};
164 };
165 
166 class TransformerTest : public ClangRefactoringTestBase {
167 protected:
168   TransformerTest() { appendToHeader(KHeaderContents); }
169 };
170 
171 // Given string s, change strlen($s.c_str()) to REPLACED.
172 static RewriteRule ruleStrlenSize() {
173   StringRef StringExpr = "strexpr";
174   auto StringType = namedDecl(hasAnyName("::basic_string", "::string"));
175   auto R = makeRule(
176       callExpr(callee(functionDecl(hasName("strlen"))),
177                hasArgument(0, cxxMemberCallExpr(
178                                   on(expr(hasType(isOrPointsTo(StringType)))
179                                          .bind(StringExpr)),
180                                   callee(cxxMethodDecl(hasName("c_str")))))),
181       changeTo(cat("REPLACED")), cat("Use size() method directly on string."));
182   return R;
183 }
184 
185 TEST_F(TransformerTest, StrlenSize) {
186   std::string Input = "int f(string s) { return strlen(s.c_str()); }";
187   std::string Expected = "int f(string s) { return REPLACED; }";
188   testRule(ruleStrlenSize(), Input, Expected);
189 }
190 
191 // Tests that no change is applied when a match is not expected.
192 TEST_F(TransformerTest, NoMatch) {
193   std::string Input = "int f(string s) { return s.size(); }";
194   testRule(ruleStrlenSize(), Input, Input);
195 }
196 
197 // Tests replacing an expression.
198 TEST_F(TransformerTest, Flag) {
199   StringRef Flag = "flag";
200   RewriteRule Rule = makeRule(
201       cxxMemberCallExpr(on(expr(hasType(cxxRecordDecl(
202                                     hasName("proto::ProtoCommandLineFlag"))))
203                                .bind(Flag)),
204                         unless(callee(cxxMethodDecl(hasName("GetProto"))))),
205       changeTo(node(std::string(Flag)), cat("EXPR")));
206 
207   std::string Input = R"cc(
208     proto::ProtoCommandLineFlag flag;
209     int x = flag.foo();
210     int y = flag.GetProto().foo();
211   )cc";
212   std::string Expected = R"cc(
213     proto::ProtoCommandLineFlag flag;
214     int x = EXPR.foo();
215     int y = flag.GetProto().foo();
216   )cc";
217 
218   testRule(std::move(Rule), Input, Expected);
219 }
220 
221 TEST_F(TransformerTest, AddIncludeQuoted) {
222   RewriteRule Rule =
223       makeRule(callExpr(callee(functionDecl(hasName("f")))),
224                {addInclude("clang/OtherLib.h"), changeTo(cat("other()"))});
225 
226   std::string Input = R"cc(
227     int f(int x);
228     int h(int x) { return f(x); }
229   )cc";
230   std::string Expected = R"cc(#include "clang/OtherLib.h"
231 
232     int f(int x);
233     int h(int x) { return other(); }
234   )cc";
235 
236   testRule(Rule, Input, Expected);
237 }
238 
239 TEST_F(TransformerTest, AddIncludeAngled) {
240   RewriteRule Rule = makeRule(
241       callExpr(callee(functionDecl(hasName("f")))),
242       {addInclude("clang/OtherLib.h", transformer::IncludeFormat::Angled),
243        changeTo(cat("other()"))});
244 
245   std::string Input = R"cc(
246     int f(int x);
247     int h(int x) { return f(x); }
248   )cc";
249   std::string Expected = R"cc(#include <clang/OtherLib.h>
250 
251     int f(int x);
252     int h(int x) { return other(); }
253   )cc";
254 
255   testRule(Rule, Input, Expected);
256 }
257 
258 TEST_F(TransformerTest, AddIncludeQuotedForRule) {
259   RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f")))),
260                               changeTo(cat("other()")));
261   addInclude(Rule, "clang/OtherLib.h");
262 
263   std::string Input = R"cc(
264     int f(int x);
265     int h(int x) { return f(x); }
266   )cc";
267   std::string Expected = R"cc(#include "clang/OtherLib.h"
268 
269     int f(int x);
270     int h(int x) { return other(); }
271   )cc";
272 
273   testRule(Rule, Input, Expected);
274 }
275 
276 TEST_F(TransformerTest, AddIncludeAngledForRule) {
277   RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f")))),
278                               changeTo(cat("other()")));
279   addInclude(Rule, "clang/OtherLib.h", transformer::IncludeFormat::Angled);
280 
281   std::string Input = R"cc(
282     int f(int x);
283     int h(int x) { return f(x); }
284   )cc";
285   std::string Expected = R"cc(#include <clang/OtherLib.h>
286 
287     int f(int x);
288     int h(int x) { return other(); }
289   )cc";
290 
291   testRule(Rule, Input, Expected);
292 }
293 
294 TEST_F(TransformerTest, NodePartNameNamedDecl) {
295   StringRef Fun = "fun";
296   RewriteRule Rule = makeRule(functionDecl(hasName("bad")).bind(Fun),
297                               changeTo(name(std::string(Fun)), cat("good")));
298 
299   std::string Input = R"cc(
300     int bad(int x);
301     int bad(int x) { return x * x; }
302   )cc";
303   std::string Expected = R"cc(
304     int good(int x);
305     int good(int x) { return x * x; }
306   )cc";
307 
308   testRule(Rule, Input, Expected);
309 }
310 
311 TEST_F(TransformerTest, NodePartNameDeclRef) {
312   std::string Input = R"cc(
313     template <typename T>
314     T bad(T x) {
315       return x;
316     }
317     int neutral(int x) { return bad<int>(x) * x; }
318   )cc";
319   std::string Expected = R"cc(
320     template <typename T>
321     T bad(T x) {
322       return x;
323     }
324     int neutral(int x) { return good<int>(x) * x; }
325   )cc";
326 
327   StringRef Ref = "ref";
328   testRule(makeRule(declRefExpr(to(functionDecl(hasName("bad")))).bind(Ref),
329                     changeTo(name(std::string(Ref)), cat("good"))),
330            Input, Expected);
331 }
332 
333 TEST_F(TransformerTest, NodePartNameDeclRefFailure) {
334   std::string Input = R"cc(
335     struct Y {
336       int operator*();
337     };
338     int neutral(int x) {
339       Y y;
340       int (Y::*ptr)() = &Y::operator*;
341       return *y + x;
342     }
343   )cc";
344 
345   StringRef Ref = "ref";
346   Transformer T(makeRule(declRefExpr(to(functionDecl())).bind(Ref),
347                          changeTo(name(std::string(Ref)), cat("good"))),
348                 consumer());
349   T.registerMatchers(&MatchFinder);
350   EXPECT_FALSE(rewrite(Input));
351 }
352 
353 TEST_F(TransformerTest, NodePartMember) {
354   StringRef E = "expr";
355   RewriteRule Rule =
356       makeRule(memberExpr(clang::ast_matchers::member(hasName("bad"))).bind(E),
357                changeTo(member(std::string(E)), cat("good")));
358 
359   std::string Input = R"cc(
360     struct S {
361       int bad;
362     };
363     int g() {
364       S s;
365       return s.bad;
366     }
367   )cc";
368   std::string Expected = R"cc(
369     struct S {
370       int bad;
371     };
372     int g() {
373       S s;
374       return s.good;
375     }
376   )cc";
377 
378   testRule(Rule, Input, Expected);
379 }
380 
381 TEST_F(TransformerTest, NodePartMemberQualified) {
382   std::string Input = R"cc(
383     struct S {
384       int bad;
385       int good;
386     };
387     struct T : public S {
388       int bad;
389     };
390     int g() {
391       T t;
392       return t.S::bad;
393     }
394   )cc";
395   std::string Expected = R"cc(
396     struct S {
397       int bad;
398       int good;
399     };
400     struct T : public S {
401       int bad;
402     };
403     int g() {
404       T t;
405       return t.S::good;
406     }
407   )cc";
408 
409   StringRef E = "expr";
410   testRule(makeRule(memberExpr().bind(E),
411                     changeTo(member(std::string(E)), cat("good"))),
412            Input, Expected);
413 }
414 
415 TEST_F(TransformerTest, NodePartMemberMultiToken) {
416   std::string Input = R"cc(
417     struct Y {
418       int operator*();
419       int good();
420       template <typename T> void foo(T t);
421     };
422     int neutral(int x) {
423       Y y;
424       y.template foo<int>(3);
425       return y.operator *();
426     }
427   )cc";
428   std::string Expected = R"cc(
429     struct Y {
430       int operator*();
431       int good();
432       template <typename T> void foo(T t);
433     };
434     int neutral(int x) {
435       Y y;
436       y.template good<int>(3);
437       return y.good();
438     }
439   )cc";
440 
441   StringRef MemExpr = "member";
442   testRule(makeRule(memberExpr().bind(MemExpr),
443                     changeTo(member(std::string(MemExpr)), cat("good"))),
444            Input, Expected);
445 }
446 
447 TEST_F(TransformerTest, NoEdits) {
448   using transformer::noEdits;
449   std::string Input = "int f(int x) { return x; }";
450   testRule(makeRule(returnStmt().bind("return"), noEdits()), Input, Input);
451 }
452 
453 TEST_F(TransformerTest, NoopEdit) {
454   using transformer::node;
455   using transformer::noopEdit;
456   std::string Input = "int f(int x) { return x; }";
457   testRule(makeRule(returnStmt().bind("return"), noopEdit(node("return"))),
458            Input, Input);
459 }
460 
461 TEST_F(TransformerTest, IfBound2Args) {
462   using transformer::ifBound;
463   std::string Input = "int f(int x) { return x; }";
464   std::string Expected = "int f(int x) { CHANGE; }";
465   testRule(makeRule(returnStmt().bind("return"),
466                     ifBound("return", changeTo(cat("CHANGE;")))),
467            Input, Expected);
468 }
469 
470 TEST_F(TransformerTest, IfBound3Args) {
471   using transformer::ifBound;
472   std::string Input = "int f(int x) { return x; }";
473   std::string Expected = "int f(int x) { CHANGE; }";
474   testRule(makeRule(returnStmt().bind("return"),
475                     ifBound("nothing", changeTo(cat("ERROR")),
476                             changeTo(cat("CHANGE;")))),
477            Input, Expected);
478 }
479 
480 TEST_F(TransformerTest, ShrinkTo) {
481   using transformer::shrinkTo;
482   std::string Input = "int f(int x) { return x; }";
483   std::string Expected = "return x;";
484   testRule(makeRule(functionDecl(hasDescendant(returnStmt().bind("return")))
485                         .bind("function"),
486                     shrinkTo(node("function"), node("return"))),
487            Input, Expected);
488 }
489 
490 // Rewrite various Stmts inside a Decl.
491 TEST_F(TransformerTest, RewriteDescendantsDeclChangeStmt) {
492   std::string Input =
493       "int f(int x) { int y = x; { int z = x * x; } return x; }";
494   std::string Expected =
495       "int f(int x) { int y = 3; { int z = 3 * 3; } return 3; }";
496   auto InlineX =
497       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
498   testRule(makeRule(functionDecl(hasName("f")).bind("fun"),
499                     rewriteDescendants("fun", InlineX)),
500            Input, Expected);
501 }
502 
503 // Rewrite various TypeLocs inside a Decl.
504 TEST_F(TransformerTest, RewriteDescendantsDeclChangeTypeLoc) {
505   std::string Input = "int f(int *x) { return *x; }";
506   std::string Expected = "char f(char *x) { return *x; }";
507   auto IntToChar = makeRule(typeLoc(loc(qualType(isInteger(), builtinType()))),
508                             changeTo(cat("char")));
509   testRule(makeRule(functionDecl(hasName("f")).bind("fun"),
510                     rewriteDescendants("fun", IntToChar)),
511            Input, Expected);
512 }
513 
514 TEST_F(TransformerTest, RewriteDescendantsStmt) {
515   // Add an unrelated definition to the header that also has a variable named
516   // "x", to test that the rewrite is limited to the scope we intend.
517   appendToHeader(R"cc(int g(int x) { return x; })cc");
518   std::string Input =
519       "int f(int x) { int y = x; { int z = x * x; } return x; }";
520   std::string Expected =
521       "int f(int x) { int y = 3; { int z = 3 * 3; } return 3; }";
522   auto InlineX =
523       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
524   testRule(makeRule(functionDecl(hasName("f"), hasBody(stmt().bind("body"))),
525                     rewriteDescendants("body", InlineX)),
526            Input, Expected);
527 }
528 
529 TEST_F(TransformerTest, RewriteDescendantsStmtWithAdditionalChange) {
530   std::string Input =
531       "int f(int x) { int y = x; { int z = x * x; } return x; }";
532   std::string Expected =
533       "int newName(int x) { int y = 3; { int z = 3 * 3; } return 3; }";
534   auto InlineX =
535       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
536   testRule(
537       makeRule(
538           functionDecl(hasName("f"), hasBody(stmt().bind("body"))).bind("f"),
539           flatten(changeTo(name("f"), cat("newName")),
540                   rewriteDescendants("body", InlineX))),
541       Input, Expected);
542 }
543 
544 TEST_F(TransformerTest, RewriteDescendantsTypeLoc) {
545   std::string Input = "int f(int *x) { return *x; }";
546   std::string Expected = "int f(char *x) { return *x; }";
547   auto IntToChar =
548       makeRule(typeLoc(loc(qualType(isInteger(), builtinType()))).bind("loc"),
549                changeTo(cat("char")));
550   testRule(
551       makeRule(functionDecl(hasName("f"),
552                             hasParameter(0, varDecl(hasTypeLoc(
553                                                 typeLoc().bind("parmType"))))),
554                rewriteDescendants("parmType", IntToChar)),
555       Input, Expected);
556 }
557 
558 TEST_F(TransformerTest, RewriteDescendantsReferToParentBinding) {
559   std::string Input =
560       "int f(int p) { int y = p; { int z = p * p; } return p; }";
561   std::string Expected =
562       "int f(int p) { int y = 3; { int z = 3 * 3; } return 3; }";
563   std::string VarId = "var";
564   auto InlineVar = makeRule(declRefExpr(to(varDecl(equalsBoundNode(VarId)))),
565                             changeTo(cat("3")));
566   testRule(makeRule(functionDecl(hasName("f"),
567                                  hasParameter(0, varDecl().bind(VarId)))
568                         .bind("fun"),
569                     rewriteDescendants("fun", InlineVar)),
570            Input, Expected);
571 }
572 
573 TEST_F(TransformerTest, RewriteDescendantsUnboundNode) {
574   std::string Input =
575       "int f(int x) { int y = x; { int z = x * x; } return x; }";
576   auto InlineX =
577       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
578   Transformer T(makeRule(functionDecl(hasName("f")),
579                          rewriteDescendants("UNBOUND", InlineX)),
580                 consumer());
581   T.registerMatchers(&MatchFinder);
582   EXPECT_FALSE(rewrite(Input));
583   EXPECT_THAT(Changes, IsEmpty());
584   EXPECT_EQ(ErrorCount, 1);
585 }
586 
587 TEST_F(TransformerTest, RewriteDescendantsInvalidNodeType) {
588   std::string Input =
589       "int f(int x) { int y = x; { int z = x * x; } return x; }";
590   auto IntToChar =
591       makeRule(qualType(isInteger(), builtinType()), changeTo(cat("char")));
592   Transformer T(
593       makeRule(functionDecl(
594                    hasName("f"),
595                    hasParameter(0, varDecl(hasType(qualType().bind("type"))))),
596                rewriteDescendants("type", IntToChar)),
597       consumer());
598   T.registerMatchers(&MatchFinder);
599   EXPECT_FALSE(rewrite(Input));
600   EXPECT_THAT(Changes, IsEmpty());
601   EXPECT_EQ(ErrorCount, 1);
602 }
603 
604 //
605 // We include one test per typed overload. We don't test extensively since that
606 // is already covered by the tests above.
607 //
608 
609 TEST_F(TransformerTest, RewriteDescendantsTypedStmt) {
610   // Add an unrelated definition to the header that also has a variable named
611   // "x", to test that the rewrite is limited to the scope we intend.
612   appendToHeader(R"cc(int g(int x) { return x; })cc");
613   std::string Input =
614       "int f(int x) { int y = x; { int z = x * x; } return x; }";
615   std::string Expected =
616       "int f(int x) { int y = 3; { int z = 3 * 3; } return 3; }";
617   auto InlineX =
618       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
619   testRule(makeRule(functionDecl(hasName("f"), hasBody(stmt().bind("body"))),
620                     [&InlineX](const MatchFinder::MatchResult &R) {
621                       const auto *Node = R.Nodes.getNodeAs<Stmt>("body");
622                       assert(Node != nullptr && "body must be bound");
623                       return transformer::detail::rewriteDescendants(
624                           *Node, InlineX, R);
625                     }),
626            Input, Expected);
627 }
628 
629 TEST_F(TransformerTest, RewriteDescendantsTypedDecl) {
630   std::string Input =
631       "int f(int x) { int y = x; { int z = x * x; } return x; }";
632   std::string Expected =
633       "int f(int x) { int y = 3; { int z = 3 * 3; } return 3; }";
634   auto InlineX =
635       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
636   testRule(makeRule(functionDecl(hasName("f")).bind("fun"),
637                     [&InlineX](const MatchFinder::MatchResult &R) {
638                       const auto *Node = R.Nodes.getNodeAs<Decl>("fun");
639                       assert(Node != nullptr && "fun must be bound");
640                       return transformer::detail::rewriteDescendants(
641                           *Node, InlineX, R);
642                     }),
643            Input, Expected);
644 }
645 
646 TEST_F(TransformerTest, RewriteDescendantsTypedTypeLoc) {
647   std::string Input = "int f(int *x) { return *x; }";
648   std::string Expected = "int f(char *x) { return *x; }";
649   auto IntToChar =
650       makeRule(typeLoc(loc(qualType(isInteger(), builtinType()))).bind("loc"),
651                changeTo(cat("char")));
652   testRule(
653       makeRule(
654           functionDecl(
655               hasName("f"),
656               hasParameter(0, varDecl(hasTypeLoc(typeLoc().bind("parmType"))))),
657           [&IntToChar](const MatchFinder::MatchResult &R) {
658             const auto *Node = R.Nodes.getNodeAs<TypeLoc>("parmType");
659             assert(Node != nullptr && "parmType must be bound");
660             return transformer::detail::rewriteDescendants(*Node, IntToChar, R);
661           }),
662       Input, Expected);
663 }
664 
665 TEST_F(TransformerTest, RewriteDescendantsTypedDynTyped) {
666   // Add an unrelated definition to the header that also has a variable named
667   // "x", to test that the rewrite is limited to the scope we intend.
668   appendToHeader(R"cc(int g(int x) { return x; })cc");
669   std::string Input =
670       "int f(int x) { int y = x; { int z = x * x; } return x; }";
671   std::string Expected =
672       "int f(int x) { int y = 3; { int z = 3 * 3; } return 3; }";
673   auto InlineX =
674       makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
675   testRule(
676       makeRule(functionDecl(hasName("f"), hasBody(stmt().bind("body"))),
677                [&InlineX](const MatchFinder::MatchResult &R) {
678                  auto It = R.Nodes.getMap().find("body");
679                  assert(It != R.Nodes.getMap().end() && "body must be bound");
680                  return transformer::detail::rewriteDescendants(It->second,
681                                                                 InlineX, R);
682                }),
683       Input, Expected);
684 }
685 
686 TEST_F(TransformerTest, InsertBeforeEdit) {
687   std::string Input = R"cc(
688     int f() {
689       return 7;
690     }
691   )cc";
692   std::string Expected = R"cc(
693     int f() {
694       int y = 3;
695       return 7;
696     }
697   )cc";
698 
699   StringRef Ret = "return";
700   testRule(
701       makeRule(returnStmt().bind(Ret),
702                insertBefore(statement(std::string(Ret)), cat("int y = 3;"))),
703       Input, Expected);
704 }
705 
706 TEST_F(TransformerTest, InsertAfterEdit) {
707   std::string Input = R"cc(
708     int f() {
709       int x = 5;
710       return 7;
711     }
712   )cc";
713   std::string Expected = R"cc(
714     int f() {
715       int x = 5;
716       int y = 3;
717       return 7;
718     }
719   )cc";
720 
721   StringRef Decl = "decl";
722   testRule(
723       makeRule(declStmt().bind(Decl),
724                insertAfter(statement(std::string(Decl)), cat("int y = 3;"))),
725       Input, Expected);
726 }
727 
728 TEST_F(TransformerTest, RemoveEdit) {
729   std::string Input = R"cc(
730     int f() {
731       int x = 5;
732       return 7;
733     }
734   )cc";
735   std::string Expected = R"cc(
736     int f() {
737       return 7;
738     }
739   )cc";
740 
741   StringRef Decl = "decl";
742   testRule(
743       makeRule(declStmt().bind(Decl), remove(statement(std::string(Decl)))),
744       Input, Expected);
745 }
746 
747 TEST_F(TransformerTest, WithMetadata) {
748   auto makeMetadata = [](const MatchFinder::MatchResult &R) -> llvm::Any {
749     int N =
750         R.Nodes.getNodeAs<IntegerLiteral>("int")->getValue().getLimitedValue();
751     return N;
752   };
753 
754   std::string Input = R"cc(
755     int f() {
756       int x = 5;
757       return 7;
758     }
759   )cc";
760 
761   Transformer T(
762       makeRule(
763           declStmt(containsDeclaration(0, varDecl(hasInitializer(
764                                               integerLiteral().bind("int")))))
765               .bind("decl"),
766           withMetadata(remove(statement(std::string("decl"))), makeMetadata)),
767       consumer());
768   T.registerMatchers(&MatchFinder);
769   auto Factory = newFrontendActionFactory(&MatchFinder);
770   EXPECT_TRUE(runToolOnCodeWithArgs(
771       Factory->create(), Input, std::vector<std::string>(), "input.cc",
772       "clang-tool", std::make_shared<PCHContainerOperations>(), {}));
773   ASSERT_EQ(Changes.size(), 1u);
774   const llvm::Any &Metadata = Changes[0].getMetadata();
775   ASSERT_TRUE(llvm::any_isa<int>(Metadata));
776   EXPECT_THAT(llvm::any_cast<int>(Metadata), 5);
777 }
778 
779 TEST_F(TransformerTest, MultiChange) {
780   std::string Input = R"cc(
781     void foo() {
782       if (10 > 1.0)
783         log(1) << "oh no!";
784       else
785         log(0) << "ok";
786     }
787   )cc";
788   std::string Expected = R"(
789     void foo() {
790       if (true) { /* then */ }
791       else { /* else */ }
792     }
793   )";
794 
795   StringRef C = "C", T = "T", E = "E";
796   testRule(
797       makeRule(ifStmt(hasCondition(expr().bind(C)), hasThen(stmt().bind(T)),
798                       hasElse(stmt().bind(E))),
799                {changeTo(node(std::string(C)), cat("true")),
800                 changeTo(statement(std::string(T)), cat("{ /* then */ }")),
801                 changeTo(statement(std::string(E)), cat("{ /* else */ }"))}),
802       Input, Expected);
803 }
804 
805 TEST_F(TransformerTest, EditList) {
806   std::string Input = R"cc(
807     void foo() {
808       if (10 > 1.0)
809         log(1) << "oh no!";
810       else
811         log(0) << "ok";
812     }
813   )cc";
814   std::string Expected = R"(
815     void foo() {
816       if (true) { /* then */ }
817       else { /* else */ }
818     }
819   )";
820 
821   StringRef C = "C", T = "T", E = "E";
822   testRule(makeRule(ifStmt(hasCondition(expr().bind(C)),
823                            hasThen(stmt().bind(T)), hasElse(stmt().bind(E))),
824                     editList({changeTo(node(std::string(C)), cat("true")),
825                               changeTo(statement(std::string(T)),
826                                        cat("{ /* then */ }")),
827                               changeTo(statement(std::string(E)),
828                                        cat("{ /* else */ }"))})),
829            Input, Expected);
830 }
831 
832 TEST_F(TransformerTest, Flatten) {
833   std::string Input = R"cc(
834     void foo() {
835       if (10 > 1.0)
836         log(1) << "oh no!";
837       else
838         log(0) << "ok";
839     }
840   )cc";
841   std::string Expected = R"(
842     void foo() {
843       if (true) { /* then */ }
844       else { /* else */ }
845     }
846   )";
847 
848   StringRef C = "C", T = "T", E = "E";
849   testRule(
850       makeRule(
851           ifStmt(hasCondition(expr().bind(C)), hasThen(stmt().bind(T)),
852                  hasElse(stmt().bind(E))),
853           flatten(changeTo(node(std::string(C)), cat("true")),
854                   changeTo(statement(std::string(T)), cat("{ /* then */ }")),
855                   changeTo(statement(std::string(E)), cat("{ /* else */ }")))),
856       Input, Expected);
857 }
858 
859 TEST_F(TransformerTest, FlattenWithMixedArgs) {
860   using clang::transformer::editList;
861   std::string Input = R"cc(
862     void foo() {
863       if (10 > 1.0)
864         log(1) << "oh no!";
865       else
866         log(0) << "ok";
867     }
868   )cc";
869   std::string Expected = R"(
870     void foo() {
871       if (true) { /* then */ }
872       else { /* else */ }
873     }
874   )";
875 
876   StringRef C = "C", T = "T", E = "E";
877   testRule(makeRule(ifStmt(hasCondition(expr().bind(C)),
878                            hasThen(stmt().bind(T)), hasElse(stmt().bind(E))),
879                     flatten(changeTo(node(std::string(C)), cat("true")),
880                             edit(changeTo(statement(std::string(T)),
881                                           cat("{ /* then */ }"))),
882                             editList({changeTo(statement(std::string(E)),
883                                                cat("{ /* else */ }"))}))),
884            Input, Expected);
885 }
886 
887 TEST_F(TransformerTest, OrderedRuleUnrelated) {
888   StringRef Flag = "flag";
889   RewriteRule FlagRule = makeRule(
890       cxxMemberCallExpr(on(expr(hasType(cxxRecordDecl(
891                                     hasName("proto::ProtoCommandLineFlag"))))
892                                .bind(Flag)),
893                         unless(callee(cxxMethodDecl(hasName("GetProto"))))),
894       changeTo(node(std::string(Flag)), cat("PROTO")));
895 
896   std::string Input = R"cc(
897     proto::ProtoCommandLineFlag flag;
898     int x = flag.foo();
899     int y = flag.GetProto().foo();
900     int f(string s) { return strlen(s.c_str()); }
901   )cc";
902   std::string Expected = R"cc(
903     proto::ProtoCommandLineFlag flag;
904     int x = PROTO.foo();
905     int y = flag.GetProto().foo();
906     int f(string s) { return REPLACED; }
907   )cc";
908 
909   testRule(applyFirst({ruleStrlenSize(), FlagRule}), Input, Expected);
910 }
911 
912 TEST_F(TransformerTest, OrderedRuleRelated) {
913   std::string Input = R"cc(
914     void f1();
915     void f2();
916     void call_f1() { f1(); }
917     void call_f2() { f2(); }
918   )cc";
919   std::string Expected = R"cc(
920     void f1();
921     void f2();
922     void call_f1() { REPLACE_F1; }
923     void call_f2() { REPLACE_F1_OR_F2; }
924   )cc";
925 
926   RewriteRule ReplaceF1 =
927       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
928                changeTo(cat("REPLACE_F1")));
929   RewriteRule ReplaceF1OrF2 =
930       makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))),
931                changeTo(cat("REPLACE_F1_OR_F2")));
932   testRule(applyFirst({ReplaceF1, ReplaceF1OrF2}), Input, Expected);
933 }
934 
935 // Change the order of the rules to get a different result. When `ReplaceF1OrF2`
936 // comes first, it applies for both uses, so `ReplaceF1` never applies.
937 TEST_F(TransformerTest, OrderedRuleRelatedSwapped) {
938   std::string Input = R"cc(
939     void f1();
940     void f2();
941     void call_f1() { f1(); }
942     void call_f2() { f2(); }
943   )cc";
944   std::string Expected = R"cc(
945     void f1();
946     void f2();
947     void call_f1() { REPLACE_F1_OR_F2; }
948     void call_f2() { REPLACE_F1_OR_F2; }
949   )cc";
950 
951   RewriteRule ReplaceF1 =
952       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
953                changeTo(cat("REPLACE_F1")));
954   RewriteRule ReplaceF1OrF2 =
955       makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))),
956                changeTo(cat("REPLACE_F1_OR_F2")));
957   testRule(applyFirst({ReplaceF1OrF2, ReplaceF1}), Input, Expected);
958 }
959 
960 // Verify that a set of rules whose matchers have different base kinds works
961 // properly, including that `applyFirst` produces multiple matchers.  We test
962 // two different kinds of rules: Expr and Decl. We place the Decl rule in the
963 // middle to test that `buildMatchers` works even when the kinds aren't grouped
964 // together.
965 TEST_F(TransformerTest, OrderedRuleMultipleKinds) {
966   std::string Input = R"cc(
967     void f1();
968     void f2();
969     void call_f1() { f1(); }
970     void call_f2() { f2(); }
971   )cc";
972   std::string Expected = R"cc(
973     void f1();
974     void DECL_RULE();
975     void call_f1() { REPLACE_F1; }
976     void call_f2() { REPLACE_F1_OR_F2; }
977   )cc";
978 
979   RewriteRule ReplaceF1 =
980       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
981                changeTo(cat("REPLACE_F1")));
982   RewriteRule ReplaceF1OrF2 =
983       makeRule(callExpr(callee(functionDecl(hasAnyName("f1", "f2")))),
984                changeTo(cat("REPLACE_F1_OR_F2")));
985   RewriteRule DeclRule = makeRule(functionDecl(hasName("f2")).bind("fun"),
986                                   changeTo(name("fun"), cat("DECL_RULE")));
987 
988   RewriteRule Rule = applyFirst({ReplaceF1, DeclRule, ReplaceF1OrF2});
989   EXPECT_EQ(transformer::detail::buildMatchers(Rule).size(), 2UL);
990   testRule(Rule, Input, Expected);
991 }
992 
993 // Verifies that a rule with a top-level matcher for an implicit node (like
994 // `implicitCastExpr`) works correctly -- the implicit nodes are not skipped.
995 TEST_F(TransformerTest, OrderedRuleImplicitMatched) {
996   std::string Input = R"cc(
997     void f1();
998     int f2();
999     void call_f1() { f1(); }
1000     float call_f2() { return f2(); }
1001   )cc";
1002   std::string Expected = R"cc(
1003     void f1();
1004     int f2();
1005     void call_f1() { REPLACE_F1; }
1006     float call_f2() { return REPLACE_F2; }
1007   )cc";
1008 
1009   RewriteRule ReplaceF1 =
1010       makeRule(callExpr(callee(functionDecl(hasName("f1")))),
1011                changeTo(cat("REPLACE_F1")));
1012   RewriteRule ReplaceF2 =
1013       makeRule(implicitCastExpr(hasSourceExpression(callExpr())),
1014                changeTo(cat("REPLACE_F2")));
1015   testRule(applyFirst({ReplaceF1, ReplaceF2}), Input, Expected);
1016 }
1017 
1018 //
1019 // Negative tests (where we expect no transformation to occur).
1020 //
1021 
1022 // Tests for a conflict in edits from a single match for a rule.
1023 TEST_F(TransformerTest, TextGeneratorFailure) {
1024   std::string Input = "int conflictOneRule() { return 3 + 7; }";
1025   // Try to change the whole binary-operator expression AND one its operands:
1026   StringRef O = "O";
1027   class AlwaysFail : public transformer::MatchComputation<std::string> {
1028     llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &,
1029                      std::string *) const override {
1030       return llvm::createStringError(llvm::errc::invalid_argument, "ERROR");
1031     }
1032     std::string toString() const override { return "AlwaysFail"; }
1033   };
1034   Transformer T(
1035       makeRule(binaryOperator().bind(O),
1036                changeTo(node(std::string(O)), std::make_shared<AlwaysFail>())),
1037       consumer());
1038   T.registerMatchers(&MatchFinder);
1039   EXPECT_FALSE(rewrite(Input));
1040   EXPECT_THAT(Changes, IsEmpty());
1041   EXPECT_EQ(ErrorCount, 1);
1042 }
1043 
1044 // Tests for a conflict in edits from a single match for a rule.
1045 TEST_F(TransformerTest, OverlappingEditsInRule) {
1046   std::string Input = "int conflictOneRule() { return 3 + 7; }";
1047   // Try to change the whole binary-operator expression AND one its operands:
1048   StringRef O = "O", L = "L";
1049   Transformer T(makeRule(binaryOperator(hasLHS(expr().bind(L))).bind(O),
1050                          {changeTo(node(std::string(O)), cat("DELETE_OP")),
1051                           changeTo(node(std::string(L)), cat("DELETE_LHS"))}),
1052                 consumer());
1053   T.registerMatchers(&MatchFinder);
1054   EXPECT_FALSE(rewrite(Input));
1055   EXPECT_THAT(Changes, IsEmpty());
1056   EXPECT_EQ(ErrorCount, 1);
1057 }
1058 
1059 // Tests for a conflict in edits across multiple matches (of the same rule).
1060 TEST_F(TransformerTest, OverlappingEditsMultipleMatches) {
1061   std::string Input = "int conflictOneRule() { return -7; }";
1062   // Try to change the whole binary-operator expression AND one its operands:
1063   StringRef E = "E";
1064   Transformer T(makeRule(expr().bind(E),
1065                          changeTo(node(std::string(E)), cat("DELETE_EXPR"))),
1066                 consumer());
1067   T.registerMatchers(&MatchFinder);
1068   // The rewrite process fails because the changes conflict with each other...
1069   EXPECT_FALSE(rewrite(Input));
1070   // ... but two changes were produced.
1071   EXPECT_EQ(Changes.size(), 2u);
1072   EXPECT_EQ(ErrorCount, 0);
1073 }
1074 
1075 TEST_F(TransformerTest, ErrorOccurredMatchSkipped) {
1076   // Syntax error in the function body:
1077   std::string Input = "void errorOccurred() { 3 }";
1078   Transformer T(makeRule(functionDecl(hasName("errorOccurred")),
1079                          changeTo(cat("DELETED;"))),
1080                 consumer());
1081   T.registerMatchers(&MatchFinder);
1082   // The rewrite process itself fails...
1083   EXPECT_FALSE(rewrite(Input));
1084   // ... and no changes or errors are produced in the process.
1085   EXPECT_THAT(Changes, IsEmpty());
1086   EXPECT_EQ(ErrorCount, 0);
1087 }
1088 
1089 TEST_F(TransformerTest, ImplicitNodes_ConstructorDecl) {
1090 
1091   std::string OtherStructPrefix = R"cpp(
1092 struct Other {
1093 )cpp";
1094   std::string OtherStructSuffix = "};";
1095 
1096   std::string CopyableStructName = "struct Copyable";
1097   std::string BrokenStructName = "struct explicit Copyable";
1098 
1099   std::string CodeSuffix = R"cpp(
1100 {
1101     Other m_i;
1102     Copyable();
1103 };
1104 )cpp";
1105 
1106   std::string CopyCtor = "Other(const Other&) = default;";
1107   std::string ExplicitCopyCtor = "explicit Other(const Other&) = default;";
1108   std::string BrokenExplicitCopyCtor =
1109       "explicit explicit explicit Other(const Other&) = default;";
1110 
1111   std::string RewriteInput = OtherStructPrefix + CopyCtor + OtherStructSuffix +
1112                              CopyableStructName + CodeSuffix;
1113   std::string ExpectedRewriteOutput = OtherStructPrefix + ExplicitCopyCtor +
1114                                       OtherStructSuffix + CopyableStructName +
1115                                       CodeSuffix;
1116   std::string BrokenRewriteOutput = OtherStructPrefix + BrokenExplicitCopyCtor +
1117                                     OtherStructSuffix + BrokenStructName +
1118                                     CodeSuffix;
1119 
1120   auto MatchedRecord =
1121       cxxConstructorDecl(isCopyConstructor()).bind("copyConstructor");
1122 
1123   auto RewriteRule =
1124       changeTo(before(node("copyConstructor")), cat("explicit "));
1125 
1126   testRule(makeRule(traverse(TK_IgnoreUnlessSpelledInSource, MatchedRecord),
1127                     RewriteRule),
1128            RewriteInput, ExpectedRewriteOutput);
1129 
1130   testRule(makeRule(traverse(TK_AsIs, MatchedRecord), RewriteRule),
1131            RewriteInput, BrokenRewriteOutput);
1132 }
1133 
1134 TEST_F(TransformerTest, ImplicitNodes_RangeFor) {
1135 
1136   std::string CodePrefix = R"cpp(
1137 struct Container
1138 {
1139     int* begin() const;
1140     int* end() const;
1141     int* cbegin() const;
1142     int* cend() const;
1143 };
1144 
1145 void foo()
1146 {
1147   const Container c;
1148 )cpp";
1149 
1150   std::string BeginCallBefore = "  c.begin();";
1151   std::string BeginCallAfter = "  c.cbegin();";
1152 
1153   std::string ForLoop = "for (auto i : c)";
1154   std::string BrokenForLoop = "for (auto i :.cbegin() c)";
1155 
1156   std::string CodeSuffix = R"cpp(
1157   {
1158   }
1159 }
1160 )cpp";
1161 
1162   std::string RewriteInput =
1163       CodePrefix + BeginCallBefore + ForLoop + CodeSuffix;
1164   std::string ExpectedRewriteOutput =
1165       CodePrefix + BeginCallAfter + ForLoop + CodeSuffix;
1166   std::string BrokenRewriteOutput =
1167       CodePrefix + BeginCallAfter + BrokenForLoop + CodeSuffix;
1168 
1169   auto MatchedRecord =
1170       cxxMemberCallExpr(on(expr(hasType(qualType(isConstQualified(),
1171                                                  hasDeclaration(cxxRecordDecl(
1172                                                      hasName("Container"))))))
1173                                .bind("callTarget")),
1174                         callee(cxxMethodDecl(hasName("begin"))))
1175           .bind("constBeginCall");
1176 
1177   auto RewriteRule =
1178       changeTo(node("constBeginCall"), cat(name("callTarget"), ".cbegin()"));
1179 
1180   testRule(makeRule(traverse(TK_IgnoreUnlessSpelledInSource, MatchedRecord),
1181                     RewriteRule),
1182            RewriteInput, ExpectedRewriteOutput);
1183 
1184   testRule(makeRule(traverse(TK_AsIs, MatchedRecord), RewriteRule),
1185            RewriteInput, BrokenRewriteOutput);
1186 }
1187 
1188 TEST_F(TransformerTest, ImplicitNodes_ForStmt) {
1189 
1190   std::string CodePrefix = R"cpp(
1191 struct NonTrivial {
1192     NonTrivial() {}
1193     NonTrivial(NonTrivial&) {}
1194     NonTrivial& operator=(NonTrivial const&) { return *this; }
1195 
1196     ~NonTrivial() {}
1197 };
1198 
1199 struct ContainsArray {
1200     NonTrivial arr[2];
1201     ContainsArray& operator=(ContainsArray const&) = default;
1202 };
1203 
1204 void testIt()
1205 {
1206     ContainsArray ca1;
1207     ContainsArray ca2;
1208     ca2 = ca1;
1209 )cpp";
1210 
1211   auto CodeSuffix = "}";
1212 
1213   auto LoopBody = R"cpp(
1214     {
1215 
1216     }
1217 )cpp";
1218 
1219   auto RawLoop = "for (auto i = 0; i != 5; ++i)";
1220 
1221   auto RangeLoop = "for (auto i : boost::irange(5))";
1222 
1223   // Expect to rewrite the raw loop to the ranged loop.
1224   // This works in TK_IgnoreUnlessSpelledInSource mode, but TK_AsIs
1225   // mode also matches the hidden for loop generated in the copy assignment
1226   // operator of ContainsArray. Transformer then fails to transform the code at
1227   // all.
1228 
1229   auto RewriteInput =
1230       CodePrefix + RawLoop + LoopBody + RawLoop + LoopBody + CodeSuffix;
1231 
1232   auto RewriteOutput =
1233       CodePrefix + RangeLoop + LoopBody + RangeLoop + LoopBody + CodeSuffix;
1234 
1235     auto MatchedLoop = forStmt(
1236         has(declStmt(
1237             hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0))))
1238                               .bind("loopVar")))),
1239         has(binaryOperator(hasOperatorName("!="),
1240                            hasLHS(ignoringImplicit(declRefExpr(
1241                                to(varDecl(equalsBoundNode("loopVar")))))),
1242                            hasRHS(expr().bind("upperBoundExpr")))),
1243         has(unaryOperator(hasOperatorName("++"),
1244                           hasUnaryOperand(declRefExpr(
1245                               to(varDecl(equalsBoundNode("loopVar"))))))
1246                 .bind("incrementOp")));
1247 
1248     auto RewriteRule =
1249         changeTo(transformer::enclose(node("loopVar"), node("incrementOp")),
1250                  cat("auto ", name("loopVar"), " : boost::irange(",
1251                      node("upperBoundExpr"), ")"));
1252 
1253     testRule(makeRule(traverse(TK_IgnoreUnlessSpelledInSource, MatchedLoop),
1254                       RewriteRule),
1255              RewriteInput, RewriteOutput);
1256 
1257     testRuleFailure(makeRule(traverse(TK_AsIs, MatchedLoop), RewriteRule),
1258                     RewriteInput);
1259 
1260 }
1261 
1262 TEST_F(TransformerTest, ImplicitNodes_ForStmt2) {
1263 
1264   std::string CodePrefix = R"cpp(
1265 struct NonTrivial {
1266     NonTrivial() {}
1267     NonTrivial(NonTrivial&) {}
1268     NonTrivial& operator=(NonTrivial const&) { return *this; }
1269 
1270     ~NonTrivial() {}
1271 };
1272 
1273 struct ContainsArray {
1274     NonTrivial arr[2];
1275     ContainsArray& operator=(ContainsArray const&) = default;
1276 };
1277 
1278 void testIt()
1279 {
1280     ContainsArray ca1;
1281     ContainsArray ca2;
1282     ca2 = ca1;
1283 )cpp";
1284 
1285   auto CodeSuffix = "}";
1286 
1287   auto LoopBody = R"cpp(
1288     {
1289 
1290     }
1291 )cpp";
1292 
1293   auto RawLoop = "for (auto i = 0; i != 5; ++i)";
1294 
1295   auto RangeLoop = "for (auto i : boost::irange(5))";
1296 
1297   // Expect to rewrite the raw loop to the ranged loop.
1298   // This works in TK_IgnoreUnlessSpelledInSource mode, but TK_AsIs
1299   // mode also matches the hidden for loop generated in the copy assignment
1300   // operator of ContainsArray. Transformer then fails to transform the code at
1301   // all.
1302 
1303   auto RewriteInput =
1304       CodePrefix + RawLoop + LoopBody + RawLoop + LoopBody + CodeSuffix;
1305 
1306   auto RewriteOutput =
1307       CodePrefix + RangeLoop + LoopBody + RangeLoop + LoopBody + CodeSuffix;
1308     auto MatchedLoop = forStmt(
1309         hasLoopInit(declStmt(
1310             hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0))))
1311                               .bind("loopVar")))),
1312         hasCondition(binaryOperator(hasOperatorName("!="),
1313                                     hasLHS(ignoringImplicit(declRefExpr(to(
1314                                         varDecl(equalsBoundNode("loopVar")))))),
1315                                     hasRHS(expr().bind("upperBoundExpr")))),
1316         hasIncrement(unaryOperator(hasOperatorName("++"),
1317                                    hasUnaryOperand(declRefExpr(to(
1318                                        varDecl(equalsBoundNode("loopVar"))))))
1319                          .bind("incrementOp")));
1320 
1321     auto RewriteRule =
1322         changeTo(transformer::enclose(node("loopVar"), node("incrementOp")),
1323                  cat("auto ", name("loopVar"), " : boost::irange(",
1324                      node("upperBoundExpr"), ")"));
1325 
1326     testRule(makeRule(traverse(TK_IgnoreUnlessSpelledInSource, MatchedLoop),
1327                       RewriteRule),
1328              RewriteInput, RewriteOutput);
1329 
1330     testRuleFailure(makeRule(traverse(TK_AsIs, MatchedLoop), RewriteRule),
1331                     RewriteInput);
1332 
1333 }
1334 
1335 TEST_F(TransformerTest, TemplateInstantiation) {
1336 
1337   std::string NonTemplatesInput = R"cpp(
1338 struct S {
1339   int m_i;
1340 };
1341 )cpp";
1342   std::string NonTemplatesExpected = R"cpp(
1343 struct S {
1344   safe_int m_i;
1345 };
1346 )cpp";
1347 
1348   std::string TemplatesInput = R"cpp(
1349 template<typename T>
1350 struct TemplStruct {
1351   TemplStruct() {}
1352   ~TemplStruct() {}
1353 
1354 private:
1355   T m_t;
1356 };
1357 
1358 void instantiate()
1359 {
1360   TemplStruct<int> ti;
1361 }
1362 )cpp";
1363 
1364   auto MatchedField = fieldDecl(hasType(asString("int"))).bind("theField");
1365 
1366   // Changes the 'int' in 'S', but not the 'T' in 'TemplStruct':
1367   testRule(makeRule(traverse(TK_IgnoreUnlessSpelledInSource, MatchedField),
1368                     changeTo(cat("safe_int ", name("theField"), ";"))),
1369            NonTemplatesInput + TemplatesInput,
1370            NonTemplatesExpected + TemplatesInput);
1371 
1372   // In AsIs mode, template instantiations are modified, which is
1373   // often not desired:
1374 
1375   std::string IncorrectTemplatesExpected = R"cpp(
1376 template<typename T>
1377 struct TemplStruct {
1378   TemplStruct() {}
1379   ~TemplStruct() {}
1380 
1381 private:
1382   safe_int m_t;
1383 };
1384 
1385 void instantiate()
1386 {
1387   TemplStruct<int> ti;
1388 }
1389 )cpp";
1390 
1391   // Changes the 'int' in 'S', and (incorrectly) the 'T' in 'TemplStruct':
1392   testRule(makeRule(traverse(TK_AsIs, MatchedField),
1393                     changeTo(cat("safe_int ", name("theField"), ";"))),
1394 
1395            NonTemplatesInput + TemplatesInput,
1396            NonTemplatesExpected + IncorrectTemplatesExpected);
1397 }
1398 
1399 // Transformation of macro source text when the change encompasses the entirety
1400 // of the expanded text.
1401 TEST_F(TransformerTest, SimpleMacro) {
1402   std::string Input = R"cc(
1403 #define ZERO 0
1404     int f(string s) { return ZERO; }
1405   )cc";
1406   std::string Expected = R"cc(
1407 #define ZERO 0
1408     int f(string s) { return 999; }
1409   )cc";
1410 
1411   StringRef zero = "zero";
1412   RewriteRule R = makeRule(integerLiteral(equals(0)).bind(zero),
1413                            changeTo(node(std::string(zero)), cat("999")));
1414   testRule(R, Input, Expected);
1415 }
1416 
1417 // Transformation of macro source text when the change encompasses the entirety
1418 // of the expanded text, for the case of function-style macros.
1419 TEST_F(TransformerTest, FunctionMacro) {
1420   std::string Input = R"cc(
1421 #define MACRO(str) strlen((str).c_str())
1422     int f(string s) { return MACRO(s); }
1423   )cc";
1424   std::string Expected = R"cc(
1425 #define MACRO(str) strlen((str).c_str())
1426     int f(string s) { return REPLACED; }
1427   )cc";
1428 
1429   testRule(ruleStrlenSize(), Input, Expected);
1430 }
1431 
1432 // Tests that expressions in macro arguments can be rewritten.
1433 TEST_F(TransformerTest, MacroArg) {
1434   std::string Input = R"cc(
1435 #define PLUS(e) e + 1
1436     int f(string s) { return PLUS(strlen(s.c_str())); }
1437   )cc";
1438   std::string Expected = R"cc(
1439 #define PLUS(e) e + 1
1440     int f(string s) { return PLUS(REPLACED); }
1441   )cc";
1442 
1443   testRule(ruleStrlenSize(), Input, Expected);
1444 }
1445 
1446 // Tests that expressions in macro arguments can be rewritten, even when the
1447 // macro call occurs inside another macro's definition.
1448 TEST_F(TransformerTest, MacroArgInMacroDef) {
1449   std::string Input = R"cc(
1450 #define NESTED(e) e
1451 #define MACRO(str) NESTED(strlen((str).c_str()))
1452     int f(string s) { return MACRO(s); }
1453   )cc";
1454   std::string Expected = R"cc(
1455 #define NESTED(e) e
1456 #define MACRO(str) NESTED(strlen((str).c_str()))
1457     int f(string s) { return REPLACED; }
1458   )cc";
1459 
1460   testRule(ruleStrlenSize(), Input, Expected);
1461 }
1462 
1463 // Tests the corner case of the identity macro, specifically that it is
1464 // discarded in the rewrite rather than preserved (like PLUS is preserved in the
1465 // previous test).  This behavior is of dubious value (and marked with a FIXME
1466 // in the code), but we test it to verify (and demonstrate) how this case is
1467 // handled.
1468 TEST_F(TransformerTest, IdentityMacro) {
1469   std::string Input = R"cc(
1470 #define ID(e) e
1471     int f(string s) { return ID(strlen(s.c_str())); }
1472   )cc";
1473   std::string Expected = R"cc(
1474 #define ID(e) e
1475     int f(string s) { return REPLACED; }
1476   )cc";
1477 
1478   testRule(ruleStrlenSize(), Input, Expected);
1479 }
1480 
1481 // Tests that two changes in a single macro expansion do not lead to conflicts
1482 // in applying the changes.
1483 TEST_F(TransformerTest, TwoChangesInOneMacroExpansion) {
1484   std::string Input = R"cc(
1485 #define PLUS(a,b) (a) + (b)
1486     int f() { return PLUS(3, 4); }
1487   )cc";
1488   std::string Expected = R"cc(
1489 #define PLUS(a,b) (a) + (b)
1490     int f() { return PLUS(LIT, LIT); }
1491   )cc";
1492 
1493   testRule(makeRule(integerLiteral(), changeTo(cat("LIT"))), Input, Expected);
1494 }
1495 
1496 // Tests case where the rule's match spans both source from the macro and its
1497 // arg, with the begin location (the "anchor") being the arg.
1498 TEST_F(TransformerTest, MatchSpansMacroTextButChangeDoesNot) {
1499   std::string Input = R"cc(
1500 #define PLUS_ONE(a) a + 1
1501     int f() { return PLUS_ONE(3); }
1502   )cc";
1503   std::string Expected = R"cc(
1504 #define PLUS_ONE(a) a + 1
1505     int f() { return PLUS_ONE(LIT); }
1506   )cc";
1507 
1508   StringRef E = "expr";
1509   testRule(makeRule(binaryOperator(hasLHS(expr().bind(E))),
1510                     changeTo(node(std::string(E)), cat("LIT"))),
1511            Input, Expected);
1512 }
1513 
1514 // Tests case where the rule's match spans both source from the macro and its
1515 // arg, with the begin location (the "anchor") being inside the macro.
1516 TEST_F(TransformerTest, MatchSpansMacroTextButChangeDoesNotAnchoredInMacro) {
1517   std::string Input = R"cc(
1518 #define PLUS_ONE(a) 1 + a
1519     int f() { return PLUS_ONE(3); }
1520   )cc";
1521   std::string Expected = R"cc(
1522 #define PLUS_ONE(a) 1 + a
1523     int f() { return PLUS_ONE(LIT); }
1524   )cc";
1525 
1526   StringRef E = "expr";
1527   testRule(makeRule(binaryOperator(hasRHS(expr().bind(E))),
1528                     changeTo(node(std::string(E)), cat("LIT"))),
1529            Input, Expected);
1530 }
1531 
1532 // No rewrite is applied when the changed text does not encompass the entirety
1533 // of the expanded text. That is, the edit would have to be applied to the
1534 // macro's definition to succeed and editing the expansion point would not
1535 // suffice.
1536 TEST_F(TransformerTest, NoPartialRewriteOMacroExpansion) {
1537   std::string Input = R"cc(
1538 #define ZERO_PLUS 0 + 3
1539     int f(string s) { return ZERO_PLUS; })cc";
1540 
1541   StringRef zero = "zero";
1542   RewriteRule R = makeRule(integerLiteral(equals(0)).bind(zero),
1543                            changeTo(node(std::string(zero)), cat("0")));
1544   testRule(R, Input, Input);
1545 }
1546 
1547 // This test handles the corner case where a macro expands within another macro
1548 // to matching code, but that code is an argument to the nested macro call.  A
1549 // simple check of isMacroArgExpansion() vs. isMacroBodyExpansion() will get
1550 // this wrong, and transform the code.
1551 TEST_F(TransformerTest, NoPartialRewriteOfMacroExpansionForMacroArgs) {
1552   std::string Input = R"cc(
1553 #define NESTED(e) e
1554 #define MACRO(str) 1 + NESTED(strlen((str).c_str()))
1555     int f(string s) { return MACRO(s); }
1556   )cc";
1557 
1558   testRule(ruleStrlenSize(), Input, Input);
1559 }
1560 
1561 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
1562 // Verifies that `Type` and `QualType` are not allowed as top-level matchers in
1563 // rules.
1564 TEST(TransformerDeathTest, OrderedRuleTypes) {
1565   RewriteRule QualTypeRule = makeRule(qualType(), changeTo(cat("Q")));
1566   EXPECT_DEATH(transformer::detail::buildMatchers(QualTypeRule),
1567                "Matcher must be.*node matcher");
1568 
1569   RewriteRule TypeRule = makeRule(arrayType(), changeTo(cat("T")));
1570   EXPECT_DEATH(transformer::detail::buildMatchers(TypeRule),
1571                "Matcher must be.*node matcher");
1572 }
1573 #endif
1574 
1575 // Edits are able to span multiple files; in this case, a header and an
1576 // implementation file.
1577 TEST_F(TransformerTest, MultipleFiles) {
1578   std::string Header = R"cc(void RemoveThisFunction();)cc";
1579   std::string Source = R"cc(#include "input.h"
1580                             void RemoveThisFunction();)cc";
1581   Transformer T(
1582       makeRule(functionDecl(hasName("RemoveThisFunction")), changeTo(cat(""))),
1583       consumer());
1584   T.registerMatchers(&MatchFinder);
1585   auto Factory = newFrontendActionFactory(&MatchFinder);
1586   EXPECT_TRUE(runToolOnCodeWithArgs(
1587       Factory->create(), Source, std::vector<std::string>(), "input.cc",
1588       "clang-tool", std::make_shared<PCHContainerOperations>(),
1589       {{"input.h", Header}}));
1590 
1591   std::sort(Changes.begin(), Changes.end(),
1592             [](const AtomicChange &L, const AtomicChange &R) {
1593               return L.getFilePath() < R.getFilePath();
1594             });
1595 
1596   ASSERT_EQ(Changes[0].getFilePath(), "./input.h");
1597   EXPECT_THAT(Changes[0].getInsertedHeaders(), IsEmpty());
1598   EXPECT_THAT(Changes[0].getRemovedHeaders(), IsEmpty());
1599   llvm::Expected<std::string> UpdatedCode =
1600       clang::tooling::applyAllReplacements(Header,
1601                                            Changes[0].getReplacements());
1602   ASSERT_TRUE(static_cast<bool>(UpdatedCode))
1603       << "Could not update code: " << llvm::toString(UpdatedCode.takeError());
1604   EXPECT_EQ(format(*UpdatedCode), "");
1605 
1606   ASSERT_EQ(Changes[1].getFilePath(), "input.cc");
1607   EXPECT_THAT(Changes[1].getInsertedHeaders(), IsEmpty());
1608   EXPECT_THAT(Changes[1].getRemovedHeaders(), IsEmpty());
1609   UpdatedCode = clang::tooling::applyAllReplacements(
1610       Source, Changes[1].getReplacements());
1611   ASSERT_TRUE(static_cast<bool>(UpdatedCode))
1612       << "Could not update code: " << llvm::toString(UpdatedCode.takeError());
1613   EXPECT_EQ(format(*UpdatedCode), format("#include \"input.h\"\n"));
1614 }
1615 
1616 TEST_F(TransformerTest, AddIncludeMultipleFiles) {
1617   std::string Header = R"cc(void RemoveThisFunction();)cc";
1618   std::string Source = R"cc(#include "input.h"
1619                             void Foo() {RemoveThisFunction();})cc";
1620   Transformer T(
1621       makeRule(callExpr(callee(
1622                    functionDecl(hasName("RemoveThisFunction")).bind("fun"))),
1623                addInclude(node("fun"), "header.h")),
1624       consumer());
1625   T.registerMatchers(&MatchFinder);
1626   auto Factory = newFrontendActionFactory(&MatchFinder);
1627   EXPECT_TRUE(runToolOnCodeWithArgs(
1628       Factory->create(), Source, std::vector<std::string>(), "input.cc",
1629       "clang-tool", std::make_shared<PCHContainerOperations>(),
1630       {{"input.h", Header}}));
1631 
1632   ASSERT_EQ(Changes.size(), 1U);
1633   ASSERT_EQ(Changes[0].getFilePath(), "./input.h");
1634   EXPECT_THAT(Changes[0].getInsertedHeaders(), ElementsAre("header.h"));
1635   EXPECT_THAT(Changes[0].getRemovedHeaders(), IsEmpty());
1636   llvm::Expected<std::string> UpdatedCode =
1637       clang::tooling::applyAllReplacements(Header,
1638                                            Changes[0].getReplacements());
1639   ASSERT_TRUE(static_cast<bool>(UpdatedCode))
1640       << "Could not update code: " << llvm::toString(UpdatedCode.takeError());
1641   EXPECT_EQ(format(*UpdatedCode), format(Header));
1642 }
1643 
1644 // A single change set can span multiple files.
1645 TEST_F(TransformerTest, MultiFileEdit) {
1646   // NB: The fixture is unused for this test, but kept for the test suite name.
1647   std::string Header = R"cc(void Func(int id);)cc";
1648   std::string Source = R"cc(#include "input.h"
1649                             void Caller() {
1650                               int id = 0;
1651                               Func(id);
1652                             })cc";
1653   int ErrorCount = 0;
1654   std::vector<AtomicChanges> ChangeSets;
1655   clang::ast_matchers::MatchFinder MatchFinder;
1656   Transformer T(
1657       makeRule(callExpr(callee(functionDecl(hasName("Func"))),
1658                         forEachArgumentWithParam(expr().bind("arg"),
1659                                                  parmVarDecl().bind("param"))),
1660                editList({changeTo(node("arg"), cat("ARG")),
1661                          changeTo(node("param"), cat("PARAM"))})),
1662       [&](Expected<MutableArrayRef<AtomicChange>> Changes) {
1663         if (Changes)
1664           ChangeSets.push_back(AtomicChanges(Changes->begin(), Changes->end()));
1665         else
1666           ++ErrorCount;
1667       });
1668   T.registerMatchers(&MatchFinder);
1669   auto Factory = newFrontendActionFactory(&MatchFinder);
1670   EXPECT_TRUE(runToolOnCodeWithArgs(
1671       Factory->create(), Source, std::vector<std::string>(), "input.cc",
1672       "clang-tool", std::make_shared<PCHContainerOperations>(),
1673       {{"input.h", Header}}));
1674 
1675   EXPECT_EQ(ErrorCount, 0);
1676   EXPECT_THAT(
1677       ChangeSets,
1678       UnorderedElementsAre(UnorderedElementsAre(
1679           ResultOf([](const AtomicChange &C) { return C.getFilePath(); },
1680                    "input.cc"),
1681           ResultOf([](const AtomicChange &C) { return C.getFilePath(); },
1682                    "./input.h"))));
1683 }
1684 
1685 } // namespace
1686