| //===- unittest/Format/FormatTest.cpp - Formatting unit tests -------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Format/Format.h" |
| |
| #include "../Tooling/ReplacementTest.h" |
| #include "FormatTestUtils.h" |
| |
| #include "clang/Frontend/TextDiagnosticPrinter.h" |
| #include "llvm/Support/Debug.h" |
| #include "llvm/Support/MemoryBuffer.h" |
| #include "gtest/gtest.h" |
| |
| #define DEBUG_TYPE "format-test" |
| |
| using clang::tooling::ReplacementTest; |
| using clang::tooling::toReplacements; |
| |
| namespace clang { |
| namespace format { |
| namespace { |
| |
| FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } |
| |
| class FormatTest : public ::testing::Test { |
| protected: |
| enum IncompleteCheck { |
| IC_ExpectComplete, |
| IC_ExpectIncomplete, |
| IC_DoNotCheck |
| }; |
| |
| std::string format(llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle(), |
| IncompleteCheck CheckIncomplete = IC_ExpectComplete) { |
| DEBUG(llvm::errs() << "---\n"); |
| DEBUG(llvm::errs() << Code << "\n\n"); |
| std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); |
| bool IncompleteFormat = false; |
| tooling::Replacements Replaces = |
| reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat); |
| if (CheckIncomplete != IC_DoNotCheck) { |
| bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete; |
| EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n"; |
| } |
| ReplacementCount = Replaces.size(); |
| auto Result = applyAllReplacements(Code, Replaces); |
| EXPECT_TRUE(static_cast<bool>(Result)); |
| DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); |
| return *Result; |
| } |
| |
| FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.ColumnLimit = ColumnLimit; |
| return Style; |
| } |
| |
| FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) { |
| FormatStyle Style = getGoogleStyle(); |
| Style.ColumnLimit = ColumnLimit; |
| return Style; |
| } |
| |
| void verifyFormat(llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); |
| } |
| |
| void verifyIncompleteFormat(llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| EXPECT_EQ(Code.str(), |
| format(test::messUp(Code), Style, IC_ExpectIncomplete)); |
| } |
| |
| void verifyGoogleFormat(llvm::StringRef Code) { |
| verifyFormat(Code, getGoogleStyle()); |
| } |
| |
| void verifyIndependentOfContext(llvm::StringRef text) { |
| verifyFormat(text); |
| verifyFormat(llvm::Twine("void f() { " + text + " }").str()); |
| } |
| |
| /// \brief Verify that clang-format does not crash on the given input. |
| void verifyNoCrash(llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| format(Code, Style, IC_DoNotCheck); |
| } |
| |
| int ReplacementCount; |
| }; |
| |
| TEST_F(FormatTest, MessUp) { |
| EXPECT_EQ("1 2 3", test::messUp("1 2 3")); |
| EXPECT_EQ("1 2 3\n", test::messUp("1\n2\n3\n")); |
| EXPECT_EQ("a\n//b\nc", test::messUp("a\n//b\nc")); |
| EXPECT_EQ("a\n#b\nc", test::messUp("a\n#b\nc")); |
| EXPECT_EQ("a\n#b c d\ne", test::messUp("a\n#b\\\nc\\\nd\ne")); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Basic function tests. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, DoesNotChangeCorrectlyFormattedCode) { |
| EXPECT_EQ(";", format(";")); |
| } |
| |
| TEST_F(FormatTest, FormatsGlobalStatementsAt0) { |
| EXPECT_EQ("int i;", format(" int i;")); |
| EXPECT_EQ("\nint i;", format(" \n\t \v \f int i;")); |
| EXPECT_EQ("int i;\nint j;", format(" int i; int j;")); |
| EXPECT_EQ("int i;\nint j;", format(" int i;\n int j;")); |
| } |
| |
| TEST_F(FormatTest, FormatsUnwrappedLinesAtFirstFormat) { |
| EXPECT_EQ("int i;", format("int\ni;")); |
| } |
| |
| TEST_F(FormatTest, FormatsNestedBlockStatements) { |
| EXPECT_EQ("{\n {\n {}\n }\n}", format("{{{}}}")); |
| } |
| |
| TEST_F(FormatTest, FormatsNestedCall) { |
| verifyFormat("Method(f1, f2(f3));"); |
| verifyFormat("Method(f1(f2, f3()));"); |
| verifyFormat("Method(f1(f2, (f3())));"); |
| } |
| |
| TEST_F(FormatTest, NestedNameSpecifiers) { |
| verifyFormat("vector<::Type> v;"); |
| verifyFormat("::ns::SomeFunction(::ns::SomeOtherFunction())"); |
| verifyFormat("static constexpr bool Bar = decltype(bar())::value;"); |
| verifyFormat("bool a = 2 < ::SomeFunction();"); |
| } |
| |
| TEST_F(FormatTest, OnlyGeneratesNecessaryReplacements) { |
| EXPECT_EQ("if (a) {\n" |
| " f();\n" |
| "}", |
| format("if(a){f();}")); |
| EXPECT_EQ(4, ReplacementCount); |
| EXPECT_EQ("if (a) {\n" |
| " f();\n" |
| "}", |
| format("if (a) {\n" |
| " f();\n" |
| "}")); |
| EXPECT_EQ(0, ReplacementCount); |
| EXPECT_EQ("/*\r\n" |
| "\r\n" |
| "*/\r\n", |
| format("/*\r\n" |
| "\r\n" |
| "*/\r\n")); |
| EXPECT_EQ(0, ReplacementCount); |
| } |
| |
| TEST_F(FormatTest, RemovesEmptyLines) { |
| EXPECT_EQ("class C {\n" |
| " int i;\n" |
| "};", |
| format("class C {\n" |
| " int i;\n" |
| "\n" |
| "};")); |
| |
| // Don't remove empty lines at the start of namespaces or extern "C" blocks. |
| EXPECT_EQ("namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| EXPECT_EQ("extern /**/ \"C\" /**/ {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("extern /**/ \"C\" /**/ {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| |
| // ...but do keep inlining and removing empty lines for non-block extern "C" |
| // functions. |
| verifyFormat("extern \"C\" int f() { return 42; }", getGoogleStyle()); |
| EXPECT_EQ("extern \"C\" int f() {\n" |
| " int i = 42;\n" |
| " return i;\n" |
| "}", |
| format("extern \"C\" int f() {\n" |
| "\n" |
| " int i = 42;\n" |
| " return i;\n" |
| "}", |
| getGoogleStyle())); |
| |
| // Remove empty lines at the beginning and end of blocks. |
| EXPECT_EQ("void f() {\n" |
| "\n" |
| " if (a) {\n" |
| "\n" |
| " f();\n" |
| " }\n" |
| "}", |
| format("void f() {\n" |
| "\n" |
| " if (a) {\n" |
| "\n" |
| " f();\n" |
| "\n" |
| " }\n" |
| "\n" |
| "}", |
| getLLVMStyle())); |
| EXPECT_EQ("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| " }\n" |
| "}", |
| format("void f() {\n" |
| "\n" |
| " if (a) {\n" |
| "\n" |
| " f();\n" |
| "\n" |
| " }\n" |
| "\n" |
| "}", |
| getGoogleStyle())); |
| |
| // Don't remove empty lines in more complex control statements. |
| EXPECT_EQ("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| "\n" |
| " } else if (b) {\n" |
| " f();\n" |
| " }\n" |
| "}", |
| format("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| "\n" |
| " } else if (b) {\n" |
| " f();\n" |
| "\n" |
| " }\n" |
| "\n" |
| "}")); |
| |
| // FIXME: This is slightly inconsistent. |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "}", |
| format("namespace {\n" |
| "int i;\n" |
| "\n" |
| "}")); |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "\n" |
| "} // namespace", |
| format("namespace {\n" |
| "int i;\n" |
| "\n" |
| "} // namespace")); |
| } |
| |
| TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) { |
| verifyFormat("x = (a) and (b);"); |
| verifyFormat("x = (a) or (b);"); |
| verifyFormat("x = (a) bitand (b);"); |
| verifyFormat("x = (a) bitor (b);"); |
| verifyFormat("x = (a) not_eq (b);"); |
| verifyFormat("x = (a) and_eq (b);"); |
| verifyFormat("x = (a) or_eq (b);"); |
| verifyFormat("x = (a) xor (b);"); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Tests for control statements. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, FormatIfWithoutCompoundStatement) { |
| verifyFormat("if (true)\n f();\ng();"); |
| verifyFormat("if (a)\n if (b)\n if (c)\n g();\nh();"); |
| verifyFormat("if (a)\n if (b) {\n f();\n }\ng();"); |
| |
| FormatStyle AllowsMergedIf = getLLVMStyle(); |
| AllowsMergedIf.AlignEscapedNewlinesLeft = true; |
| AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true; |
| verifyFormat("if (a)\n" |
| " // comment\n" |
| " f();", |
| AllowsMergedIf); |
| verifyFormat("{\n" |
| " if (a)\n" |
| " label:\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("#define A \\\n" |
| " if (a) \\\n" |
| " label: \\\n" |
| " f()", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " ;", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " if (b) return;", |
| AllowsMergedIf); |
| |
| verifyFormat("if (a) // Can't merge this\n" |
| " f();\n", |
| AllowsMergedIf); |
| verifyFormat("if (a) /* still don't merge */\n" |
| " f();", |
| AllowsMergedIf); |
| verifyFormat("if (a) { // Never merge this\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) { /* Never merge this */\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| |
| AllowsMergedIf.ColumnLimit = 14; |
| verifyFormat("if (a) return;", AllowsMergedIf); |
| verifyFormat("if (aaaaaaaaa)\n" |
| " return;", |
| AllowsMergedIf); |
| |
| AllowsMergedIf.ColumnLimit = 13; |
| verifyFormat("if (a)\n return;", AllowsMergedIf); |
| } |
| |
| TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) { |
| FormatStyle AllowsMergedLoops = getLLVMStyle(); |
| AllowsMergedLoops.AllowShortLoopsOnASingleLine = true; |
| verifyFormat("while (true) continue;", AllowsMergedLoops); |
| verifyFormat("for (;;) continue;", AllowsMergedLoops); |
| verifyFormat("for (int &v : vec) v *= 2;", AllowsMergedLoops); |
| verifyFormat("while (true)\n" |
| " ;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " ;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " for (;;) continue;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;) // Can't merge this\n" |
| " continue;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;) /* still don't merge */\n" |
| " continue;", |
| AllowsMergedLoops); |
| } |
| |
| TEST_F(FormatTest, FormatShortBracedStatements) { |
| FormatStyle AllowSimpleBracedStatements = getLLVMStyle(); |
| AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true; |
| |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true; |
| AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true; |
| |
| verifyFormat("if (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("while (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {}", AllowSimpleBracedStatements); |
| verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if (true) { //\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "} else {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| verifyFormat("template <int> struct A2 {\n" |
| " struct B {};\n" |
| "};", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false; |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "} else {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false; |
| verifyFormat("while (true) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| } |
| |
| TEST_F(FormatTest, ParseIfElse) { |
| verifyFormat("if (true)\n" |
| " if (true)\n" |
| " if (true)\n" |
| " f();\n" |
| " else\n" |
| " g();\n" |
| " else\n" |
| " h();\n" |
| "else\n" |
| " i();"); |
| verifyFormat("if (true)\n" |
| " if (true)\n" |
| " if (true) {\n" |
| " if (true)\n" |
| " f();\n" |
| " } else {\n" |
| " g();\n" |
| " }\n" |
| " else\n" |
| " h();\n" |
| "else {\n" |
| " i();\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| " if (a) {\n" |
| " } else {\n" |
| " }\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, ElseIf) { |
| verifyFormat("if (a) {\n} else if (b) {\n}"); |
| verifyFormat("if (a)\n" |
| " f();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " h();"); |
| verifyFormat("if (a) {\n" |
| " f();\n" |
| "}\n" |
| "// or else ..\n" |
| "else {\n" |
| " g()\n" |
| "}"); |
| |
| verifyFormat("if (a) {\n" |
| "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" |
| "}"); |
| verifyFormat("if (a) {\n" |
| "} else if (\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}", |
| getLLVMStyleWithColumns(62)); |
| } |
| |
| TEST_F(FormatTest, FormatsForLoop) { |
| verifyFormat( |
| "for (int VeryVeryLongLoopVariable = 0; VeryVeryLongLoopVariable < 10;\n" |
| " ++VeryVeryLongLoopVariable)\n" |
| " ;"); |
| verifyFormat("for (;;)\n" |
| " f();"); |
| verifyFormat("for (;;) {\n}"); |
| verifyFormat("for (;;) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("for (int i = 0; (i < 10); ++i) {\n}"); |
| |
| verifyFormat( |
| "for (std::vector<UnwrappedLine>::iterator I = UnwrappedLines.begin(),\n" |
| " E = UnwrappedLines.end();\n" |
| " I != E; ++I) {\n}"); |
| |
| verifyFormat( |
| "for (MachineFun::iterator IIII = PrevIt, EEEE = F.end(); IIII != EEEE;\n" |
| " ++IIIII) {\n}"); |
| verifyFormat("for (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa;\n" |
| " aaaaaaaaaaa != aaaaaaaaaaaaaaaaaaa; ++aaaaaaaaaaa) {\n}"); |
| verifyFormat("for (llvm::ArrayRef<NamedDecl *>::iterator\n" |
| " I = FD->getDeclsInPrototypeScope().begin(),\n" |
| " E = FD->getDeclsInPrototypeScope().end();\n" |
| " I != E; ++I) {\n}"); |
| verifyFormat("for (SmallVectorImpl<TemplateIdAnnotationn *>::iterator\n" |
| " I = Container.begin(),\n" |
| " E = Container.end();\n" |
| " I != E; ++I) {\n}", |
| getLLVMStyleWithColumns(76)); |
| |
| verifyFormat( |
| "for (aaaaaaaaaaaaaaaaa aaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa !=\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| " ++aaaaaaaaaaa) {\n}"); |
| verifyFormat("for (int i = 0; i < aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbbbb < ccccccccccccccc;\n" |
| " ++i) {\n}"); |
| verifyFormat("for (int aaaaaaaaaaa = 1; aaaaaaaaaaa <= bbbbbbbbbbbbbbb;\n" |
| " aaaaaaaaaaa++, bbbbbbbbbbbbbbbbb++) {\n" |
| "}"); |
| verifyFormat("for (some_namespace::SomeIterator iter( // force break\n" |
| " aaaaaaaaaa);\n" |
| " iter; ++iter) {\n" |
| "}"); |
| verifyFormat("for (auto aaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbbbbbbb;\n" |
| " ++aaaaaaaaaaaaaaaaaaaaaaaaaaa) {"); |
| |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackParameters = false; |
| verifyFormat("for (int aaaaaaaaaaa = 1;\n" |
| " aaaaaaaaaaa <= aaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa);\n" |
| " aaaaaaaaaaa++, bbbbbbbbbbbbbbbbb++) {\n" |
| "}", |
| NoBinPacking); |
| verifyFormat( |
| "for (std::vector<UnwrappedLine>::iterator I = UnwrappedLines.begin(),\n" |
| " E = UnwrappedLines.end();\n" |
| " I != E;\n" |
| " ++I) {\n}", |
| NoBinPacking); |
| } |
| |
| TEST_F(FormatTest, RangeBasedForLoops) { |
| verifyFormat("for (auto aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}"); |
| verifyFormat("for (auto aaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa, aaaaaaaaaaaaa)) {\n}"); |
| verifyFormat("for (const aaaaaaaaaaaaaaaaaaaaa &aaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}"); |
| verifyFormat("for (aaaaaaaaa aaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaa.aaaaaaaaaaaa().aaaaaaaaa().a()) {\n}"); |
| } |
| |
| TEST_F(FormatTest, ForEachLoops) { |
| verifyFormat("void f() {\n" |
| " foreach (Item *item, itemlist) {}\n" |
| " Q_FOREACH (Item *item, itemlist) {}\n" |
| " BOOST_FOREACH (Item *item, itemlist) {}\n" |
| " UNKNOWN_FORACH(Item * item, itemlist) {}\n" |
| "}"); |
| |
| // As function-like macros. |
| verifyFormat("#define foreach(x, y)\n" |
| "#define Q_FOREACH(x, y)\n" |
| "#define BOOST_FOREACH(x, y)\n" |
| "#define UNKNOWN_FOREACH(x, y)\n"); |
| |
| // Not as function-like macros. |
| verifyFormat("#define foreach (x, y)\n" |
| "#define Q_FOREACH (x, y)\n" |
| "#define BOOST_FOREACH (x, y)\n" |
| "#define UNKNOWN_FOREACH (x, y)\n"); |
| } |
| |
| TEST_F(FormatTest, FormatsWhileLoop) { |
| verifyFormat("while (true) {\n}"); |
| verifyFormat("while (true)\n" |
| " f();"); |
| verifyFormat("while () {\n}"); |
| verifyFormat("while () {\n" |
| " f();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, FormatsDoWhile) { |
| verifyFormat("do {\n" |
| " do_something();\n" |
| "} while (something());"); |
| verifyFormat("do\n" |
| " do_something();\n" |
| "while (something());"); |
| } |
| |
| TEST_F(FormatTest, FormatsSwitchStatement) { |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| " f();\n" |
| " break;\n" |
| "case kFoo:\n" |
| "case ns::kBar:\n" |
| "case kBaz:\n" |
| " break;\n" |
| "default:\n" |
| " g();\n" |
| " break;\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " {\n" |
| " g();\n" |
| " h();\n" |
| " }\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " if (foo) {\n" |
| " g();\n" |
| " h();\n" |
| " }\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " g();\n" |
| "} break;\n" |
| "}"); |
| verifyFormat("switch (test)\n" |
| " ;"); |
| verifyFormat("switch (x) {\n" |
| "default: {\n" |
| " // Do nothing.\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "// comment\n" |
| "// if 1, do f()\n" |
| "case 1:\n" |
| " f();\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| " // Do amazing stuff\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| " break;\n" |
| "}"); |
| verifyFormat("#define A \\\n" |
| " switch (x) { \\\n" |
| " case a: \\\n" |
| " foo = b; \\\n" |
| " }", |
| getLLVMStyleWithColumns(20)); |
| verifyFormat("#define OPERATION_CASE(name) \\\n" |
| " case OP_name: \\\n" |
| " return operations::Operation##name\n", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("switch (x) {\n" |
| "case 1:;\n" |
| "default:;\n" |
| " int i;\n" |
| "}"); |
| |
| verifyGoogleFormat("switch (x) {\n" |
| " case 1:\n" |
| " f();\n" |
| " break;\n" |
| " case kFoo:\n" |
| " case ns::kBar:\n" |
| " case kBaz:\n" |
| " break;\n" |
| " default:\n" |
| " g();\n" |
| " break;\n" |
| "}"); |
| verifyGoogleFormat("switch (x) {\n" |
| " case 1: {\n" |
| " f();\n" |
| " break;\n" |
| " }\n" |
| "}"); |
| verifyGoogleFormat("switch (test)\n" |
| " ;"); |
| |
| verifyGoogleFormat("#define OPERATION_CASE(name) \\\n" |
| " case OP_name: \\\n" |
| " return operations::Operation##name\n"); |
| verifyGoogleFormat("Operation codeToOperation(OperationCode OpCode) {\n" |
| " // Get the correction operation class.\n" |
| " switch (OpCode) {\n" |
| " CASE(Add);\n" |
| " CASE(Subtract);\n" |
| " default:\n" |
| " return operations::Unknown;\n" |
| " }\n" |
| "#undef OPERATION_CASE\n" |
| "}"); |
| verifyFormat("DEBUG({\n" |
| " switch (x) {\n" |
| " case A:\n" |
| " f();\n" |
| " break;\n" |
| " // On B:\n" |
| " case B:\n" |
| " g();\n" |
| " break;\n" |
| " }\n" |
| "});"); |
| verifyFormat("switch (a) {\n" |
| "case (b):\n" |
| " return;\n" |
| "}"); |
| |
| verifyFormat("switch (a) {\n" |
| "case some_namespace::\n" |
| " some_constant:\n" |
| " return;\n" |
| "}", |
| getLLVMStyleWithColumns(34)); |
| } |
| |
| TEST_F(FormatTest, CaseRanges) { |
| verifyFormat("switch (x) {\n" |
| "case 'A' ... 'Z':\n" |
| "case 1 ... 5:\n" |
| "case a ... b:\n" |
| " break;\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, ShortCaseLabels) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AllowShortCaseLabelsOnASingleLine = true; |
| verifyFormat("switch (a) {\n" |
| "case 1: x = 1; break;\n" |
| "case 2: return;\n" |
| "case 3:\n" |
| "case 4:\n" |
| "case 5: return;\n" |
| "case 6: // comment\n" |
| " return;\n" |
| "case 7:\n" |
| " // comment\n" |
| " return;\n" |
| "case 8:\n" |
| " x = 8; // comment\n" |
| " break;\n" |
| "default: y = 1; break;\n" |
| "}", |
| Style); |
| verifyFormat("switch (a) {\n" |
| "#if FOO\n" |
| "case 0: return 0;\n" |
| "#endif\n" |
| "}", |
| Style); |
| verifyFormat("switch (a) {\n" |
| "case 1: {\n" |
| "}\n" |
| "case 2: {\n" |
| " return;\n" |
| "}\n" |
| "case 3: {\n" |
| " x = 1;\n" |
| " return;\n" |
| "}\n" |
| "case 4:\n" |
| " if (x)\n" |
| " return;\n" |
| "}", |
| Style); |
| Style.ColumnLimit = 21; |
| verifyFormat("switch (a) {\n" |
| "case 1: x = 1; break;\n" |
| "case 2: return;\n" |
| "case 3:\n" |
| "case 4:\n" |
| "case 5: return;\n" |
| "default:\n" |
| " y = 1;\n" |
| " break;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsLabels) { |
| verifyFormat("void f() {\n" |
| " some_code();\n" |
| "test_label:\n" |
| " some_other_code();\n" |
| " {\n" |
| " some_more_code();\n" |
| " another_label:\n" |
| " some_more_code();\n" |
| " }\n" |
| "}"); |
| verifyFormat("{\n" |
| " some_code();\n" |
| "test_label:\n" |
| " some_other_code();\n" |
| "}"); |
| verifyFormat("{\n" |
| " some_code();\n" |
| "test_label:;\n" |
| " int i = 0;\n" |
| "}"); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Tests for comments. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, UnderstandsSingleLineComments) { |
| verifyFormat("//* */"); |
| verifyFormat("// line 1\n" |
| "// line 2\n" |
| "void f() {}\n"); |
| |
| verifyFormat("void f() {\n" |
| " // Doesn't do anything\n" |
| "}"); |
| verifyFormat("SomeObject\n" |
| " // Calling someFunction on SomeObject\n" |
| " .someFunction();"); |
| verifyFormat("auto result = SomeObject\n" |
| " // Calling someFunction on SomeObject\n" |
| " .someFunction();"); |
| verifyFormat("void f(int i, // some comment (probably for i)\n" |
| " int j, // some comment (probably for j)\n" |
| " int k); // some comment (probably for k)"); |
| verifyFormat("void f(int i,\n" |
| " // some comment (probably for j)\n" |
| " int j,\n" |
| " // some comment (probably for k)\n" |
| " int k);"); |
| |
| verifyFormat("int i // This is a fancy variable\n" |
| " = 5; // with nicely aligned comment."); |
| |
| verifyFormat("// Leading comment.\n" |
| "int a; // Trailing comment."); |
| verifyFormat("int a; // Trailing comment\n" |
| " // on 2\n" |
| " // or 3 lines.\n" |
| "int b;"); |
| verifyFormat("int a; // Trailing comment\n" |
| "\n" |
| "// Leading comment.\n" |
| "int b;"); |
| verifyFormat("int a; // Comment.\n" |
| " // More details.\n" |
| "int bbbb; // Another comment."); |
| verifyFormat( |
| "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; // comment\n" |
| "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // comment\n" |
| "int cccccccccccccccccccccccccccccc; // comment\n" |
| "int ddd; // looooooooooooooooooooooooong comment\n" |
| "int aaaaaaaaaaaaaaaaaaaaaaa; // comment\n" |
| "int bbbbbbbbbbbbbbbbbbbbb; // comment\n" |
| "int ccccccccccccccccccc; // comment"); |
| |
| verifyFormat("#include \"a\" // comment\n" |
| "#include \"a/b/c\" // comment"); |
| verifyFormat("#include <a> // comment\n" |
| "#include <a/b/c> // comment"); |
| EXPECT_EQ("#include \"a\" // comment\n" |
| "#include \"a/b/c\" // comment", |
| format("#include \\\n" |
| " \"a\" // comment\n" |
| "#include \"a/b/c\" // comment")); |
| |
| verifyFormat("enum E {\n" |
| " // comment\n" |
| " VAL_A, // comment\n" |
| " VAL_B\n" |
| "};"); |
| |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " // Comment inside a statement.\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); |
| verifyFormat("SomeFunction(a,\n" |
| " // comment\n" |
| " b + x);"); |
| verifyFormat("SomeFunction(a, a,\n" |
| " // comment\n" |
| " b + x);"); |
| verifyFormat( |
| "bool aaaaaaaaaaaaa = // comment\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| |
| verifyFormat("int aaaa; // aaaaa\n" |
| "int aa; // aaaaaaa", |
| getLLVMStyleWithColumns(20)); |
| |
| EXPECT_EQ("void f() { // This does something ..\n" |
| "}\n" |
| "int a; // This is unrelated", |
| format("void f() { // This does something ..\n" |
| " }\n" |
| "int a; // This is unrelated")); |
| EXPECT_EQ("class C {\n" |
| " void f() { // This does something ..\n" |
| " } // awesome..\n" |
| "\n" |
| " int a; // This is unrelated\n" |
| "};", |
| format("class C{void f() { // This does something ..\n" |
| " } // awesome..\n" |
| " \n" |
| "int a; // This is unrelated\n" |
| "};")); |
| |
| EXPECT_EQ("int i; // single line trailing comment", |
| format("int i;\\\n// single line trailing comment")); |
| |
| verifyGoogleFormat("int a; // Trailing comment."); |
| |
| verifyFormat("someFunction(anotherFunction( // Force break.\n" |
| " parameter));"); |
| |
| verifyGoogleFormat("#endif // HEADER_GUARD"); |
| |
| verifyFormat("const char *test[] = {\n" |
| " // A\n" |
| " \"aaaa\",\n" |
| " // B\n" |
| " \"aaaaa\"};"); |
| verifyGoogleFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaa); // 81_cols_with_this_comment"); |
| EXPECT_EQ("D(a, {\n" |
| " // test\n" |
| " int a;\n" |
| "});", |
| format("D(a, {\n" |
| "// test\n" |
| "int a;\n" |
| "});")); |
| |
| EXPECT_EQ("lineWith(); // comment\n" |
| "// at start\n" |
| "otherLine();", |
| format("lineWith(); // comment\n" |
| "// at start\n" |
| "otherLine();")); |
| EXPECT_EQ("lineWith(); // comment\n" |
| "/*\n" |
| " * at start */\n" |
| "otherLine();", |
| format("lineWith(); // comment\n" |
| "/*\n" |
| " * at start */\n" |
| "otherLine();")); |
| EXPECT_EQ("lineWith(); // comment\n" |
| " // at start\n" |
| "otherLine();", |
| format("lineWith(); // comment\n" |
| " // at start\n" |
| "otherLine();")); |
| |
| EXPECT_EQ("lineWith(); // comment\n" |
| "// at start\n" |
| "otherLine(); // comment", |
| format("lineWith(); // comment\n" |
| "// at start\n" |
| "otherLine(); // comment")); |
| EXPECT_EQ("lineWith();\n" |
| "// at start\n" |
| "otherLine(); // comment", |
| format("lineWith();\n" |
| " // at start\n" |
| "otherLine(); // comment")); |
| EXPECT_EQ("// first\n" |
| "// at start\n" |
| "otherLine(); // comment", |
| format("// first\n" |
| " // at start\n" |
| "otherLine(); // comment")); |
| EXPECT_EQ("f();\n" |
| "// first\n" |
| "// at start\n" |
| "otherLine(); // comment", |
| format("f();\n" |
| "// first\n" |
| " // at start\n" |
| "otherLine(); // comment")); |
| verifyFormat("f(); // comment\n" |
| "// first\n" |
| "// at start\n" |
| "otherLine();"); |
| EXPECT_EQ("f(); // comment\n" |
| "// first\n" |
| "// at start\n" |
| "otherLine();", |
| format("f(); // comment\n" |
| "// first\n" |
| " // at start\n" |
| "otherLine();")); |
| EXPECT_EQ("f(); // comment\n" |
| " // first\n" |
| "// at start\n" |
| "otherLine();", |
| format("f(); // comment\n" |
| " // first\n" |
| "// at start\n" |
| "otherLine();")); |
| EXPECT_EQ("void f() {\n" |
| " lineWith(); // comment\n" |
| " // at start\n" |
| "}", |
| format("void f() {\n" |
| " lineWith(); // comment\n" |
| " // at start\n" |
| "}")); |
| EXPECT_EQ("int xy; // a\n" |
| "int z; // b", |
| format("int xy; // a\n" |
| "int z; //b")); |
| EXPECT_EQ("int xy; // a\n" |
| "int z; // bb", |
| format("int xy; // a\n" |
| "int z; //bb", |
| getLLVMStyleWithColumns(12))); |
| |
| verifyFormat("#define A \\\n" |
| " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" |
| " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat( |
| "#define A \\\n" |
| " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" |
| " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", |
| getLLVMStyleWithColumns(61)); |
| |
| verifyFormat("if ( // This is some comment\n" |
| " x + 3) {\n" |
| "}"); |
| EXPECT_EQ("if ( // This is some comment\n" |
| " // spanning two lines\n" |
| " x + 3) {\n" |
| "}", |
| format("if( // This is some comment\n" |
| " // spanning two lines\n" |
| " x + 3) {\n" |
| "}")); |
| |
| verifyNoCrash("/\\\n/"); |
| verifyNoCrash("/\\\n* */"); |
| // The 0-character somehow makes the lexer return a proper comment. |
| verifyNoCrash(StringRef("/*\\\0\n/", 6)); |
| } |
| |
| TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { |
| EXPECT_EQ("SomeFunction(a,\n" |
| " b, // comment\n" |
| " c);", |
| format("SomeFunction(a,\n" |
| " b, // comment\n" |
| " c);")); |
| EXPECT_EQ("SomeFunction(a, b,\n" |
| " // comment\n" |
| " c);", |
| format("SomeFunction(a,\n" |
| " b,\n" |
| " // comment\n" |
| " c);")); |
| EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n" |
| " c);", |
| format("SomeFunction(a, b, // comment (unclear relation)\n" |
| " c);")); |
| EXPECT_EQ("SomeFunction(a, // comment\n" |
| " b,\n" |
| " c); // comment", |
| format("SomeFunction(a, // comment\n" |
| " b,\n" |
| " c); // comment")); |
| } |
| |
| TEST_F(FormatTest, RemovesTrailingWhitespaceOfComments) { |
| EXPECT_EQ("// comment", format("// comment ")); |
| EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment", |
| format("int aaaaaaa, bbbbbbb; // comment ", |
| getLLVMStyleWithColumns(33))); |
| EXPECT_EQ("// comment\\\n", format("// comment\\\n \t \v \f ")); |
| EXPECT_EQ("// comment \\\n", format("// comment \\\n \t \v \f ")); |
| } |
| |
| TEST_F(FormatTest, UnderstandsBlockComments) { |
| verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);"); |
| verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }"); |
| EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb);", |
| format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \\\n" |
| "/* Trailing comment for aa... */\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb);")); |
| EXPECT_EQ( |
| "f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);", |
| format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \n" |
| "/* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);")); |
| EXPECT_EQ( |
| "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n" |
| "}", |
| format("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaa ,\n" |
| " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n" |
| "}")); |
| verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackParameters = false; |
| verifyFormat("aaaaaaaa(/* parameter 1 */ aaaaaa,\n" |
| " /* parameter 2 */ aaaaaa,\n" |
| " /* parameter 3 */ aaaaaa,\n" |
| " /* parameter 4 */ aaaaaa);", |
| NoBinPacking); |
| |
| // Aligning block comments in macros. |
| verifyGoogleFormat("#define A \\\n" |
| " int i; /*a*/ \\\n" |
| " int jjj; /*b*/"); |
| } |
| |
| TEST_F(FormatTest, AlignsBlockComments) { |
| EXPECT_EQ("/*\n" |
| " * Really multi-line\n" |
| " * comment.\n" |
| " */\n" |
| "void f() {}", |
| format(" /*\n" |
| " * Really multi-line\n" |
| " * comment.\n" |
| " */\n" |
| " void f() {}")); |
| EXPECT_EQ("class C {\n" |
| " /*\n" |
| " * Another multi-line\n" |
| " * comment.\n" |
| " */\n" |
| " void f() {}\n" |
| "};", |
| format("class C {\n" |
| "/*\n" |
| " * Another multi-line\n" |
| " * comment.\n" |
| " */\n" |
| "void f() {}\n" |
| "};")); |
| EXPECT_EQ("/*\n" |
| " 1. This is a comment with non-trivial formatting.\n" |
| " 1.1. We have to indent/outdent all lines equally\n" |
| " 1.1.1. to keep the formatting.\n" |
| " */", |
| format(" /*\n" |
| " 1. This is a comment with non-trivial formatting.\n" |
| " 1.1. We have to indent/outdent all lines equally\n" |
| " 1.1.1. to keep the formatting.\n" |
| " */")); |
| EXPECT_EQ("/*\n" |
| "Don't try to outdent if there's not enough indentation.\n" |
| "*/", |
| format(" /*\n" |
| " Don't try to outdent if there's not enough indentation.\n" |
| " */")); |
| |
| EXPECT_EQ("int i; /* Comment with empty...\n" |
| " *\n" |
| " * line. */", |
| format("int i; /* Comment with empty...\n" |
| " *\n" |
| " * line. */")); |
| EXPECT_EQ("int foobar = 0; /* comment */\n" |
| "int bar = 0; /* multiline\n" |
| " comment 1 */\n" |
| "int baz = 0; /* multiline\n" |
| " comment 2 */\n" |
| "int bzz = 0; /* multiline\n" |
| " comment 3 */", |
| format("int foobar = 0; /* comment */\n" |
| "int bar = 0; /* multiline\n" |
| " comment 1 */\n" |
| "int baz = 0; /* multiline\n" |
| " comment 2 */\n" |
| "int bzz = 0; /* multiline\n" |
| " comment 3 */")); |
| EXPECT_EQ("int foobar = 0; /* comment */\n" |
| "int bar = 0; /* multiline\n" |
| " comment */\n" |
| "int baz = 0; /* multiline\n" |
| "comment */", |
| format("int foobar = 0; /* comment */\n" |
| "int bar = 0; /* multiline\n" |
| "comment */\n" |
| "int baz = 0; /* multiline\n" |
| "comment */")); |
| } |
| |
| TEST_F(FormatTest, CommentReflowingCanBeTurnedOff) { |
| FormatStyle Style = getLLVMStyleWithColumns(20); |
| Style.ReflowComments = false; |
| verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style); |
| verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style); |
| } |
| |
| TEST_F(FormatTest, CorrectlyHandlesLengthOfBlockComments) { |
| EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */", |
| format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */")); |
| EXPECT_EQ( |
| "void ffffffffffff(\n" |
| " int aaaaaaaa, int bbbbbbbb,\n" |
| " int cccccccccccc) { /*\n" |
| " aaaaaaaaaa\n" |
| " aaaaaaaaaaaaa\n" |
| " bbbbbbbbbbbbbb\n" |
| " bbbbbbbbbb\n" |
| " */\n" |
| "}", |
| format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n" |
| "{ /*\n" |
| " aaaaaaaaaa aaaaaaaaaaaaa\n" |
| " bbbbbbbbbbbbbb bbbbbbbbbb\n" |
| " */\n" |
| "}", |
| getLLVMStyleWithColumns(40))); |
| } |
| |
| TEST_F(FormatTest, DontBreakNonTrailingBlockComments) { |
| EXPECT_EQ("void ffffffffff(\n" |
| " int aaaaa /* test */);", |
| format("void ffffffffff(int aaaaa /* test */);", |
| getLLVMStyleWithColumns(35))); |
| } |
| |
| TEST_F(FormatTest, SplitsLongCxxComments) { |
| EXPECT_EQ("// A comment that\n" |
| "// doesn't fit on\n" |
| "// one line", |
| format("// A comment that doesn't fit on one line", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/// A comment that\n" |
| "/// doesn't fit on\n" |
| "/// one line", |
| format("/// A comment that doesn't fit on one line", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("//! A comment that\n" |
| "//! doesn't fit on\n" |
| "//! one line", |
| format("//! A comment that doesn't fit on one line", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("// a b c d\n" |
| "// e f g\n" |
| "// h i j k", |
| format("// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ( |
| "// a b c d\n" |
| "// e f g\n" |
| "// h i j k", |
| format("\\\n// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("if (true) // A comment that\n" |
| " // doesn't fit on\n" |
| " // one line", |
| format("if (true) // A comment that doesn't fit on one line ", |
| getLLVMStyleWithColumns(30))); |
| EXPECT_EQ("// Don't_touch_leading_whitespace", |
| format("// Don't_touch_leading_whitespace", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("// Add leading\n" |
| "// whitespace", |
| format("//Add leading whitespace", getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/// Add leading\n" |
| "/// whitespace", |
| format("///Add leading whitespace", getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("//! Add leading\n" |
| "//! whitespace", |
| format("//!Add leading whitespace", getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("// whitespace", format("//whitespace", getLLVMStyle())); |
| EXPECT_EQ("// Even if it makes the line exceed the column\n" |
| "// limit", |
| format("//Even if it makes the line exceed the column limit", |
| getLLVMStyleWithColumns(51))); |
| EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle())); |
| |
| EXPECT_EQ("// aa bb cc dd", |
| format("// aa bb cc dd ", |
| getLLVMStyleWithColumns(15))); |
| |
| EXPECT_EQ("// A comment before\n" |
| "// a macro\n" |
| "// definition\n" |
| "#define a b", |
| format("// A comment before a macro definition\n" |
| "#define a b", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("void ffffff(\n" |
| " int aaaaaaaaa, // wwww\n" |
| " int bbbbbbbbbb, // xxxxxxx\n" |
| " // yyyyyyyyyy\n" |
| " int c, int d, int e) {}", |
| format("void ffffff(\n" |
| " int aaaaaaaaa, // wwww\n" |
| " int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n" |
| " int c, int d, int e) {}", |
| getLLVMStyleWithColumns(40))); |
| EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
| format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ( |
| "#define XXX // a b c d\n" |
| " // e f g h", |
| format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22))); |
| EXPECT_EQ( |
| "#define XXX // q w e r\n" |
| " // t y u i", |
| format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22))); |
| } |
| |
| TEST_F(FormatTest, PreservesHangingIndentInCxxComments) { |
| EXPECT_EQ("// A comment\n" |
| "// that doesn't\n" |
| "// fit on one\n" |
| "// line", |
| format("// A comment that doesn't fit on one line", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/// A comment\n" |
| "/// that doesn't\n" |
| "/// fit on one\n" |
| "/// line", |
| format("/// A comment that doesn't fit on one line", |
| getLLVMStyleWithColumns(20))); |
| } |
| |
| TEST_F(FormatTest, DontSplitLineCommentsWithEscapedNewlines) { |
| EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
| format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); |
| EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", |
| format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", |
| getLLVMStyleWithColumns(50))); |
| // FIXME: One day we might want to implement adjustment of leading whitespace |
| // of the consecutive lines in this kind of comment: |
| EXPECT_EQ("double\n" |
| " a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", |
| format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" |
| " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", |
| getLLVMStyleWithColumns(49))); |
| } |
| |
| TEST_F(FormatTest, DontSplitLineCommentsWithPragmas) { |
| FormatStyle Pragmas = getLLVMStyleWithColumns(30); |
| Pragmas.CommentPragmas = "^ IWYU pragma:"; |
| EXPECT_EQ( |
| "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", |
| format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas)); |
| EXPECT_EQ( |
| "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", |
| format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas)); |
| } |
| |
| TEST_F(FormatTest, PriorityOfCommentBreaking) { |
| EXPECT_EQ("if (xxx ==\n" |
| " yyy && // aaaaaaaaaaaa bbbbbbbbb\n" |
| " zzz)\n" |
| " q();", |
| format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n" |
| " zzz) q();", |
| getLLVMStyleWithColumns(40))); |
| EXPECT_EQ("if (xxxxxxxxxx ==\n" |
| " yyy && // aaaaaa bbbbbbbb cccc\n" |
| " zzz)\n" |
| " q();", |
| format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n" |
| " zzz) q();", |
| getLLVMStyleWithColumns(40))); |
| EXPECT_EQ("if (xxxxxxxxxx &&\n" |
| " yyy || // aaaaaa bbbbbbbb cccc\n" |
| " zzz)\n" |
| " q();", |
| format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n" |
| " zzz) q();", |
| getLLVMStyleWithColumns(40))); |
| EXPECT_EQ("fffffffff(\n" |
| " &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" |
| " zzz);", |
| format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" |
| " zzz);", |
| getLLVMStyleWithColumns(40))); |
| } |
| |
| TEST_F(FormatTest, MultiLineCommentsInDefines) { |
| EXPECT_EQ("#define A(x) /* \\\n" |
| " a comment \\\n" |
| " inside */ \\\n" |
| " f();", |
| format("#define A(x) /* \\\n" |
| " a comment \\\n" |
| " inside */ \\\n" |
| " f();", |
| getLLVMStyleWithColumns(17))); |
| EXPECT_EQ("#define A( \\\n" |
| " x) /* \\\n" |
| " a comment \\\n" |
| " inside */ \\\n" |
| " f();", |
| format("#define A( \\\n" |
| " x) /* \\\n" |
| " a comment \\\n" |
| " inside */ \\\n" |
| " f();", |
| getLLVMStyleWithColumns(17))); |
| } |
| |
| TEST_F(FormatTest, ParsesCommentsAdjacentToPPDirectives) { |
| EXPECT_EQ("namespace {}\n// Test\n#define A", |
| format("namespace {}\n // Test\n#define A")); |
| EXPECT_EQ("namespace {}\n/* Test */\n#define A", |
| format("namespace {}\n /* Test */\n#define A")); |
| EXPECT_EQ("namespace {}\n/* Test */ #define A", |
| format("namespace {}\n /* Test */ #define A")); |
| } |
| |
| TEST_F(FormatTest, SplitsLongLinesInComments) { |
| EXPECT_EQ("/* This is a long\n" |
| " * comment that\n" |
| " * doesn't\n" |
| " * fit on one line.\n" |
| " */", |
| format("/* " |
| "This is a long " |
| "comment that " |
| "doesn't " |
| "fit on one line. */", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ( |
| "/* a b c d\n" |
| " * e f g\n" |
| " * h i j k\n" |
| " */", |
| format("/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ( |
| "/* a b c d\n" |
| " * e f g\n" |
| " * h i j k\n" |
| " */", |
| format("\\\n/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("/*\n" |
| "This is a long\n" |
| "comment that doesn't\n" |
| "fit on one line.\n" |
| "*/", |
| format("/*\n" |
| "This is a long " |
| "comment that doesn't " |
| "fit on one line. \n" |
| "*/", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/*\n" |
| " * This is a long\n" |
| " * comment that\n" |
| " * doesn't fit on\n" |
| " * one line.\n" |
| " */", |
| format("/* \n" |
| " * This is a long " |
| " comment that " |
| " doesn't fit on " |
| " one line. \n" |
| " */", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/*\n" |
| " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n" |
| " * so_it_should_be_broken\n" |
| " * wherever_a_space_occurs\n" |
| " */", |
| format("/*\n" |
| " * This_is_a_comment_with_words_that_dont_fit_on_one_line " |
| " so_it_should_be_broken " |
| " wherever_a_space_occurs \n" |
| " */", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/*\n" |
| " * This_comment_can_not_be_broken_into_lines\n" |
| " */", |
| format("/*\n" |
| " * This_comment_can_not_be_broken_into_lines\n" |
| " */", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("{\n" |
| " /*\n" |
| " This is another\n" |
| " long comment that\n" |
| " doesn't fit on one\n" |
| " line 1234567890\n" |
| " */\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| "This is another " |
| " long comment that " |
| " doesn't fit on one" |
| " line 1234567890\n" |
| "*/\n" |
| "}", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("{\n" |
| " /*\n" |
| " * This i s\n" |
| " * another comment\n" |
| " * t hat doesn' t\n" |
| " * fit on one l i\n" |
| " * n e\n" |
| " */\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| " * This i s" |
| " another comment" |
| " t hat doesn' t" |
| " fit on one l i" |
| " n e\n" |
| " */\n" |
| "}", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("/*\n" |
| " * This is a long\n" |
| " * comment that\n" |
| " * doesn't fit on\n" |
| " * one line\n" |
| " */", |
| format(" /*\n" |
| " * This is a long comment that doesn't fit on one line\n" |
| " */", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("{\n" |
| " if (something) /* This is a\n" |
| " long\n" |
| " comment */\n" |
| " ;\n" |
| "}", |
| format("{\n" |
| " if (something) /* This is a long comment */\n" |
| " ;\n" |
| "}", |
| getLLVMStyleWithColumns(30))); |
| |
| EXPECT_EQ("/* A comment before\n" |
| " * a macro\n" |
| " * definition */\n" |
| "#define a b", |
| format("/* A comment before a macro definition */\n" |
| "#define a b", |
| getLLVMStyleWithColumns(20))); |
| |
| EXPECT_EQ("/* some comment\n" |
| " * a comment\n" |
| "* that we break\n" |
| " * another comment\n" |
| "* we have to break\n" |
| "* a left comment\n" |
| " */", |
| format(" /* some comment\n" |
| " * a comment that we break\n" |
| " * another comment we have to break\n" |
| "* a left comment\n" |
| " */", |
| getLLVMStyleWithColumns(20))); |
| |
| EXPECT_EQ("/**\n" |
| " * multiline block\n" |
| " * comment\n" |
| " *\n" |
| " */", |
| format("/**\n" |
| " * multiline block comment\n" |
| " *\n" |
| " */", |
| getLLVMStyleWithColumns(20))); |
| |
| EXPECT_EQ("/*\n" |
| "\n" |
| "\n" |
| " */\n", |
| format(" /* \n" |
| " \n" |
| " \n" |
| " */\n")); |
| |
| EXPECT_EQ("/* a a */", |
| format("/* a a */", getLLVMStyleWithColumns(15))); |
| EXPECT_EQ("/* a a bc */", |
| format("/* a a bc */", getLLVMStyleWithColumns(15))); |
| EXPECT_EQ("/* aaa aaa\n" |
| " * aaaaa */", |
| format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); |
| EXPECT_EQ("/* aaa aaa\n" |
| " * aaaaa */", |
| format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); |
| } |
| |
| TEST_F(FormatTest, SplitsLongLinesInCommentsInPreprocessor) { |
| EXPECT_EQ("#define X \\\n" |
| " /* \\\n" |
| " Test \\\n" |
| " Macro comment \\\n" |
| " with a long \\\n" |
| " line \\\n" |
| " */ \\\n" |
| " A + B", |
| format("#define X \\\n" |
| " /*\n" |
| " Test\n" |
| " Macro comment with a long line\n" |
| " */ \\\n" |
| " A + B", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("#define X \\\n" |
| " /* Macro comment \\\n" |
| " with a long \\\n" |
| " line */ \\\n" |
| " A + B", |
| format("#define X \\\n" |
| " /* Macro comment with a long\n" |
| " line */ \\\n" |
| " A + B", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("#define X \\\n" |
| " /* Macro comment \\\n" |
| " * with a long \\\n" |
| " * line */ \\\n" |
| " A + B", |
| format("#define X \\\n" |
| " /* Macro comment with a long line */ \\\n" |
| " A + B", |
| getLLVMStyleWithColumns(20))); |
| } |
| |
| TEST_F(FormatTest, CommentsInStaticInitializers) { |
| EXPECT_EQ( |
| "static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n" |
| " aaaaaaaaaaaaaaaaaaaa /* comment */,\n" |
| " /* comment */ aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaa, // comment\n" |
| " aaaaaaaaaaaaaaaaaaaa};", |
| format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa , /* comment */\n" |
| " aaaaaaaaaaaaaaaaaaaa /* comment */ ,\n" |
| " /* comment */ aaaaaaaaaaaaaaaaaaaa ,\n" |
| " aaaaaaaaaaaaaaaaaaaa , // comment\n" |
| " aaaaaaaaaaaaaaaaaaaa };")); |
| verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" |
| " bbbbbbbbbbb, ccccccccccc};"); |
| verifyFormat("static SomeType type = {aaaaaaaaaaa,\n" |
| " // comment for bb....\n" |
| " bbbbbbbbbbb, ccccccccccc};"); |
| verifyGoogleFormat( |
| "static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" |
| " bbbbbbbbbbb, ccccccccccc};"); |
| verifyGoogleFormat("static SomeType type = {aaaaaaaaaaa,\n" |
| " // comment for bb....\n" |
| " bbbbbbbbbbb, ccccccccccc};"); |
| |
| verifyFormat("S s = {{a, b, c}, // Group #1\n" |
| " {d, e, f}, // Group #2\n" |
| " {g, h, i}}; // Group #3"); |
| verifyFormat("S s = {{// Group #1\n" |
| " a, b, c},\n" |
| " {// Group #2\n" |
| " d, e, f},\n" |
| " {// Group #3\n" |
| " g, h, i}};"); |
| |
| EXPECT_EQ("S s = {\n" |
| " // Some comment\n" |
| " a,\n" |
| "\n" |
| " // Comment after empty line\n" |
| " b}", |
| format("S s = {\n" |
| " // Some comment\n" |
| " a,\n" |
| " \n" |
| " // Comment after empty line\n" |
| " b\n" |
| "}")); |
| EXPECT_EQ("S s = {\n" |
| " /* Some comment */\n" |
| " a,\n" |
| "\n" |
| " /* Comment after empty line */\n" |
| " b}", |
| format("S s = {\n" |
| " /* Some comment */\n" |
| " a,\n" |
| " \n" |
| " /* Comment after empty line */\n" |
| " b\n" |
| "}")); |
| verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n" |
| " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" |
| " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" |
| " 0x00, 0x00, 0x00, 0x00}; // comment\n"); |
| } |
| |
| TEST_F(FormatTest, IgnoresIf0Contents) { |
| EXPECT_EQ("#if 0\n" |
| "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" |
| "#endif\n" |
| "void f() {}", |
| format("#if 0\n" |
| "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" |
| "#endif\n" |
| "void f( ) { }")); |
| EXPECT_EQ("#if false\n" |
| "void f( ) { }\n" |
| "#endif\n" |
| "void g() {}\n", |
| format("#if false\n" |
| "void f( ) { }\n" |
| "#endif\n" |
| "void g( ) { }\n")); |
| EXPECT_EQ("enum E {\n" |
| " One,\n" |
| " Two,\n" |
| "#if 0\n" |
| "Three,\n" |
| " Four,\n" |
| "#endif\n" |
| " Five\n" |
| "};", |
| format("enum E {\n" |
| " One,Two,\n" |
| "#if 0\n" |
| "Three,\n" |
| " Four,\n" |
| "#endif\n" |
| " Five};")); |
| EXPECT_EQ("enum F {\n" |
| " One,\n" |
| "#if 1\n" |
| " Two,\n" |
| "#if 0\n" |
| "Three,\n" |
| " Four,\n" |
| "#endif\n" |
| " Five\n" |
| "#endif\n" |
| "};", |
| format("enum F {\n" |
| "One,\n" |
| "#if 1\n" |
| "Two,\n" |
| "#if 0\n" |
| "Three,\n" |
| " Four,\n" |
| "#endif\n" |
| "Five\n" |
| "#endif\n" |
| "};")); |
| EXPECT_EQ("enum G {\n" |
| " One,\n" |
| "#if 0\n" |
| "Two,\n" |
| "#else\n" |
| " Three,\n" |
| "#endif\n" |
| " Four\n" |
| "};", |
| format("enum G {\n" |
| "One,\n" |
| "#if 0\n" |
| "Two,\n" |
| "#else\n" |
| "Three,\n" |
| "#endif\n" |
| "Four\n" |
| "};")); |
| EXPECT_EQ("enum H {\n" |
| " One,\n" |
| "#if 0\n" |
| "#ifdef Q\n" |
| "Two,\n" |
| "#else\n" |
| "Three,\n" |
| "#endif\n" |
| "#endif\n" |
| " Four\n" |
| "};", |
| format("enum H {\n" |
| "One,\n" |
| "#if 0\n" |
| "#ifdef Q\n" |
| "Two,\n" |
| "#else\n" |
| "Three,\n" |
| "#endif\n" |
| "#endif\n" |
| "Four\n" |
| "};")); |
| EXPECT_EQ("enum I {\n" |
| " One,\n" |
| "#if /* test */ 0 || 1\n" |
| "Two,\n" |
| "Three,\n" |
| "#endif\n" |
| " Four\n" |
| "};", |
| format("enum I {\n" |
| "One,\n" |
| "#if /* test */ 0 || 1\n" |
| "Two,\n" |
| "Three,\n" |
| "#endif\n" |
| "Four\n" |
| "};")); |
| EXPECT_EQ("enum J {\n" |
| " One,\n" |
| "#if 0\n" |
| "#if 0\n" |
| "Two,\n" |
| "#else\n" |
| "Three,\n" |
| "#endif\n" |
| "Four,\n" |
| "#endif\n" |
| " Five\n" |
| "};", |
| format("enum J {\n" |
| "One,\n" |
| "#if 0\n" |
| "#if 0\n" |
| "Two,\n" |
| "#else\n" |
| "Three,\n" |
| "#endif\n" |
| "Four,\n" |
| "#endif\n" |
| "Five\n" |
| "};")); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Tests for classes, namespaces, etc. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, DoesNotBreakSemiAfterClassDecl) { |
| verifyFormat("class A {};"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsAccessSpecifiers) { |
| verifyFormat("class A {\n" |
| "public:\n" |
| "public: // comment\n" |
| "protected:\n" |
| "private:\n" |
| " void f() {}\n" |
| "};"); |
| verifyGoogleFormat("class A {\n" |
| " public:\n" |
| " protected:\n" |
| " private:\n" |
| " void f() {}\n" |
| "};"); |
| verifyFormat("class A {\n" |
| "public slots:\n" |
| " void f1() {}\n" |
| "public Q_SLOTS:\n" |
| " void f2() {}\n" |
| "protected slots:\n" |
| " void f3() {}\n" |
| "protected Q_SLOTS:\n" |
| " void f4() {}\n" |
| "private slots:\n" |
| " void f5() {}\n" |
| "private Q_SLOTS:\n" |
| " void f6() {}\n" |
| "signals:\n" |
| " void g1();\n" |
| "Q_SIGNALS:\n" |
| " void g2();\n" |
| "};"); |
| |
| // Don't interpret 'signals' the wrong way. |
| verifyFormat("signals.set();"); |
| verifyFormat("for (Signals signals : f()) {\n}"); |
| verifyFormat("{\n" |
| " signals.set(); // This needs indentation.\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| "label:\n" |
| " signals.baz();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, SeparatesLogicalBlocks) { |
| EXPECT_EQ("class A {\n" |
| "public:\n" |
| " void f();\n" |
| "\n" |
| "private:\n" |
| " void g() {}\n" |
| " // test\n" |
| "protected:\n" |
| " int h;\n" |
| "};", |
| format("class A {\n" |
| "public:\n" |
| "void f();\n" |
| "private:\n" |
| "void g() {}\n" |
| "// test\n" |
| "protected:\n" |
| "int h;\n" |
| "};")); |
| EXPECT_EQ("class A {\n" |
| "protected:\n" |
| "public:\n" |
| " void f();\n" |
| "};", |
| format("class A {\n" |
| "protected:\n" |
| "\n" |
| "public:\n" |
| "\n" |
| " void f();\n" |
| "};")); |
| |
| // Even ensure proper spacing inside macros. |
| EXPECT_EQ("#define B \\\n" |
| " class A { \\\n" |
| " protected: \\\n" |
| " public: \\\n" |
| " void f(); \\\n" |
| " };", |
| format("#define B \\\n" |
| " class A { \\\n" |
| " protected: \\\n" |
| " \\\n" |
| " public: \\\n" |
| " \\\n" |
| " void f(); \\\n" |
| " };", |
| getGoogleStyle())); |
| // But don't remove empty lines after macros ending in access specifiers. |
| EXPECT_EQ("#define A private:\n" |
| "\n" |
| "int i;", |
| format("#define A private:\n" |
| "\n" |
| "int i;")); |
| } |
| |
| TEST_F(FormatTest, FormatsClasses) { |
| verifyFormat("class A : public B {};"); |
| verifyFormat("class A : public ::B {};"); |
| |
| verifyFormat( |
| "class AAAAAAAAAAAAAAAAAAAA : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" |
| " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};"); |
| verifyFormat("class AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" |
| " : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" |
| " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};"); |
| verifyFormat( |
| "class A : public B, public C, public D, public E, public F {};"); |
| verifyFormat("class AAAAAAAAAAAA : public B,\n" |
| " public C,\n" |
| " public D,\n" |
| " public E,\n" |
| " public F,\n" |
| " public G {};"); |
| |
| verifyFormat("class\n" |
| " ReallyReallyLongClassName {\n" |
| " int i;\n" |
| "};", |
| getLLVMStyleWithColumns(32)); |
| verifyFormat("struct aaaaaaaaaaaaa : public aaaaaaaaaaaaaaaaaaa< // break\n" |
| " aaaaaaaaaaaaaaaa> {};"); |
| verifyFormat("struct aaaaaaaaaaaaaaaaaaaa\n" |
| " : public aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaa> {};"); |
| verifyFormat("template <class R, class C>\n" |
| "struct Aaaaaaaaaaaaaaaaa<R (C::*)(int) const>\n" |
| " : Aaaaaaaaaaaaaaaaa<R (C::*)(int)> {};"); |
| verifyFormat("class ::A::B {};"); |
| } |
| |
| TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) { |
| verifyFormat("class A {\n} a, b;"); |
| verifyFormat("struct A {\n} a, b;"); |
| verifyFormat("union A {\n} a;"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnum) { |
| verifyFormat("enum {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyGoogleFormat("enum {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyFormat("enum Enum {};"); |
| verifyFormat("enum {};"); |
| verifyFormat("enum X E {} d;"); |
| verifyFormat("enum __attribute__((...)) E {} d;"); |
| verifyFormat("enum __declspec__((...)) E {} d;"); |
| verifyFormat("enum {\n" |
| " Bar = Foo<int, int>::value\n" |
| "};", |
| getLLVMStyleWithColumns(30)); |
| |
| verifyFormat("enum ShortEnum { A, B, C };"); |
| verifyGoogleFormat("enum ShortEnum { A, B, C };"); |
| |
| EXPECT_EQ("enum KeepEmptyLines {\n" |
| " ONE,\n" |
| "\n" |
| " TWO,\n" |
| "\n" |
| " THREE\n" |
| "}", |
| format("enum KeepEmptyLines {\n" |
| " ONE,\n" |
| "\n" |
| " TWO,\n" |
| "\n" |
| "\n" |
| " THREE\n" |
| "}")); |
| verifyFormat("enum E { // comment\n" |
| " ONE,\n" |
| " TWO\n" |
| "};\n" |
| "int i;"); |
| // Not enums. |
| verifyFormat("enum X f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| verifyFormat("enum X Type::f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| verifyFormat("enum ::X f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| verifyFormat("enum ns::X f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumsWithErrors) { |
| verifyFormat("enum Type {\n" |
| " One = 0; // These semicolons should be commas.\n" |
| " Two = 1;\n" |
| "};"); |
| verifyFormat("namespace n {\n" |
| "enum Type {\n" |
| " One,\n" |
| " Two, // missing };\n" |
| " int i;\n" |
| "}\n" |
| "void g() {}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumStruct) { |
| verifyFormat("enum struct {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyFormat("enum struct Enum {};"); |
| verifyFormat("enum struct {};"); |
| verifyFormat("enum struct X E {} d;"); |
| verifyFormat("enum struct __attribute__((...)) E {} d;"); |
| verifyFormat("enum struct __declspec__((...)) E {} d;"); |
| verifyFormat("enum struct X f() {\n a();\n return 42;\n}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumClass) { |
| verifyFormat("enum class {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyFormat("enum class Enum {};"); |
| verifyFormat("enum class {};"); |
| verifyFormat("enum class X E {} d;"); |
| verifyFormat("enum class __attribute__((...)) E {} d;"); |
| verifyFormat("enum class __declspec__((...)) E {} d;"); |
| verifyFormat("enum class X f() {\n a();\n return 42;\n}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumTypes) { |
| verifyFormat("enum X : int {\n" |
| " A, // Force multiple lines.\n" |
| " B\n" |
| "};"); |
| verifyFormat("enum X : int { A, B };"); |
| verifyFormat("enum X : std::uint32_t { A, B };"); |
| } |
| |
| TEST_F(FormatTest, FormatsNSEnums) { |
| verifyGoogleFormat("typedef NS_ENUM(NSInteger, SomeName) { AAA, BBB }"); |
| verifyGoogleFormat("typedef NS_ENUM(NSInteger, MyType) {\n" |
| " // Information about someDecentlyLongValue.\n" |
| " someDecentlyLongValue,\n" |
| " // Information about anotherDecentlyLongValue.\n" |
| " anotherDecentlyLongValue,\n" |
| " // Information about aThirdDecentlyLongValue.\n" |
| " aThirdDecentlyLongValue\n" |
| "};"); |
| verifyGoogleFormat("typedef NS_OPTIONS(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| verifyGoogleFormat("typedef CF_ENUM(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| verifyGoogleFormat("typedef CF_OPTIONS(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, FormatsBitfields) { |
| verifyFormat("struct Bitfields {\n" |
| " unsigned sClass : 8;\n" |
| " unsigned ValueKind : 2;\n" |
| "};"); |
| verifyFormat("struct A {\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa : 1,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb;\n" |
| "};"); |
| verifyFormat("struct MyStruct {\n" |
| " uchar data;\n" |
| " uchar : 8;\n" |
| " uchar : 8;\n" |
| " uchar other;\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, FormatsNamespaces) { |
| verifyFormat("namespace some_namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}"); |
| verifyFormat("namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}"); |
| verifyFormat("inline namespace X {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}"); |
| verifyFormat("using namespace some_namespace;\n" |
| "class A {};\n" |
| "void f() { f(); }"); |
| |
| // This code is more common than we thought; if we |
| // layout this correctly the semicolon will go into |
| // its own line, which is undesirable. |
| verifyFormat("namespace {};"); |
| verifyFormat("namespace {\n" |
| "class A {};\n" |
| "};"); |
| |
| verifyFormat("namespace {\n" |
| "int SomeVariable = 0; // comment\n" |
| "} // namespace"); |
| EXPECT_EQ("#ifndef HEADER_GUARD\n" |
| "#define HEADER_GUARD\n" |
| "namespace my_namespace {\n" |
| "int i;\n" |
| "} // my_namespace\n" |
| "#endif // HEADER_GUARD", |
| format("#ifndef HEADER_GUARD\n" |
| " #define HEADER_GUARD\n" |
| " namespace my_namespace {\n" |
| "int i;\n" |
| "} // my_namespace\n" |
| "#endif // HEADER_GUARD")); |
| |
| EXPECT_EQ("namespace A::B {\n" |
| "class C {};\n" |
| "}", |
| format("namespace A::B {\n" |
| "class C {};\n" |
| "}")); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.NamespaceIndentation = FormatStyle::NI_All; |
| EXPECT_EQ("namespace out {\n" |
| " int i;\n" |
| " namespace in {\n" |
| " int i;\n" |
| " } // namespace\n" |
| "} // namespace", |
| format("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace\n" |
| "} // namespace", |
| Style)); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_Inner; |
| EXPECT_EQ("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| " int i;\n" |
| "} // namespace\n" |
| "} // namespace", |
| format("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace\n" |
| "} // namespace", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); } |
| |
| TEST_F(FormatTest, FormatsInlineASM) { |
| verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));"); |
| verifyFormat("asm(\"nop\" ::: \"memory\");"); |
| verifyFormat( |
| "asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n" |
| " \"cpuid\\n\\t\"\n" |
| " \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n" |
| " : \"=a\"(*rEAX), \"=S\"(*rEBX), \"=c\"(*rECX), \"=d\"(*rEDX)\n" |
| " : \"a\"(value));"); |
| EXPECT_EQ( |
| "void NS_InvokeByIndex(void *that, unsigned int methodIndex) {\n" |
| " __asm {\n" |
| " mov edx,[that] // vtable in edx\n" |
| " mov eax,methodIndex\n" |
| " call [edx][eax*4] // stdcall\n" |
| " }\n" |
| "}", |
| format("void NS_InvokeByIndex(void *that, unsigned int methodIndex) {\n" |
| " __asm {\n" |
| " mov edx,[that] // vtable in edx\n" |
| " mov eax,methodIndex\n" |
| " call [edx][eax*4] // stdcall\n" |
| " }\n" |
| "}")); |
| EXPECT_EQ("_asm {\n" |
| " xor eax, eax;\n" |
| " cpuid;\n" |
| "}", |
| format("_asm {\n" |
| " xor eax, eax;\n" |
| " cpuid;\n" |
| "}")); |
| verifyFormat("void function() {\n" |
| " // comment\n" |
| " asm(\"\");\n" |
| "}"); |
| EXPECT_EQ("__asm {\n" |
| "}\n" |
| "int i;", |
| format("__asm {\n" |
| "}\n" |
| "int i;")); |
| } |
| |
| TEST_F(FormatTest, FormatTryCatch) { |
| verifyFormat("try {\n" |
| " throw a * b;\n" |
| "} catch (int a) {\n" |
| " // Do nothing.\n" |
| "} catch (...) {\n" |
| " exit(42);\n" |
| "}"); |
| |
| // Function-level try statements. |
| verifyFormat("int f() try { return 4; } catch (...) {\n" |
| " return 5;\n" |
| "}"); |
| verifyFormat("class A {\n" |
| " int a;\n" |
| " A() try : a(0) {\n" |
| " } catch (...) {\n" |
| " throw;\n" |
| " }\n" |
| "};\n"); |
| |
| // Incomplete try-catch blocks. |
| verifyIncompleteFormat("try {} catch ("); |
| } |
| |
| TEST_F(FormatTest, FormatSEHTryCatch) { |
| verifyFormat("__try {\n" |
| " int a = b * c;\n" |
| "} __except (EXCEPTION_EXECUTE_HANDLER) {\n" |
| " // Do nothing.\n" |
| "}"); |
| |
| verifyFormat("__try {\n" |
| " int a = b * c;\n" |
| "} __finally {\n" |
| " // Do nothing.\n" |
| "}"); |
| |
| verifyFormat("DEBUG({\n" |
| " __try {\n" |
| " } __finally {\n" |
| " }\n" |
| "});\n"); |
| } |
| |
| TEST_F(FormatTest, IncompleteTryCatchBlocks) { |
| verifyFormat("try {\n" |
| " f();\n" |
| "} catch {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("try {\n" |
| " f();\n" |
| "} catch (A a) MACRO(x) {\n" |
| " g();\n" |
| "} catch (B b) MACRO(x) {\n" |
| " g();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, FormatTryCatchBraceStyles) { |
| FormatStyle Style = getLLVMStyle(); |
| for (auto BraceStyle : {FormatStyle::BS_Attach, FormatStyle::BS_Mozilla, |
| FormatStyle::BS_WebKit}) { |
| Style.BreakBeforeBraces = BraceStyle; |
| verifyFormat("try {\n" |
| " // something\n" |
| "} catch (...) {\n" |
| " // something\n" |
| "}", |
| Style); |
| } |
| Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; |
| verifyFormat("try {\n" |
| " // something\n" |
| "}\n" |
| "catch (...) {\n" |
| " // something\n" |
| "}", |
| Style); |
| verifyFormat("__try {\n" |
| " // something\n" |
| "}\n" |
| "__finally {\n" |
| " // something\n" |
| "}", |
| Style); |
| verifyFormat("@try {\n" |
| " // something\n" |
| "}\n" |
| "@finally {\n" |
| " // something\n" |
| "}", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Allman; |
| verifyFormat("try\n" |
| "{\n" |
| " // something\n" |
| "}\n" |
| "catch (...)\n" |
| "{\n" |
| " // something\n" |
| "}", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_GNU; |
| verifyFormat("try\n" |
| " {\n" |
| " // something\n" |
| " }\n" |
| "catch (...)\n" |
| " {\n" |
| " // something\n" |
| " }", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.BeforeCatch = true; |
| verifyFormat("try {\n" |
| " // something\n" |
| "}\n" |
| "catch (...) {\n" |
| " // something\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatObjCTryCatch) { |
| verifyFormat("@try {\n" |
| " f();\n" |
| "} @catch (NSException e) {\n" |
| " @throw;\n" |
| "} @finally {\n" |
| " exit(42);\n" |
| "}"); |
| verifyFormat("DEBUG({\n" |
| " @try {\n" |
| " } @finally {\n" |
| " }\n" |
| "});\n"); |
| } |
| |
| TEST_F(FormatTest, FormatObjCAutoreleasepool) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("@autoreleasepool {\n" |
| " f();\n" |
| "}\n" |
| "@autoreleasepool {\n" |
| " f();\n" |
| "}\n", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Allman; |
| verifyFormat("@autoreleasepool\n" |
| "{\n" |
| " f();\n" |
| "}\n" |
| "@autoreleasepool\n" |
| "{\n" |
| " f();\n" |
| "}\n", |
| Style); |
| } |
| |
| TEST_F(FormatTest, StaticInitializers) { |
| verifyFormat("static SomeClass SC = {1, 'a'};"); |
| |
| verifyFormat("static SomeClass WithALoooooooooooooooooooongName = {\n" |
| " 100000000, " |
| "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"};"); |
| |
| // Here, everything other than the "}" would fit on a line. |
| verifyFormat("static int LooooooooooooooooooooooooongVariable[1] = {\n" |
| " 10000000000000000000000000};"); |
| EXPECT_EQ("S s = {a,\n" |
| "\n" |
| " b};", |
| format("S s = {\n" |
| " a,\n" |
| "\n" |
| " b\n" |
| "};")); |
| |
| // FIXME: This would fit into the column limit if we'd fit "{ {" on the first |
| // line. However, the formatting looks a bit off and this probably doesn't |
| // happen often in practice. |
| verifyFormat("static int Variable[1] = {\n" |
| " {1000000000000000000000000000000000000}};", |
| getLLVMStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, DesignatedInitializers) { |
| verifyFormat("const struct A a = {.a = 1, .b = 2};"); |
| verifyFormat("const struct A a = {.aaaaaaaaaa = 1,\n" |
| " .bbbbbbbbbb = 2,\n" |
| " .cccccccccc = 3,\n" |
| " .dddddddddd = 4,\n" |
| " .eeeeeeeeee = 5};"); |
| verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaa = 1,\n" |
| " .bbbbbbbbbbbbbbbbbbbbbbbbbbb = 2,\n" |
| " .ccccccccccccccccccccccccccc = 3,\n" |
| " .ddddddddddddddddddddddddddd = 4,\n" |
| " .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5};"); |
| |
| verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};"); |
| } |
| |
| TEST_F(FormatTest, NestedStaticInitializers) { |
| verifyFormat("static A x = {{{}}};\n"); |
| verifyFormat("static A x = {{{init1, init2, init3, init4},\n" |
| " {init1, init2, init3, init4}}};", |
| getLLVMStyleWithColumns(50)); |
| |
| verifyFormat("somes Status::global_reps[3] = {\n" |
| " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};", |
| getLLVMStyleWithColumns(60)); |
| verifyGoogleFormat("SomeType Status::global_reps[3] = {\n" |
| " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};"); |
| verifyFormat("CGRect cg_rect = {{rect.fLeft, rect.fTop},\n" |
| " {rect.fRight - rect.fLeft, rect.fBottom - " |
| "rect.fTop}};"); |
| |
| verifyFormat( |
| "SomeArrayOfSomeType a = {\n" |
| " {{1, 2, 3},\n" |
| " {1, 2, 3},\n" |
| " {111111111111111111111111111111, 222222222222222222222222222222,\n" |
| " 333333333333333333333333333333},\n" |
| " {1, 2, 3},\n" |
| " {1, 2, 3}}};"); |
| verifyFormat( |
| "SomeArrayOfSomeType a = {\n" |
| " {{1, 2, 3}},\n" |
| " {{1, 2, 3}},\n" |
| " {{111111111111111111111111111111, 222222222222222222222222222222,\n" |
| " 333333333333333333333333333333}},\n" |
| " {{1, 2, 3}},\n" |
| " {{1, 2, 3}}};"); |
| |
| verifyFormat("struct {\n" |
| " unsigned bit;\n" |
| " const char *const name;\n" |
| "} kBitsToOs[] = {{kOsMac, \"Mac\"},\n" |
| " {kOsWin, \"Windows\"},\n" |
| " {kOsLinux, \"Linux\"},\n" |
| " {kOsCrOS, \"Chrome OS\"}};"); |
| verifyFormat("struct {\n" |
| " unsigned bit;\n" |
| " const char *const name;\n" |
| "} kBitsToOs[] = {\n" |
| " {kOsMac, \"Mac\"},\n" |
| " {kOsWin, \"Windows\"},\n" |
| " {kOsLinux, \"Linux\"},\n" |
| " {kOsCrOS, \"Chrome OS\"},\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) { |
| verifyFormat("#define ALooooooooooooooooooooooooooooooooooooooongMacro(" |
| " \\\n" |
| " aLoooooooooooooooooooooooongFuuuuuuuuuuuuuunctiooooooooo)"); |
| } |
| |
| TEST_F(FormatTest, DoesNotBreakPureVirtualFunctionDefinition) { |
| verifyFormat("virtual void write(ELFWriter *writerrr,\n" |
| " OwningPtr<FileOutputBuffer> &buffer) = 0;"); |
| |
| // Do break defaulted and deleted functions. |
| verifyFormat("virtual void ~Deeeeeeeestructor() =\n" |
| " default;", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("virtual void ~Deeeeeeeestructor() =\n" |
| " delete;", |
| getLLVMStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiteralsOnlyInDefine) { |
| verifyFormat("# 1111 \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/aaaaaaaa.cpp\" 2 3", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("#line 11111 \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/aaaaaaaa.cpp\"", |
| getLLVMStyleWithColumns(40)); |
| EXPECT_EQ("#define Q \\\n" |
| " \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/\" \\\n" |
| " \"aaaaaaaa.cpp\"", |
| format("#define Q \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/aaaaaaaa.cpp\"", |
| getLLVMStyleWithColumns(40))); |
| } |
| |
| TEST_F(FormatTest, UnderstandsLinePPDirective) { |
| EXPECT_EQ("# 123 \"A string literal\"", |
| format(" # 123 \"A string literal\"")); |
| } |
| |
| TEST_F(FormatTest, LayoutUnknownPPDirective) { |
| EXPECT_EQ("#;", format("#;")); |
| verifyFormat("#\n;\n;\n;"); |
| } |
| |
| TEST_F(FormatTest, UnescapedEndOfLineEndsPPDirective) { |
| EXPECT_EQ("#line 42 \"test\"\n", |
| format("# \\\n line \\\n 42 \\\n \"test\"\n")); |
| EXPECT_EQ("#define A B\n", format("# \\\n define \\\n A \\\n B\n", |
| getLLVMStyleWithColumns(12))); |
| } |
| |
| TEST_F(FormatTest, EndOfFileEndsPPDirective) { |
| EXPECT_EQ("#line 42 \"test\"", |
| format("# \\\n line \\\n 42 \\\n \"test\"")); |
| EXPECT_EQ("#define A B", format("# \\\n define \\\n A \\\n B")); |
| } |
| |
| TEST_F(FormatTest, DoesntRemoveUnknownTokens) { |
| verifyFormat("#define A \\x20"); |
| verifyFormat("#define A \\ x20"); |
| EXPECT_EQ("#define A \\ x20", format("#define A \\ x20")); |
| verifyFormat("#define A ''"); |
| verifyFormat("#define A ''qqq"); |
| verifyFormat("#define A `qqq"); |
| verifyFormat("f(\"aaaa, bbbb, \"\\\"ccccc\\\"\");"); |
| EXPECT_EQ("const char *c = STRINGIFY(\n" |
| "\\na : b);", |
| format("const char * c = STRINGIFY(\n" |
| "\\na : b);")); |
| |
| verifyFormat("a\r\\"); |
| verifyFormat("a\v\\"); |
| verifyFormat("a\f\\"); |
| } |
| |
| TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) { |
| verifyFormat("#define A(BB)", getLLVMStyleWithColumns(13)); |
| verifyFormat("#define A( \\\n BB)", getLLVMStyleWithColumns(12)); |
| verifyFormat("#define A( \\\n A, B)", getLLVMStyleWithColumns(12)); |
| // FIXME: We never break before the macro name. |
| verifyFormat("#define AA( \\\n B)", getLLVMStyleWithColumns(12)); |
| |
| verifyFormat("#define A A\n#define A A"); |
| verifyFormat("#define A(X) A\n#define A A"); |
| |
| verifyFormat("#define Something Other", getLLVMStyleWithColumns(23)); |
| verifyFormat("#define Something \\\n Other", getLLVMStyleWithColumns(22)); |
| } |
| |
| TEST_F(FormatTest, HandlePreprocessorDirectiveContext) { |
| EXPECT_EQ("// somecomment\n" |
| "#include \"a.h\"\n" |
| "#define A( \\\n" |
| " A, B)\n" |
| "#include \"b.h\"\n" |
| "// somecomment\n", |
| format(" // somecomment\n" |
| " #include \"a.h\"\n" |
| "#define A(A,\\\n" |
| " B)\n" |
| " #include \"b.h\"\n" |
| " // somecomment\n", |
| getLLVMStyleWithColumns(13))); |
| } |
| |
| TEST_F(FormatTest, LayoutSingleHash) { EXPECT_EQ("#\na;", format("#\na;")); } |
| |
| TEST_F(FormatTest, LayoutCodeInMacroDefinitions) { |
| EXPECT_EQ("#define A \\\n" |
| " c; \\\n" |
| " e;\n" |
| "f;", |
| format("#define A c; e;\n" |
| "f;", |
| getLLVMStyleWithColumns(14))); |
| } |
| |
| TEST_F(FormatTest, LayoutRemainingTokens) { EXPECT_EQ("{}", format("{}")); } |
| |
| TEST_F(FormatTest, MacroDefinitionInsideStatement) { |
| EXPECT_EQ("int x,\n" |
| "#define A\n" |
| " y;", |
| format("int x,\n#define A\ny;")); |
| } |
| |
| TEST_F(FormatTest, HashInMacroDefinition) { |
| EXPECT_EQ("#define A(c) L#c", format("#define A(c) L#c", getLLVMStyle())); |
| verifyFormat("#define A \\\n b #c;", getLLVMStyleWithColumns(11)); |
| verifyFormat("#define A \\\n" |
| " { \\\n" |
| " f(#c); \\\n" |
| " }", |
| getLLVMStyleWithColumns(11)); |
| |
| verifyFormat("#define A(X) \\\n" |
| " void function##X()", |
| getLLVMStyleWithColumns(22)); |
| |
| verifyFormat("#define A(a, b, c) \\\n" |
| " void a##b##c()", |
| getLLVMStyleWithColumns(22)); |
| |
| verifyFormat("#define A void # ## #", getLLVMStyleWithColumns(22)); |
| } |
| |
| TEST_F(FormatTest, RespectWhitespaceInMacroDefinitions) { |
| EXPECT_EQ("#define A (x)", format("#define A (x)")); |
| EXPECT_EQ("#define A(x)", format("#define A(x)")); |
| } |
| |
| TEST_F(FormatTest, EmptyLinesInMacroDefinitions) { |
| EXPECT_EQ("#define A b;", format("#define A \\\n" |
| " \\\n" |
| " b;", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("#define A \\\n" |
| " \\\n" |
| " a; \\\n" |
| " b;", |
| format("#define A \\\n" |
| " \\\n" |
| " a; \\\n" |
| " b;", |
| getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("#define A \\\n" |
| " a; \\\n" |
| " \\\n" |
| " b;", |
| format("#define A \\\n" |
| " a; \\\n" |
| " \\\n" |
| " b;", |
| getLLVMStyleWithColumns(11))); |
| } |
| |
| TEST_F(FormatTest, MacroDefinitionsWithIncompleteCode) { |
| verifyIncompleteFormat("#define A :"); |
| verifyFormat("#define SOMECASES \\\n" |
| " case 1: \\\n" |
| " case 2\n", |
| getLLVMStyleWithColumns(20)); |
| verifyFormat("#define MACRO(a) \\\n" |
| " if (a) \\\n" |
| " f(); \\\n" |
| " else \\\n" |
| " g()", |
| getLLVMStyleWithColumns(18)); |
| verifyFormat("#define A template <typename T>"); |
| verifyIncompleteFormat("#define STR(x) #x\n" |
| "f(STR(this_is_a_string_literal{));"); |
| verifyFormat("#pragma omp threadprivate( \\\n" |
| " y)), // expected-warning", |
| getLLVMStyleWithColumns(28)); |
| verifyFormat("#d, = };"); |
| verifyFormat("#if \"a"); |
| verifyIncompleteFormat("({\n" |
| "#define b \\\n" |
| " } \\\n" |
| " a\n" |
| "a", |
| getLLVMStyleWithColumns(15)); |
| verifyFormat("#define A \\\n" |
| " { \\\n" |
| " {\n" |
| "#define B \\\n" |
| " } \\\n" |
| " }", |
| getLLVMStyleWithColumns(15)); |
| verifyNoCrash("#if a\na(\n#else\n#endif\n{a"); |
| verifyNoCrash("a={0,1\n#if a\n#else\n;\n#endif\n}"); |
| verifyNoCrash("#if a\na(\n#else\n#endif\n) a {a,b,c,d,f,g};"); |
| verifyNoCrash("#ifdef A\n a(\n #else\n #endif\n) = []() { \n)}"); |
| } |
| |
| TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { |
| verifyFormat("SOME_TYPE_NAME abc;"); // Gated on the newline. |
| EXPECT_EQ("class A : public QObject {\n" |
| " Q_OBJECT\n" |
| "\n" |
| " A() {}\n" |
| "};", |
| format("class A : public QObject {\n" |
| " Q_OBJECT\n" |
| "\n" |
| " A() {\n}\n" |
| "} ;")); |
| EXPECT_EQ("MACRO\n" |
| "/*static*/ int i;", |
| format("MACRO\n" |
| " /*static*/ int i;")); |
| EXPECT_EQ("SOME_MACRO\n" |
| "namespace {\n" |
| "void f();\n" |
| "}", |
| format("SOME_MACRO\n" |
| " namespace {\n" |
| "void f( );\n" |
| "}")); |
| // Only if the identifier contains at least 5 characters. |
| EXPECT_EQ("HTTP f();", format("HTTP\nf();")); |
| EXPECT_EQ("MACRO\nf();", format("MACRO\nf();")); |
| // Only if everything is upper case. |
| EXPECT_EQ("class A : public QObject {\n" |
| " Q_Object A() {}\n" |
| "};", |
| format("class A : public QObject {\n" |
| " Q_Object\n" |
| " A() {\n}\n" |
| "} ;")); |
| |
| // Only if the next line can actually start an unwrapped line. |
| EXPECT_EQ("SOME_WEIRD_LOG_MACRO << SomeThing;", |
| format("SOME_WEIRD_LOG_MACRO\n" |
| "<< SomeThing;")); |
| |
| verifyFormat("VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint* buffers), " |
| "(n, buffers))\n", |
| getChromiumStyle(FormatStyle::LK_Cpp)); |
| } |
| |
| TEST_F(FormatTest, MacroCallsWithoutTrailingSemicolon) { |
| EXPECT_EQ("INITIALIZE_PASS_BEGIN(ScopDetection, \"polly-detect\")\n" |
| "INITIALIZE_AG_DEPENDENCY(AliasAnalysis)\n" |
| "INITIALIZE_PASS_DEPENDENCY(DominatorTree)\n" |
| "class X {};\n" |
| "INITIALIZE_PASS_END(ScopDetection, \"polly-detect\")\n" |
| "int *createScopDetectionPass() { return 0; }", |
| format(" INITIALIZE_PASS_BEGIN(ScopDetection, \"polly-detect\")\n" |
| " INITIALIZE_AG_DEPENDENCY(AliasAnalysis)\n" |
| " INITIALIZE_PASS_DEPENDENCY(DominatorTree)\n" |
| " class X {};\n" |
| " INITIALIZE_PASS_END(ScopDetection, \"polly-detect\")\n" |
| " int *createScopDetectionPass() { return 0; }")); |
| // FIXME: We could probably treat IPC_BEGIN_MESSAGE_MAP/IPC_END_MESSAGE_MAP as |
| // braces, so that inner block is indented one level more. |
| EXPECT_EQ("int q() {\n" |
| " IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message)\n" |
| " IPC_MESSAGE_HANDLER(xxx, qqq)\n" |
| " IPC_END_MESSAGE_MAP()\n" |
| "}", |
| format("int q() {\n" |
| " IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message)\n" |
| " IPC_MESSAGE_HANDLER(xxx, qqq)\n" |
| " IPC_END_MESSAGE_MAP()\n" |
| "}")); |
| |
| // Same inside macros. |
| EXPECT_EQ("#define LIST(L) \\\n" |
| " L(A) \\\n" |
| " L(B) \\\n" |
| " L(C)", |
| format("#define LIST(L) \\\n" |
| " L(A) \\\n" |
| " L(B) \\\n" |
| " L(C)", |
| getGoogleStyle())); |
| |
| // These must not be recognized as macros. |
| EXPECT_EQ("int q() {\n" |
| " f(x);\n" |
| " f(x) {}\n" |
| " f(x)->g();\n" |
| " f(x)->*g();\n" |
| " f(x).g();\n" |
| " f(x) = x;\n" |
| " f(x) += x;\n" |
| " f(x) -= x;\n" |
| " f(x) *= x;\n" |
| " f(x) /= x;\n" |
| " f(x) %= x;\n" |
| " f(x) &= x;\n" |
| " f(x) |= x;\n" |
| " f(x) ^= x;\n" |
| " f(x) >>= x;\n" |
| " f(x) <<= x;\n" |
| " f(x)[y].z();\n" |
| " LOG(INFO) << x;\n" |
| " ifstream(x) >> x;\n" |
| "}\n", |
| format("int q() {\n" |
| " f(x)\n;\n" |
| " f(x)\n {}\n" |
| " f(x)\n->g();\n" |
| " f(x)\n->*g();\n" |
| " f(x)\n.g();\n" |
| " f(x)\n = x;\n" |
| " f(x)\n += x;\n" |
| " f(x)\n -= x;\n" |
| " f(x)\n *= x;\n" |
| " f(x)\n /= x;\n" |
| " f(x)\n %= x;\n" |
| " f(x)\n &= x;\n" |
| " f(x)\n |= x;\n" |
| " f(x)\n ^= x;\n" |
| " f(x)\n >>= x;\n" |
| " f(x)\n <<= x;\n" |
| " f(x)\n[y].z();\n" |
| " LOG(INFO)\n << x;\n" |
| " ifstream(x)\n >> x;\n" |
| "}\n")); |
| EXPECT_EQ("int q() {\n" |
| " F(x)\n" |
| " if (1) {\n" |
| " }\n" |
| " F(x)\n" |
| " while (1) {\n" |
| " }\n" |
| " F(x)\n" |
| " G(x);\n" |
| " F(x)\n" |
| " try {\n" |
| " Q();\n" |
| " } catch (...) {\n" |
| " }\n" |
| "}\n", |
| format("int q() {\n" |
| "F(x)\n" |
| "if (1) {}\n" |
| "F(x)\n" |
| "while (1) {}\n" |
| "F(x)\n" |
| "G(x);\n" |
| "F(x)\n" |
| "try { Q(); } catch (...) {}\n" |
| "}\n")); |
| EXPECT_EQ("class A {\n" |
| " A() : t(0) {}\n" |
| " A(int i) noexcept() : {}\n" |
| " A(X x)\n" // FIXME: function-level try blocks are broken. |
| " try : t(0) {\n" |
| " } catch (...) {\n" |
| " }\n" |
| "};", |
| format("class A {\n" |
| " A()\n : t(0) {}\n" |
| " A(int i)\n noexcept() : {}\n" |
| " A(X x)\n" |
| " try : t(0) {} catch (...) {}\n" |
| "};")); |
| EXPECT_EQ("class SomeClass {\n" |
| "public:\n" |
| " SomeClass() EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};", |
| format("class SomeClass {\n" |
| "public:\n" |
| " SomeClass()\n" |
| " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};")); |
| EXPECT_EQ("class SomeClass {\n" |
| "public:\n" |
| " SomeClass()\n" |
| " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};", |
| format("class SomeClass {\n" |
| "public:\n" |
| " SomeClass()\n" |
| " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};", |
| getLLVMStyleWithColumns(40))); |
| |
| verifyFormat("MACRO(>)"); |
| } |
| |
| TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) { |
| verifyFormat("#define A \\\n" |
| " f({ \\\n" |
| " g(); \\\n" |
| " });", |
| getLLVMStyleWithColumns(11)); |
| } |
| |
| TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) { |
| EXPECT_EQ("{\n {\n#define A\n }\n}", format("{{\n#define A\n}}")); |
| } |
| |
| TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) { |
| verifyFormat("{\n { a #c; }\n}"); |
| } |
| |
| TEST_F(FormatTest, FormatUnbalancedStructuralElements) { |
| EXPECT_EQ("#define A \\\n { \\\n {\nint i;", |
| format("#define A { {\nint i;", getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("#define A \\\n } \\\n }\nint i;", |
| format("#define A } }\nint i;", getLLVMStyleWithColumns(11))); |
| } |
| |
| TEST_F(FormatTest, EscapedNewlines) { |
| EXPECT_EQ( |
| "#define A \\\n int i; \\\n int j;", |
| format("#define A \\\nint i;\\\n int j;", getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("#define A\n\nint i;", format("#define A \\\n\n int i;")); |
| EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();")); |
| EXPECT_EQ("/* \\ \\ \\\n*/", format("\\\n/* \\ \\ \\\n*/")); |
| EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>")); |
| } |
| |
| TEST_F(FormatTest, DontCrashOnBlockComments) { |
| EXPECT_EQ( |
| "int xxxxxxxxx; /* " |
| "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" |
| "zzzzzz\n" |
| "0*/", |
| format("int xxxxxxxxx; /* " |
| "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n" |
| "0*/")); |
| } |
| |
| TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) { |
| verifyFormat("#define A \\\n" |
| " int v( \\\n" |
| " a); \\\n" |
| " int i;", |
| getLLVMStyleWithColumns(11)); |
| } |
| |
| TEST_F(FormatTest, MixingPreprocessorDirectivesAndNormalCode) { |
| EXPECT_EQ( |
| "#define ALooooooooooooooooooooooooooooooooooooooongMacro(" |
| " \\\n" |
| " aLoooooooooooooooooooooooongFuuuuuuuuuuuuuunctiooooooooo)\n" |
| "\n" |
| "AlooooooooooooooooooooooooooooooooooooooongCaaaaaaaaaal(\n" |
| " aLooooooooooooooooooooooonPaaaaaaaaaaaaaaaaaaaaarmmmm);\n", |
| format(" #define ALooooooooooooooooooooooooooooooooooooooongMacro(" |
| "\\\n" |
| "aLoooooooooooooooooooooooongFuuuuuuuuuuuuuunctiooooooooo)\n" |
| " \n" |
| " AlooooooooooooooooooooooooooooooooooooooongCaaaaaaaaaal(\n" |
| " aLooooooooooooooooooooooonPaaaaaaaaaaaaaaaaaaaaarmmmm);\n")); |
| } |
| |
| TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { |
| EXPECT_EQ("int\n" |
| "#define A\n" |
| " a;", |
| format("int\n#define A\na;")); |
| verifyFormat("functionCallTo(\n" |
| " someOtherFunction(\n" |
| " withSomeParameters, whichInSequence,\n" |
| " areLongerThanALine(andAnotherCall,\n" |
| "#define A B\n" |
| " withMoreParamters,\n" |
| " whichStronglyInfluenceTheLayout),\n" |
| " andMoreParameters),\n" |
| " trailing);", |
| getLLVMStyleWithColumns(69)); |
| verifyFormat("Foo::Foo()\n" |
| "#ifdef BAR\n" |
| " : baz(0)\n" |
| "#endif\n" |
| "{\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| " if (true)\n" |
| "#ifdef A\n" |
| " f(42);\n" |
| " x();\n" |
| "#else\n" |
| " g();\n" |
| " x();\n" |
| "#endif\n" |
| "}"); |
| verifyFormat("void f(param1, param2,\n" |
| " param3,\n" |
| "#ifdef A\n" |
| " param4(param5,\n" |
| "#ifdef A1\n" |
| " param6,\n" |
| "#ifdef A2\n" |
| " param7),\n" |
| "#else\n" |
| " param8),\n" |
| " param9,\n" |
| "#endif\n" |
| " param10,\n" |
| "#endif\n" |
| " param11)\n" |
| "#else\n" |
| " param12)\n" |
| "#endif\n" |
| "{\n" |
| " x();\n" |
| "}", |
| getLLVMStyleWithColumns(28)); |
| verifyFormat("#if 1\n" |
| "int i;"); |
| verifyFormat("#if 1\n" |
| "#endif\n" |
| "#if 1\n" |
| "#else\n" |
| "#endif\n"); |
| verifyFormat("DEBUG({\n" |
| " return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n" |
| "});\n" |
| "#if a\n" |
| "#else\n" |
| "#endif"); |
| |
| verifyIncompleteFormat("void f(\n" |
| "#if A\n" |
| " );\n" |
| "#else\n" |
| "#endif"); |
| } |
| |
| TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) { |
| verifyFormat("#endif\n" |
| "#if B"); |
| } |
| |
| TEST_F(FormatTest, FormatsJoinedLinesOnSubsequentRuns) { |
| FormatStyle SingleLine = getLLVMStyle(); |
| SingleLine.AllowShortIfStatementsOnASingleLine = true; |
| verifyFormat("#if 0\n" |
| "#elif 1\n" |
| "#endif\n" |
| "void foo() {\n" |
| " if (test) foo2();\n" |
| "}", |
| SingleLine); |
| } |
| |
| TEST_F(FormatTest, LayoutBlockInsideParens) { |
| verifyFormat("functionCall({ int i; });"); |
| verifyFormat("functionCall({\n" |
| " int i;\n" |
| " int j;\n" |
| "});"); |
| verifyFormat("functionCall(\n" |
| " {\n" |
| " int i;\n" |
| " int j;\n" |
| " },\n" |
| " aaaa, bbbb, cccc);"); |
| verifyFormat("functionA(functionB({\n" |
| " int i;\n" |
| " int j;\n" |
| " }),\n" |
| " aaaa, bbbb, cccc);"); |
| verifyFormat("functionCall(\n" |
| " {\n" |
| " int i;\n" |
| " int j;\n" |
| " },\n" |
| " aaaa, bbbb, // comment\n" |
| " cccc);"); |
| verifyFormat("functionA(functionB({\n" |
| " int i;\n" |
| " int j;\n" |
| " }),\n" |
| " aaaa, bbbb, // comment\n" |
| " cccc);"); |
| verifyFormat("functionCall(aaaa, bbbb, { int i; });"); |
| verifyFormat("functionCall(aaaa, bbbb, {\n" |
| " int i;\n" |
| " int j;\n" |
| "});"); |
| verifyFormat( |
| "Aaa(\n" // FIXME: There shouldn't be a linebreak here. |
| " {\n" |
| " int i; // break\n" |
| " },\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n" |
| " ccccccccccccccccc));"); |
| verifyFormat("DEBUG({\n" |
| " if (a)\n" |
| " f();\n" |
| "});"); |
| } |
| |
| TEST_F(FormatTest, LayoutBlockInsideStatement) { |
| EXPECT_EQ("SOME_MACRO { int i; }\n" |
| "int i;", |
| format(" SOME_MACRO {int i;} int i;")); |
| } |
| |
| TEST_F(FormatTest, LayoutNestedBlocks) { |
| verifyFormat("void AddOsStrings(unsigned bitmask) {\n" |
| " struct s {\n" |
| " int i;\n" |
| " };\n" |
| " s kBitsToOs[] = {{10}};\n" |
| " for (int i = 0; i < 10; ++i)\n" |
| " return;\n" |
| "}"); |
| verifyFormat("call(parameter, {\n" |
| " something();\n" |
| " // Comment using all columns.\n" |
| " somethingelse();\n" |
| "});", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("DEBUG( //\n" |
| " { f(); }, a);"); |
| verifyFormat("DEBUG( //\n" |
| " {\n" |
| " f(); //\n" |
| " },\n" |
| " a);"); |
| |
| EXPECT_EQ("call(parameter, {\n" |
| " something();\n" |
| " // Comment too\n" |
| " // looooooooooong.\n" |
| " somethingElse();\n" |
| "});", |
| format("call(parameter, {\n" |
| " something();\n" |
| " // Comment too looooooooooong.\n" |
| " somethingElse();\n" |
| "});", |
| getLLVMStyleWithColumns(29))); |
| EXPECT_EQ("DEBUG({ int i; });", format("DEBUG({ int i; });")); |
| EXPECT_EQ("DEBUG({ // comment\n" |
| " int i;\n" |
| "});", |
| format("DEBUG({ // comment\n" |
| "int i;\n" |
| "});")); |
| EXPECT_EQ("DEBUG({\n" |
| " int i;\n" |
| "\n" |
| " // comment\n" |
| " int j;\n" |
| "});", |
| format("DEBUG({\n" |
| " int i;\n" |
| "\n" |
| " // comment\n" |
| " int j;\n" |
| "});")); |
| |
| verifyFormat("DEBUG({\n" |
| " if (a)\n" |
| " return;\n" |
| "});"); |
| verifyGoogleFormat("DEBUG({\n" |
| " if (a) return;\n" |
| "});"); |
| FormatStyle Style = getGoogleStyle(); |
| Style.ColumnLimit = 45; |
| verifyFormat("Debug(aaaaa,\n" |
| " {\n" |
| " if (aaaaaaaaaaaaaaaaaaaaaaaa) return;\n" |
| " },\n" |
| " a);", |
| Style); |
| |
| verifyFormat("SomeFunction({MACRO({ return output; }), b});"); |
| |
| verifyNoCrash("^{v^{a}}"); |
| } |
| |
| TEST_F(FormatTest, FormatNestedBlocksInMacros) { |
| EXPECT_EQ("#define MACRO() \\\n" |
| " Debug(aaa, /* force line break */ \\\n" |
| " { \\\n" |
| " int i; \\\n" |
| " int j; \\\n" |
| " })", |
| format("#define MACRO() Debug(aaa, /* force line break */ \\\n" |
| " { int i; int j; })", |
| getGoogleStyle())); |
| |
| EXPECT_EQ("#define A \\\n" |
| " [] { \\\n" |
| " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" |
| " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); \\\n" |
| " }", |
| format("#define A [] { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" |
| "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); }", |
| getGoogleStyle())); |
| } |
| |
| TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) { |
| EXPECT_EQ("{}", format("{}")); |
| verifyFormat("enum E {};"); |
| verifyFormat("enum E {}"); |
| } |
| |
| TEST_F(FormatTest, FormatBeginBlockEndMacros) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.MacroBlockBegin = "^[A-Z_]+_BEGIN$"; |
| Style.MacroBlockEnd = "^[A-Z_]+_END$"; |
| verifyFormat("FOO_BEGIN\n" |
| " FOO_ENTRY\n" |
| "FOO_END", Style); |
| verifyFormat("FOO_BEGIN\n" |
| " NESTED_FOO_BEGIN\n" |
| " NESTED_FOO_ENTRY\n" |
| " NESTED_FOO_END\n" |
| "FOO_END", Style); |
| verifyFormat("FOO_BEGIN(Foo, Bar)\n" |
| " int x;\n" |
| " x = 1;\n" |
| "FOO_END(Baz)", Style); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Line break tests. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, PreventConfusingIndents) { |
| verifyFormat( |
| "void f() {\n" |
| " SomeLongMethodName(SomeReallyLongMethod(CallOtherReallyLongMethod(\n" |
| " parameter, parameter, parameter)),\n" |
| " SecondLongCall(parameter));\n" |
| "}"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaa]];"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa>;"); |
| verifyFormat("int a = bbbb && ccc && fffff(\n" |
| "#define A Just forcing a new line\n" |
| " ddd);"); |
| } |
| |
| TEST_F(FormatTest, LineBreakingInBinaryExpressions) { |
| verifyFormat( |
| "bool aaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() ||\n" |
| " bbbbbbbb();"); |
| verifyFormat( |
| "bool aaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() or\n" |
| " bbbbbbbb();"); |
| |
| verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb &&\n" |
| " ccccccccc == ddddddddddd;"); |
| verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb and\n" |
| " ccccccccc == ddddddddddd;"); |
| verifyFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa not_eq bbbbbbbbbbbbbbbbbb and\n" |
| " ccccccccc == ddddddddddd;"); |
| |
| verifyFormat("aaaaaa = aaaaaaa(aaaaaaa, // break\n" |
| " aaaaaa) &&\n" |
| " bbbbbb && cccccc;"); |
| verifyFormat("aaaaaa = aaaaaaa(aaaaaaa, // break\n" |
| " aaaaaa) >>\n" |
| " bbbbbb;"); |
| verifyFormat("aa = Whitespaces.addUntouchableComment(\n" |
| " SourceMgr.getSpellingColumnNumber(\n" |
| " TheLine.Last->FormatTok.Tok.getLocation()) -\n" |
| " 1);"); |
| |
| verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaaaaaaa\n" |
| " cccccc) {\n}"); |
| verifyFormat("b = a &&\n" |
| " // Comment\n" |
| " b.c && d;"); |
| |
| // If the LHS of a comparison is not a binary expression itself, the |
| // additional linebreak confuses many people. |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) > 5) {\n" |
| "}"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" |
| "}"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" |
| "}"); |
| // Even explicit parentheses stress the precedence enough to make the |
| // additional break unnecessary. |
| verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" |
| "}"); |
| // This cases is borderline, but with the indentation it is still readable. |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaa) > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}", |
| getLLVMStyleWithColumns(75)); |
| |
| // If the LHS is a binary expression, we should still use the additional break |
| // as otherwise the formatting hides the operator precedence. |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " 5) {\n" |
| "}"); |
| |
| FormatStyle OnePerLine = getLLVMStyle(); |
| OnePerLine.BinPackParameters = false; |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}", |
| OnePerLine); |
| } |
| |
| TEST_F(FormatTest, ExpressionIndentation) { |
| verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb &&\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\n" |
| " ccccccccccccccccccccccccccccccccccccccccc;"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}"); |
| |