xref: /llvm-project/clang/unittests/Format/MacroCallReconstructorTest.cpp (revision cac6777ca14e162eb6e97e20da266802846ab953)
1 #include "../../lib/Format/Macros.h"
2 #include "../../lib/Format/UnwrappedLineParser.h"
3 #include "TestLexer.h"
4 #include "llvm/ADT/ArrayRef.h"
5 #include "llvm/ADT/SmallVector.h"
6 #include "llvm/ADT/StringRef.h"
7 
8 #include "gmock/gmock.h"
9 #include "gtest/gtest.h"
10 #include <map>
11 #include <memory>
12 #include <vector>
13 
14 namespace clang {
15 namespace format {
16 namespace {
17 
18 using UnexpandedMap =
19     llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>;
20 
21 // Keeps track of a sequence of macro expansions.
22 //
23 // The expanded tokens are accessible via getTokens(), while a map of macro call
24 // identifier token to unexpanded token stream is accessible via
25 // getUnexpanded().
26 class Expansion {
27 public:
28   Expansion(TestLexer &Lex, MacroExpander &Macros) : Lex(Lex), Macros(Macros) {}
29 
30   // Appends the token stream obtained from expanding the macro Name given
31   // the provided arguments, to be later retrieved with getTokens().
32   // Returns the list of tokens making up the unexpanded macro call.
33   TokenList expand(StringRef Name,
34                    const SmallVector<SmallVector<FormatToken *, 8>, 1> &Args) {
35     return expandInternal(Name, Args);
36   }
37 
38   TokenList expand(StringRef Name) { return expandInternal(Name, {}); }
39 
40   TokenList expand(StringRef Name, const std::vector<std::string> &Args) {
41     return expandInternal(Name, lexArgs(Args));
42   }
43 
44   const UnexpandedMap &getUnexpanded() const { return Unexpanded; }
45 
46   const TokenList &getTokens() const { return Tokens; }
47 
48 private:
49   TokenList expandInternal(
50       StringRef Name,
51       const std::optional<SmallVector<SmallVector<FormatToken *, 8>, 1>>
52           &Args) {
53     auto *ID = Lex.id(Name);
54     auto UnexpandedLine = std::make_unique<UnwrappedLine>();
55     UnexpandedLine->Tokens.push_back(ID);
56     if (Args && !Args->empty()) {
57       UnexpandedLine->Tokens.push_back(Lex.id("("));
58       for (auto I = Args->begin(), E = Args->end(); I != E; ++I) {
59         if (I != Args->begin())
60           UnexpandedLine->Tokens.push_back(Lex.id(","));
61         UnexpandedLine->Tokens.insert(UnexpandedLine->Tokens.end(), I->begin(),
62                                       I->end());
63       }
64       UnexpandedLine->Tokens.push_back(Lex.id(")"));
65     }
66     Unexpanded[ID] = std::move(UnexpandedLine);
67 
68     auto Expanded = Macros.expand(ID, Args);
69     if (Expanded.size() > 1)
70       Expanded = uneof(Expanded);
71     Tokens.append(Expanded.begin(), Expanded.end());
72 
73     TokenList UnexpandedTokens;
74     for (const UnwrappedLineNode &Node : Unexpanded[ID]->Tokens)
75       UnexpandedTokens.push_back(Node.Tok);
76     return UnexpandedTokens;
77   }
78 
79   SmallVector<TokenList, 1> lexArgs(const std::vector<std::string> &Args) {
80     SmallVector<TokenList, 1> Result;
81     for (const auto &Arg : Args)
82       Result.push_back(uneof(Lex.lex(Arg)));
83     return Result;
84   }
85   llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>> Unexpanded;
86   SmallVector<FormatToken *, 8> Tokens;
87   TestLexer &Lex;
88   MacroExpander &Macros;
89 };
90 
91 struct Chunk {
92   Chunk(ArrayRef<FormatToken *> Tokens) : Tokens(Tokens) {}
93   Chunk(ArrayRef<UnwrappedLine> Children) : Children(Children) {}
94   SmallVector<UnwrappedLineNode, 1> Tokens;
95   SmallVector<UnwrappedLine, 0> Children;
96 };
97 
98 // Allows to produce chunks of a token list by typing the code of equal tokens.
99 //
100 // Created from a list of tokens, users call "consume" to get the next chunk
101 // of tokens, checking that they match the written code.
102 struct Matcher {
103   Matcher(const TokenList &Tokens, TestLexer &Lex)
104       : Tokens(Tokens), It(this->Tokens.begin()), Lex(Lex) {}
105 
106   bool tokenMatches(const FormatToken *Left, const FormatToken *Right) {
107     if (Left->getType() == Right->getType() &&
108         Left->TokenText == Right->TokenText) {
109       return true;
110     }
111     llvm::dbgs() << Left->TokenText << " != " << Right->TokenText << "\n";
112     return false;
113   }
114 
115   Chunk consume(StringRef Tokens) {
116     TokenList Result;
117     for (const FormatToken *Token : uneof(Lex.lex(Tokens))) {
118       (void)Token; // Fix unused variable warning when asserts are disabled.
119       assert(tokenMatches(*It, Token));
120       Result.push_back(*It);
121       ++It;
122     }
123     return Chunk(Result);
124   }
125 
126   TokenList Tokens;
127   TokenList::iterator It;
128   TestLexer &Lex;
129 };
130 
131 UnexpandedMap mergeUnexpanded(const UnexpandedMap &M1,
132                               const UnexpandedMap &M2) {
133   UnexpandedMap Result;
134   for (const auto &KV : M1)
135     Result[KV.first] = std::make_unique<UnwrappedLine>(*KV.second);
136   for (const auto &KV : M2)
137     Result[KV.first] = std::make_unique<UnwrappedLine>(*KV.second);
138   return Result;
139 }
140 
141 class MacroCallReconstructorTest : public testing::Test {
142 public:
143   MacroCallReconstructorTest() : Lex(Allocator, Buffers) {}
144 
145   std::unique_ptr<MacroExpander>
146   createExpander(const std::vector<std::string> &MacroDefinitions) {
147     return std::make_unique<MacroExpander>(MacroDefinitions,
148                                            Lex.SourceMgr.get(), Lex.Style,
149                                            Lex.Allocator, Lex.IdentTable);
150   }
151 
152   UnwrappedLine line(ArrayRef<FormatToken *> Tokens, unsigned Level = 0) {
153     UnwrappedLine Result;
154     Result.Level = Level;
155     for (FormatToken *Tok : Tokens)
156       Result.Tokens.push_back(UnwrappedLineNode(Tok));
157     return Result;
158   }
159 
160   UnwrappedLine line(StringRef Text, unsigned Level = 0) {
161     return line({lex(Text)}, Level);
162   }
163 
164   UnwrappedLine line(ArrayRef<Chunk> Chunks, unsigned Level = 0) {
165     UnwrappedLine Result;
166     Result.Level = Level;
167     for (const Chunk &Chunk : Chunks) {
168       Result.Tokens.insert(Result.Tokens.end(), Chunk.Tokens.begin(),
169                            Chunk.Tokens.end());
170       assert(!Result.Tokens.empty());
171       Result.Tokens.back().Children.append(Chunk.Children.begin(),
172                                            Chunk.Children.end());
173     }
174     return Result;
175   }
176 
177   TokenList lex(StringRef Text) { return uneof(Lex.lex(Text)); }
178 
179   Chunk tokens(StringRef Text) { return Chunk(lex(Text)); }
180 
181   Chunk children(ArrayRef<UnwrappedLine> Children) { return Chunk(Children); }
182 
183   llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
184   std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
185   TestLexer Lex;
186 };
187 
188 bool matchesTokens(const UnwrappedLine &L1, const UnwrappedLine &L2) {
189   if (L1.Level != L2.Level)
190     return false;
191   if (L1.Tokens.size() != L2.Tokens.size())
192     return false;
193   for (auto L1It = L1.Tokens.begin(), L2It = L2.Tokens.begin();
194        L1It != L1.Tokens.end(); ++L1It, ++L2It) {
195     if (L1It->Tok != L2It->Tok)
196       return false;
197     if (L1It->Children.size() != L2It->Children.size())
198       return false;
199     for (auto L1ChildIt = L1It->Children.begin(),
200               L2ChildIt = L2It->Children.begin();
201          L1ChildIt != L1It->Children.end(); ++L1ChildIt, ++L2ChildIt) {
202       if (!matchesTokens(*L1ChildIt, *L2ChildIt))
203         return false;
204     }
205   }
206   return true;
207 }
208 MATCHER_P(matchesLine, line, "") { return matchesTokens(arg, line); }
209 
210 TEST_F(MacroCallReconstructorTest, Identifier) {
211   auto Macros = createExpander({"X=x"});
212   Expansion Exp(Lex, *Macros);
213   TokenList Call = Exp.expand("X");
214 
215   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
216   Unexp.addLine(line(Exp.getTokens()));
217   EXPECT_TRUE(Unexp.finished());
218   Matcher U(Call, Lex);
219   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(line(U.consume("X"))));
220 }
221 
222 TEST_F(MacroCallReconstructorTest, EmptyDefinition) {
223   auto Macros = createExpander({"X"});
224   Expansion Exp(Lex, *Macros);
225   TokenList Call = Exp.expand("X");
226 
227   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
228   Unexp.addLine(line(Exp.getTokens()));
229   EXPECT_TRUE(Unexp.finished());
230   Matcher U(Call, Lex);
231   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(line(U.consume("X"))));
232 }
233 
234 TEST_F(MacroCallReconstructorTest, EmptyExpansion) {
235   auto Macros = createExpander({"A(x)=x"});
236   Expansion Exp(Lex, *Macros);
237   TokenList Call = Exp.expand("A", {""});
238 
239   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
240   Unexp.addLine(line(Exp.getTokens()));
241   EXPECT_TRUE(Unexp.finished());
242   Matcher U(Call, Lex);
243   EXPECT_THAT(std::move(Unexp).takeResult(),
244               matchesLine(line(U.consume("A()"))));
245 }
246 
247 TEST_F(MacroCallReconstructorTest, NestedLineWithinCall) {
248   auto Macros = createExpander({"C(a)=class X { a; };"});
249   Expansion Exp(Lex, *Macros);
250   TokenList Call = Exp.expand("C", {"void f()"});
251 
252   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
253   Matcher E(Exp.getTokens(), Lex);
254   Unexp.addLine(line(E.consume("class X {")));
255   EXPECT_FALSE(Unexp.finished());
256   Unexp.addLine(line(E.consume("void f();")));
257   EXPECT_FALSE(Unexp.finished());
258   Unexp.addLine(line(E.consume("};")));
259   EXPECT_TRUE(Unexp.finished());
260   Matcher U(Call, Lex);
261   EXPECT_THAT(std::move(Unexp).takeResult(),
262               matchesLine(line(U.consume("C(void f())"))));
263 }
264 
265 TEST_F(MacroCallReconstructorTest, MultipleLinesInNestedMultiParamsExpansion) {
266   auto Macros = createExpander({"C(a, b)=a b", "B(a)={a}"});
267   Expansion Exp1(Lex, *Macros);
268   TokenList Call1 = Exp1.expand("B", {"b"});
269   Expansion Exp2(Lex, *Macros);
270   TokenList Call2 = Exp2.expand("C", {uneof(Lex.lex("a")), Exp1.getTokens()});
271 
272   UnexpandedMap Unexpanded =
273       mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded());
274   MacroCallReconstructor Unexp(0, Unexpanded);
275   Matcher E(Exp2.getTokens(), Lex);
276   Unexp.addLine(line(E.consume("a")));
277   EXPECT_FALSE(Unexp.finished());
278   Unexp.addLine(line(E.consume("{")));
279   EXPECT_FALSE(Unexp.finished());
280   Unexp.addLine(line(E.consume("b")));
281   EXPECT_FALSE(Unexp.finished());
282   Unexp.addLine(line(E.consume("}")));
283   EXPECT_TRUE(Unexp.finished());
284 
285   Matcher U1(Call1, Lex);
286   auto Middle = U1.consume("B(b)");
287   Matcher U2(Call2, Lex);
288   auto Chunk1 = U2.consume("C(a, ");
289   auto Chunk2 = U2.consume("{ b }");
290   auto Chunk3 = U2.consume(")");
291 
292   EXPECT_THAT(std::move(Unexp).takeResult(),
293               matchesLine(line({Chunk1, Middle, Chunk3})));
294 }
295 
296 TEST_F(MacroCallReconstructorTest, StatementSequence) {
297   auto Macros = createExpander({"SEMI=;"});
298   Expansion Exp(Lex, *Macros);
299   TokenList Call1 = Exp.expand("SEMI");
300   TokenList Call2 = Exp.expand("SEMI");
301   TokenList Call3 = Exp.expand("SEMI");
302 
303   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
304   Matcher E(Exp.getTokens(), Lex);
305   Unexp.addLine(line(E.consume(";")));
306   EXPECT_TRUE(Unexp.finished());
307   Unexp.addLine(line(E.consume(";")));
308   EXPECT_TRUE(Unexp.finished());
309   Unexp.addLine(line(E.consume(";")));
310   EXPECT_TRUE(Unexp.finished());
311   Matcher U1(Call1, Lex);
312   Matcher U2(Call2, Lex);
313   Matcher U3(Call3, Lex);
314   EXPECT_THAT(std::move(Unexp).takeResult(),
315               matchesLine(line(
316                   {U1.consume("SEMI"),
317                    children({line({U2.consume("SEMI"),
318                                    children({line(U3.consume("SEMI"), 2)})},
319                                   1)})})));
320 }
321 
322 TEST_F(MacroCallReconstructorTest, NestedBlock) {
323   auto Macros = createExpander({"ID(x)=x"});
324   // Test: ID({ ID(a *b); })
325   // 1. expand ID(a *b) -> a *b
326   Expansion Exp1(Lex, *Macros);
327   TokenList Call1 = Exp1.expand("ID", {"a *b"});
328   // 2. expand ID({ a *b; })
329   TokenList Arg;
330   Arg.push_back(Lex.id("{"));
331   Arg.append(Exp1.getTokens().begin(), Exp1.getTokens().end());
332   Arg.push_back(Lex.id(";"));
333   Arg.push_back(Lex.id("}"));
334   Expansion Exp2(Lex, *Macros);
335   TokenList Call2 = Exp2.expand("ID", {Arg});
336 
337   // Consume as-if formatted:
338   // {
339   //   a *b;
340   // }
341   UnexpandedMap Unexpanded =
342       mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded());
343   MacroCallReconstructor Unexp(0, Unexpanded);
344   Matcher E(Exp2.getTokens(), Lex);
345   Unexp.addLine(line(E.consume("{")));
346   EXPECT_FALSE(Unexp.finished());
347   Unexp.addLine(line(E.consume("a *b;")));
348   EXPECT_FALSE(Unexp.finished());
349   Unexp.addLine(line(E.consume("}")));
350   EXPECT_TRUE(Unexp.finished());
351 
352   // Expect lines:
353   // ID({
354   //   ID(a *b);
355   // })
356   Matcher U1(Call1, Lex);
357   Matcher U2(Call2, Lex);
358   auto Chunk2Start = U2.consume("ID(");
359   auto Chunk2LBrace = U2.consume("{");
360   U2.consume("a *b");
361   auto Chunk2Mid = U2.consume(";");
362   auto Chunk2RBrace = U2.consume("}");
363   auto Chunk2End = U2.consume(")");
364   auto Chunk1 = U1.consume("ID(a *b)");
365 
366   auto Expected = line({Chunk2Start,
367                         children({
368                             line(Chunk2LBrace, 1),
369                             line({Chunk1, Chunk2Mid}, 1),
370                             line(Chunk2RBrace, 1),
371                         }),
372                         Chunk2End});
373   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
374 }
375 
376 TEST_F(MacroCallReconstructorTest, NestedChildBlocks) {
377   auto Macros = createExpander({"ID(x)=x", "CALL(x)=f([] { x })"});
378   // Test: ID(CALL(CALL(return a * b;)))
379   // 1. expand CALL(return a * b;)
380   Expansion Exp1(Lex, *Macros);
381   TokenList Call1 = Exp1.expand("CALL", {"return a * b;"});
382   // 2. expand CALL(f([] { return a * b; }))
383   Expansion Exp2(Lex, *Macros);
384   TokenList Call2 = Exp2.expand("CALL", {Exp1.getTokens()});
385   // 3. expand ID({ f([] { f([] { return a * b; }) }) })
386   TokenList Arg3;
387   Arg3.push_back(Lex.id("{"));
388   Arg3.append(Exp2.getTokens().begin(), Exp2.getTokens().end());
389   Arg3.push_back(Lex.id("}"));
390   Expansion Exp3(Lex, *Macros);
391   TokenList Call3 = Exp3.expand("ID", {Arg3});
392 
393   // Consume as-if formatted in three unwrapped lines:
394   // 0: {
395   // 1:   f([] {
396   //        f([] {
397   //          return a * b;
398   //        })
399   //      })
400   // 2: }
401   UnexpandedMap Unexpanded = mergeUnexpanded(
402       Exp1.getUnexpanded(),
403       mergeUnexpanded(Exp2.getUnexpanded(), Exp3.getUnexpanded()));
404   MacroCallReconstructor Unexp(0, Unexpanded);
405   Matcher E(Exp3.getTokens(), Lex);
406   Unexp.addLine(line(E.consume("{")));
407   Unexp.addLine(
408       line({E.consume("f([] {"),
409             children({line({E.consume("f([] {"),
410                             children({line(E.consume("return a * b;"), 3)}),
411                             E.consume("})")},
412                            2)}),
413             E.consume("})")},
414            1));
415   Unexp.addLine(line(E.consume("}")));
416   EXPECT_TRUE(Unexp.finished());
417 
418   // Expect lines:
419   // ID(
420   //   {
421   //   CALL(CALL(return a * b;))
422   //   }
423   // )
424   Matcher U1(Call1, Lex);
425   Matcher U2(Call2, Lex);
426   Matcher U3(Call3, Lex);
427   auto Chunk3Start = U3.consume("ID(");
428   auto Chunk3LBrace = U3.consume("{");
429   U3.consume("f([] { f([] { return a * b; }) })");
430   auto Chunk3RBrace = U3.consume("}");
431   auto Chunk3End = U3.consume(")");
432   auto Chunk2Start = U2.consume("CALL(");
433   U2.consume("f([] { return a * b; })");
434   auto Chunk2End = U2.consume(")");
435   auto Chunk1 = U1.consume("CALL(return a * b;)");
436 
437   auto Expected = line({
438       Chunk3Start,
439       children({
440           line(Chunk3LBrace, 1),
441           line(
442               {
443                   Chunk2Start,
444                   Chunk1,
445                   Chunk2End,
446               },
447               2),
448           line(Chunk3RBrace, 1),
449       }),
450       Chunk3End,
451   });
452   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
453 }
454 
455 TEST_F(MacroCallReconstructorTest, NestedChildrenMultipleArguments) {
456   auto Macros = createExpander({"CALL(a, b)=f([] { a; b; })"});
457   Expansion Exp(Lex, *Macros);
458   TokenList Call = Exp.expand("CALL", {std::string("int a"), "int b"});
459 
460   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
461   Matcher E(Exp.getTokens(), Lex);
462   Unexp.addLine(line({
463       E.consume("f([] {"),
464       children({
465           line(E.consume("int a;")),
466           line(E.consume("int b;")),
467       }),
468       E.consume("})"),
469   }));
470   EXPECT_TRUE(Unexp.finished());
471   Matcher U(Call, Lex);
472   auto Expected = line(U.consume("CALL(int a, int b)"));
473   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
474 }
475 
476 TEST_F(MacroCallReconstructorTest, ReverseOrderArgumentsInExpansion) {
477   auto Macros = createExpander({"CALL(a, b)=b + a"});
478   Expansion Exp(Lex, *Macros);
479   TokenList Call = Exp.expand("CALL", {std::string("x"), "y"});
480 
481   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
482   Matcher E(Exp.getTokens(), Lex);
483   Unexp.addLine(line(E.consume("y + x")));
484   EXPECT_TRUE(Unexp.finished());
485   Matcher U(Call, Lex);
486   auto Expected = line(U.consume("CALL(x, y)"));
487   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
488 }
489 
490 TEST_F(MacroCallReconstructorTest, MultipleToplevelUnwrappedLines) {
491   auto Macros = createExpander({"ID(a, b)=a b"});
492   Expansion Exp(Lex, *Macros);
493   TokenList Call = Exp.expand("ID", {std::string("x; x"), "y"});
494 
495   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
496   Matcher E(Exp.getTokens(), Lex);
497   Unexp.addLine(line(E.consume("x;")));
498   Unexp.addLine(line(E.consume("x y")));
499   EXPECT_TRUE(Unexp.finished());
500   Matcher U(Call, Lex);
501   auto Expected = line({
502       U.consume("ID("),
503       children({
504           line(U.consume("x;"), 1),
505           line(U.consume("x"), 1),
506       }),
507       U.consume(", y)"),
508   });
509   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
510 }
511 
512 TEST_F(MacroCallReconstructorTest, NestedCallsMultipleLines) {
513   auto Macros = createExpander({"ID(x)=x"});
514   // Test: ID({ID(a * b);})
515   // 1. expand ID(a * b)
516   Expansion Exp1(Lex, *Macros);
517   TokenList Call1 = Exp1.expand("ID", {"a * b"});
518   // 2. expand ID({ a * b; })
519   Expansion Exp2(Lex, *Macros);
520   TokenList Arg2;
521   Arg2.push_back(Lex.id("{"));
522   Arg2.append(Exp1.getTokens().begin(), Exp1.getTokens().end());
523   Arg2.push_back(Lex.id(";"));
524   Arg2.push_back(Lex.id("}"));
525   TokenList Call2 = Exp2.expand("ID", {Arg2});
526 
527   // Consume as-if formatted in three unwrapped lines:
528   // 0: {
529   // 1:   a * b;
530   // 2: }
531   UnexpandedMap Unexpanded =
532       mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded());
533   MacroCallReconstructor Unexp(0, Unexpanded);
534   Matcher E(Exp2.getTokens(), Lex);
535   Unexp.addLine(line(E.consume("{")));
536   Unexp.addLine(line(E.consume("a * b;")));
537   Unexp.addLine(line(E.consume("}")));
538   EXPECT_TRUE(Unexp.finished());
539 
540   // Expect lines:
541   // ID(
542   //     {
543   //     ID(a * b);
544   //     }
545   // )
546   Matcher U1(Call1, Lex);
547   Matcher U2(Call2, Lex);
548   auto Chunk2Start = U2.consume("ID(");
549   auto Chunk2LBrace = U2.consume("{");
550   U2.consume("a * b");
551   auto Chunk2Semi = U2.consume(";");
552   auto Chunk2RBrace = U2.consume("}");
553   auto Chunk2End = U2.consume(")");
554   auto Chunk1 = U1.consume("ID(a * b)");
555 
556   auto Expected = line({
557       Chunk2Start,
558       children({
559           line({Chunk2LBrace}, 1),
560           line({Chunk1, Chunk2Semi}, 1),
561           line({Chunk2RBrace}, 1),
562       }),
563       Chunk2End,
564   });
565   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
566 }
567 
568 TEST_F(MacroCallReconstructorTest, ParentOutsideMacroCall) {
569   auto Macros = createExpander({"ID(a)=a"});
570   Expansion Exp(Lex, *Macros);
571   TokenList Call = Exp.expand("ID", {std::string("x; y; z;")});
572 
573   auto Prefix = tokens("int a = []() {");
574   auto Postfix = tokens("}();");
575   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
576   Matcher E(Exp.getTokens(), Lex);
577   Unexp.addLine(line({
578       Prefix,
579       children({
580           line(E.consume("x;")),
581           line(E.consume("y;")),
582           line(E.consume("z;")),
583       }),
584       Postfix,
585   }));
586   EXPECT_TRUE(Unexp.finished());
587   Matcher U(Call, Lex);
588   auto Expected = line({
589       Prefix,
590       children({
591           line(
592               {
593                   U.consume("ID("),
594                   children({
595                       line(U.consume("x;"), 2),
596                       line(U.consume("y;"), 2),
597                       line(U.consume("z;"), 2),
598                   }),
599                   U.consume(")"),
600               },
601               1),
602       }),
603       Postfix,
604   });
605   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
606 }
607 
608 TEST_F(MacroCallReconstructorTest, ChildrenSplitAcrossArguments) {
609   auto Macros = createExpander({"CALL(a, b)=f([]() a b)"});
610   Expansion Exp(Lex, *Macros);
611   TokenList Call = Exp.expand("CALL", {std::string("{ a;"), "b; }"});
612 
613   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
614   Matcher E(Exp.getTokens(), Lex);
615   Unexp.addLine(line({
616       E.consume("f([]() {"),
617       children({
618           line(E.consume("a;")),
619           line(E.consume("b;")),
620       }),
621       E.consume("})"),
622   }));
623   EXPECT_TRUE(Unexp.finished());
624   Matcher U(Call, Lex);
625   auto Expected = line({
626       U.consume("CALL({"),
627       children(line(U.consume("a;"), 1)),
628       U.consume(", b; })"),
629   });
630   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
631 }
632 
633 TEST_F(MacroCallReconstructorTest, ChildrenAfterMacroCall) {
634   auto Macros = createExpander({"CALL(a, b)=f([]() a b"});
635   Expansion Exp(Lex, *Macros);
636   TokenList Call = Exp.expand("CALL", {std::string("{ a"), "b"});
637 
638   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
639   Matcher E(Exp.getTokens(), Lex);
640   auto Semi = tokens(";");
641   auto SecondLine = tokens("c d;");
642   auto ThirdLine = tokens("e f;");
643   auto Postfix = tokens("})");
644   Unexp.addLine(line({
645       E.consume("f([]() {"),
646       children({
647           line({E.consume("a b"), Semi}),
648           line(SecondLine),
649           line(ThirdLine),
650       }),
651       Postfix,
652   }));
653   EXPECT_TRUE(Unexp.finished());
654   Matcher U(Call, Lex);
655   auto Expected = line({
656       U.consume("CALL({"),
657       children(line(U.consume("a"), 1)),
658       U.consume(", b)"),
659       Semi,
660       children(line(
661           {
662               SecondLine,
663               children(line(
664                   {
665                       ThirdLine,
666                       Postfix,
667                   },
668                   2)),
669           },
670           1)),
671   });
672   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
673 }
674 
675 TEST_F(MacroCallReconstructorTest, InvalidCodeSplittingBracesAcrossArgs) {
676   auto Macros = createExpander({"M(a, b, c)=(a) (b) c"});
677   Expansion Exp(Lex, *Macros);
678   TokenList Call = Exp.expand("M", {std::string("{"), "x", ""});
679 
680   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
681   Matcher E(Exp.getTokens(), Lex);
682   auto Prefix = tokens("({");
683   Unexp.addLine(line({
684       Prefix,
685       children({
686           line({
687               E.consume("({"),
688               children({line(E.consume(")(x)"))}),
689           }),
690       }),
691   }));
692   EXPECT_TRUE(Unexp.finished());
693   Matcher U(Call, Lex);
694   auto Expected = line({
695       Prefix,
696       children({line(U.consume("M({,x,)"), 1)}),
697   });
698   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
699 }
700 
701 TEST_F(MacroCallReconstructorTest, IndentLevelInExpandedCode) {
702   auto Macros = createExpander({"ID(a)=a"});
703   Expansion Exp(Lex, *Macros);
704   TokenList Call = Exp.expand("ID", {std::string("[] { { x; } }")});
705 
706   MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
707   Matcher E(Exp.getTokens(), Lex);
708   Unexp.addLine(line({
709       E.consume("[] {"),
710       children({
711           line(E.consume("{"), 1),
712           line(E.consume("x;"), 2),
713           line(E.consume("}"), 1),
714       }),
715       E.consume("}"),
716   }));
717   EXPECT_TRUE(Unexp.finished());
718   Matcher U(Call, Lex);
719   auto Expected = line({
720       U.consume("ID([] {"),
721       children({
722           line(U.consume("{"), 1),
723           line(U.consume("x;"), 2),
724           line(U.consume("}"), 1),
725       }),
726       U.consume("})"),
727   });
728   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
729 }
730 
731 } // namespace
732 } // namespace format
733 } // namespace clang
734