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