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