1 #include "../../lib/Format/Macros.h"
2 #include "../../lib/Format/UnwrappedLineParser.h"
4 #include "llvm/ADT/ArrayRef.h"
5 #include "llvm/ADT/SmallVector.h"
6 #include "llvm/ADT/StringRef.h"
8 #include "gmock/gmock.h"
9 #include "gtest/gtest.h"
19 llvm::DenseMap
<FormatToken
*, std::unique_ptr
<UnwrappedLine
>>;
21 // Keeps track of a sequence of macro expansions.
23 // The expanded tokens are accessible via getTokens(), while a map of macro call
24 // identifier token to unexpanded token stream is accessible via
28 Expansion(TestLexer
&Lex
, MacroExpander
&Macros
) : Lex(Lex
), Macros(Macros
) {}
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
);
38 TokenList
expand(StringRef Name
) { return expandInternal(Name
, {}); }
40 TokenList
expand(StringRef Name
, const std::vector
<std::string
> &Args
) {
41 return expandInternal(Name
, lexArgs(Args
));
44 const UnexpandedMap
&getUnexpanded() const { return Unexpanded
; }
46 const TokenList
&getTokens() const { return Tokens
; }
49 TokenList
expandInternal(
51 const std::optional
<SmallVector
<SmallVector
<FormatToken
*, 8>, 1>>
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(),
64 UnexpandedLine
->Tokens
.push_back(Lex
.id(")"));
66 Unexpanded
[ID
] = std::move(UnexpandedLine
);
68 auto Expanded
= uneof(Macros
.expand(ID
, Args
));
69 Tokens
.append(Expanded
.begin(), Expanded
.end());
71 TokenList UnexpandedTokens
;
72 for (const UnwrappedLineNode
&Node
: Unexpanded
[ID
]->Tokens
)
73 UnexpandedTokens
.push_back(Node
.Tok
);
74 return UnexpandedTokens
;
77 SmallVector
<TokenList
, 1> lexArgs(const std::vector
<std::string
> &Args
) {
78 SmallVector
<TokenList
, 1> Result
;
79 for (const auto &Arg
: Args
)
80 Result
.push_back(uneof(Lex
.lex(Arg
)));
83 llvm::DenseMap
<FormatToken
*, std::unique_ptr
<UnwrappedLine
>> Unexpanded
;
84 SmallVector
<FormatToken
*, 8> Tokens
;
86 MacroExpander
&Macros
;
90 Chunk(ArrayRef
<FormatToken
*> Tokens
) : Tokens(Tokens
) {}
91 Chunk(ArrayRef
<UnwrappedLine
> Children
) : Children(Children
) {}
92 SmallVector
<UnwrappedLineNode
, 1> Tokens
;
93 SmallVector
<UnwrappedLine
, 0> Children
;
96 // Allows to produce chunks of a token list by typing the code of equal tokens.
98 // Created from a list of tokens, users call "consume" to get the next chunk
99 // of tokens, checking that they match the written code.
101 Matcher(const TokenList
&Tokens
, TestLexer
&Lex
)
102 : Tokens(Tokens
), It(this->Tokens
.begin()), Lex(Lex
) {}
104 bool tokenMatches(const FormatToken
*Left
, const FormatToken
*Right
) {
105 if (Left
->getType() == Right
->getType() &&
106 Left
->TokenText
== Right
->TokenText
) {
109 llvm::dbgs() << Left
->TokenText
<< " != " << Right
->TokenText
<< "\n";
113 Chunk
consume(StringRef Tokens
) {
115 for (const FormatToken
*Token
: uneof(Lex
.lex(Tokens
))) {
116 (void)Token
; // Fix unused variable warning when asserts are disabled.
117 assert(tokenMatches(*It
, Token
));
118 Result
.push_back(*It
);
121 return Chunk(Result
);
125 TokenList::iterator It
;
129 UnexpandedMap
mergeUnexpanded(const UnexpandedMap
&M1
,
130 const UnexpandedMap
&M2
) {
131 UnexpandedMap Result
;
132 for (const auto &KV
: M1
)
133 Result
[KV
.first
] = std::make_unique
<UnwrappedLine
>(*KV
.second
);
134 for (const auto &KV
: M2
)
135 Result
[KV
.first
] = std::make_unique
<UnwrappedLine
>(*KV
.second
);
139 class MacroCallReconstructorTest
: public testing::Test
{
141 MacroCallReconstructorTest() : Lex(Allocator
, Buffers
) {}
143 std::unique_ptr
<MacroExpander
>
144 createExpander(const std::vector
<std::string
> &MacroDefinitions
) {
145 return std::make_unique
<MacroExpander
>(MacroDefinitions
,
146 Lex
.SourceMgr
.get(), Lex
.Style
,
147 Lex
.Allocator
, Lex
.IdentTable
);
150 UnwrappedLine
line(ArrayRef
<FormatToken
*> Tokens
, unsigned Level
= 0) {
151 UnwrappedLine Result
;
152 Result
.Level
= Level
;
153 for (FormatToken
*Tok
: Tokens
)
154 Result
.Tokens
.push_back(UnwrappedLineNode(Tok
));
158 UnwrappedLine
line(StringRef Text
, unsigned Level
= 0) {
159 return line({lex(Text
)}, Level
);
162 UnwrappedLine
line(ArrayRef
<Chunk
> Chunks
, unsigned Level
= 0) {
163 UnwrappedLine Result
;
164 Result
.Level
= Level
;
165 for (const Chunk
&Chunk
: Chunks
) {
166 Result
.Tokens
.insert(Result
.Tokens
.end(), Chunk
.Tokens
.begin(),
168 assert(!Result
.Tokens
.empty());
169 Result
.Tokens
.back().Children
.append(Chunk
.Children
.begin(),
170 Chunk
.Children
.end());
175 TokenList
lex(StringRef Text
) { return uneof(Lex
.lex(Text
)); }
177 Chunk
tokens(StringRef Text
) { return Chunk(lex(Text
)); }
179 Chunk
children(ArrayRef
<UnwrappedLine
> Children
) { return Chunk(Children
); }
181 llvm::SpecificBumpPtrAllocator
<FormatToken
> Allocator
;
182 std::vector
<std::unique_ptr
<llvm::MemoryBuffer
>> Buffers
;
186 bool matchesTokens(const UnwrappedLine
&L1
, const UnwrappedLine
&L2
) {
187 if (L1
.Level
!= L2
.Level
)
189 if (L1
.Tokens
.size() != L2
.Tokens
.size())
191 for (auto L1It
= L1
.Tokens
.begin(), L2It
= L2
.Tokens
.begin();
192 L1It
!= L1
.Tokens
.end(); ++L1It
, ++L2It
) {
193 if (L1It
->Tok
!= L2It
->Tok
)
195 if (L1It
->Children
.size() != L2It
->Children
.size())
197 for (auto L1ChildIt
= L1It
->Children
.begin(),
198 L2ChildIt
= L2It
->Children
.begin();
199 L1ChildIt
!= L1It
->Children
.end(); ++L1ChildIt
, ++L2ChildIt
) {
200 if (!matchesTokens(*L1ChildIt
, *L2ChildIt
))
206 MATCHER_P(matchesLine
, line
, "") { return matchesTokens(arg
, line
); }
208 TEST_F(MacroCallReconstructorTest
, Identifier
) {
209 auto Macros
= createExpander({"X=x"});
210 Expansion
Exp(Lex
, *Macros
);
211 TokenList Call
= Exp
.expand("X");
213 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
214 Unexp
.addLine(line(Exp
.getTokens()));
215 EXPECT_TRUE(Unexp
.finished());
216 Matcher
U(Call
, Lex
);
217 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(line(U
.consume("X"))));
220 TEST_F(MacroCallReconstructorTest
, NestedLineWithinCall
) {
221 auto Macros
= createExpander({"C(a)=class X { a; };"});
222 Expansion
Exp(Lex
, *Macros
);
223 TokenList Call
= Exp
.expand("C", {"void f()"});
225 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
226 Matcher
E(Exp
.getTokens(), Lex
);
227 Unexp
.addLine(line(E
.consume("class X {")));
228 EXPECT_FALSE(Unexp
.finished());
229 Unexp
.addLine(line(E
.consume("void f();")));
230 EXPECT_FALSE(Unexp
.finished());
231 Unexp
.addLine(line(E
.consume("};")));
232 EXPECT_TRUE(Unexp
.finished());
233 Matcher
U(Call
, Lex
);
234 EXPECT_THAT(std::move(Unexp
).takeResult(),
235 matchesLine(line(U
.consume("C(void f())"))));
238 TEST_F(MacroCallReconstructorTest
, MultipleLinesInNestedMultiParamsExpansion
) {
239 auto Macros
= createExpander({"C(a, b)=a b", "B(a)={a}"});
240 Expansion
Exp1(Lex
, *Macros
);
241 TokenList Call1
= Exp1
.expand("B", {"b"});
242 Expansion
Exp2(Lex
, *Macros
);
243 TokenList Call2
= Exp2
.expand("C", {uneof(Lex
.lex("a")), Exp1
.getTokens()});
245 UnexpandedMap Unexpanded
=
246 mergeUnexpanded(Exp1
.getUnexpanded(), Exp2
.getUnexpanded());
247 MacroCallReconstructor
Unexp(0, Unexpanded
);
248 Matcher
E(Exp2
.getTokens(), Lex
);
249 Unexp
.addLine(line(E
.consume("a")));
250 EXPECT_FALSE(Unexp
.finished());
251 Unexp
.addLine(line(E
.consume("{")));
252 EXPECT_FALSE(Unexp
.finished());
253 Unexp
.addLine(line(E
.consume("b")));
254 EXPECT_FALSE(Unexp
.finished());
255 Unexp
.addLine(line(E
.consume("}")));
256 EXPECT_TRUE(Unexp
.finished());
258 Matcher
U1(Call1
, Lex
);
259 auto Middle
= U1
.consume("B(b)");
260 Matcher
U2(Call2
, Lex
);
261 auto Chunk1
= U2
.consume("C(a, ");
262 auto Chunk2
= U2
.consume("{ b }");
263 auto Chunk3
= U2
.consume(")");
265 EXPECT_THAT(std::move(Unexp
).takeResult(),
266 matchesLine(line({Chunk1
, Middle
, Chunk3
})));
269 TEST_F(MacroCallReconstructorTest
, StatementSequence
) {
270 auto Macros
= createExpander({"SEMI=;"});
271 Expansion
Exp(Lex
, *Macros
);
272 TokenList Call1
= Exp
.expand("SEMI");
273 TokenList Call2
= Exp
.expand("SEMI");
274 TokenList Call3
= Exp
.expand("SEMI");
276 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
277 Matcher
E(Exp
.getTokens(), Lex
);
278 Unexp
.addLine(line(E
.consume(";")));
279 EXPECT_TRUE(Unexp
.finished());
280 Unexp
.addLine(line(E
.consume(";")));
281 EXPECT_TRUE(Unexp
.finished());
282 Unexp
.addLine(line(E
.consume(";")));
283 EXPECT_TRUE(Unexp
.finished());
284 Matcher
U1(Call1
, Lex
);
285 Matcher
U2(Call2
, Lex
);
286 Matcher
U3(Call3
, Lex
);
287 EXPECT_THAT(std::move(Unexp
).takeResult(),
290 children({line({U2
.consume("SEMI"),
291 children({line(U3
.consume("SEMI"), 2)})},
295 TEST_F(MacroCallReconstructorTest
, NestedBlock
) {
296 auto Macros
= createExpander({"ID(x)=x"});
297 // Test: ID({ ID(a *b); })
298 // 1. expand ID(a *b) -> a *b
299 Expansion
Exp1(Lex
, *Macros
);
300 TokenList Call1
= Exp1
.expand("ID", {"a *b"});
301 // 2. expand ID({ a *b; })
303 Arg
.push_back(Lex
.id("{"));
304 Arg
.append(Exp1
.getTokens().begin(), Exp1
.getTokens().end());
305 Arg
.push_back(Lex
.id(";"));
306 Arg
.push_back(Lex
.id("}"));
307 Expansion
Exp2(Lex
, *Macros
);
308 TokenList Call2
= Exp2
.expand("ID", {Arg
});
310 // Consume as-if formatted:
314 UnexpandedMap Unexpanded
=
315 mergeUnexpanded(Exp1
.getUnexpanded(), Exp2
.getUnexpanded());
316 MacroCallReconstructor
Unexp(0, Unexpanded
);
317 Matcher
E(Exp2
.getTokens(), Lex
);
318 Unexp
.addLine(line(E
.consume("{")));
319 EXPECT_FALSE(Unexp
.finished());
320 Unexp
.addLine(line(E
.consume("a *b;")));
321 EXPECT_FALSE(Unexp
.finished());
322 Unexp
.addLine(line(E
.consume("}")));
323 EXPECT_TRUE(Unexp
.finished());
329 Matcher
U1(Call1
, Lex
);
330 Matcher
U2(Call2
, Lex
);
331 auto Chunk2Start
= U2
.consume("ID(");
332 auto Chunk2LBrace
= U2
.consume("{");
334 auto Chunk2Mid
= U2
.consume(";");
335 auto Chunk2RBrace
= U2
.consume("}");
336 auto Chunk2End
= U2
.consume(")");
337 auto Chunk1
= U1
.consume("ID(a *b)");
339 auto Expected
= line({Chunk2Start
,
341 line(Chunk2LBrace
, 1),
342 line({Chunk1
, Chunk2Mid
}, 1),
343 line(Chunk2RBrace
, 1),
346 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
349 TEST_F(MacroCallReconstructorTest
, NestedChildBlocks
) {
350 auto Macros
= createExpander({"ID(x)=x", "CALL(x)=f([] { x })"});
351 // Test: ID(CALL(CALL(return a * b;)))
352 // 1. expand CALL(return a * b;)
353 Expansion
Exp1(Lex
, *Macros
);
354 TokenList Call1
= Exp1
.expand("CALL", {"return a * b;"});
355 // 2. expand CALL(f([] { return a * b; }))
356 Expansion
Exp2(Lex
, *Macros
);
357 TokenList Call2
= Exp2
.expand("CALL", {Exp1
.getTokens()});
358 // 3. expand ID({ f([] { f([] { return a * b; }) }) })
360 Arg3
.push_back(Lex
.id("{"));
361 Arg3
.append(Exp2
.getTokens().begin(), Exp2
.getTokens().end());
362 Arg3
.push_back(Lex
.id("}"));
363 Expansion
Exp3(Lex
, *Macros
);
364 TokenList Call3
= Exp3
.expand("ID", {Arg3
});
366 // Consume as-if formatted in three unwrapped lines:
374 UnexpandedMap Unexpanded
= mergeUnexpanded(
375 Exp1
.getUnexpanded(),
376 mergeUnexpanded(Exp2
.getUnexpanded(), Exp3
.getUnexpanded()));
377 MacroCallReconstructor
Unexp(0, Unexpanded
);
378 Matcher
E(Exp3
.getTokens(), Lex
);
379 Unexp
.addLine(line(E
.consume("{")));
381 line({E
.consume("f([] {"),
382 children({line({E
.consume("f([] {"),
383 children({line(E
.consume("return a * b;"), 3)}),
388 Unexp
.addLine(line(E
.consume("}")));
389 EXPECT_TRUE(Unexp
.finished());
394 // CALL(CALL(return a * b;))
397 Matcher
U1(Call1
, Lex
);
398 Matcher
U2(Call2
, Lex
);
399 Matcher
U3(Call3
, Lex
);
400 auto Chunk3Start
= U3
.consume("ID(");
401 auto Chunk3LBrace
= U3
.consume("{");
402 U3
.consume("f([] { f([] { return a * b; }) })");
403 auto Chunk3RBrace
= U3
.consume("}");
404 auto Chunk3End
= U3
.consume(")");
405 auto Chunk2Start
= U2
.consume("CALL(");
406 U2
.consume("f([] { return a * b; })");
407 auto Chunk2End
= U2
.consume(")");
408 auto Chunk1
= U1
.consume("CALL(return a * b;)");
410 auto Expected
= line({
413 line(Chunk3LBrace
, 1),
421 line(Chunk3RBrace
, 1),
425 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
428 TEST_F(MacroCallReconstructorTest
, NestedChildrenMultipleArguments
) {
429 auto Macros
= createExpander({"CALL(a, b)=f([] { a; b; })"});
430 Expansion
Exp(Lex
, *Macros
);
431 TokenList Call
= Exp
.expand("CALL", {std::string("int a"), "int b"});
433 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
434 Matcher
E(Exp
.getTokens(), Lex
);
438 line(E
.consume("int a;")),
439 line(E
.consume("int b;")),
443 EXPECT_TRUE(Unexp
.finished());
444 Matcher
U(Call
, Lex
);
445 auto Expected
= line(U
.consume("CALL(int a, int b)"));
446 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
449 TEST_F(MacroCallReconstructorTest
, ReverseOrderArgumentsInExpansion
) {
450 auto Macros
= createExpander({"CALL(a, b)=b + a"});
451 Expansion
Exp(Lex
, *Macros
);
452 TokenList Call
= Exp
.expand("CALL", {std::string("x"), "y"});
454 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
455 Matcher
E(Exp
.getTokens(), Lex
);
456 Unexp
.addLine(line(E
.consume("y + x")));
457 EXPECT_TRUE(Unexp
.finished());
458 Matcher
U(Call
, Lex
);
459 auto Expected
= line(U
.consume("CALL(x, y)"));
460 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
463 TEST_F(MacroCallReconstructorTest
, MultipleToplevelUnwrappedLines
) {
464 auto Macros
= createExpander({"ID(a, b)=a b"});
465 Expansion
Exp(Lex
, *Macros
);
466 TokenList Call
= Exp
.expand("ID", {std::string("x; x"), "y"});
468 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
469 Matcher
E(Exp
.getTokens(), Lex
);
470 Unexp
.addLine(line(E
.consume("x;")));
471 Unexp
.addLine(line(E
.consume("x y")));
472 EXPECT_TRUE(Unexp
.finished());
473 Matcher
U(Call
, Lex
);
474 auto Expected
= line({
477 line(U
.consume("x;"), 1),
478 line(U
.consume("x"), 1),
482 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
485 TEST_F(MacroCallReconstructorTest
, NestedCallsMultipleLines
) {
486 auto Macros
= createExpander({"ID(x)=x"});
487 // Test: ID({ID(a * b);})
488 // 1. expand ID(a * b)
489 Expansion
Exp1(Lex
, *Macros
);
490 TokenList Call1
= Exp1
.expand("ID", {"a * b"});
491 // 2. expand ID({ a * b; })
492 Expansion
Exp2(Lex
, *Macros
);
494 Arg2
.push_back(Lex
.id("{"));
495 Arg2
.append(Exp1
.getTokens().begin(), Exp1
.getTokens().end());
496 Arg2
.push_back(Lex
.id(";"));
497 Arg2
.push_back(Lex
.id("}"));
498 TokenList Call2
= Exp2
.expand("ID", {Arg2
});
500 // Consume as-if formatted in three unwrapped lines:
504 UnexpandedMap Unexpanded
=
505 mergeUnexpanded(Exp1
.getUnexpanded(), Exp2
.getUnexpanded());
506 MacroCallReconstructor
Unexp(0, Unexpanded
);
507 Matcher
E(Exp2
.getTokens(), Lex
);
508 Unexp
.addLine(line(E
.consume("{")));
509 Unexp
.addLine(line(E
.consume("a * b;")));
510 Unexp
.addLine(line(E
.consume("}")));
511 EXPECT_TRUE(Unexp
.finished());
519 Matcher
U1(Call1
, Lex
);
520 Matcher
U2(Call2
, Lex
);
521 auto Chunk2Start
= U2
.consume("ID(");
522 auto Chunk2LBrace
= U2
.consume("{");
524 auto Chunk2Semi
= U2
.consume(";");
525 auto Chunk2RBrace
= U2
.consume("}");
526 auto Chunk2End
= U2
.consume(")");
527 auto Chunk1
= U1
.consume("ID(a * b)");
529 auto Expected
= line({
532 line({Chunk2LBrace
}, 1),
533 line({Chunk1
, Chunk2Semi
}, 1),
534 line({Chunk2RBrace
}, 1),
538 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
541 TEST_F(MacroCallReconstructorTest
, ParentOutsideMacroCall
) {
542 auto Macros
= createExpander({"ID(a)=a"});
543 Expansion
Exp(Lex
, *Macros
);
544 TokenList Call
= Exp
.expand("ID", {std::string("x; y; z;")});
546 auto Prefix
= tokens("int a = []() {");
547 auto Postfix
= tokens("}();");
548 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
549 Matcher
E(Exp
.getTokens(), Lex
);
553 line(E
.consume("x;")),
554 line(E
.consume("y;")),
555 line(E
.consume("z;")),
559 EXPECT_TRUE(Unexp
.finished());
560 Matcher
U(Call
, Lex
);
561 auto Expected
= line({
568 line(U
.consume("x;"), 2),
569 line(U
.consume("y;"), 2),
570 line(U
.consume("z;"), 2),
578 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
581 TEST_F(MacroCallReconstructorTest
, ChildrenSplitAcrossArguments
) {
582 auto Macros
= createExpander({"CALL(a, b)=f([]() a b)"});
583 Expansion
Exp(Lex
, *Macros
);
584 TokenList Call
= Exp
.expand("CALL", {std::string("{ a;"), "b; }"});
586 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
587 Matcher
E(Exp
.getTokens(), Lex
);
589 E
.consume("f([]() {"),
591 line(E
.consume("a;")),
592 line(E
.consume("b;")),
596 EXPECT_TRUE(Unexp
.finished());
597 Matcher
U(Call
, Lex
);
598 auto Expected
= line({
600 children(line(U
.consume("a;"), 1)),
601 U
.consume(", b; })"),
603 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
606 TEST_F(MacroCallReconstructorTest
, ChildrenAfterMacroCall
) {
607 auto Macros
= createExpander({"CALL(a, b)=f([]() a b"});
608 Expansion
Exp(Lex
, *Macros
);
609 TokenList Call
= Exp
.expand("CALL", {std::string("{ a"), "b"});
611 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
612 Matcher
E(Exp
.getTokens(), Lex
);
613 auto Semi
= tokens(";");
614 auto SecondLine
= tokens("c d;");
615 auto ThirdLine
= tokens("e f;");
616 auto Postfix
= tokens("})");
618 E
.consume("f([]() {"),
620 line({E
.consume("a b"), Semi
}),
626 EXPECT_TRUE(Unexp
.finished());
627 Matcher
U(Call
, Lex
);
628 auto Expected
= line({
630 children(line(U
.consume("a"), 1)),
645 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
648 TEST_F(MacroCallReconstructorTest
, InvalidCodeSplittingBracesAcrossArgs
) {
649 auto Macros
= createExpander({"M(a, b, c)=(a) (b) c"});
650 Expansion
Exp(Lex
, *Macros
);
651 TokenList Call
= Exp
.expand("M", {std::string("{"), "x", ""});
653 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
654 Matcher
E(Exp
.getTokens(), Lex
);
655 auto Prefix
= tokens("({");
661 children({line(E
.consume(")(x)"))}),
665 EXPECT_TRUE(Unexp
.finished());
666 Matcher
U(Call
, Lex
);
667 auto Expected
= line({
669 children({line(U
.consume("M({,x,)"), 1)}),
671 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
674 TEST_F(MacroCallReconstructorTest
, IndentLevelInExpandedCode
) {
675 auto Macros
= createExpander({"ID(a)=a"});
676 Expansion
Exp(Lex
, *Macros
);
677 TokenList Call
= Exp
.expand("ID", {std::string("[] { { x; } }")});
679 MacroCallReconstructor
Unexp(0, Exp
.getUnexpanded());
680 Matcher
E(Exp
.getTokens(), Lex
);
684 line(E
.consume("{"), 1),
685 line(E
.consume("x;"), 2),
686 line(E
.consume("}"), 1),
690 EXPECT_TRUE(Unexp
.finished());
691 Matcher
U(Call
, Lex
);
692 auto Expected
= line({
693 U
.consume("ID([] {"),
695 line(U
.consume("{"), 1),
696 line(U
.consume("x;"), 2),
697 line(U
.consume("}"), 1),
701 EXPECT_THAT(std::move(Unexp
).takeResult(), matchesLine(Expected
));
705 } // namespace format