1*67e74705SXin Li //===- unittest/Format/CleanupTest.cpp - Code cleanup unit tests ----------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "clang/Format/Format.h"
11*67e74705SXin Li
12*67e74705SXin Li #include "../Tooling/RewriterTestContext.h"
13*67e74705SXin Li #include "clang/Tooling/Core/Replacement.h"
14*67e74705SXin Li
15*67e74705SXin Li #include "gtest/gtest.h"
16*67e74705SXin Li
17*67e74705SXin Li namespace clang {
18*67e74705SXin Li namespace format {
19*67e74705SXin Li namespace {
20*67e74705SXin Li
21*67e74705SXin Li class CleanupTest : public ::testing::Test {
22*67e74705SXin Li protected:
cleanup(llvm::StringRef Code,const std::vector<tooling::Range> & Ranges,const FormatStyle & Style=getLLVMStyle ())23*67e74705SXin Li std::string cleanup(llvm::StringRef Code,
24*67e74705SXin Li const std::vector<tooling::Range> &Ranges,
25*67e74705SXin Li const FormatStyle &Style = getLLVMStyle()) {
26*67e74705SXin Li tooling::Replacements Replaces = format::cleanup(Style, Code, Ranges);
27*67e74705SXin Li
28*67e74705SXin Li auto Result = applyAllReplacements(Code, Replaces);
29*67e74705SXin Li EXPECT_TRUE(static_cast<bool>(Result));
30*67e74705SXin Li return *Result;
31*67e74705SXin Li }
32*67e74705SXin Li };
33*67e74705SXin Li
TEST_F(CleanupTest,DeleteEmptyNamespaces)34*67e74705SXin Li TEST_F(CleanupTest, DeleteEmptyNamespaces) {
35*67e74705SXin Li std::string Code = "namespace A {\n"
36*67e74705SXin Li "namespace B {\n"
37*67e74705SXin Li "} // namespace B\n"
38*67e74705SXin Li "} // namespace A\n\n"
39*67e74705SXin Li "namespace C {\n"
40*67e74705SXin Li "namespace D { int i; }\n"
41*67e74705SXin Li "inline namespace E { namespace { } }\n"
42*67e74705SXin Li "}";
43*67e74705SXin Li std::string Expected = "\n\n\n\n\nnamespace C {\n"
44*67e74705SXin Li "namespace D { int i; }\n \n"
45*67e74705SXin Li "}";
46*67e74705SXin Li std::vector<tooling::Range> Ranges;
47*67e74705SXin Li Ranges.push_back(tooling::Range(28, 0));
48*67e74705SXin Li Ranges.push_back(tooling::Range(91, 6));
49*67e74705SXin Li Ranges.push_back(tooling::Range(132, 0));
50*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
51*67e74705SXin Li EXPECT_EQ(Expected, Result);
52*67e74705SXin Li }
53*67e74705SXin Li
TEST_F(CleanupTest,NamespaceWithSyntaxError)54*67e74705SXin Li TEST_F(CleanupTest, NamespaceWithSyntaxError) {
55*67e74705SXin Li std::string Code = "namespace A {\n"
56*67e74705SXin Li "namespace B {\n" // missing r_brace
57*67e74705SXin Li "} // namespace A\n\n"
58*67e74705SXin Li "namespace C {\n"
59*67e74705SXin Li "namespace D int i; }\n"
60*67e74705SXin Li "inline namespace E { namespace { } }\n"
61*67e74705SXin Li "}";
62*67e74705SXin Li std::string Expected = "namespace A {\n"
63*67e74705SXin Li "\n\n\nnamespace C {\n"
64*67e74705SXin Li "namespace D int i; }\n \n"
65*67e74705SXin Li "}";
66*67e74705SXin Li std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
67*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
68*67e74705SXin Li EXPECT_EQ(Expected, Result);
69*67e74705SXin Li }
70*67e74705SXin Li
TEST_F(CleanupTest,EmptyNamespaceNotAffected)71*67e74705SXin Li TEST_F(CleanupTest, EmptyNamespaceNotAffected) {
72*67e74705SXin Li std::string Code = "namespace A {\n\n"
73*67e74705SXin Li "namespace {\n\n}}";
74*67e74705SXin Li // Even though the namespaces are empty, but the inner most empty namespace
75*67e74705SXin Li // block is not affected by the changed ranges.
76*67e74705SXin Li std::string Expected = "namespace A {\n\n"
77*67e74705SXin Li "namespace {\n\n}}";
78*67e74705SXin Li // Set the changed range to be the second "\n".
79*67e74705SXin Li std::vector<tooling::Range> Ranges(1, tooling::Range(14, 0));
80*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
81*67e74705SXin Li EXPECT_EQ(Expected, Result);
82*67e74705SXin Li }
83*67e74705SXin Li
TEST_F(CleanupTest,EmptyNamespaceWithCommentsNoBreakBeforeBrace)84*67e74705SXin Li TEST_F(CleanupTest, EmptyNamespaceWithCommentsNoBreakBeforeBrace) {
85*67e74705SXin Li std::string Code = "namespace A {\n"
86*67e74705SXin Li "namespace B {\n"
87*67e74705SXin Li "// Yo\n"
88*67e74705SXin Li "} // namespace B\n"
89*67e74705SXin Li "} // namespace A\n"
90*67e74705SXin Li "namespace C { // Yo\n"
91*67e74705SXin Li "}";
92*67e74705SXin Li std::string Expected = "\n\n\n\n\n\n";
93*67e74705SXin Li std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
94*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
95*67e74705SXin Li EXPECT_EQ(Expected, Result);
96*67e74705SXin Li }
97*67e74705SXin Li
TEST_F(CleanupTest,EmptyNamespaceWithCommentsBreakBeforeBrace)98*67e74705SXin Li TEST_F(CleanupTest, EmptyNamespaceWithCommentsBreakBeforeBrace) {
99*67e74705SXin Li std::string Code = "namespace A\n"
100*67e74705SXin Li "/* Yo */ {\n"
101*67e74705SXin Li "namespace B\n"
102*67e74705SXin Li "{\n"
103*67e74705SXin Li "// Yo\n"
104*67e74705SXin Li "} // namespace B\n"
105*67e74705SXin Li "} // namespace A\n"
106*67e74705SXin Li "namespace C\n"
107*67e74705SXin Li "{ // Yo\n"
108*67e74705SXin Li "}\n";
109*67e74705SXin Li std::string Expected = "\n\n\n\n\n\n\n\n\n\n";
110*67e74705SXin Li std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
111*67e74705SXin Li FormatStyle Style = getLLVMStyle();
112*67e74705SXin Li Style.BraceWrapping.AfterNamespace = true;
113*67e74705SXin Li std::string Result = cleanup(Code, Ranges, Style);
114*67e74705SXin Li EXPECT_EQ(Expected, Result);
115*67e74705SXin Li }
116*67e74705SXin Li
TEST_F(CleanupTest,CtorInitializationSimpleRedundantComma)117*67e74705SXin Li TEST_F(CleanupTest, CtorInitializationSimpleRedundantComma) {
118*67e74705SXin Li std::string Code = "class A {\nA() : , {} };";
119*67e74705SXin Li std::string Expected = "class A {\nA() {} };";
120*67e74705SXin Li std::vector<tooling::Range> Ranges;
121*67e74705SXin Li Ranges.push_back(tooling::Range(17, 0));
122*67e74705SXin Li Ranges.push_back(tooling::Range(19, 0));
123*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
124*67e74705SXin Li EXPECT_EQ(Expected, Result);
125*67e74705SXin Li
126*67e74705SXin Li Code = "class A {\nA() : x(1), {} };";
127*67e74705SXin Li Expected = "class A {\nA() : x(1) {} };";
128*67e74705SXin Li Ranges.clear();
129*67e74705SXin Li Ranges.push_back(tooling::Range(23, 0));
130*67e74705SXin Li Result = cleanup(Code, Ranges);
131*67e74705SXin Li EXPECT_EQ(Expected, Result);
132*67e74705SXin Li
133*67e74705SXin Li Code = "class A {\nA() :,,,,{} };";
134*67e74705SXin Li Expected = "class A {\nA() {} };";
135*67e74705SXin Li Ranges.clear();
136*67e74705SXin Li Ranges.push_back(tooling::Range(15, 0));
137*67e74705SXin Li Result = cleanup(Code, Ranges);
138*67e74705SXin Li EXPECT_EQ(Expected, Result);
139*67e74705SXin Li }
140*67e74705SXin Li
TEST_F(CleanupTest,ListSimpleRedundantComma)141*67e74705SXin Li TEST_F(CleanupTest, ListSimpleRedundantComma) {
142*67e74705SXin Li std::string Code = "void f() { std::vector<int> v = {1,2,,,3,{4,5}}; }";
143*67e74705SXin Li std::string Expected = "void f() { std::vector<int> v = {1,2,3,{4,5}}; }";
144*67e74705SXin Li std::vector<tooling::Range> Ranges;
145*67e74705SXin Li Ranges.push_back(tooling::Range(40, 0));
146*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
147*67e74705SXin Li EXPECT_EQ(Expected, Result);
148*67e74705SXin Li
149*67e74705SXin Li Code = "int main() { f(1,,2,3,,4);}";
150*67e74705SXin Li Expected = "int main() { f(1,2,3,4);}";
151*67e74705SXin Li Ranges.clear();
152*67e74705SXin Li Ranges.push_back(tooling::Range(17, 0));
153*67e74705SXin Li Ranges.push_back(tooling::Range(22, 0));
154*67e74705SXin Li Result = cleanup(Code, Ranges);
155*67e74705SXin Li EXPECT_EQ(Expected, Result);
156*67e74705SXin Li }
157*67e74705SXin Li
TEST_F(CleanupTest,CtorInitializationBracesInParens)158*67e74705SXin Li TEST_F(CleanupTest, CtorInitializationBracesInParens) {
159*67e74705SXin Li std::string Code = "class A {\nA() : x({1}),, {} };";
160*67e74705SXin Li std::string Expected = "class A {\nA() : x({1}) {} };";
161*67e74705SXin Li std::vector<tooling::Range> Ranges;
162*67e74705SXin Li Ranges.push_back(tooling::Range(24, 0));
163*67e74705SXin Li Ranges.push_back(tooling::Range(26, 0));
164*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
165*67e74705SXin Li EXPECT_EQ(Expected, Result);
166*67e74705SXin Li }
167*67e74705SXin Li
TEST_F(CleanupTest,RedundantCommaNotInAffectedRanges)168*67e74705SXin Li TEST_F(CleanupTest, RedundantCommaNotInAffectedRanges) {
169*67e74705SXin Li std::string Code =
170*67e74705SXin Li "class A {\nA() : x({1}), /* comment */, { int x = 0; } };";
171*67e74705SXin Li std::string Expected =
172*67e74705SXin Li "class A {\nA() : x({1}), /* comment */, { int x = 0; } };";
173*67e74705SXin Li // Set the affected range to be "int x = 0", which does not intercept the
174*67e74705SXin Li // constructor initialization list.
175*67e74705SXin Li std::vector<tooling::Range> Ranges(1, tooling::Range(42, 9));
176*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
177*67e74705SXin Li EXPECT_EQ(Expected, Result);
178*67e74705SXin Li
179*67e74705SXin Li Code = "class A {\nA() : x(1), {} };";
180*67e74705SXin Li Expected = "class A {\nA() : x(1), {} };";
181*67e74705SXin Li // No range. Fixer should do nothing.
182*67e74705SXin Li Ranges.clear();
183*67e74705SXin Li Result = cleanup(Code, Ranges);
184*67e74705SXin Li EXPECT_EQ(Expected, Result);
185*67e74705SXin Li }
186*67e74705SXin Li
187*67e74705SXin Li // FIXME: delete comments too.
TEST_F(CleanupTest,CtorInitializationCommentAroundCommas)188*67e74705SXin Li TEST_F(CleanupTest, CtorInitializationCommentAroundCommas) {
189*67e74705SXin Li // Remove redundant commas around comment.
190*67e74705SXin Li std::string Code = "class A {\nA() : x({1}), /* comment */, {} };";
191*67e74705SXin Li std::string Expected = "class A {\nA() : x({1}) /* comment */ {} };";
192*67e74705SXin Li std::vector<tooling::Range> Ranges;
193*67e74705SXin Li Ranges.push_back(tooling::Range(25, 0));
194*67e74705SXin Li Ranges.push_back(tooling::Range(40, 0));
195*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
196*67e74705SXin Li EXPECT_EQ(Expected, Result);
197*67e74705SXin Li
198*67e74705SXin Li // Remove trailing comma and ignore comment.
199*67e74705SXin Li Code = "class A {\nA() : x({1}), // comment\n{} };";
200*67e74705SXin Li Expected = "class A {\nA() : x({1}) // comment\n{} };";
201*67e74705SXin Li Ranges = std::vector<tooling::Range>(1, tooling::Range(25, 0));
202*67e74705SXin Li Result = cleanup(Code, Ranges);
203*67e74705SXin Li EXPECT_EQ(Expected, Result);
204*67e74705SXin Li
205*67e74705SXin Li // Remove trailing comma and ignore comment.
206*67e74705SXin Li Code = "class A {\nA() : x({1}), // comment\n , y(1),{} };";
207*67e74705SXin Li Expected = "class A {\nA() : x({1}), // comment\n y(1){} };";
208*67e74705SXin Li Ranges = std::vector<tooling::Range>(1, tooling::Range(38, 0));
209*67e74705SXin Li Result = cleanup(Code, Ranges);
210*67e74705SXin Li EXPECT_EQ(Expected, Result);
211*67e74705SXin Li
212*67e74705SXin Li // Remove trailing comma and ignore comment.
213*67e74705SXin Li Code = "class A {\nA() : x({1}), \n/* comment */, y(1),{} };";
214*67e74705SXin Li Expected = "class A {\nA() : x({1}), \n/* comment */ y(1){} };";
215*67e74705SXin Li Ranges = std::vector<tooling::Range>(1, tooling::Range(40, 0));
216*67e74705SXin Li Result = cleanup(Code, Ranges);
217*67e74705SXin Li EXPECT_EQ(Expected, Result);
218*67e74705SXin Li
219*67e74705SXin Li // Remove trailing comma and ignore comment.
220*67e74705SXin Li Code = "class A {\nA() : , // comment\n y(1),{} };";
221*67e74705SXin Li Expected = "class A {\nA() : // comment\n y(1){} };";
222*67e74705SXin Li Ranges = std::vector<tooling::Range>(1, tooling::Range(17, 0));
223*67e74705SXin Li Result = cleanup(Code, Ranges);
224*67e74705SXin Li EXPECT_EQ(Expected, Result);
225*67e74705SXin Li }
226*67e74705SXin Li
TEST_F(CleanupTest,CtorInitializerInNamespace)227*67e74705SXin Li TEST_F(CleanupTest, CtorInitializerInNamespace) {
228*67e74705SXin Li std::string Code = "namespace A {\n"
229*67e74705SXin Li "namespace B {\n" // missing r_brace
230*67e74705SXin Li "} // namespace A\n\n"
231*67e74705SXin Li "namespace C {\n"
232*67e74705SXin Li "class A { A() : x(0),, {} };\n"
233*67e74705SXin Li "inline namespace E { namespace { } }\n"
234*67e74705SXin Li "}";
235*67e74705SXin Li std::string Expected = "namespace A {\n"
236*67e74705SXin Li "\n\n\nnamespace C {\n"
237*67e74705SXin Li "class A { A() : x(0) {} };\n \n"
238*67e74705SXin Li "}";
239*67e74705SXin Li std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
240*67e74705SXin Li std::string Result = cleanup(Code, Ranges);
241*67e74705SXin Li EXPECT_EQ(Expected, Result);
242*67e74705SXin Li }
243*67e74705SXin Li
244*67e74705SXin Li class CleanUpReplacementsTest : public ::testing::Test {
245*67e74705SXin Li protected:
createReplacement(unsigned Offset,unsigned Length,StringRef Text)246*67e74705SXin Li tooling::Replacement createReplacement(unsigned Offset, unsigned Length,
247*67e74705SXin Li StringRef Text) {
248*67e74705SXin Li return tooling::Replacement(FileName, Offset, Length, Text);
249*67e74705SXin Li }
250*67e74705SXin Li
createInsertion(StringRef HeaderName)251*67e74705SXin Li tooling::Replacement createInsertion(StringRef HeaderName) {
252*67e74705SXin Li return createReplacement(UINT_MAX, 0, HeaderName);
253*67e74705SXin Li }
254*67e74705SXin Li
apply(StringRef Code,const tooling::Replacements Replaces)255*67e74705SXin Li inline std::string apply(StringRef Code,
256*67e74705SXin Li const tooling::Replacements Replaces) {
257*67e74705SXin Li auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
258*67e74705SXin Li EXPECT_TRUE(static_cast<bool>(CleanReplaces))
259*67e74705SXin Li << llvm::toString(CleanReplaces.takeError()) << "\n";
260*67e74705SXin Li auto Result = applyAllReplacements(Code, *CleanReplaces);
261*67e74705SXin Li EXPECT_TRUE(static_cast<bool>(Result));
262*67e74705SXin Li return *Result;
263*67e74705SXin Li }
264*67e74705SXin Li
formatAndApply(StringRef Code,const tooling::Replacements Replaces)265*67e74705SXin Li inline std::string formatAndApply(StringRef Code,
266*67e74705SXin Li const tooling::Replacements Replaces) {
267*67e74705SXin Li
268*67e74705SXin Li auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
269*67e74705SXin Li EXPECT_TRUE(static_cast<bool>(CleanReplaces))
270*67e74705SXin Li << llvm::toString(CleanReplaces.takeError()) << "\n";
271*67e74705SXin Li auto FormattedReplaces = formatReplacements(Code, *CleanReplaces, Style);
272*67e74705SXin Li EXPECT_TRUE(static_cast<bool>(FormattedReplaces))
273*67e74705SXin Li << llvm::toString(FormattedReplaces.takeError()) << "\n";
274*67e74705SXin Li auto Result = applyAllReplacements(Code, *FormattedReplaces);
275*67e74705SXin Li EXPECT_TRUE(static_cast<bool>(Result));
276*67e74705SXin Li return *Result;
277*67e74705SXin Li }
278*67e74705SXin Li
getOffset(StringRef Code,int Line,int Column)279*67e74705SXin Li int getOffset(StringRef Code, int Line, int Column) {
280*67e74705SXin Li RewriterTestContext Context;
281*67e74705SXin Li FileID ID = Context.createInMemoryFile(FileName, Code);
282*67e74705SXin Li auto DecomposedLocation =
283*67e74705SXin Li Context.Sources.getDecomposedLoc(Context.getLocation(ID, Line, Column));
284*67e74705SXin Li return DecomposedLocation.second;
285*67e74705SXin Li }
286*67e74705SXin Li
287*67e74705SXin Li const std::string FileName = "fix.cpp";
288*67e74705SXin Li FormatStyle Style = getLLVMStyle();
289*67e74705SXin Li };
290*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,FixOnlyAffectedCodeAfterReplacements)291*67e74705SXin Li TEST_F(CleanUpReplacementsTest, FixOnlyAffectedCodeAfterReplacements) {
292*67e74705SXin Li std::string Code = "namespace A {\n"
293*67e74705SXin Li "namespace B {\n"
294*67e74705SXin Li " int x;\n"
295*67e74705SXin Li "} // namespace B\n"
296*67e74705SXin Li "} // namespace A\n"
297*67e74705SXin Li "\n"
298*67e74705SXin Li "namespace C {\n"
299*67e74705SXin Li "namespace D { int i; }\n"
300*67e74705SXin Li "inline namespace E { namespace { int y; } }\n"
301*67e74705SXin Li "int x= 0;"
302*67e74705SXin Li "}";
303*67e74705SXin Li std::string Expected = "\n\nnamespace C {\n"
304*67e74705SXin Li "namespace D { int i; }\n\n"
305*67e74705SXin Li "int x= 0;"
306*67e74705SXin Li "}";
307*67e74705SXin Li tooling::Replacements Replaces = {
308*67e74705SXin Li createReplacement(getOffset(Code, 3, 3), 6, ""),
309*67e74705SXin Li createReplacement(getOffset(Code, 9, 34), 6, "")};
310*67e74705SXin Li
311*67e74705SXin Li EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
312*67e74705SXin Li }
313*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,NoExistingIncludeWithoutDefine)314*67e74705SXin Li TEST_F(CleanUpReplacementsTest, NoExistingIncludeWithoutDefine) {
315*67e74705SXin Li std::string Code = "int main() {}";
316*67e74705SXin Li std::string Expected = "#include \"a.h\"\n"
317*67e74705SXin Li "int main() {}";
318*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"a.h\"")};
319*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
320*67e74705SXin Li }
321*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,NoExistingIncludeWithDefine)322*67e74705SXin Li TEST_F(CleanUpReplacementsTest, NoExistingIncludeWithDefine) {
323*67e74705SXin Li std::string Code = "#ifndef A_H\n"
324*67e74705SXin Li "#define A_H\n"
325*67e74705SXin Li "class A {};\n"
326*67e74705SXin Li "#define MMM 123\n"
327*67e74705SXin Li "#endif";
328*67e74705SXin Li std::string Expected = "#ifndef A_H\n"
329*67e74705SXin Li "#define A_H\n"
330*67e74705SXin Li "#include \"b.h\"\n"
331*67e74705SXin Li "class A {};\n"
332*67e74705SXin Li "#define MMM 123\n"
333*67e74705SXin Li "#endif";
334*67e74705SXin Li
335*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"b.h\"")};
336*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
337*67e74705SXin Li }
338*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertBeforeCategoryWithLowerPriority)339*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertBeforeCategoryWithLowerPriority) {
340*67e74705SXin Li std::string Code = "#ifndef A_H\n"
341*67e74705SXin Li "#define A_H\n"
342*67e74705SXin Li "\n"
343*67e74705SXin Li "\n"
344*67e74705SXin Li "\n"
345*67e74705SXin Li "#include <vector>\n"
346*67e74705SXin Li "class A {};\n"
347*67e74705SXin Li "#define MMM 123\n"
348*67e74705SXin Li "#endif";
349*67e74705SXin Li std::string Expected = "#ifndef A_H\n"
350*67e74705SXin Li "#define A_H\n"
351*67e74705SXin Li "\n"
352*67e74705SXin Li "\n"
353*67e74705SXin Li "\n"
354*67e74705SXin Li "#include \"a.h\"\n"
355*67e74705SXin Li "#include <vector>\n"
356*67e74705SXin Li "class A {};\n"
357*67e74705SXin Li "#define MMM 123\n"
358*67e74705SXin Li "#endif";
359*67e74705SXin Li
360*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"a.h\"")};
361*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
362*67e74705SXin Li }
363*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertAfterMainHeader)364*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertAfterMainHeader) {
365*67e74705SXin Li std::string Code = "#include \"fix.h\"\n"
366*67e74705SXin Li "\n"
367*67e74705SXin Li "int main() {}";
368*67e74705SXin Li std::string Expected = "#include \"fix.h\"\n"
369*67e74705SXin Li "#include <a>\n"
370*67e74705SXin Li "\n"
371*67e74705SXin Li "int main() {}";
372*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <a>")};
373*67e74705SXin Li Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
374*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
375*67e74705SXin Li }
376*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertBeforeSystemHeaderLLVM)377*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertBeforeSystemHeaderLLVM) {
378*67e74705SXin Li std::string Code = "#include <memory>\n"
379*67e74705SXin Li "\n"
380*67e74705SXin Li "int main() {}";
381*67e74705SXin Li std::string Expected = "#include \"z.h\"\n"
382*67e74705SXin Li "#include <memory>\n"
383*67e74705SXin Li "\n"
384*67e74705SXin Li "int main() {}";
385*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"z.h\"")};
386*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
387*67e74705SXin Li }
388*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertAfterSystemHeaderGoogle)389*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertAfterSystemHeaderGoogle) {
390*67e74705SXin Li std::string Code = "#include <memory>\n"
391*67e74705SXin Li "\n"
392*67e74705SXin Li "int main() {}";
393*67e74705SXin Li std::string Expected = "#include <memory>\n"
394*67e74705SXin Li "#include \"z.h\"\n"
395*67e74705SXin Li "\n"
396*67e74705SXin Li "int main() {}";
397*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"z.h\"")};
398*67e74705SXin Li Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
399*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
400*67e74705SXin Li }
401*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertOneIncludeLLVMStyle)402*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertOneIncludeLLVMStyle) {
403*67e74705SXin Li std::string Code = "#include \"x/fix.h\"\n"
404*67e74705SXin Li "#include \"a.h\"\n"
405*67e74705SXin Li "#include \"b.h\"\n"
406*67e74705SXin Li "#include \"clang/Format/Format.h\"\n"
407*67e74705SXin Li "#include <memory>\n";
408*67e74705SXin Li std::string Expected = "#include \"x/fix.h\"\n"
409*67e74705SXin Li "#include \"a.h\"\n"
410*67e74705SXin Li "#include \"b.h\"\n"
411*67e74705SXin Li "#include \"d.h\"\n"
412*67e74705SXin Li "#include \"clang/Format/Format.h\"\n"
413*67e74705SXin Li "#include \"llvm/x/y.h\"\n"
414*67e74705SXin Li "#include <memory>\n";
415*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"d.h\""),
416*67e74705SXin Li createInsertion("#include \"llvm/x/y.h\"")};
417*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
418*67e74705SXin Li }
419*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertMultipleIncludesLLVMStyle)420*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertMultipleIncludesLLVMStyle) {
421*67e74705SXin Li std::string Code = "#include \"x/fix.h\"\n"
422*67e74705SXin Li "#include \"a.h\"\n"
423*67e74705SXin Li "#include \"b.h\"\n"
424*67e74705SXin Li "#include \"clang/Format/Format.h\"\n"
425*67e74705SXin Li "#include <memory>\n";
426*67e74705SXin Li std::string Expected = "#include \"x/fix.h\"\n"
427*67e74705SXin Li "#include \"a.h\"\n"
428*67e74705SXin Li "#include \"b.h\"\n"
429*67e74705SXin Li "#include \"new/new.h\"\n"
430*67e74705SXin Li "#include \"clang/Format/Format.h\"\n"
431*67e74705SXin Li "#include <memory>\n"
432*67e74705SXin Li "#include <list>\n";
433*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <list>"),
434*67e74705SXin Li createInsertion("#include \"new/new.h\"")};
435*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
436*67e74705SXin Li }
437*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertNewSystemIncludeGoogleStyle)438*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertNewSystemIncludeGoogleStyle) {
439*67e74705SXin Li std::string Code = "#include \"x/fix.h\"\n"
440*67e74705SXin Li "\n"
441*67e74705SXin Li "#include \"y/a.h\"\n"
442*67e74705SXin Li "#include \"z/b.h\"\n";
443*67e74705SXin Li // FIXME: inserting after the empty line following the main header might be
444*67e74705SXin Li // prefered.
445*67e74705SXin Li std::string Expected = "#include \"x/fix.h\"\n"
446*67e74705SXin Li "#include <vector>\n"
447*67e74705SXin Li "\n"
448*67e74705SXin Li "#include \"y/a.h\"\n"
449*67e74705SXin Li "#include \"z/b.h\"\n";
450*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
451*67e74705SXin Li Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
452*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
453*67e74705SXin Li }
454*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertMultipleIncludesGoogleStyle)455*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertMultipleIncludesGoogleStyle) {
456*67e74705SXin Li std::string Code = "#include \"x/fix.h\"\n"
457*67e74705SXin Li "\n"
458*67e74705SXin Li "#include <vector>\n"
459*67e74705SXin Li "\n"
460*67e74705SXin Li "#include \"y/a.h\"\n"
461*67e74705SXin Li "#include \"z/b.h\"\n";
462*67e74705SXin Li std::string Expected = "#include \"x/fix.h\"\n"
463*67e74705SXin Li "\n"
464*67e74705SXin Li "#include <vector>\n"
465*67e74705SXin Li "#include <list>\n"
466*67e74705SXin Li "\n"
467*67e74705SXin Li "#include \"y/a.h\"\n"
468*67e74705SXin Li "#include \"z/b.h\"\n"
469*67e74705SXin Li "#include \"x/x.h\"\n";
470*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <list>"),
471*67e74705SXin Li createInsertion("#include \"x/x.h\"")};
472*67e74705SXin Li Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
473*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
474*67e74705SXin Li }
475*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertMultipleNewHeadersAndSortLLVM)476*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortLLVM) {
477*67e74705SXin Li std::string Code = "\nint x;";
478*67e74705SXin Li std::string Expected = "\n#include \"fix.h\"\n"
479*67e74705SXin Li "#include \"a.h\"\n"
480*67e74705SXin Li "#include \"b.h\"\n"
481*67e74705SXin Li "#include \"c.h\"\n"
482*67e74705SXin Li "#include <list>\n"
483*67e74705SXin Li "#include <vector>\n"
484*67e74705SXin Li "int x;";
485*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"a.h\""),
486*67e74705SXin Li createInsertion("#include \"c.h\""),
487*67e74705SXin Li createInsertion("#include \"b.h\""),
488*67e74705SXin Li createInsertion("#include <vector>"),
489*67e74705SXin Li createInsertion("#include <list>"),
490*67e74705SXin Li createInsertion("#include \"fix.h\"")};
491*67e74705SXin Li EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
492*67e74705SXin Li }
493*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,InsertMultipleNewHeadersAndSortGoogle)494*67e74705SXin Li TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortGoogle) {
495*67e74705SXin Li std::string Code = "\nint x;";
496*67e74705SXin Li std::string Expected = "\n#include \"fix.h\"\n"
497*67e74705SXin Li "#include <list>\n"
498*67e74705SXin Li "#include <vector>\n"
499*67e74705SXin Li "#include \"a.h\"\n"
500*67e74705SXin Li "#include \"b.h\"\n"
501*67e74705SXin Li "#include \"c.h\"\n"
502*67e74705SXin Li "int x;";
503*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"a.h\""),
504*67e74705SXin Li createInsertion("#include \"c.h\""),
505*67e74705SXin Li createInsertion("#include \"b.h\""),
506*67e74705SXin Li createInsertion("#include <vector>"),
507*67e74705SXin Li createInsertion("#include <list>"),
508*67e74705SXin Li createInsertion("#include \"fix.h\"")};
509*67e74705SXin Li Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
510*67e74705SXin Li EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
511*67e74705SXin Li }
512*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,FormatCorrectLineWhenHeadersAreInserted)513*67e74705SXin Li TEST_F(CleanUpReplacementsTest, FormatCorrectLineWhenHeadersAreInserted) {
514*67e74705SXin Li std::string Code = "\n"
515*67e74705SXin Li "int x;\n"
516*67e74705SXin Li "int a;\n"
517*67e74705SXin Li "int a;\n"
518*67e74705SXin Li "int a;";
519*67e74705SXin Li
520*67e74705SXin Li std::string Expected = "\n#include \"x.h\"\n"
521*67e74705SXin Li "#include \"y.h\"\n"
522*67e74705SXin Li "#include \"clang/x/x.h\"\n"
523*67e74705SXin Li "#include <list>\n"
524*67e74705SXin Li "#include <vector>\n"
525*67e74705SXin Li "int x;\n"
526*67e74705SXin Li "int a;\n"
527*67e74705SXin Li "int b;\n"
528*67e74705SXin Li "int a;";
529*67e74705SXin Li tooling::Replacements Replaces = {
530*67e74705SXin Li createReplacement(getOffset(Code, 4, 8), 1, "b"),
531*67e74705SXin Li createInsertion("#include <vector>"),
532*67e74705SXin Li createInsertion("#include <list>"),
533*67e74705SXin Li createInsertion("#include \"clang/x/x.h\""),
534*67e74705SXin Li createInsertion("#include \"y.h\""),
535*67e74705SXin Li createInsertion("#include \"x.h\"")};
536*67e74705SXin Li EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
537*67e74705SXin Li }
538*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,NotConfusedByDefine)539*67e74705SXin Li TEST_F(CleanUpReplacementsTest, NotConfusedByDefine) {
540*67e74705SXin Li std::string Code = "void f() {}\n"
541*67e74705SXin Li "#define A \\\n"
542*67e74705SXin Li " int i;";
543*67e74705SXin Li std::string Expected = "#include <vector>\n"
544*67e74705SXin Li "void f() {}\n"
545*67e74705SXin Li "#define A \\\n"
546*67e74705SXin Li " int i;";
547*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
548*67e74705SXin Li EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
549*67e74705SXin Li }
550*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,SkippedTopComment)551*67e74705SXin Li TEST_F(CleanUpReplacementsTest, SkippedTopComment) {
552*67e74705SXin Li std::string Code = "// comment\n"
553*67e74705SXin Li "\n"
554*67e74705SXin Li " // comment\n";
555*67e74705SXin Li std::string Expected = "// comment\n"
556*67e74705SXin Li "\n"
557*67e74705SXin Li " // comment\n"
558*67e74705SXin Li "#include <vector>\n";
559*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
560*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
561*67e74705SXin Li }
562*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,SkippedMixedComments)563*67e74705SXin Li TEST_F(CleanUpReplacementsTest, SkippedMixedComments) {
564*67e74705SXin Li std::string Code = "// comment\n"
565*67e74705SXin Li "// comment \\\n"
566*67e74705SXin Li " comment continued\n"
567*67e74705SXin Li "/*\n"
568*67e74705SXin Li "* comment\n"
569*67e74705SXin Li "*/\n";
570*67e74705SXin Li std::string Expected = "// comment\n"
571*67e74705SXin Li "// comment \\\n"
572*67e74705SXin Li " comment continued\n"
573*67e74705SXin Li "/*\n"
574*67e74705SXin Li "* comment\n"
575*67e74705SXin Li "*/\n"
576*67e74705SXin Li "#include <vector>\n";
577*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
578*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
579*67e74705SXin Li }
580*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,MultipleBlockCommentsInOneLine)581*67e74705SXin Li TEST_F(CleanUpReplacementsTest, MultipleBlockCommentsInOneLine) {
582*67e74705SXin Li std::string Code = "/*\n"
583*67e74705SXin Li "* comment\n"
584*67e74705SXin Li "*/ /* comment\n"
585*67e74705SXin Li "*/\n"
586*67e74705SXin Li "\n\n"
587*67e74705SXin Li "/* c1 */ /*c2 */\n";
588*67e74705SXin Li std::string Expected = "/*\n"
589*67e74705SXin Li "* comment\n"
590*67e74705SXin Li "*/ /* comment\n"
591*67e74705SXin Li "*/\n"
592*67e74705SXin Li "\n\n"
593*67e74705SXin Li "/* c1 */ /*c2 */\n"
594*67e74705SXin Li "#include <vector>\n";
595*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
596*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
597*67e74705SXin Li }
598*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,CodeAfterComments)599*67e74705SXin Li TEST_F(CleanUpReplacementsTest, CodeAfterComments) {
600*67e74705SXin Li std::string Code = "/*\n"
601*67e74705SXin Li "* comment\n"
602*67e74705SXin Li "*/ /* comment\n"
603*67e74705SXin Li "*/\n"
604*67e74705SXin Li "\n\n"
605*67e74705SXin Li "/* c1 */ /*c2 */\n"
606*67e74705SXin Li "\n"
607*67e74705SXin Li "int x;\n";
608*67e74705SXin Li std::string Expected = "/*\n"
609*67e74705SXin Li "* comment\n"
610*67e74705SXin Li "*/ /* comment\n"
611*67e74705SXin Li "*/\n"
612*67e74705SXin Li "\n\n"
613*67e74705SXin Li "/* c1 */ /*c2 */\n"
614*67e74705SXin Li "\n"
615*67e74705SXin Li "#include <vector>\n"
616*67e74705SXin Li "int x;\n";
617*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
618*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
619*67e74705SXin Li }
620*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,FakeHeaderGuardIfDef)621*67e74705SXin Li TEST_F(CleanUpReplacementsTest, FakeHeaderGuardIfDef) {
622*67e74705SXin Li std::string Code = "// comment \n"
623*67e74705SXin Li "#ifdef X\n"
624*67e74705SXin Li "#define X\n";
625*67e74705SXin Li std::string Expected = "// comment \n"
626*67e74705SXin Li "#include <vector>\n"
627*67e74705SXin Li "#ifdef X\n"
628*67e74705SXin Li "#define X\n";
629*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
630*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
631*67e74705SXin Li }
632*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,RealHeaderGuardAfterComments)633*67e74705SXin Li TEST_F(CleanUpReplacementsTest, RealHeaderGuardAfterComments) {
634*67e74705SXin Li std::string Code = "// comment \n"
635*67e74705SXin Li "#ifndef X\n"
636*67e74705SXin Li "#define X\n"
637*67e74705SXin Li "int x;\n"
638*67e74705SXin Li "#define Y 1\n";
639*67e74705SXin Li std::string Expected = "// comment \n"
640*67e74705SXin Li "#ifndef X\n"
641*67e74705SXin Li "#define X\n"
642*67e74705SXin Li "#include <vector>\n"
643*67e74705SXin Li "int x;\n"
644*67e74705SXin Li "#define Y 1\n";
645*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
646*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
647*67e74705SXin Li }
648*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,IfNDefWithNoDefine)649*67e74705SXin Li TEST_F(CleanUpReplacementsTest, IfNDefWithNoDefine) {
650*67e74705SXin Li std::string Code = "// comment \n"
651*67e74705SXin Li "#ifndef X\n"
652*67e74705SXin Li "int x;\n"
653*67e74705SXin Li "#define Y 1\n";
654*67e74705SXin Li std::string Expected = "// comment \n"
655*67e74705SXin Li "#include <vector>\n"
656*67e74705SXin Li "#ifndef X\n"
657*67e74705SXin Li "int x;\n"
658*67e74705SXin Li "#define Y 1\n";
659*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
660*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
661*67e74705SXin Li }
662*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,HeaderGuardWithComment)663*67e74705SXin Li TEST_F(CleanUpReplacementsTest, HeaderGuardWithComment) {
664*67e74705SXin Li std::string Code = "// comment \n"
665*67e74705SXin Li "#ifndef X // comment\n"
666*67e74705SXin Li "// comment\n"
667*67e74705SXin Li "/* comment\n"
668*67e74705SXin Li "*/\n"
669*67e74705SXin Li "/* comment */ #define X\n"
670*67e74705SXin Li "int x;\n"
671*67e74705SXin Li "#define Y 1\n";
672*67e74705SXin Li std::string Expected = "// comment \n"
673*67e74705SXin Li "#ifndef X // comment\n"
674*67e74705SXin Li "// comment\n"
675*67e74705SXin Li "/* comment\n"
676*67e74705SXin Li "*/\n"
677*67e74705SXin Li "/* comment */ #define X\n"
678*67e74705SXin Li "#include <vector>\n"
679*67e74705SXin Li "int x;\n"
680*67e74705SXin Li "#define Y 1\n";
681*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
682*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
683*67e74705SXin Li }
684*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,EmptyCode)685*67e74705SXin Li TEST_F(CleanUpReplacementsTest, EmptyCode) {
686*67e74705SXin Li std::string Code = "";
687*67e74705SXin Li std::string Expected = "#include <vector>\n";
688*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
689*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
690*67e74705SXin Li }
691*67e74705SXin Li
692*67e74705SXin Li // FIXME: although this case does not crash, the insertion is wrong. A '\n'
693*67e74705SXin Li // should be inserted between the two #includes.
TEST_F(CleanUpReplacementsTest,NoNewLineAtTheEndOfCode)694*67e74705SXin Li TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCode) {
695*67e74705SXin Li std::string Code = "#include <map>";
696*67e74705SXin Li std::string Expected = "#include <map>#include <vector>\n";
697*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>")};
698*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
699*67e74705SXin Li }
700*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,SkipExistingHeaders)701*67e74705SXin Li TEST_F(CleanUpReplacementsTest, SkipExistingHeaders) {
702*67e74705SXin Li std::string Code = "#include \"a.h\"\n"
703*67e74705SXin Li "#include <vector>\n";
704*67e74705SXin Li std::string Expected = "#include \"a.h\"\n"
705*67e74705SXin Li "#include <vector>\n";
706*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include <vector>"),
707*67e74705SXin Li createInsertion("#include \"a.h\"")};
708*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
709*67e74705SXin Li }
710*67e74705SXin Li
TEST_F(CleanUpReplacementsTest,AddIncludesWithDifferentForms)711*67e74705SXin Li TEST_F(CleanUpReplacementsTest, AddIncludesWithDifferentForms) {
712*67e74705SXin Li std::string Code = "#include \"a.h\"\n"
713*67e74705SXin Li "#include <vector>\n";
714*67e74705SXin Li // FIXME: this might not be the best behavior.
715*67e74705SXin Li std::string Expected = "#include \"a.h\"\n"
716*67e74705SXin Li "#include \"vector\"\n"
717*67e74705SXin Li "#include <vector>\n"
718*67e74705SXin Li "#include <a.h>\n";
719*67e74705SXin Li tooling::Replacements Replaces = {createInsertion("#include \"vector\""),
720*67e74705SXin Li createInsertion("#include <a.h>")};
721*67e74705SXin Li EXPECT_EQ(Expected, apply(Code, Replaces));
722*67e74705SXin Li }
723*67e74705SXin Li
724*67e74705SXin Li } // end namespace
725*67e74705SXin Li } // end namespace format
726*67e74705SXin Li } // end namespace clang
727