940 lines · cpp
1//===- unittest/Format/BracesRemoverTest.cpp ------------------------------===//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 "FormatTestBase.h"10 11#define DEBUG_TYPE "braces-remover-test"12 13namespace clang {14namespace format {15namespace test {16namespace {17 18class BracesRemoverTest : public FormatTestBase {};19 20TEST_F(BracesRemoverTest, RemoveBraces) {21 FormatStyle Style = getLLVMStyle();22 Style.RemoveBracesLLVM = true;23 24 // The following test cases are fully-braced versions of the examples at25 // "llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-26 // statement-bodies-of-if-else-loop-statements".27 28 // Omit the braces since the body is simple and clearly associated with the29 // `if`.30 verifyFormat("if (isa<FunctionDecl>(D))\n"31 " handleFunctionDecl(D);\n"32 "else if (isa<VarDecl>(D))\n"33 " handleVarDecl(D);",34 "if (isa<FunctionDecl>(D)) {\n"35 " handleFunctionDecl(D);\n"36 "} else if (isa<VarDecl>(D)) {\n"37 " handleVarDecl(D);\n"38 "}",39 Style);40 41 // Here we document the condition itself and not the body.42 verifyFormat("if (isa<VarDecl>(D)) {\n"43 " // It is necessary that we explain the situation with this\n"44 " // surprisingly long comment, so it would be unclear\n"45 " // without the braces whether the following statement is in\n"46 " // the scope of the `if`.\n"47 " // Because the condition is documented, we can't really\n"48 " // hoist this comment that applies to the body above the\n"49 " // `if`.\n"50 " handleOtherDecl(D);\n"51 "}",52 Style);53 54 // Use braces on the outer `if` to avoid a potential dangling `else`55 // situation.56 verifyFormat("if (isa<VarDecl>(D)) {\n"57 " if (shouldProcessAttr(A))\n"58 " handleAttr(A);\n"59 "}",60 "if (isa<VarDecl>(D)) {\n"61 " if (shouldProcessAttr(A)) {\n"62 " handleAttr(A);\n"63 " }\n"64 "}",65 Style);66 67 // Use braces for the `if` block to keep it uniform with the `else` block.68 verifyFormat("if (isa<FunctionDecl>(D)) {\n"69 " handleFunctionDecl(D);\n"70 "} else {\n"71 " // In this `else` case, it is necessary that we explain the\n"72 " // situation with this surprisingly long comment, so it\n"73 " // would be unclear without the braces whether the\n"74 " // following statement is in the scope of the `if`.\n"75 " handleOtherDecl(D);\n"76 "}",77 Style);78 79 // This should also omit braces. The `for` loop contains only a single80 // statement, so it shouldn't have braces. The `if` also only contains a81 // single simple statement (the `for` loop), so it also should omit braces.82 verifyFormat("if (isa<FunctionDecl>(D))\n"83 " for (auto *A : D.attrs())\n"84 " handleAttr(A);",85 "if (isa<FunctionDecl>(D)) {\n"86 " for (auto *A : D.attrs()) {\n"87 " handleAttr(A);\n"88 " }\n"89 "}",90 Style);91 92 // Use braces for a `do-while` loop and its enclosing statement.93 verifyFormat("if (Tok->is(tok::l_brace)) {\n"94 " do {\n"95 " Tok = Tok->Next;\n"96 " } while (Tok);\n"97 "}",98 Style);99 100 // Use braces for the outer `if` since the nested `for` is braced.101 verifyFormat("if (isa<FunctionDecl>(D)) {\n"102 " for (auto *A : D.attrs()) {\n"103 " // In this `for` loop body, it is necessary that we\n"104 " // explain the situation with this surprisingly long\n"105 " // comment, forcing braces on the `for` block.\n"106 " handleAttr(A);\n"107 " }\n"108 "}",109 Style);110 111 // Use braces on the outer block because there are more than two levels of112 // nesting.113 verifyFormat("if (isa<FunctionDecl>(D)) {\n"114 " for (auto *A : D.attrs())\n"115 " for (ssize_t i : llvm::seq<ssize_t>(count))\n"116 " handleAttrOnDecl(D, A, i);\n"117 "}",118 "if (isa<FunctionDecl>(D)) {\n"119 " for (auto *A : D.attrs()) {\n"120 " for (ssize_t i : llvm::seq<ssize_t>(count)) {\n"121 " handleAttrOnDecl(D, A, i);\n"122 " }\n"123 " }\n"124 "}",125 Style);126 127 // Use braces on the outer block because of a nested `if`; otherwise the128 // compiler would warn: `add explicit braces to avoid dangling else`129 verifyFormat("if (auto *D = dyn_cast<FunctionDecl>(D)) {\n"130 " if (shouldProcess(D))\n"131 " handleVarDecl(D);\n"132 " else\n"133 " markAsIgnored(D);\n"134 "}",135 "if (auto *D = dyn_cast<FunctionDecl>(D)) {\n"136 " if (shouldProcess(D)) {\n"137 " handleVarDecl(D);\n"138 " } else {\n"139 " markAsIgnored(D);\n"140 " }\n"141 "}",142 Style);143 144 verifyFormat("// clang-format off\n"145 "// comment\n"146 "while (i > 0) { --i; }\n"147 "// clang-format on\n"148 "while (j < 0)\n"149 " ++j;",150 "// clang-format off\n"151 "// comment\n"152 "while (i > 0) { --i; }\n"153 "// clang-format on\n"154 "while (j < 0) { ++j; }",155 Style);156 157 verifyFormat("for (;;) {\n"158 " for (;;)\n"159 " for (;;)\n"160 " a;\n"161 "}",162 "for (;;) {\n"163 " for (;;) {\n"164 " for (;;) {\n"165 " a;\n"166 " }\n"167 " }\n"168 "}",169 Style);170 171 verifyFormat("if (a)\n"172 " b; // comment\n"173 "else if (c)\n"174 " d; /* comment */\n"175 "else\n"176 " e;",177 "if (a) {\n"178 " b; // comment\n"179 "} else if (c) {\n"180 " d; /* comment */\n"181 "} else {\n"182 " e;\n"183 "}",184 Style);185 186 verifyFormat("if (a) {\n"187 " b;\n"188 " c;\n"189 "} else if (d) {\n"190 " e;\n"191 "}",192 Style);193 194 verifyFormat("if (a) {\n"195 "#undef NDEBUG\n"196 " b;\n"197 "} else {\n"198 " c;\n"199 "}",200 Style);201 202 verifyFormat("if (a) {\n"203 " // comment\n"204 "} else if (b) {\n"205 " c;\n"206 "}",207 Style);208 209 verifyFormat("if (a) {\n"210 " b;\n"211 "} else {\n"212 " {\n"213 " c;\n"214 " }\n"215 "}",216 Style);217 218 verifyFormat("if (a) {\n"219 " if (b) // comment\n"220 " c;\n"221 "} else if (d) {\n"222 " e;\n"223 "}",224 "if (a) {\n"225 " if (b) { // comment\n"226 " c;\n"227 " }\n"228 "} else if (d) {\n"229 " e;\n"230 "}",231 Style);232 233 verifyFormat("if (a) {\n"234 " if (b) {\n"235 " c;\n"236 " // comment\n"237 " } else if (d) {\n"238 " e;\n"239 " }\n"240 "}",241 Style);242 243 verifyFormat("if (a) {\n"244 " if (b)\n"245 " c;\n"246 "}",247 "if (a) {\n"248 " if (b) {\n"249 " c;\n"250 " }\n"251 "}",252 Style);253 254 verifyFormat("if (a)\n"255 " if (b)\n"256 " c;\n"257 " else\n"258 " d;\n"259 "else\n"260 " e;",261 "if (a) {\n"262 " if (b) {\n"263 " c;\n"264 " } else {\n"265 " d;\n"266 " }\n"267 "} else {\n"268 " e;\n"269 "}",270 Style);271 272 verifyFormat("if (a) {\n"273 " // comment\n"274 " if (b)\n"275 " c;\n"276 " else if (d)\n"277 " e;\n"278 "} else {\n"279 " g;\n"280 "}",281 "if (a) {\n"282 " // comment\n"283 " if (b) {\n"284 " c;\n"285 " } else if (d) {\n"286 " e;\n"287 " }\n"288 "} else {\n"289 " g;\n"290 "}",291 Style);292 293 verifyFormat("if (a)\n"294 " b;\n"295 "else if (c)\n"296 " d;\n"297 "else\n"298 " e;",299 "if (a) {\n"300 " b;\n"301 "} else {\n"302 " if (c) {\n"303 " d;\n"304 " } else {\n"305 " e;\n"306 " }\n"307 "}",308 Style);309 310 verifyFormat("if (a) {\n"311 " if (b)\n"312 " c;\n"313 " else if (d)\n"314 " e;\n"315 "} else {\n"316 " g;\n"317 "}",318 "if (a) {\n"319 " if (b)\n"320 " c;\n"321 " else {\n"322 " if (d)\n"323 " e;\n"324 " }\n"325 "} else {\n"326 " g;\n"327 "}",328 Style);329 330 verifyFormat("if (isa<VarDecl>(D)) {\n"331 " for (auto *A : D.attrs())\n"332 " if (shouldProcessAttr(A))\n"333 " handleAttr(A);\n"334 "}",335 "if (isa<VarDecl>(D)) {\n"336 " for (auto *A : D.attrs()) {\n"337 " if (shouldProcessAttr(A)) {\n"338 " handleAttr(A);\n"339 " }\n"340 " }\n"341 "}",342 Style);343 344 verifyFormat("do {\n"345 " ++I;\n"346 "} while (hasMore() && Filter(*I));",347 "do { ++I; } while (hasMore() && Filter(*I));", Style);348 349 verifyFormat("if (a)\n"350 " if (b)\n"351 " c;\n"352 " else {\n"353 " if (d)\n"354 " e;\n"355 " }\n"356 "else\n"357 " f;",358 Style);359 360 verifyFormat("if (a)\n"361 " if (b)\n"362 " c;\n"363 " else {\n"364 " if (d)\n"365 " e;\n"366 " else if (f)\n"367 " g;\n"368 " }\n"369 "else\n"370 " h;",371 Style);372 373 verifyFormat("if (a) {\n"374 " b;\n"375 "} else if (c) {\n"376 " d;\n"377 " e;\n"378 "}",379 "if (a) {\n"380 " b;\n"381 "} else {\n"382 " if (c) {\n"383 " d;\n"384 " e;\n"385 " }\n"386 "}",387 Style);388 389 verifyFormat("if (a) {\n"390 " b;\n"391 " c;\n"392 "} else if (d) {\n"393 " e;\n"394 " f;\n"395 "}",396 "if (a) {\n"397 " b;\n"398 " c;\n"399 "} else {\n"400 " if (d) {\n"401 " e;\n"402 " f;\n"403 " }\n"404 "}",405 Style);406 407 verifyFormat("if (a) {\n"408 " b;\n"409 "} else if (c) {\n"410 " d;\n"411 "} else {\n"412 " e;\n"413 " f;\n"414 "}",415 "if (a) {\n"416 " b;\n"417 "} else {\n"418 " if (c) {\n"419 " d;\n"420 " } else {\n"421 " e;\n"422 " f;\n"423 " }\n"424 "}",425 Style);426 427 verifyFormat("if (a) {\n"428 " b;\n"429 "} else if (c) {\n"430 " d;\n"431 "} else if (e) {\n"432 " f;\n"433 " g;\n"434 "}",435 "if (a) {\n"436 " b;\n"437 "} else {\n"438 " if (c) {\n"439 " d;\n"440 " } else if (e) {\n"441 " f;\n"442 " g;\n"443 " }\n"444 "}",445 Style);446 447 verifyFormat("if (a) {\n"448 " if (b)\n"449 " c;\n"450 " else if (d) {\n"451 " e;\n"452 " f;\n"453 " }\n"454 "} else {\n"455 " g;\n"456 "}",457 "if (a) {\n"458 " if (b)\n"459 " c;\n"460 " else {\n"461 " if (d) {\n"462 " e;\n"463 " f;\n"464 " }\n"465 " }\n"466 "} else {\n"467 " g;\n"468 "}",469 Style);470 471 verifyFormat("if (a)\n"472 " if (b)\n"473 " c;\n"474 " else {\n"475 " if (d) {\n"476 " e;\n"477 " f;\n"478 " }\n"479 " }\n"480 "else\n"481 " g;",482 Style);483 484 verifyFormat("if (a) {\n"485 " b;\n"486 " c;\n"487 "} else { // comment\n"488 " if (d) {\n"489 " e;\n"490 " f;\n"491 " }\n"492 "}",493 Style);494 495 verifyFormat("if (a)\n"496 " b;\n"497 "else if (c)\n"498 " while (d)\n"499 " e;\n"500 "// comment",501 "if (a)\n"502 "{\n"503 " b;\n"504 "} else if (c) {\n"505 " while (d) {\n"506 " e;\n"507 " }\n"508 "}\n"509 "// comment",510 Style);511 512 verifyFormat("if (a) {\n"513 " b;\n"514 "} else if (c) {\n"515 " d;\n"516 "} else {\n"517 " e;\n"518 " g;\n"519 "}",520 Style);521 522 verifyFormat("if (a) {\n"523 " b;\n"524 "} else if (c) {\n"525 " d;\n"526 "} else {\n"527 " e;\n"528 "} // comment",529 Style);530 531 verifyFormat("int abs = [](int i) {\n"532 " if (i >= 0)\n"533 " return i;\n"534 " return -i;\n"535 "};",536 "int abs = [](int i) {\n"537 " if (i >= 0) {\n"538 " return i;\n"539 " }\n"540 " return -i;\n"541 "};",542 Style);543 544 verifyFormat("if (a)\n"545 " foo();\n"546 "else\n"547 " bar();",548 "if (a)\n"549 "{\n"550 " foo();\n"551 "}\n"552 "else\n"553 "{\n"554 " bar();\n"555 "}",556 Style);557 558 verifyFormat("if (a)\n"559 " foo();\n"560 "// comment\n"561 "else\n"562 " bar();",563 "if (a) {\n"564 " foo();\n"565 "}\n"566 "// comment\n"567 "else {\n"568 " bar();\n"569 "}",570 Style);571 572 verifyFormat("if (a) {\n"573 " if (b)\n"574 " c = 1; // comment\n"575 "}",576 "if (a) {\n"577 " if (b) {\n"578 " c = 1; // comment\n"579 " }\n"580 "}",581 Style);582 583 verifyFormat("if (a) // comment\n"584 " b = 1;",585 "if (a) // comment\n"586 "{\n"587 " b = 1;\n"588 "}",589 Style);590 591 verifyFormat("if (a) {\n"592 "Label:\n"593 "}",594 Style);595 596 verifyFormat("if (a) {\n"597 "Label:\n"598 " f();\n"599 "}",600 Style);601 602 verifyFormat("if (a) {\n"603 " f();\n"604 "Label:\n"605 "}",606 Style);607 608 verifyFormat("if consteval {\n"609 " f();\n"610 "} else {\n"611 " g();\n"612 "}",613 Style);614 615 verifyFormat("if not consteval {\n"616 " f();\n"617 "} else if (a) {\n"618 " g();\n"619 "}",620 Style);621 622 verifyFormat("if !consteval {\n"623 " g();\n"624 "}",625 Style);626 627 verifyFormat("while (0)\n"628 " if (a)\n"629 " return b;\n"630 "return a;",631 "while (0) {\n"632 " if (a) {\n"633 " return b;\n"634 "}}\n"635 "return a;",636 Style);637 638 verifyFormat("if (a)\n"639 "#ifdef FOO\n"640 " if (b)\n"641 " bar = c;\n"642 " else\n"643 "#endif\n"644 " {\n"645 " foo = d;\n"646 "#ifdef FOO\n"647 " bar = e;\n"648 "#else\n"649 " bar = f;\n" // FIXME: should be indented 1 more level.650 "#endif\n"651 " }\n"652 "else\n"653 " bar = g;",654 "if (a)\n"655 "#ifdef FOO\n"656 " if (b)\n"657 " bar = c;\n"658 " else\n"659 "#endif\n"660 " {\n"661 " foo = d;\n"662 "#ifdef FOO\n"663 " bar = e;\n"664 "#else\n"665 " bar = f;\n"666 "#endif\n"667 " }\n"668 "else {\n"669 " bar = g;\n"670 "}",671 Style);672 673 Style.ColumnLimit = 65;674 verifyFormat("if (condition) {\n"675 " ff(Indices,\n"676 " [&](unsigned LHSI, unsigned RHSI) { return true; });\n"677 "} else {\n"678 " ff(Indices,\n"679 " [&](unsigned LHSI, unsigned RHSI) { return true; });\n"680 "}",681 Style);682 683 Style.ColumnLimit = 20;684 685 verifyFormat("int i;\n"686 "#define FOO(a, b) \\\n"687 " while (a) { \\\n"688 " b; \\\n"689 " }",690 Style);691 692 verifyFormat("int ab = [](int i) {\n"693 " if (i > 0) {\n"694 " i = 12345678 -\n"695 " i;\n"696 " }\n"697 " return i;\n"698 "};",699 Style);700 701 verifyFormat("if (a) {\n"702 " b = c + // 1 -\n"703 " d;\n"704 "}",705 Style);706 707 verifyFormat("if (a) {\n"708 " b = c >= 0 ? d\n"709 " : e;\n"710 "}",711 "if (a) {\n"712 " b = c >= 0 ? d : e;\n"713 "}",714 Style);715 716 verifyFormat("if (a)\n"717 " b = c > 0 ? d : e;",718 "if (a) {\n"719 " b = c > 0 ? d : e;\n"720 "}",721 Style);722 723 verifyFormat("if (-b >=\n"724 " c) { // Keep.\n"725 " foo();\n"726 "} else {\n"727 " bar();\n"728 "}",729 "if (-b >= c) { // Keep.\n"730 " foo();\n"731 "} else {\n"732 " bar();\n"733 "}",734 Style);735 736 verifyFormat("if (a) /* Remove. */\n"737 " f();\n"738 "else\n"739 " g();",740 "if (a) <% /* Remove. */\n"741 " f();\n"742 "%> else <%\n"743 " g();\n"744 "%>",745 Style);746 747 verifyFormat("while (\n"748 " !i--) <% // Keep.\n"749 " foo();\n"750 "%>",751 "while (!i--) <% // Keep.\n"752 " foo();\n"753 "%>",754 Style);755 756 verifyFormat("for (int &i : chars)\n"757 " ++i;",758 "for (int &i :\n"759 " chars) {\n"760 " ++i;\n"761 "}",762 Style);763 764 verifyFormat("if (a)\n"765 " b;\n"766 "else if (c) {\n"767 " d;\n"768 " e;\n"769 "} else\n"770 " f = g(foo, bar,\n"771 " baz);",772 "if (a)\n"773 " b;\n"774 "else {\n"775 " if (c) {\n"776 " d;\n"777 " e;\n"778 " } else\n"779 " f = g(foo, bar, baz);\n"780 "}",781 Style);782 783 verifyFormat("if (foo)\n"784 " f();\n"785 "else if (bar || baz)\n"786 " g();",787 "if (foo) {\n"788 " f();\n"789 "} else if (bar || baz) {\n"790 " g();\n"791 "}",792 Style);793 794 Style.ColumnLimit = 0;795 verifyFormat("if (a)\n"796 " b234567890223456789032345678904234567890 = "797 "c234567890223456789032345678904234567890;",798 "if (a) {\n"799 " b234567890223456789032345678904234567890 = "800 "c234567890223456789032345678904234567890;\n"801 "}",802 Style);803 804 Style.BreakBeforeBraces = FormatStyle::BS_Custom;805 Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;806 Style.BraceWrapping.BeforeElse = true;807 808 Style.ColumnLimit = 65;809 810 verifyFormat("if (condition)\n"811 "{\n"812 " ff(Indices,\n"813 " [&](unsigned LHSI, unsigned RHSI) { return true; });\n"814 "}\n"815 "else\n"816 "{\n"817 " ff(Indices,\n"818 " [&](unsigned LHSI, unsigned RHSI) { return true; });\n"819 "}",820 "if (condition) {\n"821 " ff(Indices,\n"822 " [&](unsigned LHSI, unsigned RHSI) { return true; });\n"823 "} else {\n"824 " ff(Indices,\n"825 " [&](unsigned LHSI, unsigned RHSI) { return true; });\n"826 "}",827 Style);828 829 verifyFormat("if (a)\n"830 "{ //\n"831 " foo();\n"832 "}",833 "if (a) { //\n"834 " foo();\n"835 "}",836 Style);837 838 verifyFormat("if (a) // comment\n"839 " b = 1;",840 "if (a) // comment\n"841 "{\n"842 " b = 1;\n"843 "}",844 Style);845 846 Style.ColumnLimit = 20;847 848 verifyFormat("int ab = [](int i) {\n"849 " if (i > 0)\n"850 " {\n"851 " i = 12345678 -\n"852 " i;\n"853 " }\n"854 " return i;\n"855 "};",856 "int ab = [](int i) {\n"857 " if (i > 0) {\n"858 " i = 12345678 -\n"859 " i;\n"860 " }\n"861 " return i;\n"862 "};",863 Style);864 865 verifyFormat("if (a)\n"866 "{\n"867 " b = c + // 1 -\n"868 " d;\n"869 "}",870 "if (a) {\n"871 " b = c + // 1 -\n"872 " d;\n"873 "}",874 Style);875 876 verifyFormat("if (a)\n"877 "{\n"878 " b = c >= 0 ? d\n"879 " : e;\n"880 "}",881 "if (a) {\n"882 " b = c >= 0 ? d : e;\n"883 "}",884 Style);885 886 verifyFormat("if (a)\n"887 " b = c > 0 ? d : e;",888 "if (a)\n"889 "{\n"890 " b = c > 0 ? d : e;\n"891 "}",892 Style);893 894 verifyFormat("if (foo + bar <=\n"895 " baz)\n"896 "{\n"897 " func(arg1, arg2);\n"898 "}",899 "if (foo + bar <= baz) {\n"900 " func(arg1, arg2);\n"901 "}",902 Style);903 904 verifyFormat("if (foo + bar < baz)\n"905 " func(arg1, arg2);\n"906 "else\n"907 " func();",908 "if (foo + bar < baz)\n"909 "<%\n"910 " func(arg1, arg2);\n"911 "%>\n"912 "else\n"913 "<%\n"914 " func();\n"915 "%>",916 Style);917 918 verifyFormat("while (i--)\n"919 "<% // Keep.\n"920 " foo();\n"921 "%>",922 "while (i--) <% // Keep.\n"923 " foo();\n"924 "%>",925 Style);926 927 verifyFormat("for (int &i : chars)\n"928 " ++i;",929 "for (int &i : chars)\n"930 "{\n"931 " ++i;\n"932 "}",933 Style);934}935 936} // namespace937} // namespace test938} // namespace format939} // namespace clang940