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, HeaderGuardWithComment) { 351 std::string Code = "// comment \n" 352 "#ifndef X // comment\n" 353 "// comment\n" 354 "/* comment\n" 355 "*/\n" 356 "/* comment */ #define X\n" 357 "int x;\n" 358 "#define Y 1\n"; 359 std::string Expected = "// comment \n" 360 "#ifndef X // comment\n" 361 "// comment\n" 362 "/* comment\n" 363 "*/\n" 364 "/* comment */ #define X\n" 365 "#include <vector>\n" 366 "int x;\n" 367 "#define Y 1\n"; 368 EXPECT_EQ(Expected, insert(Code, "<vector>")); 369 } 370 371 TEST_F(HeaderIncludesTest, EmptyCode) { 372 std::string Code = ""; 373 std::string Expected = "#include <vector>\n"; 374 EXPECT_EQ(Expected, insert(Code, "<vector>")); 375 } 376 377 TEST_F(HeaderIncludesTest, NoNewLineAtTheEndOfCode) { 378 std::string Code = "#include <map>"; 379 std::string Expected = "#include <map>\n#include <vector>\n"; 380 EXPECT_EQ(Expected, insert(Code, "<vector>")); 381 } 382 383 TEST_F(HeaderIncludesTest, SkipExistingHeaders) { 384 std::string Code = "#include \"a.h\"\n" 385 "#include <vector>\n"; 386 std::string Expected = "#include \"a.h\"\n" 387 "#include <vector>\n"; 388 EXPECT_EQ(Expected, insert(Code, "<vector>")); 389 EXPECT_EQ(Expected, insert(Code, "\"a.h\"")); 390 } 391 392 TEST_F(HeaderIncludesTest, AddIncludesWithDifferentForms) { 393 std::string Code = "#include <vector>\n"; 394 // FIXME: this might not be the best behavior. 395 std::string Expected = "#include \"vector\"\n" 396 "#include <vector>\n"; 397 EXPECT_EQ(Expected, insert(Code, "\"vector\"")); 398 } 399 400 TEST_F(HeaderIncludesTest, NoInsertionAfterCode) { 401 std::string Code = "#include \"a.h\"\n" 402 "void f() {}\n" 403 "#include \"b.h\"\n"; 404 std::string Expected = "#include \"a.h\"\n" 405 "#include \"c.h\"\n" 406 "void f() {}\n" 407 "#include \"b.h\"\n"; 408 EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); 409 } 410 411 TEST_F(HeaderIncludesTest, NoInsertionInStringLiteral) { 412 std::string Code = "#include \"a.h\"\n" 413 "const char[] = R\"(\n" 414 "#include \"b.h\"\n" 415 ")\";\n"; 416 std::string Expected = "#include \"a.h\"\n" 417 "#include \"c.h\"\n" 418 "const char[] = R\"(\n" 419 "#include \"b.h\"\n" 420 ")\";\n"; 421 EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); 422 } 423 424 TEST_F(HeaderIncludesTest, NoInsertionAfterOtherDirective) { 425 std::string Code = "#include \"a.h\"\n" 426 "#ifdef X\n" 427 "#include \"b.h\"\n" 428 "#endif\n"; 429 std::string Expected = "#include \"a.h\"\n" 430 "#include \"c.h\"\n" 431 "#ifdef X\n" 432 "#include \"b.h\"\n" 433 "#endif\n"; 434 EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); 435 } 436 437 TEST_F(HeaderIncludesTest, CanInsertAfterLongSystemInclude) { 438 std::string Code = "#include \"a.h\"\n" 439 "// comment\n\n" 440 "#include <a/b/c/d/e.h>\n"; 441 std::string Expected = "#include \"a.h\"\n" 442 "// comment\n\n" 443 "#include <a/b/c/d/e.h>\n" 444 "#include <x.h>\n"; 445 EXPECT_EQ(Expected, insert(Code, "<x.h>")); 446 } 447 448 TEST_F(HeaderIncludesTest, CanInsertAfterComment) { 449 std::string Code = "#include \"a.h\"\n" 450 "// Comment\n" 451 "\n" 452 "/* Comment */\n" 453 "// Comment\n" 454 "\n" 455 "#include \"b.h\"\n"; 456 std::string Expected = "#include \"a.h\"\n" 457 "// Comment\n" 458 "\n" 459 "/* Comment */\n" 460 "// Comment\n" 461 "\n" 462 "#include \"b.h\"\n" 463 "#include \"c.h\"\n"; 464 EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); 465 } 466 467 TEST_F(HeaderIncludesTest, LongCommentsInTheBeginningOfFile) { 468 std::string Code = "// Loooooooooooooooooooooooooong comment\n" 469 "// Loooooooooooooooooooooooooong comment\n" 470 "// Loooooooooooooooooooooooooong comment\n" 471 "#include <string>\n" 472 "#include <vector>\n" 473 "\n" 474 "#include \"a.h\"\n" 475 "#include \"b.h\"\n"; 476 std::string Expected = "// Loooooooooooooooooooooooooong comment\n" 477 "// Loooooooooooooooooooooooooong comment\n" 478 "// Loooooooooooooooooooooooooong comment\n" 479 "#include <string>\n" 480 "#include <vector>\n" 481 "\n" 482 "#include \"a.h\"\n" 483 "#include \"b.h\"\n" 484 "#include \"third.h\"\n"; 485 Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp) 486 .IncludeStyle; 487 EXPECT_EQ(Expected, insert(Code, "\"third.h\"")); 488 } 489 490 TEST_F(HeaderIncludesTest, SimpleDeleteInclude) { 491 std::string Code = "#include \"abc.h\"\n" 492 "#include \"xyz.h\" // comment\n" 493 "int x;\n"; 494 std::string Expected = "#include \"abc.h\"\n" 495 "int x;\n"; 496 EXPECT_EQ(Expected, remove(Code, "\"xyz.h\"")); 497 } 498 499 TEST_F(HeaderIncludesTest, DeleteQuotedOnly) { 500 std::string Code = "#include \"abc.h\"\n" 501 "#include <abc.h>\n" 502 "int x;\n"; 503 std::string Expected = "#include <abc.h>\n" 504 "int x;\n"; 505 EXPECT_EQ(Expected, remove(Code, "\"abc.h\"")); 506 } 507 508 TEST_F(HeaderIncludesTest, DeleteAllCode) { 509 std::string Code = "#include \"xyz.h\"\n"; 510 std::string Expected = ""; 511 EXPECT_EQ(Expected, remove(Code, "\"xyz.h\"")); 512 } 513 514 TEST_F(HeaderIncludesTest, DeleteOnlyIncludesWithSameQuote) { 515 std::string Code = "#include \"xyz.h\"\n" 516 "#include \"xyz\"\n" 517 "#include <xyz.h>\n"; 518 std::string Expected = "#include \"xyz.h\"\n" 519 "#include \"xyz\"\n"; 520 EXPECT_EQ(Expected, remove(Code, "<xyz.h>")); 521 } 522 523 TEST_F(HeaderIncludesTest, CanDeleteAfterCode) { 524 std::string Code = "#include \"a.h\"\n" 525 "void f() {}\n" 526 "#include \"b.h\"\n"; 527 std::string Expected = "#include \"a.h\"\n" 528 "void f() {}\n"; 529 EXPECT_EQ(Expected, remove(Code, "\"b.h\"")); 530 } 531 532 } // namespace 533 } // namespace tooling 534 } // namespace clang 535