1 //===- unittest/Tooling/CleanupTest.cpp - Include insertion/deletion tests ===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
11 #include "../Tooling/ReplacementTest.h"
12 #include "../Tooling/RewriterTestContext.h"
13 #include "clang/Format/Format.h"
14 #include "clang/Tooling/Core/Replacement.h"
15 
16 #include "gtest/gtest.h"
17 
18 using clang::tooling::ReplacementTest;
19 using clang::tooling::toReplacements;
20 
21 namespace clang {
22 namespace tooling {
23 namespace {
24 
25 class HeaderIncludesTest : public ::testing::Test {
26 protected:
27   std::string insert(llvm::StringRef Code, llvm::StringRef Header) {
28     HeaderIncludes Includes(FileName, Code, Style);
29     assert(Header.startswith("\"") || Header.startswith("<"));
30     auto R = Includes.insert(Header.trim("\"<>"), Header.startswith("<"));
31     if (!R)
32       return Code;
33     auto Result = applyAllReplacements(Code, Replacements(*R));
34     EXPECT_TRUE(static_cast<bool>(Result));
35     return *Result;
36   }
37 
38   std::string remove(llvm::StringRef Code, llvm::StringRef Header) {
39     HeaderIncludes Includes(FileName, Code, Style);
40     assert(Header.startswith("\"") || Header.startswith("<"));
41     auto Replaces = Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
42     auto Result = applyAllReplacements(Code, Replaces);
43     EXPECT_TRUE(static_cast<bool>(Result));
44     return *Result;
45   }
46 
47   const std::string FileName = "fix.cpp";
48   IncludeStyle Style = format::getLLVMStyle().IncludeStyle;
49 };
50 
51 TEST_F(HeaderIncludesTest, NoExistingIncludeWithoutDefine) {
52   std::string Code = "int main() {}";
53   std::string Expected = "#include \"a.h\"\n"
54                          "int main() {}";
55   EXPECT_EQ(Expected, insert(Code, "\"a.h\""));
56 }
57 
58 TEST_F(HeaderIncludesTest, NoExistingIncludeWithDefine) {
59   std::string Code = "#ifndef A_H\n"
60                      "#define A_H\n"
61                      "class A {};\n"
62                      "#define MMM 123\n"
63                      "#endif";
64   std::string Expected = "#ifndef A_H\n"
65                          "#define A_H\n"
66                          "#include \"b.h\"\n"
67                          "class A {};\n"
68                          "#define MMM 123\n"
69                          "#endif";
70 
71   EXPECT_EQ(Expected, insert(Code, "\"b.h\""));
72 }
73 
74 TEST_F(HeaderIncludesTest, InsertBeforeCategoryWithLowerPriority) {
75   std::string Code = "#ifndef A_H\n"
76                      "#define A_H\n"
77                      "\n"
78                      "\n"
79                      "\n"
80                      "#include <vector>\n"
81                      "class A {};\n"
82                      "#define MMM 123\n"
83                      "#endif";
84   std::string Expected = "#ifndef A_H\n"
85                          "#define A_H\n"
86                          "\n"
87                          "\n"
88                          "\n"
89                          "#include \"a.h\"\n"
90                          "#include <vector>\n"
91                          "class A {};\n"
92                          "#define MMM 123\n"
93                          "#endif";
94 
95   EXPECT_EQ(Expected, insert(Code, "\"a.h\""));
96 }
97 
98 TEST_F(HeaderIncludesTest, InsertAfterMainHeader) {
99   std::string Code = "#include \"fix.h\"\n"
100                      "\n"
101                      "int main() {}";
102   std::string Expected = "#include \"fix.h\"\n"
103                          "#include <a>\n"
104                          "\n"
105                          "int main() {}";
106   Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
107               .IncludeStyle;
108   EXPECT_EQ(Expected, insert(Code, "<a>"));
109 }
110 
111 TEST_F(HeaderIncludesTest, InsertBeforeSystemHeaderLLVM) {
112   std::string Code = "#include <memory>\n"
113                      "\n"
114                      "int main() {}";
115   std::string Expected = "#include \"z.h\"\n"
116                          "#include <memory>\n"
117                          "\n"
118                          "int main() {}";
119   EXPECT_EQ(Expected, insert(Code, "\"z.h\""));
120 }
121 
122 TEST_F(HeaderIncludesTest, InsertAfterSystemHeaderGoogle) {
123   std::string Code = "#include <memory>\n"
124                      "\n"
125                      "int main() {}";
126   std::string Expected = "#include <memory>\n"
127                          "#include \"z.h\"\n"
128                          "\n"
129                          "int main() {}";
130   Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
131               .IncludeStyle;
132   EXPECT_EQ(Expected, insert(Code, "\"z.h\""));
133 }
134 
135 TEST_F(HeaderIncludesTest, InsertOneIncludeLLVMStyle) {
136   std::string Code = "#include \"x/fix.h\"\n"
137                      "#include \"a.h\"\n"
138                      "#include \"b.h\"\n"
139                      "#include \"clang/Format/Format.h\"\n"
140                      "#include <memory>\n";
141   std::string Expected = "#include \"x/fix.h\"\n"
142                          "#include \"a.h\"\n"
143                          "#include \"b.h\"\n"
144                          "#include \"clang/Format/Format.h\"\n"
145                          "#include \"llvm/x/y.h\"\n"
146                          "#include <memory>\n";
147   EXPECT_EQ(Expected, insert(Code, "\"llvm/x/y.h\""));
148 }
149 
150 TEST_F(HeaderIncludesTest, InsertIntoBlockSorted) {
151   std::string Code = "#include \"x/fix.h\"\n"
152                      "#include \"a.h\"\n"
153                      "#include \"c.h\"\n"
154                      "#include <memory>\n";
155   std::string Expected = "#include \"x/fix.h\"\n"
156                          "#include \"a.h\"\n"
157                          "#include \"b.h\"\n"
158                          "#include \"c.h\"\n"
159                          "#include <memory>\n";
160   EXPECT_EQ(Expected, insert(Code, "\"b.h\""));
161 }
162 
163 TEST_F(HeaderIncludesTest, InsertIntoFirstBlockOfSameKind) {
164   std::string Code = "#include \"x/fix.h\"\n"
165                      "#include \"c.h\"\n"
166                      "#include \"e.h\"\n"
167                      "#include \"f.h\"\n"
168                      "#include <memory>\n"
169                      "#include <vector>\n"
170                      "#include \"m.h\"\n"
171                      "#include \"n.h\"\n";
172   std::string Expected = "#include \"x/fix.h\"\n"
173                          "#include \"c.h\"\n"
174                          "#include \"d.h\"\n"
175                          "#include \"e.h\"\n"
176                          "#include \"f.h\"\n"
177                          "#include <memory>\n"
178                          "#include <vector>\n"
179                          "#include \"m.h\"\n"
180                          "#include \"n.h\"\n";
181   EXPECT_EQ(Expected, insert(Code, "\"d.h\""));
182 }
183 
184 TEST_F(HeaderIncludesTest, InsertIntoSystemBlockSorted) {
185   std::string Code = "#include \"x/fix.h\"\n"
186                      "#include \"a.h\"\n"
187                      "#include \"c.h\"\n"
188                      "#include <a>\n"
189                      "#include <z>\n";
190   std::string Expected = "#include \"x/fix.h\"\n"
191                          "#include \"a.h\"\n"
192                          "#include \"c.h\"\n"
193                          "#include <a>\n"
194                          "#include <vector>\n"
195                          "#include <z>\n";
196   EXPECT_EQ(Expected, insert(Code, "<vector>"));
197 }
198 
199 TEST_F(HeaderIncludesTest, InsertNewSystemIncludeGoogleStyle) {
200   std::string Code = "#include \"x/fix.h\"\n"
201                      "\n"
202                      "#include \"y/a.h\"\n"
203                      "#include \"z/b.h\"\n";
204   // FIXME: inserting after the empty line following the main header might be
205   // preferred.
206   std::string Expected = "#include \"x/fix.h\"\n"
207                          "#include <vector>\n"
208                          "\n"
209                          "#include \"y/a.h\"\n"
210                          "#include \"z/b.h\"\n";
211   Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
212               .IncludeStyle;
213   EXPECT_EQ(Expected, insert(Code, "<vector>"));
214 }
215 
216 TEST_F(HeaderIncludesTest, NotConfusedByDefine) {
217   std::string Code = "void f() {}\n"
218                      "#define A \\\n"
219                      "  int i;";
220   std::string Expected = "#include <vector>\n"
221                          "void f() {}\n"
222                          "#define A \\\n"
223                          "  int i;";
224   EXPECT_EQ(Expected, insert(Code, "<vector>"));
225 }
226 
227 TEST_F(HeaderIncludesTest, SkippedTopComment) {
228   std::string Code = "// comment\n"
229                      "\n"
230                      "   // comment\n";
231   std::string Expected = "// comment\n"
232                          "\n"
233                          "   // comment\n"
234                          "#include <vector>\n";
235   EXPECT_EQ(Expected, insert(Code, "<vector>"));
236 }
237 
238 TEST_F(HeaderIncludesTest, SkippedMixedComments) {
239   std::string Code = "// comment\n"
240                      "// comment \\\n"
241                      " comment continued\n"
242                      "/*\n"
243                      "* comment\n"
244                      "*/\n";
245   std::string Expected = "// comment\n"
246                          "// comment \\\n"
247                          " comment continued\n"
248                          "/*\n"
249                          "* comment\n"
250                          "*/\n"
251                          "#include <vector>\n";
252   EXPECT_EQ(Expected, insert(Code, "<vector>"));
253 }
254 
255 TEST_F(HeaderIncludesTest, MultipleBlockCommentsInOneLine) {
256   std::string Code = "/*\n"
257                      "* comment\n"
258                      "*/ /* comment\n"
259                      "*/\n"
260                      "\n\n"
261                      "/* c1 */ /*c2 */\n";
262   std::string Expected = "/*\n"
263                          "* comment\n"
264                          "*/ /* comment\n"
265                          "*/\n"
266                          "\n\n"
267                          "/* c1 */ /*c2 */\n"
268                          "#include <vector>\n";
269   EXPECT_EQ(Expected, insert(Code, "<vector>"));
270 }
271 
272 TEST_F(HeaderIncludesTest, CodeAfterComments) {
273   std::string Code = "/*\n"
274                      "* comment\n"
275                      "*/ /* comment\n"
276                      "*/\n"
277                      "\n\n"
278                      "/* c1 */ /*c2 */\n"
279                      "\n"
280                      "int x;\n";
281   std::string Expected = "/*\n"
282                          "* comment\n"
283                          "*/ /* comment\n"
284                          "*/\n"
285                          "\n\n"
286                          "/* c1 */ /*c2 */\n"
287                          "\n"
288                          "#include <vector>\n"
289                          "int x;\n";
290   EXPECT_EQ(Expected, insert(Code, "<vector>"));
291 }
292 
293 TEST_F(HeaderIncludesTest, FakeHeaderGuardIfDef) {
294   std::string Code = "// comment \n"
295                      "#ifdef X\n"
296                      "#define X\n";
297   std::string Expected = "// comment \n"
298                          "#include <vector>\n"
299                          "#ifdef X\n"
300                          "#define X\n";
301   EXPECT_EQ(Expected, insert(Code, "<vector>"));
302 }
303 
304 TEST_F(HeaderIncludesTest, RealHeaderGuardAfterComments) {
305   std::string Code = "// comment \n"
306                      "#ifndef X\n"
307                      "#define X\n"
308                      "int x;\n"
309                      "#define Y 1\n";
310   std::string Expected = "// comment \n"
311                          "#ifndef X\n"
312                          "#define X\n"
313                          "#include <vector>\n"
314                          "int x;\n"
315                          "#define Y 1\n";
316   EXPECT_EQ(Expected, insert(Code, "<vector>"));
317 }
318 
319 TEST_F(HeaderIncludesTest, IfNDefWithNoDefine) {
320   std::string Code = "// comment \n"
321                      "#ifndef X\n"
322                      "int x;\n"
323                      "#define Y 1\n";
324   std::string Expected = "// comment \n"
325                          "#include <vector>\n"
326                          "#ifndef X\n"
327                          "int x;\n"
328                          "#define Y 1\n";
329   EXPECT_EQ(Expected, insert(Code, "<vector>"));
330 }
331 
332 TEST_F(HeaderIncludesTest, FakeHeaderGuard) {
333   std::string Code = "// comment \n"
334                      "#ifndef X\n"
335                      "#define 1\n";
336   std::string Expected = "// comment \n"
337                          "#include <vector>\n"
338                          "#ifndef X\n"
339                          "#define 1\n";
340   EXPECT_EQ(Expected, insert(Code, "<vector>"));
341 }
342 
343 TEST_F(HeaderIncludesTest, HeaderGuardWithComment) {
344   std::string Code = "// comment \n"
345                      "#ifndef X // comment\n"
346                      "// comment\n"
347                      "/* comment\n"
348                      "*/\n"
349                      "/* comment */ #define X\n"
350                      "int x;\n"
351                      "#define Y 1\n";
352   std::string Expected = "// comment \n"
353                          "#ifndef X // comment\n"
354                          "// comment\n"
355                          "/* comment\n"
356                          "*/\n"
357                          "/* comment */ #define X\n"
358                          "#include <vector>\n"
359                          "int x;\n"
360                          "#define Y 1\n";
361   EXPECT_EQ(Expected, insert(Code, "<vector>"));
362 }
363 
364 TEST_F(HeaderIncludesTest, EmptyCode) {
365   std::string Code = "";
366   std::string Expected = "#include <vector>\n";
367   EXPECT_EQ(Expected, insert(Code, "<vector>"));
368 }
369 
370 TEST_F(HeaderIncludesTest, NoNewLineAtTheEndOfCode) {
371   std::string Code = "#include <map>";
372   std::string Expected = "#include <map>\n#include <vector>\n";
373   EXPECT_EQ(Expected, insert(Code, "<vector>"));
374 }
375 
376 TEST_F(HeaderIncludesTest, SkipExistingHeaders) {
377   std::string Code = "#include \"a.h\"\n"
378                      "#include <vector>\n";
379   std::string Expected = "#include \"a.h\"\n"
380                          "#include <vector>\n";
381   EXPECT_EQ(Expected, insert(Code, "<vector>"));
382   EXPECT_EQ(Expected, insert(Code, "\"a.h\""));
383 }
384 
385 TEST_F(HeaderIncludesTest, AddIncludesWithDifferentForms) {
386   std::string Code = "#include <vector>\n";
387   // FIXME: this might not be the best behavior.
388   std::string Expected = "#include \"vector\"\n"
389                          "#include <vector>\n";
390   EXPECT_EQ(Expected, insert(Code, "\"vector\""));
391 }
392 
393 TEST_F(HeaderIncludesTest, NoInsertionAfterCode) {
394   std::string Code = "#include \"a.h\"\n"
395                      "void f() {}\n"
396                      "#include \"b.h\"\n";
397   std::string Expected = "#include \"a.h\"\n"
398                          "#include \"c.h\"\n"
399                          "void f() {}\n"
400                          "#include \"b.h\"\n";
401   EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
402 }
403 
404 TEST_F(HeaderIncludesTest, NoInsertionInStringLiteral) {
405   std::string Code = "#include \"a.h\"\n"
406                      "const char[] = R\"(\n"
407                      "#include \"b.h\"\n"
408                      ")\";\n";
409   std::string Expected = "#include \"a.h\"\n"
410                          "#include \"c.h\"\n"
411                          "const char[] = R\"(\n"
412                          "#include \"b.h\"\n"
413                          ")\";\n";
414   EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
415 }
416 
417 TEST_F(HeaderIncludesTest, NoInsertionAfterOtherDirective) {
418   std::string Code = "#include \"a.h\"\n"
419                      "#ifdef X\n"
420                      "#include \"b.h\"\n"
421                      "#endif\n";
422   std::string Expected = "#include \"a.h\"\n"
423                          "#include \"c.h\"\n"
424                          "#ifdef X\n"
425                          "#include \"b.h\"\n"
426                          "#endif\n";
427   EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
428 }
429 
430 TEST_F(HeaderIncludesTest, CanInsertAfterLongSystemInclude) {
431   std::string Code = "#include \"a.h\"\n"
432                      "// comment\n\n"
433                      "#include <a/b/c/d/e.h>\n";
434   std::string Expected = "#include \"a.h\"\n"
435                          "// comment\n\n"
436                          "#include <a/b/c/d/e.h>\n"
437                          "#include <x.h>\n";
438   EXPECT_EQ(Expected, insert(Code, "<x.h>"));
439 }
440 
441 TEST_F(HeaderIncludesTest, CanInsertAfterComment) {
442   std::string Code = "#include \"a.h\"\n"
443                      "// Comment\n"
444                      "\n"
445                      "/* Comment */\n"
446                      "// Comment\n"
447                      "\n"
448                      "#include \"b.h\"\n";
449   std::string Expected = "#include \"a.h\"\n"
450                          "// Comment\n"
451                          "\n"
452                          "/* Comment */\n"
453                          "// Comment\n"
454                          "\n"
455                          "#include \"b.h\"\n"
456                          "#include \"c.h\"\n";
457   EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
458 }
459 
460 TEST_F(HeaderIncludesTest, LongCommentsInTheBeginningOfFile) {
461   std::string Code = "// Loooooooooooooooooooooooooong comment\n"
462                      "// Loooooooooooooooooooooooooong comment\n"
463                      "// Loooooooooooooooooooooooooong comment\n"
464                      "#include <string>\n"
465                      "#include <vector>\n"
466                      "\n"
467                      "#include \"a.h\"\n"
468                      "#include \"b.h\"\n";
469   std::string Expected = "// Loooooooooooooooooooooooooong comment\n"
470                          "// Loooooooooooooooooooooooooong comment\n"
471                          "// Loooooooooooooooooooooooooong comment\n"
472                          "#include <string>\n"
473                          "#include <vector>\n"
474                          "\n"
475                          "#include \"a.h\"\n"
476                          "#include \"b.h\"\n"
477                          "#include \"third.h\"\n";
478   Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
479               .IncludeStyle;
480   EXPECT_EQ(Expected, insert(Code, "\"third.h\""));
481 }
482 
483 TEST_F(HeaderIncludesTest, SimpleDeleteInclude) {
484   std::string Code = "#include \"abc.h\"\n"
485                      "#include \"xyz.h\" // comment\n"
486                      "int x;\n";
487   std::string Expected = "#include \"abc.h\"\n"
488                          "int x;\n";
489   EXPECT_EQ(Expected, remove(Code, "\"xyz.h\""));
490 }
491 
492 TEST_F(HeaderIncludesTest, DeleteQuotedOnly) {
493   std::string Code = "#include \"abc.h\"\n"
494                      "#include <abc.h>\n"
495                      "int x;\n";
496   std::string Expected = "#include <abc.h>\n"
497                          "int x;\n";
498   EXPECT_EQ(Expected, remove(Code, "\"abc.h\""));
499 }
500 
501 TEST_F(HeaderIncludesTest, DeleteAllCode) {
502   std::string Code = "#include \"xyz.h\"\n";
503   std::string Expected = "";
504   EXPECT_EQ(Expected, remove(Code, "\"xyz.h\""));
505 }
506 
507 TEST_F(HeaderIncludesTest, DeleteOnlyIncludesWithSameQuote) {
508   std::string Code = "#include \"xyz.h\"\n"
509                      "#include \"xyz\"\n"
510                      "#include <xyz.h>\n";
511   std::string Expected = "#include \"xyz.h\"\n"
512                          "#include \"xyz\"\n";
513   EXPECT_EQ(Expected, remove(Code, "<xyz.h>"));
514 }
515 
516 TEST_F(HeaderIncludesTest, CanDeleteAfterCode) {
517   std::string Code = "#include \"a.h\"\n"
518                      "void f() {}\n"
519                      "#include \"b.h\"\n";
520   std::string Expected = "#include \"a.h\"\n"
521                          "void f() {}\n";
522   EXPECT_EQ(Expected, remove(Code, "\"b.h\""));
523 }
524 
525 } // namespace
526 } // namespace tooling
527 } // namespace clang
528