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