713 lines · cpp
1//===- unittest/Format/FormatTestSelective.cpp - Formatting unit 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "FormatTestUtils.h"10#include "clang/Format/Format.h"11#include "llvm/Support/Debug.h"12#include "gtest/gtest.h"13 14#define DEBUG_TYPE "format-test"15 16namespace clang {17namespace format {18namespace {19 20class FormatTestSelective : public testing::Test {21protected:22 std::string format(StringRef Code, unsigned Offset, unsigned Length) {23 LLVM_DEBUG(llvm::errs() << "---\n");24 LLVM_DEBUG(llvm::errs() << Code << "\n\n");25 std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));26 FormattingAttemptStatus Status;27 tooling::Replacements Replaces =28 reformat(Style, Code, Ranges, "<stdin>", &Status);29 EXPECT_TRUE(Status.FormatComplete) << Code << "\n\n";30 auto Result = applyAllReplacements(Code, Replaces);31 EXPECT_TRUE(static_cast<bool>(Result));32 LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");33 return *Result;34 }35 36 FormatStyle Style = getLLVMStyle();37};38 39TEST_F(FormatTestSelective, RemovesTrailingWhitespaceOfFormattedLine) {40 EXPECT_EQ("int a;\nint b;", format("int a; \nint b;", 0, 0));41 EXPECT_EQ("int a;", format("int a; ", 0, 0));42 EXPECT_EQ("int a;\n", format("int a; \n \n \n ", 0, 0));43 EXPECT_EQ("int a;\nint b; ", format("int a; \nint b; ", 0, 0));44 45 EXPECT_EQ("void f() {}", format("void f() {\n"46 " \n"47 "}",48 11, 0));49}50 51TEST_F(FormatTestSelective, FormatsCorrectRegionForLeadingWhitespace) {52 EXPECT_EQ("{int b;\n"53 " int a;\n"54 "}",55 format("{int b;\n int a;}", 8, 0));56 EXPECT_EQ("{\n"57 " int b;\n"58 " int a;}",59 format("{int b;\n int a;}", 7, 0));60 61 Style.ColumnLimit = 12;62 EXPECT_EQ("#define A \\\n"63 " int a; \\\n"64 " int b;",65 format("#define A \\\n"66 " int a; \\\n"67 " int b;",68 26, 0));69 EXPECT_EQ("#define A \\\n"70 " int a; \\\n"71 " int b;",72 format("#define A \\\n"73 " int a; \\\n"74 " int b;",75 25, 0));76}77 78TEST_F(FormatTestSelective, FormatLineWhenInvokedOnTrailingNewline) {79 EXPECT_EQ("int b;\n\nint a;", format("int b;\n\nint a;", 8, 0));80 EXPECT_EQ("int b;\n\nint a;", format("int b;\n\nint a;", 7, 0));81 82 // This might not strictly be correct, but is likely good in all practical83 // cases.84 EXPECT_EQ("int b;\nint a;", format("int b;int a;", 7, 0));85}86 87TEST_F(FormatTestSelective, RemovesWhitespaceWhenTriggeredOnEmptyLine) {88 EXPECT_EQ("int a;\n\n int b;", format("int a;\n \n\n int b;", 8, 0));89 EXPECT_EQ("int a;\n\n int b;", format("int a;\n \n\n int b;", 9, 0));90}91 92TEST_F(FormatTestSelective, ReformatsMovedLines) {93 EXPECT_EQ(94 "template <typename T> T *getFETokenInfo() const {\n"95 " return static_cast<T *>(FETokenInfo);\n"96 "}\n"97 "int a; // <- Should not be formatted",98 format(99 "template<typename T>\n"100 "T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }\n"101 "int a; // <- Should not be formatted",102 9, 5));103}104 105TEST_F(FormatTestSelective, FormatsIfWithoutCompoundStatement) {106 Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;107 EXPECT_EQ("if (a) return;", format("if(a)\nreturn;", 7, 1));108 EXPECT_EQ("if (a) return; // comment",109 format("if(a)\nreturn; // comment", 20, 1));110}111 112TEST_F(FormatTestSelective, FormatsCommentsLocally) {113 EXPECT_EQ("int a; // comment\n"114 "int b; // comment",115 format("int a; // comment\n"116 "int b; // comment",117 0, 0));118 EXPECT_EQ("int a; // comment\n"119 " // line 2\n"120 "int b;",121 format("int a; // comment\n"122 " // line 2\n"123 "int b;",124 28, 0));125 EXPECT_EQ("int a; // comment\n"126 "// comment 2\n"127 "int b;",128 format("int a; // comment\n"129 "// comment 2\n"130 "int b;",131 28, 0));132 EXPECT_EQ("int aaaaaa; // comment\n"133 "int b;\n"134 "int c; // unrelated comment",135 format("int aaaaaa; // comment\n"136 "int b;\n"137 "int c; // unrelated comment",138 31, 0));139 140 EXPECT_EQ("int a; // This\n"141 " // is\n"142 " // a",143 format("int a; // This\n"144 " // is\n"145 " // a",146 0, 0));147 EXPECT_EQ("int a; // This\n"148 " // is\n"149 " // a\n"150 "// This is b\n"151 "int b;",152 format("int a; // This\n"153 " // is\n"154 " // a\n"155 "// This is b\n"156 "int b;",157 0, 0));158 EXPECT_EQ("int a; // This\n"159 " // is\n"160 " // a\n"161 "\n"162 "//This is unrelated",163 format("int a; // This\n"164 " // is\n"165 " // a\n"166 "\n"167 "//This is unrelated",168 0, 0));169 EXPECT_EQ("int a;\n"170 "// This is\n"171 "// not formatted. ",172 format("int a;\n"173 "// This is\n"174 "// not formatted. ",175 0, 0));176 EXPECT_EQ("int x; // Format this line.\n"177 "int xx; //\n"178 "int xxxxx; //",179 format("int x; // Format this line.\n"180 "int xx; //\n"181 "int xxxxx; //",182 0, 0));183}184 185TEST_F(FormatTestSelective, ContinueReindenting) {186 // When we change an indent, we continue formatting as long as following187 // lines are not indented correctly.188 EXPECT_EQ("int i;\n"189 "int b;\n"190 "int c;\n"191 "int d;\n"192 "int e;\n"193 " int f;",194 format("int i;\n"195 " int b;\n"196 " int c;\n"197 " int d;\n"198 "int e;\n"199 " int f;",200 11, 0));201}202 203TEST_F(FormatTestSelective, ReindentClosingBrace) {204 EXPECT_EQ("int i;\n"205 "int f() {\n"206 " int a;\n"207 " int b;\n"208 "}\n"209 " int c;",210 format("int i;\n"211 " int f(){\n"212 "int a;\n"213 "int b;\n"214 " }\n"215 " int c;",216 11, 0));217 EXPECT_EQ("void f() {\n"218 " if (foo) {\n"219 " b();\n"220 " } else {\n"221 " c();\n"222 " }\n"223 "int d;\n"224 "}",225 format("void f() {\n"226 " if (foo) {\n"227 "b();\n"228 "}else{\n"229 "c();\n"230 "}\n"231 "int d;\n"232 "}",233 13, 0));234 EXPECT_EQ("int i = []() {\n"235 " class C {\n"236 " int a;\n"237 " int b;\n"238 " };\n"239 " int c;\n"240 "};",241 format("int i = []() {\n"242 " class C{\n"243 "int a;\n"244 "int b;\n"245 "};\n"246 "int c;\n"247 " };",248 17, 0));249}250 251TEST_F(FormatTestSelective, IndividualStatementsOfNestedBlocks) {252 EXPECT_EQ("DEBUG({\n"253 " int i;\n"254 " int j;\n"255 "});",256 format("DEBUG( {\n"257 " int i;\n"258 " int j;\n"259 "} ) ;",260 20, 1));261 EXPECT_EQ("DEBUG( {\n"262 " int i;\n"263 " int j;\n"264 "} ) ;",265 format("DEBUG( {\n"266 " int i;\n"267 " int j;\n"268 "} ) ;",269 41, 1));270 EXPECT_EQ("DEBUG( {\n"271 " int i;\n"272 " int j;\n"273 "} ) ;",274 format("DEBUG( {\n"275 " int i;\n"276 " int j;\n"277 "} ) ;",278 41, 1));279 EXPECT_EQ("DEBUG({\n"280 " int i;\n"281 " int j;\n"282 "});",283 format("DEBUG( {\n"284 " int i;\n"285 " int j;\n"286 "} ) ;",287 20, 1));288 289 EXPECT_EQ("Debug({\n"290 " if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"291 " return;\n"292 " },\n"293 " a);",294 format("Debug({\n"295 " if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"296 " return;\n"297 " },\n"298 " a);",299 50, 1));300 EXPECT_EQ("DEBUG({\n"301 " DEBUG({\n"302 " int a;\n"303 " int b;\n"304 " }) ;\n"305 "});",306 format("DEBUG({\n"307 " DEBUG({\n"308 " int a;\n"309 " int b;\n" // Format this line only.310 " }) ;\n" // Don't touch this line.311 "});",312 35, 0));313 EXPECT_EQ("DEBUG({\n"314 " int a; //\n"315 "});",316 format("DEBUG({\n"317 " int a; //\n"318 "});",319 0, 0));320 EXPECT_EQ("someFunction(\n"321 " [] {\n"322 " // Only with this comment.\n"323 " int i; // invoke formatting here.\n"324 " }, // force line break\n"325 " aaa);",326 format("someFunction(\n"327 " [] {\n"328 " // Only with this comment.\n"329 " int i; // invoke formatting here.\n"330 " }, // force line break\n"331 " aaa);",332 63, 1));333 334 EXPECT_EQ("int longlongname; // comment\n"335 "int x = f({\n"336 " int x; // comment\n"337 " int y; // comment\n"338 "});",339 format("int longlongname; // comment\n"340 "int x = f({\n"341 " int x; // comment\n"342 " int y; // comment\n"343 "});",344 65, 0));345 EXPECT_EQ("int s = f({\n"346 " class X {\n"347 " public:\n"348 " void f();\n"349 " };\n"350 "});",351 format("int s = f({\n"352 " class X {\n"353 " public:\n"354 " void f();\n"355 " };\n"356 "});",357 0, 0));358 EXPECT_EQ("SomeFunction(\n"359 " [] {\n"360 " int i;\n"361 " return i;\n" // Format this line.362 " },\n"363 " [] {\n"364 " return 2;\n" // Don't fix this.365 " });",366 format("SomeFunction(\n"367 " [] {\n"368 " int i;\n"369 " return i;\n" // Format this line.370 " },\n"371 " [] {\n"372 " return 2;\n" // Don't fix this.373 " });",374 40, 0));375}376 377TEST_F(FormatTestSelective, WrongIndent) {378 EXPECT_EQ("namespace {\n"379 "int i;\n"380 "int j;\n"381 "}",382 format("namespace {\n"383 " int i;\n" // Format here.384 " int j;\n"385 "}",386 15, 0));387 EXPECT_EQ("namespace {\n"388 " int i;\n"389 " int j;\n"390 "}",391 format("namespace {\n"392 " int i;\n"393 " int j;\n" // Format here.394 "}",395 24, 0));396 EXPECT_EQ("namespace {\n"397 "class C {\n"398 " int i;\n"399 "};\n"400 "} // namespace",401 format("namespace {\n" // Format here.402 " class C {\n"403 " int i;\n"404 " };\n"405 "}",406 1, 0));407}408 409TEST_F(FormatTestSelective, AlwaysFormatsEntireMacroDefinitions) {410 Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;411 EXPECT_EQ("int i;\n"412 "#define A \\\n"413 " int i; \\\n"414 " int j\n"415 "int k;",416 format("int i;\n"417 "#define A \\\n"418 " int i ; \\\n"419 " int j\n"420 "int k;",421 8, 0)); // 8: position of "#define".422 EXPECT_EQ("int i;\n"423 "#define A \\\n"424 " int i; \\\n"425 " int j\n"426 "int k;",427 format("int i;\n"428 "#define A \\\n"429 " int i ; \\\n"430 " int j\n"431 "int k;",432 45, 0)); // 45: position of "j".433}434 435TEST_F(FormatTestSelective, ReformatRegionAdjustsIndent) {436 EXPECT_EQ("{\n"437 "{\n"438 "a;\n"439 "b;\n"440 "}\n"441 "}",442 format("{\n"443 "{\n"444 "a;\n"445 " b;\n"446 "}\n"447 "}",448 13, 2));449 EXPECT_EQ("{\n"450 "{\n"451 " a;\n"452 " b;\n"453 " c;\n"454 " d;\n"455 "}\n"456 "}",457 format("{\n"458 "{\n"459 " a;\n"460 " b;\n"461 " c;\n"462 " d;\n"463 "}\n"464 "}",465 9, 2));466 EXPECT_EQ("{\n"467 "{\n"468 "public:\n"469 " b;\n"470 "}\n"471 "}",472 format("{\n"473 "{\n"474 "public:\n"475 " b;\n"476 "}\n"477 "}",478 17, 2));479 EXPECT_EQ("{\n"480 "{\n"481 "a;\n"482 "}\n"483 "{\n"484 " b; //\n"485 "}\n"486 "}",487 format("{\n"488 "{\n"489 "a;\n"490 "}\n"491 "{\n"492 " b; //\n"493 "}\n"494 "}",495 22, 2));496 EXPECT_EQ(" {\n"497 " a; //\n"498 " }",499 format(" {\n"500 "a; //\n"501 " }",502 4, 2));503 EXPECT_EQ("void f() {}\n"504 "void g() {}",505 format("void f() {}\n"506 "void g() {}",507 13, 0));508 EXPECT_EQ("int a; // comment\n"509 " // line 2\n"510 "int b;",511 format("int a; // comment\n"512 " // line 2\n"513 " int b;",514 35, 0));515 516 EXPECT_EQ(" void f() {\n"517 "#define A 1\n"518 " }",519 format(" void f() {\n"520 " #define A 1\n" // Format this line.521 " }",522 20, 0));523 EXPECT_EQ(" void f() {\n"524 " int i;\n"525 "#define A \\\n"526 " int i; \\\n"527 " int j;\n"528 " int k;\n"529 " }",530 format(" void f() {\n"531 " int i;\n"532 "#define A \\\n"533 " int i; \\\n"534 " int j;\n"535 " int k;\n" // Format this line.536 " }",537 67, 0));538 539 Style.ColumnLimit = 11;540 EXPECT_EQ(" int a;\n"541 " void\n"542 " ffffff() {\n"543 " }",544 format(" int a;\n"545 "void ffffff() {}",546 11, 0));547 548 // https://github.com/llvm/llvm-project/issues/59178549 Style = getMozillaStyle();550 EXPECT_EQ("int a()\n"551 "{\n"552 "return 0;\n"553 "}\n"554 "int b()\n"555 "{\n"556 " return 42;\n"557 "}",558 format("int a()\n"559 "{\n"560 "return 0;\n"561 "}\n"562 "int b()\n"563 "{\n"564 "return 42;\n" // Format this line only565 "}",566 32, 0));567}568 569TEST_F(FormatTestSelective, UnderstandsTabs) {570 Style.IndentWidth = 8;571 Style.UseTab = FormatStyle::UT_Always;572 Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;573 EXPECT_EQ("void f() {\n"574 "\tf();\n"575 "\tg();\n"576 "}",577 format("void f() {\n"578 "\tf();\n"579 "\tg();\n"580 "}",581 0, 0));582 EXPECT_EQ("void f() {\n"583 "\tf();\n"584 "\tg();\n"585 "}",586 format("void f() {\n"587 "\tf();\n"588 "\tg();\n"589 "}",590 16, 0));591 EXPECT_EQ("void f() {\n"592 " \tf();\n"593 "\tg();\n"594 "}",595 format("void f() {\n"596 " \tf();\n"597 " \tg();\n"598 "}",599 21, 0));600}601 602TEST_F(FormatTestSelective, StopFormattingWhenLeavingScope) {603 EXPECT_EQ(604 "void f() {\n"605 " if (a) {\n"606 " g();\n"607 " h();\n"608 " }\n"609 "\n"610 "void g() {\n"611 "}",612 format("void f() {\n"613 " if (a) {\n" // Assume this was added without the closing brace.614 " g();\n"615 " h();\n"616 "}\n"617 "\n"618 "void g() {\n" // Make sure not to format this.619 "}",620 15, 0));621}622 623TEST_F(FormatTestSelective, SelectivelyRequoteJavaScript) {624 Style = getGoogleStyle(FormatStyle::LK_JavaScript);625 EXPECT_EQ("var x = \"a\";\n"626 "var x = 'a';\n"627 "var x = \"a\";",628 format("var x = \"a\";\n"629 "var x = \"a\";\n"630 "var x = \"a\";",631 20, 0));632}633 634TEST_F(FormatTestSelective, KeepsIndentAfterCommentSectionImport) {635 std::string Code = "#include <a> // line 1\n" // 23 chars long636 " // line 2\n" // 23 chars long637 "\n" // this newline is char 47638 "int i;"; // this line is not indented639 EXPECT_EQ(Code, format(Code, 47, 1));640}641 642TEST_F(FormatTestSelective, DontAssert) {643 // https://llvm.org/PR53880644 std::string Code = "void f() {\n"645 " return a == 8 ? 32 : 16;\n"646 "}\n";647 EXPECT_EQ(Code, format(Code, 40, 0));648 649 // https://llvm.org/PR56352650 Style.CompactNamespaces = true;651 Style.NamespaceIndentation = FormatStyle::NI_All;652 Code = "\n"653 "namespace ns1 { namespace ns2 {\n"654 "}}";655 EXPECT_EQ(Code, format(Code, 0, 0));656 657 // https://reviews.llvm.org/D151047#4369742658 Style = getLLVMStyle();659 Style.FixNamespaceComments = false;660 Code = "namespace ns {\n"661 "#define REF(alias) alias alias_var;\n"662 "}"; // Format this line only663 EXPECT_EQ(Code, format(Code, 51, 0));664}665 666TEST_F(FormatTestSelective, FormatMacroRegardlessOfPreviousIndent) {667 // clang-format currently does not (or should not) take into account the668 // indent of previous unformatted lines when formatting a PP directive.669 // Technically speaking, LevelIndentTracker::IndentForLevel is only for non-PP670 // lines. So these tests here check that the indent of previous non-PP lines671 // do not affect the formatting. If this requirement changes, the tests here672 // need to be adapted.673 Style = getLLVMStyle();674 675 constexpr StringRef Code(" class Foo {\n"676 " void test() {\n"677 " #ifdef 1\n"678 " #define some\n" // format this line679 " #endif\n"680 " }};");681 682 EXPECT_EQ(Style.IndentPPDirectives, FormatStyle::PPDIS_None);683 EXPECT_EQ(" class Foo {\n"684 " void test() {\n"685 " #ifdef 1\n"686 "#define some\n" // Formatted line687 "#endif\n" // That this line is also formatted might be a bug.688 " }};", // Ditto: Bug?689 format(Code, 57, 0));690 691 Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;692 EXPECT_EQ(" class Foo {\n"693 " void test() {\n"694 " #ifdef 1\n"695 " #define some\n" // Formatted line696 " #endif\n"697 " }};",698 format(Code, 57, 0));699 700 Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash;701 EXPECT_EQ(" class Foo {\n"702 " void test() {\n"703 " #ifdef 1\n"704 "# define some\n" // Formatted line705 "#endif\n" // That this line is also formatted might be a bug.706 " }};",707 format(Code, 57, 0));708}709 710} // end namespace711} // end namespace format712} // end namespace clang713