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