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