diff options
Diffstat (limited to 'unittests/Format/FormatTest.cpp')
-rw-r--r-- | unittests/Format/FormatTest.cpp | 1706 |
1 files changed, 1646 insertions, 60 deletions
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index bcbdbbf3e5..82530c0376 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -30,24 +30,25 @@ FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } class FormatTest : public ::testing::Test { protected: - enum IncompleteCheck { - IC_ExpectComplete, - IC_ExpectIncomplete, - IC_DoNotCheck + enum StatusCheck { + SC_ExpectComplete, + SC_ExpectIncomplete, + SC_DoNotCheck }; std::string format(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle(), - IncompleteCheck CheckIncomplete = IC_ExpectComplete) { + StatusCheck CheckComplete = SC_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; + FormattingAttemptStatus Status; 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"; + reformat(Style, Code, Ranges, "<stdin>", &Status); + if (CheckComplete != SC_DoNotCheck) { + bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; + EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) + << Code << "\n\n"; } ReplacementCount = Replaces.size(); auto Result = applyAllReplacements(Code, Replaces); @@ -56,16 +57,17 @@ protected: return *Result; } - FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { - FormatStyle Style = getLLVMStyle(); + FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) { Style.ColumnLimit = ColumnLimit; return Style; } + FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { + return getStyleWithColumns(getLLVMStyle(), ColumnLimit); + } + FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) { - FormatStyle Style = getGoogleStyle(); - Style.ColumnLimit = ColumnLimit; - return Style; + return getStyleWithColumns(getGoogleStyle(), ColumnLimit); } void verifyFormat(llvm::StringRef Code, @@ -83,7 +85,7 @@ protected: void verifyIncompleteFormat(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { EXPECT_EQ(Code.str(), - format(test::messUp(Code), Style, IC_ExpectIncomplete)); + format(test::messUp(Code), Style, SC_ExpectIncomplete)); } void verifyGoogleFormat(llvm::StringRef Code) { @@ -98,7 +100,7 @@ protected: /// \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); + format(Code, Style, SC_DoNotCheck); } int ReplacementCount; @@ -331,6 +333,16 @@ TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) { verifyFormat("x = (a) xor (b);"); } +TEST_F(FormatTest, RecognizesUnaryOperatorKeywords) { + verifyFormat("x = compl(a);"); + verifyFormat("x = not(a);"); + verifyFormat("x = bitand(a);"); + // Unary operator must not be merged with the next identifier + verifyFormat("x = compl a;"); + verifyFormat("x = not a;"); + verifyFormat("x = bitand a;"); +} + //===----------------------------------------------------------------------===// // Tests for control statements. //===----------------------------------------------------------------------===// @@ -339,9 +351,21 @@ 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();"); + verifyFormat("if constexpr (true)\n" + " f();\ng();"); + verifyFormat("if constexpr (a)\n" + " if constexpr (b)\n" + " if constexpr (c)\n" + " g();\n" + "h();"); + verifyFormat("if constexpr (a)\n" + " if constexpr (b) {\n" + " f();\n" + " }\n" + "g();"); FormatStyle AllowsMergedIf = getLLVMStyle(); - AllowsMergedIf.AlignEscapedNewlinesLeft = true; + AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left; AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true; verifyFormat("if (a)\n" " // comment\n" @@ -415,17 +439,28 @@ TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) { TEST_F(FormatTest, FormatShortBracedStatements) { FormatStyle AllowSimpleBracedStatements = getLLVMStyle(); + AllowSimpleBracedStatements.ColumnLimit = 40; AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true; AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true; AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true; + AllowSimpleBracedStatements.BreakBeforeBraces = FormatStyle::BS_Custom; + AllowSimpleBracedStatements.BraceWrapping.AfterFunction = true; + AllowSimpleBracedStatements.BraceWrapping.SplitEmptyRecord = false; + verifyFormat("if (true) {}", AllowSimpleBracedStatements); + verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements); verifyFormat("while (true) {}", AllowSimpleBracedStatements); verifyFormat("for (;;) {}", AllowSimpleBracedStatements); verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements); + verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements); + verifyFormat("if (true) {\n" + " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n" + "}", + AllowSimpleBracedStatements); verifyFormat("if (true) { //\n" " f();\n" "}", @@ -442,12 +477,21 @@ TEST_F(FormatTest, FormatShortBracedStatements) { "}", AllowSimpleBracedStatements); + verifyFormat("struct A2 {\n" + " int X;\n" + "};", + AllowSimpleBracedStatements); + verifyFormat("typedef struct A2 {\n" + " int X;\n" + "} A2_t;", + AllowSimpleBracedStatements); verifyFormat("template <int> struct A2 {\n" " struct B {};\n" "};", AllowSimpleBracedStatements); AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false; + verifyFormat("if (true) {}", AllowSimpleBracedStatements); verifyFormat("if (true) {\n" " f();\n" "}", @@ -460,14 +504,83 @@ TEST_F(FormatTest, FormatShortBracedStatements) { AllowSimpleBracedStatements); AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false; + verifyFormat("while (true) {}", AllowSimpleBracedStatements); verifyFormat("while (true) {\n" " f();\n" "}", AllowSimpleBracedStatements); + verifyFormat("for (;;) {}", AllowSimpleBracedStatements); verifyFormat("for (;;) {\n" " f();\n" "}", AllowSimpleBracedStatements); + + AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true; + AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true; + AllowSimpleBracedStatements.BraceWrapping.AfterControlStatement = true; + + verifyFormat("if (true) {}", AllowSimpleBracedStatements); + verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements); + verifyFormat("while (true) {}", AllowSimpleBracedStatements); + verifyFormat("for (;;) {}", AllowSimpleBracedStatements); + verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements); + verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements); + verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements); + verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements); + verifyFormat("if (true)\n" + "{\n" + " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n" + "}", + AllowSimpleBracedStatements); + verifyFormat("if (true)\n" + "{ //\n" + " f();\n" + "}", + AllowSimpleBracedStatements); + verifyFormat("if (true)\n" + "{\n" + " f();\n" + " f();\n" + "}", + AllowSimpleBracedStatements); + verifyFormat("if (true)\n" + "{\n" + " f();\n" + "} else\n" + "{\n" + " f();\n" + "}", + AllowSimpleBracedStatements); + + AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false; + verifyFormat("if (true) {}", AllowSimpleBracedStatements); + verifyFormat("if (true)\n" + "{\n" + " f();\n" + "}", + AllowSimpleBracedStatements); + verifyFormat("if (true)\n" + "{\n" + " f();\n" + "} else\n" + "{\n" + " f();\n" + "}", + AllowSimpleBracedStatements); + + AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false; + verifyFormat("while (true) {}", AllowSimpleBracedStatements); + verifyFormat("while (true)\n" + "{\n" + " f();\n" + "}", + AllowSimpleBracedStatements); + verifyFormat("for (;;) {}", AllowSimpleBracedStatements); + verifyFormat("for (;;)\n" + "{\n" + " f();\n" + "}", + AllowSimpleBracedStatements); } TEST_F(FormatTest, ParseIfElse) { @@ -494,6 +607,19 @@ TEST_F(FormatTest, ParseIfElse) { "else {\n" " i();\n" "}"); + verifyFormat("if (true)\n" + " if constexpr (true)\n" + " if (true) {\n" + " if constexpr (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" @@ -509,6 +635,12 @@ TEST_F(FormatTest, ElseIf) { " g();\n" "else\n" " h();"); + verifyFormat("if constexpr (a)\n" + " f();\n" + "else if constexpr (b)\n" + " g();\n" + "else\n" + " h();"); verifyFormat("if (a) {\n" " f();\n" "}\n" @@ -526,6 +658,11 @@ TEST_F(FormatTest, ElseIf) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" "}", getLLVMStyleWithColumns(62)); + verifyFormat("if (a) {\n" + "} else if constexpr (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" + "}", + getLLVMStyleWithColumns(62)); } TEST_F(FormatTest, FormatsForLoop) { @@ -599,6 +736,10 @@ TEST_F(FormatTest, FormatsForLoop) { " I != E;\n" " ++I) {\n}", NoBinPacking); + + FormatStyle AlignLeft = getLLVMStyle(); + AlignLeft.PointerAlignment = FormatStyle::PAS_Left; + verifyFormat("for (A* a = start; a < end; ++a, ++value) {\n}", AlignLeft); } TEST_F(FormatTest, RangeBasedForLoops) { @@ -777,12 +918,35 @@ TEST_F(FormatTest, FormatsSwitchStatement) { " case A:\n" " f();\n" " break;\n" - " // On B:\n" + " // fallthrough\n" " case B:\n" " g();\n" " break;\n" " }\n" "});"); + EXPECT_EQ("DEBUG({\n" + " switch (x) {\n" + " case A:\n" + " f();\n" + " break;\n" + " // On B:\n" + " case B:\n" + " g();\n" + " break;\n" + " }\n" + "});", + format("DEBUG({\n" + " switch (x) {\n" + " case A:\n" + " f();\n" + " break;\n" + " // On B:\n" + " case B:\n" + " g();\n" + " break;\n" + " }\n" + "});", + getLLVMStyle())); verifyFormat("switch (a) {\n" "case (b):\n" " return;\n" @@ -826,6 +990,77 @@ TEST_F(FormatTest, ShortCaseLabels) { "}", Style); verifyFormat("switch (a) {\n" + "case 0: return; // comment\n" + "case 1: break; // comment\n" + "case 2: return;\n" + "// comment\n" + "case 3: return;\n" + "// comment 1\n" + "// comment 2\n" + "// comment 3\n" + "case 4: break; /* comment */\n" + "case 5:\n" + " // comment\n" + " break;\n" + "case 6: /* comment */ x = 1; break;\n" + "case 7: x = /* comment */ 1; break;\n" + "case 8:\n" + " x = 1; /* comment */\n" + " break;\n" + "case 9:\n" + " break; // comment line 1\n" + " // comment line 2\n" + "}", + Style); + EXPECT_EQ("switch (a) {\n" + "case 1:\n" + " x = 8;\n" + " // fall through\n" + "case 2: x = 8;\n" + "// comment\n" + "case 3:\n" + " return; /* comment line 1\n" + " * comment line 2 */\n" + "case 4: i = 8;\n" + "// something else\n" + "#if FOO\n" + "case 5: break;\n" + "#endif\n" + "}", + format("switch (a) {\n" + "case 1: x = 8;\n" + " // fall through\n" + "case 2:\n" + " x = 8;\n" + "// comment\n" + "case 3:\n" + " return; /* comment line 1\n" + " * comment line 2 */\n" + "case 4:\n" + " i = 8;\n" + "// something else\n" + "#if FOO\n" + "case 5: break;\n" + "#endif\n" + "}", + Style)); + EXPECT_EQ("switch (a) {\n" "case 0:\n" + " return; // long long long long long long long long long long long long comment\n" + " // line\n" "}", + format("switch (a) {\n" + "case 0: return; // long long long long long long long long long long long long comment line\n" + "}", + Style)); + EXPECT_EQ("switch (a) {\n" + "case 0:\n" + " return; /* long long long long long long long long long long long long comment\n" + " line */\n" + "}", + format("switch (a) {\n" + "case 0: return; /* long long long long long long long long long long long long comment line */\n" + "}", + Style)); + verifyFormat("switch (a) {\n" "#if FOO\n" "case 0: return 0;\n" "#endif\n" @@ -1172,6 +1407,32 @@ TEST_F(FormatTest, FormatsEnumTypes) { verifyFormat("enum X : std::uint32_t { A, B };"); } +TEST_F(FormatTest, FormatsTypedefEnum) { + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = 40; + verifyFormat("typedef enum {} EmptyEnum;"); + verifyFormat("typedef enum { A, B, C } ShortEnum;"); + verifyFormat("typedef enum {\n" + " ZERO = 0,\n" + " ONE = 1,\n" + " TWO = 2,\n" + " THREE = 3\n" + "} LongEnum;", + Style); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterEnum = true; + verifyFormat("typedef enum {} EmptyEnum;"); + verifyFormat("typedef enum { A, B, C } ShortEnum;"); + verifyFormat("typedef enum\n" + "{\n" + " ZERO = 0,\n" + " ONE = 1,\n" + " TWO = 2,\n" + " THREE = 3\n" + "} LongEnum;", + Style); +} + TEST_F(FormatTest, FormatsNSEnums) { verifyGoogleFormat("typedef NS_ENUM(NSInteger, SomeName) { AAA, BBB }"); verifyGoogleFormat("typedef NS_ENUM(NSInteger, MyType) {\n" @@ -1308,7 +1569,177 @@ TEST_F(FormatTest, FormatsNamespaces) { Style)); } -TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); } +TEST_F(FormatTest, FormatsCompactNamespaces) { + FormatStyle Style = getLLVMStyle(); + Style.CompactNamespaces = true; + + verifyFormat("namespace A { namespace B {\n" + "}} // namespace A::B", + Style); + + EXPECT_EQ("namespace out { namespace in {\n" + "}} // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "} // namespace in\n" + "} // namespace out", + Style)); + + // Only namespaces which have both consecutive opening and end get compacted + EXPECT_EQ("namespace out {\n" + "namespace in1 {\n" + "} // namespace in1\n" + "namespace in2 {\n" + "} // namespace in2\n" + "} // namespace out", + format("namespace out {\n" + "namespace in1 {\n" + "} // namespace in1\n" + "namespace in2 {\n" + "} // namespace in2\n" + "} // namespace out", + Style)); + + EXPECT_EQ("namespace out {\n" + "int i;\n" + "namespace in {\n" + "int j;\n" + "} // namespace in\n" + "int k;\n" + "} // namespace out", + format("namespace out { int i;\n" + "namespace in { int j; } // namespace in\n" + "int k; } // namespace out", + Style)); + + EXPECT_EQ("namespace A { namespace B { namespace C {\n" + "}}} // namespace A::B::C\n", + format("namespace A { namespace B {\n" + "namespace C {\n" + "}} // namespace B::C\n" + "} // namespace A\n", + Style)); + + Style.ColumnLimit = 40; + EXPECT_EQ("namespace aaaaaaaaaa {\n" + "namespace bbbbbbbbbb {\n" + "}} // namespace aaaaaaaaaa::bbbbbbbbbb", + format("namespace aaaaaaaaaa {\n" + "namespace bbbbbbbbbb {\n" + "} // namespace bbbbbbbbbb\n" + "} // namespace aaaaaaaaaa", + Style)); + + EXPECT_EQ("namespace aaaaaa { namespace bbbbbb {\n" + "namespace cccccc {\n" + "}}} // namespace aaaaaa::bbbbbb::cccccc", + format("namespace aaaaaa {\n" + "namespace bbbbbb {\n" + "namespace cccccc {\n" + "} // namespace cccccc\n" + "} // namespace bbbbbb\n" + "} // namespace aaaaaa", + Style)); + Style.ColumnLimit = 80; + + // Extra semicolon after 'inner' closing brace prevents merging + EXPECT_EQ("namespace out { namespace in {\n" + "}; } // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "}; // namespace in\n" + "} // namespace out", + Style)); + + // Extra semicolon after 'outer' closing brace is conserved + EXPECT_EQ("namespace out { namespace in {\n" + "}}; // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "} // namespace in\n" + "}; // namespace out", + Style)); + + Style.NamespaceIndentation = FormatStyle::NI_All; + EXPECT_EQ("namespace out { namespace in {\n" + " int i;\n" + "}} // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "int i;\n" + "} // namespace in\n" + "} // namespace out", + Style)); + EXPECT_EQ("namespace out { namespace mid {\n" + " namespace in {\n" + " int j;\n" + " } // namespace in\n" + " int k;\n" + "}} // namespace out::mid", + format("namespace out { namespace mid {\n" + "namespace in { int j; } // namespace in\n" + "int k; }} // namespace out::mid", + Style)); + + Style.NamespaceIndentation = FormatStyle::NI_Inner; + EXPECT_EQ("namespace out { namespace in {\n" + " int i;\n" + "}} // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "int i;\n" + "} // namespace in\n" + "} // namespace out", + Style)); + EXPECT_EQ("namespace out { namespace mid { namespace in {\n" + " int i;\n" + "}}} // namespace out::mid::in", + format("namespace out {\n" + "namespace mid {\n" + "namespace in {\n" + "int i;\n" + "} // namespace in\n" + "} // namespace mid\n" + "} // namespace out", + Style)); +} + +TEST_F(FormatTest, FormatsExternC) { + verifyFormat("extern \"C\" {\nint a;"); + verifyFormat("extern \"C\" {}"); + verifyFormat("extern \"C\" {\n" + "int foo();\n" + "}"); + verifyFormat("extern \"C\" int foo() {}"); + verifyFormat("extern \"C\" int foo();"); + verifyFormat("extern \"C\" int foo() {\n" + " int i = 42;\n" + " return i;\n" + "}"); + + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterFunction = true; + verifyFormat("extern \"C\" int foo() {}", Style); + verifyFormat("extern \"C\" int foo();", Style); + verifyFormat("extern \"C\" int foo()\n" + "{\n" + " int i = 42;\n" + " return i;\n" + "}", + Style); + + Style.BraceWrapping.AfterExternBlock = true; + Style.BraceWrapping.SplitEmptyRecord = false; + verifyFormat("extern \"C\"\n" + "{}", + Style); + verifyFormat("extern \"C\"\n" + "{\n" + " int foo();\n" + "}", + Style); +} TEST_F(FormatTest, FormatsInlineASM) { verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));"); @@ -1521,6 +1952,19 @@ TEST_F(FormatTest, DesignatedInitializers) { " .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5};"); verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};"); + + verifyFormat("const struct A a = {[0] = 1, [1] = 2};"); + verifyFormat("const struct A a = {[1] = aaaaaaaaaa,\n" + " [2] = bbbbbbbbbb,\n" + " [3] = cccccccccc,\n" + " [4] = dddddddddd,\n" + " [5] = eeeeeeeeee};"); + verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n" + " [1] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " [2] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n" + " [3] = cccccccccccccccccccccccccccccccccccccc,\n" + " [4] = dddddddddddddddddddddddddddddddddddddd,\n" + " [5] = eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee};"); } TEST_F(FormatTest, NestedStaticInitializers) { @@ -1986,8 +2430,191 @@ TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) { getLLVMStyleWithColumns(11)); } -TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) { - EXPECT_EQ("{\n {\n#define A\n }\n}", format("{{\n#define A\n}}")); +TEST_F(FormatTest, IndentPreprocessorDirectives) { + FormatStyle Style = getLLVMStyle(); + Style.IndentPPDirectives = FormatStyle::PPDIS_None; + Style.ColumnLimit = 40; + verifyFormat("#ifdef _WIN32\n" + "#define A 0\n" + "#ifdef VAR2\n" + "#define B 1\n" + "#include <someheader.h>\n" + "#define MACRO \\\n" + " some_very_long_func_aaaaaaaaaa();\n" + "#endif\n" + "#else\n" + "#define A 1\n" + "#endif", + Style); + Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash; + verifyFormat("#ifdef _WIN32\n" + "# define A 0\n" + "# ifdef VAR2\n" + "# define B 1\n" + "# include <someheader.h>\n" + "# define MACRO \\\n" + " some_very_long_func_aaaaaaaaaa();\n" + "# endif\n" + "#else\n" + "# define A 1\n" + "#endif", + Style); + verifyFormat("#if A\n" + "# define MACRO \\\n" + " void a(int x) { \\\n" + " b(); \\\n" + " c(); \\\n" + " d(); \\\n" + " e(); \\\n" + " f(); \\\n" + " }\n" + "#endif", + Style); + // Comments before include guard. + verifyFormat("// file comment\n" + "// file comment\n" + "#ifndef HEADER_H\n" + "#define HEADER_H\n" + "code();\n" + "#endif", + Style); + // Test with include guards. + // EXPECT_EQ is used because verifyFormat() calls messUp() which incorrectly + // merges lines. + verifyFormat("#ifndef HEADER_H\n" + "#define HEADER_H\n" + "code();\n" + "#endif", + Style); + // Include guards must have a #define with the same variable immediately + // after #ifndef. + verifyFormat("#ifndef NOT_GUARD\n" + "# define FOO\n" + "code();\n" + "#endif", + Style); + + // Include guards must cover the entire file. + verifyFormat("code();\n" + "code();\n" + "#ifndef NOT_GUARD\n" + "# define NOT_GUARD\n" + "code();\n" + "#endif", + Style); + verifyFormat("#ifndef NOT_GUARD\n" + "# define NOT_GUARD\n" + "code();\n" + "#endif\n" + "code();", + Style); + // Test with trailing blank lines. + verifyFormat("#ifndef HEADER_H\n" + "#define HEADER_H\n" + "code();\n" + "#endif\n", + Style); + // Include guards don't have #else. + verifyFormat("#ifndef NOT_GUARD\n" + "# define NOT_GUARD\n" + "code();\n" + "#else\n" + "#endif", + Style); + verifyFormat("#ifndef NOT_GUARD\n" + "# define NOT_GUARD\n" + "code();\n" + "#elif FOO\n" + "#endif", + Style); + // FIXME: This doesn't handle the case where there's code between the + // #ifndef and #define but all other conditions hold. This is because when + // the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the + // previous code line yet, so we can't detect it. + EXPECT_EQ("#ifndef NOT_GUARD\n" + "code();\n" + "#define NOT_GUARD\n" + "code();\n" + "#endif", + format("#ifndef NOT_GUARD\n" + "code();\n" + "# define NOT_GUARD\n" + "code();\n" + "#endif", + Style)); + // FIXME: This doesn't handle cases where legitimate preprocessor lines may + // be outside an include guard. Examples are #pragma once and + // #pragma GCC diagnostic, or anything else that does not change the meaning + // of the file if it's included multiple times. + EXPECT_EQ("#ifdef WIN32\n" + "# pragma once\n" + "#endif\n" + "#ifndef HEADER_H\n" + "# define HEADER_H\n" + "code();\n" + "#endif", + format("#ifdef WIN32\n" + "# pragma once\n" + "#endif\n" + "#ifndef HEADER_H\n" + "#define HEADER_H\n" + "code();\n" + "#endif", + Style)); + // FIXME: This does not detect when there is a single non-preprocessor line + // in front of an include-guard-like structure where other conditions hold + // because ScopedLineState hides the line. + EXPECT_EQ("code();\n" + "#ifndef HEADER_H\n" + "#define HEADER_H\n" + "code();\n" + "#endif", + format("code();\n" + "#ifndef HEADER_H\n" + "# define HEADER_H\n" + "code();\n" + "#endif", + Style)); + // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by + // preprocessor indentation. + EXPECT_EQ("#if 1\n" + " // comment\n" + "# define A 0\n" + "// comment\n" + "# define B 0\n" + "#endif", + format("#if 1\n" + "// comment\n" + "# define A 0\n" + " // comment\n" + "# define B 0\n" + "#endif", + Style)); + // Test with tabs. + Style.UseTab = FormatStyle::UT_Always; + Style.IndentWidth = 8; + Style.TabWidth = 8; + verifyFormat("#ifdef _WIN32\n" + "#\tdefine A 0\n" + "#\tifdef VAR2\n" + "#\t\tdefine B 1\n" + "#\t\tinclude <someheader.h>\n" + "#\t\tdefine MACRO \\\n" + "\t\t\tsome_very_long_func_aaaaaaaaaa();\n" + "#\tendif\n" + "#else\n" + "#\tdefine A 1\n" + "#endif", + Style); + + // Regression test: Multiline-macro inside include guards. + verifyFormat("#ifndef HEADER_H\n" + "#define HEADER_H\n" + "#define A() \\\n" + " int i; \\\n" + " int j;\n" + "#endif // HEADER_H", + getLLVMStyleWithColumns(20)); } TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) { @@ -2002,13 +2629,63 @@ TEST_F(FormatTest, FormatUnbalancedStructuralElements) { } TEST_F(FormatTest, EscapedNewlines) { - EXPECT_EQ( - "#define A \\\n int i; \\\n int j;", - format("#define A \\\nint i;\\\n int j;", getLLVMStyleWithColumns(11))); + FormatStyle Narrow = getLLVMStyleWithColumns(11); + EXPECT_EQ("#define A \\\n int i; \\\n int j;", + format("#define A \\\nint i;\\\n int j;", Narrow)); 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>")); + + FormatStyle AlignLeft = getLLVMStyle(); + AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left; + EXPECT_EQ("#define MACRO(x) \\\n" + "private: \\\n" + " int x(int a);\n", + format("#define MACRO(x) \\\n" + "private: \\\n" + " int x(int a);\n", + AlignLeft)); + + // CRLF line endings + EXPECT_EQ("#define A \\\r\n int i; \\\r\n int j;", + format("#define A \\\r\nint i;\\\r\n int j;", Narrow)); + EXPECT_EQ("#define A\r\n\r\nint i;", format("#define A \\\r\n\r\n int i;")); + EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();")); + EXPECT_EQ("/* \\ \\ \\\r\n */", format("\\\r\n/* \\ \\ \\\r\n */")); + EXPECT_EQ("<a\r\n\\\\\r\n>", format("<a\r\n\\\\\r\n>")); + EXPECT_EQ("#define MACRO(x) \\\r\n" + "private: \\\r\n" + " int x(int a);\r\n", + format("#define MACRO(x) \\\r\n" + "private: \\\r\n" + " int x(int a);\r\n", + AlignLeft)); + + FormatStyle DontAlign = getLLVMStyle(); + DontAlign.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; + DontAlign.MaxEmptyLinesToKeep = 3; + // FIXME: can't use verifyFormat here because the newline before + // "public:" is not inserted the first time it's reformatted + EXPECT_EQ("#define A \\\n" + " class Foo { \\\n" + " void bar(); \\\n" + "\\\n" + "\\\n" + "\\\n" + " public: \\\n" + " void baz(); \\\n" + " };", + format("#define A \\\n" + " class Foo { \\\n" + " void bar(); \\\n" + "\\\n" + "\\\n" + "\\\n" + " public: \\\n" + " void baz(); \\\n" + " };", + DontAlign)); } TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) { @@ -2105,7 +2782,7 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { verifyIncompleteFormat("void f(\n" "#if A\n" - " );\n" + ");\n" "#else\n" "#endif"); } @@ -2369,6 +3046,9 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) { verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaaaaaaa\n" " cccccc) {\n}"); + verifyFormat("if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaa\n" + " cccccc) {\n}"); verifyFormat("b = a &&\n" " // Comment\n" " b.c && d;"); @@ -2590,6 +3270,60 @@ TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) { Style); } +TEST_F(FormatTest, AllowBinPackingInsideArguments) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; + Style.BinPackArguments = false; + Style.ColumnLimit = 40; + verifyFormat("void test() {\n" + " someFunction(\n" + " this + argument + is + quite\n" + " + long + so + it + gets + wrapped\n" + " + but + remains + bin - packed);\n" + "}", + Style); + verifyFormat("void test() {\n" + " someFunction(arg1,\n" + " this + argument + is\n" + " + quite + long + so\n" + " + it + gets + wrapped\n" + " + but + remains + bin\n" + " - packed,\n" + " arg3);\n" + "}", + Style); + verifyFormat("void test() {\n" + " someFunction(\n" + " arg1,\n" + " this + argument + has\n" + " + anotherFunc(nested,\n" + " calls + whose\n" + " + arguments\n" + " + are + also\n" + " + wrapped,\n" + " in + addition)\n" + " + to + being + bin - packed,\n" + " arg3);\n" + "}", + Style); + + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; + verifyFormat("void test() {\n" + " someFunction(\n" + " arg1,\n" + " this + argument + has +\n" + " anotherFunc(nested,\n" + " calls + whose +\n" + " arguments +\n" + " are + also +\n" + " wrapped,\n" + " in + addition) +\n" + " to + being + bin - packed,\n" + " arg3);\n" + "}", + Style); +} + TEST_F(FormatTest, ConstructorInitializers) { verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}"); verifyFormat("Constructor() : Inttializer(FitsOnTheLine) {}", @@ -2699,6 +3433,169 @@ TEST_F(FormatTest, ConstructorInitializers) { " aaaa(aaaa) {}")); } +TEST_F(FormatTest, BreakConstructorInitializersAfterColon) { + FormatStyle Style = getLLVMStyle(); + Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; + + verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}"); + verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}", + getStyleWithColumns(Style, 45)); + verifyFormat("Constructor() :\n" + " Initializer(FitsOnTheLine) {}", + getStyleWithColumns(Style, 44)); + verifyFormat("Constructor() :\n" + " Initializer(FitsOnTheLine) {}", + getStyleWithColumns(Style, 43)); + + verifyFormat("template <typename T>\n" + "Constructor() : Initializer(FitsOnTheLine) {}", + getStyleWithColumns(Style, 50)); + + verifyFormat( + "SomeClass::Constructor() :\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", + Style); + + verifyFormat( + "SomeClass::Constructor() :\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", + Style); + verifyFormat( + "SomeClass::Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", + Style); + verifyFormat("Constructor(aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n" + " aaaaaaaaaa(aaaaaa) {}", + Style); + + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaaaaaaaaaaaa() {}", + Style); + + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", + Style); + + verifyFormat("Constructor(int Parameter = 0) :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaa(aaaaaaaaaaaaaaaaa) {}", + Style); + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbbbbb(b) {\n" + "}", + getStyleWithColumns(Style, 60)); + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}", + Style); + + // Here a line could be saved by splitting the second initializer onto two + // lines, but that is not desirable. + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n" + " aaaaaaaaaaa(aaaaaaaaaaa),\n" + " aaaaaaaaaaaaaaaaaaaaat(aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", + Style); + + FormatStyle OnePerLine = Style; + OnePerLine.ConstructorInitializerAllOnOneLineOrOnePerLine = true; + OnePerLine.AllowAllParametersOfDeclarationOnNextLine = false; + verifyFormat("SomeClass::Constructor() :\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", + OnePerLine); + verifyFormat("SomeClass::Constructor() :\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), // Some comment\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", + OnePerLine); + verifyFormat("MyClass::MyClass(int var) :\n" + " some_var_(var), // 4 space indent\n" + " some_other_var_(var + 1) { // lined up\n" + "}", + OnePerLine); + verifyFormat("Constructor() :\n" + " aaaaa(aaaaaa),\n" + " aaaaa(aaaaaa),\n" + " aaaaa(aaaaaa),\n" + " aaaaa(aaaaaa),\n" + " aaaaa(aaaaaa) {}", + OnePerLine); + verifyFormat("Constructor() :\n" + " aaaaa(aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaa) {}", + OnePerLine); + OnePerLine.BinPackParameters = false; + verifyFormat( + "Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaa().aaa(),\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", + OnePerLine); + OnePerLine.ColumnLimit = 60; + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbbbbb(b) {}", + OnePerLine); + + EXPECT_EQ("Constructor() :\n" + " // Comment forcing unwanted break.\n" + " aaaa(aaaa) {}", + format("Constructor() :\n" + " // Comment forcing unwanted break.\n" + " aaaa(aaaa) {}", + Style)); + + Style.ColumnLimit = 0; + verifyFormat("SomeClass::Constructor() :\n" + " a(a) {}", + Style); + verifyFormat("SomeClass::Constructor() noexcept :\n" + " a(a) {}", + Style); + verifyFormat("SomeClass::Constructor() :\n" + " a(a), b(b), c(c) {}", + Style); + verifyFormat("SomeClass::Constructor() :\n" + " a(a) {\n" + " foo();\n" + " bar();\n" + "}", + Style); + + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; + verifyFormat("SomeClass::Constructor() :\n" + " a(a), b(b), c(c) {\n" + "}", + Style); + verifyFormat("SomeClass::Constructor() :\n" + " a(a) {\n" + "}", + Style); + + Style.ColumnLimit = 80; + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; + Style.ConstructorInitializerIndentWidth = 2; + verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}", + Style); + verifyFormat("SomeClass::Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}", + Style); +} + +#ifndef EXPENSIVE_CHECKS +// Expensive checks enables libstdc++ checking which includes validating the +// state of ranges used in std::priority_queue - this blows out the +// runtime/scalability of the function and makes this test unacceptably slow. TEST_F(FormatTest, MemoizationTests) { // This breaks if the memoization lookup does not take \c Indent and // \c LastSpace into account. @@ -2777,6 +3674,7 @@ TEST_F(FormatTest, MemoizationTests) { input += " a) {}"; verifyFormat(input, OnePerLine); } +#endif TEST_F(FormatTest, BreaksAsHighAsPossible) { verifyFormat( @@ -3402,6 +4300,18 @@ TEST_F(FormatTest, BreaksAfterAssignments) { " 1;"); } +TEST_F(FormatTest, ConfigurableBreakAssignmentPenalty) { + FormatStyle Style = getLLVMStyle(); + verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccccc;", + Style); + + Style.PenaltyBreakAssignment = 20; + verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbb +\n" + " cccccccccccccccccccccccccc;", + Style); +} + TEST_F(FormatTest, AlignsAfterAssignments) { verifyFormat( "int Result = aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" @@ -4090,9 +5000,9 @@ TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { "c\";", Break)); - // Exempt ObjC strings for now. - EXPECT_EQ("NSString *const kString = @\"aaaa\"\n" - " @\"bbbb\";", + EXPECT_EQ("NSString *const kString =\n" + " @\"aaaa\"\n" + " @\"bbbb\";", format("NSString *const kString = @\"aaaa\"\n" "@\"bbbb\";", Break)); @@ -4132,6 +5042,9 @@ TEST_F(FormatTest, AlignsPipes) { verifyFormat( "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat( + "auto Diag = diag() << aaaaaaaaaaaaaaaa(aaaaaaaaaaaa, aaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n" " << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();"); @@ -4417,7 +5330,7 @@ TEST_F(FormatTest, WrapsTemplateDeclarations) { EXPECT_EQ("static_cast<A< //\n" " B> *>(\n" "\n" - " );", + ");", format("static_cast<A<//\n" " B>*>(\n" "\n" @@ -4728,7 +5641,8 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("SomeType MemberFunction(const Deleted &) && {}"); verifyFormat("SomeType MemberFunction(const Deleted &) && final {}"); verifyFormat("SomeType MemberFunction(const Deleted &) && override {}"); - verifyFormat("SomeType MemberFunction(const Deleted &) const &;"); + verifyFormat("void Fn(T const &) const &;"); + verifyFormat("void Fn(T const volatile &&) const volatile &&;"); verifyFormat("template <typename T>\n" "void F(T) && = delete;", getGoogleStyle()); @@ -4745,7 +5659,8 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("auto Function(T... t) & -> void {}", AlignLeft); verifyFormat("auto Function(T) & -> void {}", AlignLeft); verifyFormat("auto Function(T) & -> void;", AlignLeft); - verifyFormat("SomeType MemberFunction(const Deleted&) const &;", AlignLeft); + verifyFormat("void Fn(T const&) const&;", AlignLeft); + verifyFormat("void Fn(T const volatile&&) const volatile&&;", AlignLeft); FormatStyle Spaces = getLLVMStyle(); Spaces.SpacesInCStyleCastParentheses = true; @@ -4890,6 +5805,11 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("x = *a(x) = *a(y);", Left); verifyFormat("for (;; *a = b) {\n}", Left); verifyFormat("return *this += 1;", Left); + verifyFormat("throw *x;", Left); + verifyFormat("delete *x;", Left); + verifyFormat("typedef typeof(int(int, int))* MyFuncPtr;", Left); + verifyFormat("[](const decltype(*a)* ptr) {}", Left); + verifyFormat("typedef typeof /*comment*/ (int(int, int))* MyFuncPtr;", Left); verifyIndependentOfContext("a = *(x + y);"); verifyIndependentOfContext("a = &(x + y);"); @@ -4936,9 +5856,6 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyGoogleFormat("T** t = new T*;"); verifyGoogleFormat("T** t = new T*();"); - FormatStyle PointerLeft = getLLVMStyle(); - PointerLeft.PointerAlignment = FormatStyle::PAS_Left; - verifyFormat("delete *x;", PointerLeft); verifyFormat("STATIC_ASSERT((a & b) == 0);"); verifyFormat("STATIC_ASSERT(0 == (a & b));"); verifyFormat("template <bool a, bool b> " @@ -5217,6 +6134,12 @@ TEST_F(FormatTest, FormatsFunctionTypes) { verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }"); verifyFormat("int x = f(&h)();"); verifyFormat("returnsFunction(¶m1, ¶m2)(param);"); + verifyFormat("std::function<\n" + " LooooooooooongTemplatedType<\n" + " SomeType>*(\n" + " LooooooooooooooooongType type)>\n" + " function;", + getGoogleStyleWithColumns(40)); } TEST_F(FormatTest, FormatsPointersToArrayTypes) { @@ -5571,7 +6494,10 @@ TEST_F(FormatTest, LayoutBraceInitializersInReturnStatement) { TEST_F(FormatTest, LayoutCxx11BraceInitializers) { verifyFormat("vector<int> x{1, 2, 3, 4};"); verifyFormat("vector<int> x{\n" - " 1, 2, 3, 4,\n" + " 1,\n" + " 2,\n" + " 3,\n" + " 4,\n" "};"); verifyFormat("vector<T> x{{}, {}, {}, {}};"); verifyFormat("f({1, 2});"); @@ -5590,6 +6516,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { " T member = {arg1, arg2};\n" "};"); verifyFormat("vector<int> foo = {::SomeGlobalFunction()};"); + verifyFormat("const struct A a = {.a = 1, .b = 2};"); + verifyFormat("const struct A a = {[0] = 1, [1] = 2};"); verifyFormat("static_assert(std::is_integral<int>{} + 0, \"\");"); verifyFormat("int a = std::is_integral<int>{} + 0;"); @@ -5614,6 +6542,17 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { "};"); verifyFormat("#define A {a, a},"); + // Binpacking only if there is no trailing comma + verifyFormat("const Aaaaaa aaaaa = {aaaaaaaaaa, bbbbbbbbbb,\n" + " cccccccccc, dddddddddd};", + getLLVMStyleWithColumns(50)); + verifyFormat("const Aaaaaa aaaaa = {\n" + " aaaaaaaaaaa,\n" + " bbbbbbbbbbb,\n" + " ccccccccccc,\n" + " ddddddddddd,\n" + "};", getLLVMStyleWithColumns(50)); + // Cases where distinguising braced lists and blocks is hard. verifyFormat("vector<int> v{12} GUARDED_BY(mutex);"); verifyFormat("void f() {\n" @@ -5693,10 +6632,12 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { " // Second element:\n" " 2};", getLLVMStyleWithColumns(30))); - // A trailing comma should still lead to an enforced line break. + // A trailing comma should still lead to an enforced line break and no + // binpacking. EXPECT_EQ("vector<int> SomeVector = {\n" " // aaa\n" - " 1, 2,\n" + " 1,\n" + " 2,\n" "};", format("vector<int> SomeVector = { // aaa\n" " 1, 2, };")); @@ -5755,6 +6696,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { " aaaaaaa,\n" " a};"); verifyFormat("vector<int> foo = { ::SomeGlobalFunction() };", ExtraSpaces); + verifyFormat("const struct A a = { .a = 1, .b = 2 };", ExtraSpaces); + verifyFormat("const struct A a = { [0] = 1, [1] = 2 };", ExtraSpaces); } TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { @@ -5860,7 +6803,7 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { " aaaaaaaaaaaa, a, aaaaaaaaaa, aaaaaaaaa, aaa}};"); // No column layout should be used here. - verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n" + verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};"); verifyNoCrash("a<,"); @@ -6003,6 +6946,35 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { getLLVMStyleWithColumns(23)); } +TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) { + FormatStyle MergeEmptyOnly = getLLVMStyle(); + MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeEmptyOnly); + verifyFormat("class C {\n" + " int f() {\n" + " return 42;\n" + " }\n" + "};", + MergeEmptyOnly); + verifyFormat("int f() {}", MergeEmptyOnly); + verifyFormat("int f() {\n" + " return 42;\n" + "}", + MergeEmptyOnly); + + // Also verify behavior when BraceWrapping.AfterFunction = true + MergeEmptyOnly.BreakBeforeBraces = FormatStyle::BS_Custom; + MergeEmptyOnly.BraceWrapping.AfterFunction = true; + verifyFormat("int f() {}", MergeEmptyOnly); + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeEmptyOnly); +} + TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) { FormatStyle MergeInlineOnly = getLLVMStyle(); MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; @@ -6014,6 +6986,329 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) { " return 42;\n" "}", MergeInlineOnly); + + // SFS_Inline implies SFS_Empty + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeInlineOnly); + verifyFormat("int f() {}", MergeInlineOnly); + + // Also verify behavior when BraceWrapping.AfterFunction = true + MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom; + MergeInlineOnly.BraceWrapping.AfterFunction = true; + verifyFormat("class C {\n" + " int f() { return 42; }\n" + "};", + MergeInlineOnly); + verifyFormat("int f()\n" + "{\n" + " return 42;\n" + "}", + MergeInlineOnly); + + // SFS_Inline implies SFS_Empty + verifyFormat("int f() {}", MergeInlineOnly); + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeInlineOnly); +} + +TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) { + FormatStyle MergeInlineOnly = getLLVMStyle(); + MergeInlineOnly.AllowShortFunctionsOnASingleLine = + FormatStyle::SFS_InlineOnly; + verifyFormat("class C {\n" + " int f() { return 42; }\n" + "};", + MergeInlineOnly); + verifyFormat("int f() {\n" + " return 42;\n" + "}", + MergeInlineOnly); + + // SFS_InlineOnly does not imply SFS_Empty + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeInlineOnly); + verifyFormat("int f() {\n" + "}", + MergeInlineOnly); + + // Also verify behavior when BraceWrapping.AfterFunction = true + MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom; + MergeInlineOnly.BraceWrapping.AfterFunction = true; + verifyFormat("class C {\n" + " int f() { return 42; }\n" + "};", + MergeInlineOnly); + verifyFormat("int f()\n" + "{\n" + " return 42;\n" + "}", + MergeInlineOnly); + + // SFS_InlineOnly does not imply SFS_Empty + verifyFormat("int f()\n" + "{\n" + "}", + MergeInlineOnly); + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeInlineOnly); +} + +TEST_F(FormatTest, SplitEmptyFunction) { + FormatStyle Style = getLLVMStyle(); + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterFunction = true; + Style.BraceWrapping.SplitEmptyFunction = false; + Style.ColumnLimit = 40; + + verifyFormat("int f()\n" + "{}", + Style); + verifyFormat("int f()\n" + "{\n" + " return 42;\n" + "}", + Style); + verifyFormat("int f()\n" + "{\n" + " // some comment\n" + "}", + Style); + + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + verifyFormat("int f() {}", Style); + verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" + "{}", + Style); + verifyFormat("int f()\n" + "{\n" + " return 0;\n" + "}", + Style); + + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; + verifyFormat("class Foo {\n" + " int f() {}\n" + "};\n", + Style); + verifyFormat("class Foo {\n" + " int f() { return 0; }\n" + "};\n", + Style); + verifyFormat("class Foo {\n" + " int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" + " {}\n" + "};\n", + Style); + verifyFormat("class Foo {\n" + " int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" + " {\n" + " return 0;\n" + " }\n" + "};\n", + Style); + + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; + verifyFormat("int f() {}", Style); + verifyFormat("int f() { return 0; }", Style); + verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" + "{}", + Style); + verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" + "{\n" + " return 0;\n" + "}", + Style); +} +TEST_F(FormatTest, KeepShortFunctionAfterPPElse) { + FormatStyle Style = getLLVMStyle(); + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; + verifyFormat("#ifdef A\n" + "int f() {}\n" + "#else\n" + "int g() {}\n" + "#endif", + Style); +} + +TEST_F(FormatTest, SplitEmptyClass) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterClass = true; + Style.BraceWrapping.SplitEmptyRecord = false; + + verifyFormat("class Foo\n" + "{};", + Style); + verifyFormat("/* something */ class Foo\n" + "{};", + Style); + verifyFormat("template <typename X> class Foo\n" + "{};", + Style); + verifyFormat("class Foo\n" + "{\n" + " Foo();\n" + "};", + Style); + verifyFormat("typedef class Foo\n" + "{\n" + "} Foo_t;", + Style); +} + +TEST_F(FormatTest, SplitEmptyStruct) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterStruct = true; + Style.BraceWrapping.SplitEmptyRecord = false; + + verifyFormat("struct Foo\n" + "{};", + Style); + verifyFormat("/* something */ struct Foo\n" + "{};", + Style); + verifyFormat("template <typename X> struct Foo\n" + "{};", + Style); + verifyFormat("struct Foo\n" + "{\n" + " Foo();\n" + "};", + Style); + verifyFormat("typedef struct Foo\n" + "{\n" + "} Foo_t;", + Style); + //typedef struct Bar {} Bar_t; +} + +TEST_F(FormatTest, SplitEmptyUnion) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterUnion = true; + Style.BraceWrapping.SplitEmptyRecord = false; + + verifyFormat("union Foo\n" + "{};", + Style); + verifyFormat("/* something */ union Foo\n" + "{};", + Style); + verifyFormat("union Foo\n" + "{\n" + " A,\n" + "};", + Style); + verifyFormat("typedef union Foo\n" + "{\n" + "} Foo_t;", + Style); +} + +TEST_F(FormatTest, SplitEmptyNamespace) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterNamespace = true; + Style.BraceWrapping.SplitEmptyNamespace = false; + + verifyFormat("namespace Foo\n" + "{};", + Style); + verifyFormat("/* something */ namespace Foo\n" + "{};", + Style); + verifyFormat("inline namespace Foo\n" + "{};", + Style); + verifyFormat("namespace Foo\n" + "{\n" + "void Bar();\n" + "};", + Style); +} + +TEST_F(FormatTest, NeverMergeShortRecords) { + FormatStyle Style = getLLVMStyle(); + + verifyFormat("class Foo {\n" + " Foo();\n" + "};", + Style); + verifyFormat("typedef class Foo {\n" + " Foo();\n" + "} Foo_t;", + Style); + verifyFormat("struct Foo {\n" + " Foo();\n" + "};", + Style); + verifyFormat("typedef struct Foo {\n" + " Foo();\n" + "} Foo_t;", + Style); + verifyFormat("union Foo {\n" + " A,\n" + "};", + Style); + verifyFormat("typedef union Foo {\n" + " A,\n" + "} Foo_t;", + Style); + verifyFormat("namespace Foo {\n" + "void Bar();\n" + "};", + Style); + + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterClass = true; + Style.BraceWrapping.AfterStruct = true; + Style.BraceWrapping.AfterUnion = true; + Style.BraceWrapping.AfterNamespace = true; + verifyFormat("class Foo\n" + "{\n" + " Foo();\n" + "};", + Style); + verifyFormat("typedef class Foo\n" + "{\n" + " Foo();\n" + "} Foo_t;", + Style); + verifyFormat("struct Foo\n" + "{\n" + " Foo();\n" + "};", + Style); + verifyFormat("typedef struct Foo\n" + "{\n" + " Foo();\n" + "} Foo_t;", + Style); + verifyFormat("union Foo\n" + "{\n" + " A,\n" + "};", + Style); + verifyFormat("typedef union Foo\n" + "{\n" + " A,\n" + "} Foo_t;", + Style); + verifyFormat("namespace Foo\n" + "{\n" + "void Bar();\n" + "};", + Style); } TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { @@ -6132,6 +7427,10 @@ TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) { " if (true) continue;\n" "}", ShortMergedIf); + ShortMergedIf.ColumnLimit = 33; + verifyFormat("#define A \\\n" + " if constexpr (true) return 42;", + ShortMergedIf); ShortMergedIf.ColumnLimit = 29; verifyFormat("#define A \\\n" " if (aaaaaaaaaa) return 1; \\\n" @@ -6143,6 +7442,11 @@ TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) { " return 1; \\\n" " return 2;", ShortMergedIf); + verifyFormat("#define A \\\n" + " if constexpr (aaaaaaa) \\\n" + " return 1; \\\n" + " return 2;", + ShortMergedIf); } TEST_F(FormatTest, FormatStarDependingOnContext) { @@ -6186,7 +7490,7 @@ TEST_F(FormatTest, SkipsDeeplyNestedLines) { // Deeply nested part is untouched, rest is formatted. EXPECT_EQ(std::string("int i;\n") + Code + "int j;\n", format(std::string("int i;\n") + Code + "int j;\n", - getLLVMStyle(), IC_ExpectIncomplete)); + getLLVMStyle(), SC_ExpectIncomplete)); } //===----------------------------------------------------------------------===// @@ -6413,7 +7717,7 @@ TEST_F(FormatTest, BreaksStringLiterals) { EXPECT_EQ("\"some text other\";", format("\"some text other\";", Style)); FormatStyle AlignLeft = getLLVMStyleWithColumns(12); - AlignLeft.AlignEscapedNewlinesLeft = true; + AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left; EXPECT_EQ("#define A \\\n" " \"some \" \\\n" " \"text \" \\\n" @@ -6457,6 +7761,7 @@ TEST_F(FormatTest, BreaksWideAndNSStringLiterals) { EXPECT_EQ("@\"NSString \"\n" "@\"literal\";", format("@\"NSString literal\";", getGoogleStyleWithColumns(19))); + verifyFormat(R"(NSString *s = @"那那那那";)", getLLVMStyleWithColumns(26)); // This input makes clang-format try to split the incomplete unicode escape // sequence, which used to lead to a crasher. @@ -6502,7 +7807,7 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) { "#if !TEST\n" " _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n" "#endif\n" - " );", + ");", format("f(\n" "#if !TEST\n" "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n" @@ -6813,7 +8118,7 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { FormatStyle Tab = getLLVMStyleWithColumns(42); Tab.IndentWidth = 8; Tab.UseTab = FormatStyle::UT_Always; - Tab.AlignEscapedNewlinesLeft = true; + Tab.AlignEscapedNewlines = FormatStyle::ENAS_Left; EXPECT_EQ("if (aaaaaaaa && // q\n" " bb)\t\t// w\n" @@ -7594,14 +8899,21 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { "int oneTwoThree = 123;\n" "int oneTwo = 12;", Alignment)); - Alignment.AlignEscapedNewlinesLeft = true; + Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; + verifyFormat("#define A \\\n" + " int aaaa = 12; \\\n" + " int b = 23; \\\n" + " int ccc = 234; \\\n" + " int dddddddddd = 2345;", + Alignment); + Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left; verifyFormat("#define A \\\n" " int aaaa = 12; \\\n" " int b = 23; \\\n" " int ccc = 234; \\\n" " int dddddddddd = 2345;", Alignment); - Alignment.AlignEscapedNewlinesLeft = false; + Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right; verifyFormat("#define A " " \\\n" " int aaaa = 12; " @@ -7669,12 +8981,11 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { "};", Alignment); - // FIXME: Should align all three assignments verifyFormat( "int i = 1;\n" "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" " loooooooooooooooooooooongParameterB);\n" - "int j = 2;", + "int j = 2;", Alignment); verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n" @@ -7689,6 +9000,13 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n" "float b[1][] = {{3.f}};\n", Alignment); + verifyFormat("for (int i = 0; i < 1; i++)\n" + " int x = 1;\n", + Alignment); + verifyFormat("for (i = 0; i < 1; i++)\n" + " x = 1;\n" + "y = 1;\n", + Alignment); } TEST_F(FormatTest, AlignConsecutiveDeclarations) { @@ -7756,7 +9074,57 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "unsigned oneTwoThree = 123;\n" "int oneTwo = 12;", Alignment)); + // Function prototype alignment + verifyFormat("int a();\n" + "double b();", + Alignment); + verifyFormat("int a(int x);\n" + "double b();", + Alignment); + unsigned OldColumnLimit = Alignment.ColumnLimit; + // We need to set ColumnLimit to zero, in order to stress nested alignments, + // otherwise the function parameters will be re-flowed onto a single line. + Alignment.ColumnLimit = 0; + EXPECT_EQ("int a(int x,\n" + " float y);\n" + "double b(int x,\n" + " double y);", + format("int a(int x,\n" + " float y);\n" + "double b(int x,\n" + " double y);", + Alignment)); + // This ensures that function parameters of function declarations are + // correctly indented when their owning functions are indented. + // The failure case here is for 'double y' to not be indented enough. + EXPECT_EQ("double a(int x);\n" + "int b(int y,\n" + " double z);", + format("double a(int x);\n" + "int b(int y,\n" + " double z);", + Alignment)); + // Set ColumnLimit low so that we induce wrapping immediately after + // the function name and opening paren. + Alignment.ColumnLimit = 13; + verifyFormat("int function(\n" + " int x,\n" + " bool y);", + Alignment); + Alignment.ColumnLimit = OldColumnLimit; + // Ensure function pointers don't screw up recursive alignment + verifyFormat("int a(int x, void (*fp)(int y));\n" + "double b();", + Alignment); Alignment.AlignConsecutiveAssignments = true; + // Ensure recursive alignment is broken by function braces, so that the + // "a = 1" does not align with subsequent assignments inside the function + // body. + verifyFormat("int func(int a = 1) {\n" + " int b = 2;\n" + " int cc = 3;\n" + "}", + Alignment); verifyFormat("float something = 2000;\n" "double another = 911;\n" "int i = 1, j = 10;\n" @@ -7766,6 +9134,28 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { verifyFormat("int oneTwoThree = {0}; // comment\n" "unsigned oneTwo = 0; // comment", Alignment); + // Make sure that scope is correctly tracked, in the absence of braces + verifyFormat("for (int i = 0; i < n; i++)\n" + " j = i;\n" + "double x = 1;\n", + Alignment); + verifyFormat("if (int i = 0)\n" + " j = i;\n" + "double x = 1;\n", + Alignment); + // Ensure operator[] and operator() are comprehended + verifyFormat("struct test {\n" + " long long int foo();\n" + " int operator[](int a);\n" + " double bar();\n" + "};\n", + Alignment); + verifyFormat("struct test {\n" + " long long int foo();\n" + " int operator()(int a);\n" + " double bar();\n" + "};\n", + Alignment); EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" " int const i = 1;\n" " int * j = 2;\n" @@ -7790,14 +9180,21 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "}", Alignment)); Alignment.AlignConsecutiveAssignments = false; - Alignment.AlignEscapedNewlinesLeft = true; + Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; + verifyFormat("#define A \\\n" + " int aaaa = 12; \\\n" + " float b = 23; \\\n" + " const int ccc = 234; \\\n" + " unsigned dddddddddd = 2345;", + Alignment); + Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left; verifyFormat("#define A \\\n" " int aaaa = 12; \\\n" " float b = 23; \\\n" " const int ccc = 234; \\\n" " unsigned dddddddddd = 2345;", Alignment); - Alignment.AlignEscapedNewlinesLeft = false; + Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right; Alignment.ColumnLimit = 30; verifyFormat("#define A \\\n" " int aaaa = 12; \\\n" @@ -7867,17 +9264,16 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { Alignment); Alignment.AlignConsecutiveAssignments = false; - // FIXME: Should align all three declarations verifyFormat( "int i = 1;\n" "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" " loooooooooooooooooooooongParameterB);\n" - "int j = 2;", + "int j = 2;", Alignment); // Test interactions with ColumnLimit and AlignConsecutiveAssignments: // We expect declarations and assignments to align, as long as it doesn't - // exceed the column limit, starting a new alignemnt sequence whenever it + // exceed the column limit, starting a new alignment sequence whenever it // happens. Alignment.AlignConsecutiveAssignments = true; Alignment.ColumnLimit = 30; @@ -7930,6 +9326,16 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { Alignment); Alignment.BinPackParameters = true; Alignment.ColumnLimit = 80; + + // Bug 33507 + Alignment.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat( + "auto found = range::find_if(vsProducts, [&](auto * aProduct) {\n" + " static const Version verVs2017;\n" + " return true;\n" + "});\n", + Alignment); + Alignment.PointerAlignment = FormatStyle::PAS_Right; } TEST_F(FormatTest, LinuxBraceBreaking) { @@ -7953,7 +9359,7 @@ TEST_F(FormatTest, LinuxBraceBreaking) { "struct B {\n" " int x;\n" "};\n" - "}\n", + "} // namespace a\n", LinuxBraceStyle); verifyFormat("enum X {\n" " Y = 0,\n" @@ -8083,6 +9489,19 @@ TEST_F(FormatTest, StroustrupBraceBreaking) { TEST_F(FormatTest, AllmanBraceBreaking) { FormatStyle AllmanBraceStyle = getLLVMStyle(); AllmanBraceStyle.BreakBeforeBraces = FormatStyle::BS_Allman; + + EXPECT_EQ("namespace a\n" + "{\n" + "void f();\n" + "void g();\n" + "} // namespace a\n", + format("namespace a\n" + "{\n" + "void f();\n" + "void g();\n" + "}\n", + AllmanBraceStyle)); + verifyFormat("namespace a\n" "{\n" "class A\n" @@ -8101,7 +9520,7 @@ TEST_F(FormatTest, AllmanBraceBreaking) { "{\n" " int x;\n" "};\n" - "}", + "} // namespace a", AllmanBraceStyle); verifyFormat("void f()\n" @@ -8221,7 +9640,14 @@ TEST_F(FormatTest, AllmanBraceBreaking) { // .. or dict literals. verifyFormat("void f()\n" "{\n" - " [object someMethod:@{ @\"a\" : @\"b\" }];\n" + " // ...\n" + " [object someMethod:@{@\"a\" : @\"b\"}];\n" + "}", + AllmanBraceStyle); + verifyFormat("void f()\n" + "{\n" + " // ...\n" + " [object someMethod:@{a : @\"b\"}];\n" "}", AllmanBraceStyle); verifyFormat("int f()\n" @@ -8253,11 +9679,24 @@ TEST_F(FormatTest, AllmanBraceBreaking) { BreakBeforeBraceShortIfs); verifyFormat("void f(bool b)\n" "{\n" + " if constexpr (b)\n" + " {\n" + " return;\n" + " }\n" + "}\n", + BreakBeforeBraceShortIfs); + verifyFormat("void f(bool b)\n" + "{\n" " if (b) return;\n" "}\n", BreakBeforeBraceShortIfs); verifyFormat("void f(bool b)\n" "{\n" + " if constexpr (b) return;\n" + "}\n", + BreakBeforeBraceShortIfs); + verifyFormat("void f(bool b)\n" + "{\n" " while (b)\n" " {\n" " return;\n" @@ -8287,7 +9726,7 @@ TEST_F(FormatTest, GNUBraceBreaking) { " }\n" " void g() { return; }\n" "}\n" - "}", + "} // namespace a", GNUBraceStyle); verifyFormat("void f()\n" @@ -8576,7 +10015,6 @@ TEST_F(FormatTest, GetsCorrectBasedOnStyle) { TEST_F(FormatTest, ParsesConfigurationBools) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; - CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft); CHECK_PARSE_BOOL(AlignOperands); CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AlignConsecutiveAssignments); @@ -8591,9 +10029,9 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(BinPackParameters); CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations); CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); - CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma); CHECK_PARSE_BOOL(BreakStringLiterals); CHECK_PARSE_BOOL(BreakBeforeInheritanceComma) + CHECK_PARSE_BOOL(CompactNamespaces); CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine); CHECK_PARSE_BOOL(DerivePointerAlignment); CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding"); @@ -8606,6 +10044,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(Cpp11BracedListStyle); CHECK_PARSE_BOOL(ReflowComments); CHECK_PARSE_BOOL(SortIncludes); + CHECK_PARSE_BOOL(SortUsingDeclarations); CHECK_PARSE_BOOL(SpacesInParentheses); CHECK_PARSE_BOOL(SpacesInSquareBrackets); CHECK_PARSE_BOOL(SpacesInAngles); @@ -8624,9 +10063,13 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock); CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch); CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse); CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace); } #undef CHECK_PARSE_BOOL @@ -8640,6 +10083,8 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("ObjCBlockIndentWidth: 1234", ObjCBlockIndentWidth, 1234u); CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u); CHECK_PARSE("MaxEmptyLinesToKeep: 1234", MaxEmptyLinesToKeep, 1234u); + CHECK_PARSE("PenaltyBreakAssignment: 1234", + PenaltyBreakAssignment, 1234u); CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234", PenaltyBreakBeforeFirstCallParameter, 1234u); CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u); @@ -8686,6 +10131,17 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators, FormatStyle::BOS_All); + Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; + CHECK_PARSE("BreakConstructorInitializers: BeforeComma", + BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma); + CHECK_PARSE("BreakConstructorInitializers: AfterColon", + BreakConstructorInitializers, FormatStyle::BCIS_AfterColon); + CHECK_PARSE("BreakConstructorInitializers: BeforeColon", + BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon); + // For backward compatibility: + CHECK_PARSE("BreakConstructorInitializersBeforeComma: true", + BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, FormatStyle::BAS_Align); @@ -8699,6 +10155,19 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, FormatStyle::BAS_Align); + Style.AlignEscapedNewlines = FormatStyle::ENAS_Left; + CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines, + FormatStyle::ENAS_DontAlign); + CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines, + FormatStyle::ENAS_Left); + CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines, + FormatStyle::ENAS_Right); + // For backward compatibility: + CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines, + FormatStyle::ENAS_Left); + CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines, + FormatStyle::ENAS_Right); + Style.UseTab = FormatStyle::UT_ForIndentation; CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never); CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation); @@ -8811,6 +10280,20 @@ TEST_F(FormatTest, ParsesConfiguration) { " Priority: 1", IncludeCategories, ExpectedCategories); CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeIsMainRegex, "abc$"); + + Style.RawStringFormats.clear(); + std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = { + {"pb", FormatStyle::LK_TextProto, "llvm"}, + {"cpp", FormatStyle::LK_Cpp, "google"}}; + + CHECK_PARSE("RawStringFormats:\n" + " - Delimiter: 'pb'\n" + " Language: TextProto\n" + " BasedOnStyle: llvm\n" + " - Delimiter: 'cpp'\n" + " Language: Cpp\n" + " BasedOnStyle: google", + RawStringFormats, ExpectedRawStringFormats); } TEST_F(FormatTest, ParsesConfigurationWithLanguages) { @@ -9105,7 +10588,7 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) { TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) { FormatStyle Style = getLLVMStyle(); - Style.BreakConstructorInitializersBeforeComma = true; + Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; Style.ConstructorInitializerIndentWidth = 4; verifyFormat("SomeClass::Constructor()\n" " : a(a)\n" @@ -9350,6 +10833,8 @@ TEST_F(FormatTest, FormatsLambdas) { verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n"); verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n"); verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n"); + verifyFormat("auto c = [a = [b = 42] {}] {};\n"); + verifyFormat("auto c = [a = &i + 10, b = [] {}] {};\n"); verifyFormat("int x = f(*+[] {});"); verifyFormat("void f() {\n" " other(x.begin(), x.end(), [&](int, int) { return 1; });\n" @@ -9464,7 +10949,7 @@ TEST_F(FormatTest, FormatsLambdas) { // Other corner cases. verifyFormat("void f() {\n" " bar([]() {} // Did not respect SpacesBeforeTrailingComments\n" - " );\n" + " );\n" "}"); // Lambdas created through weird macros. @@ -9478,6 +10963,11 @@ TEST_F(FormatTest, FormatsLambdas) { " doo_dah();\n" " })) {\n" "}"); + verifyFormat("if constexpr (blah_blah(whatever, whatever, [] {\n" + " doo_dah();\n" + " doo_dah();\n" + " })) {\n" + "}"); verifyFormat("auto lambda = []() {\n" " int a = 2\n" "#if A\n" @@ -9974,6 +11464,10 @@ TEST_F(FormatTest, ArrayAsTemplateType) { format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces)); } +TEST_F(FormatTest, NoSpaceAfterSuper) { + verifyFormat("__super::FooBar();"); +} + TEST(FormatStyle, GetStyleOfFile) { vfs::InMemoryFileSystem FS; // Test 1: format file in the same directory. @@ -10111,6 +11605,98 @@ TEST_F(ReplacementTest, SortIncludesAfterReplacement) { EXPECT_EQ(Expected, *Result); } +TEST_F(FormatTest, FormatSortsUsingDeclarations) { + EXPECT_EQ("using std::cin;\n" + "using std::cout;", + format("using std::cout;\n" + "using std::cin;", getGoogleStyle())); +} + +TEST_F(FormatTest, UTF8CharacterLiteralCpp03) { + format::FormatStyle Style = format::getLLVMStyle(); + Style.Standard = FormatStyle::LS_Cpp03; + // cpp03 recognize this string as identifier u8 and literal character 'a' + EXPECT_EQ("auto c = u8 'a';", format("auto c = u8'a';", Style)); +} + +TEST_F(FormatTest, UTF8CharacterLiteralCpp11) { + // u8'a' is a C++17 feature, utf8 literal character, LS_Cpp11 covers + // all modes, including C++11, C++14 and C++17 + EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';")); +} + +TEST_F(FormatTest, DoNotFormatLikelyXml) { + EXPECT_EQ("<!-- ;> -->", + format("<!-- ;> -->", getGoogleStyle())); + EXPECT_EQ(" <!-- >; -->", + format(" <!-- >; -->", getGoogleStyle())); +} + +TEST_F(FormatTest, StructuredBindings) { + // Structured bindings is a C++17 feature. + // all modes, including C++11, C++14 and C++17 + verifyFormat("auto [a, b] = f();"); + EXPECT_EQ("auto [a, b] = f();", format("auto[a, b] = f();")); + EXPECT_EQ("const auto [a, b] = f();", format("const auto[a, b] = f();")); + EXPECT_EQ("auto const [a, b] = f();", format("auto const[a, b] = f();")); + EXPECT_EQ("auto const volatile [a, b] = f();", + format("auto const volatile[a, b] = f();")); + EXPECT_EQ("auto [a, b, c] = f();", format("auto [ a , b,c ] = f();")); + EXPECT_EQ("auto &[a, b, c] = f();", + format("auto &[ a , b,c ] = f();")); + EXPECT_EQ("auto &&[a, b, c] = f();", + format("auto &&[ a , b,c ] = f();")); + EXPECT_EQ("auto const &[a, b] = f();", format("auto const&[a, b] = f();")); + EXPECT_EQ("auto const volatile &&[a, b] = f();", + format("auto const volatile &&[a, b] = f();")); + EXPECT_EQ("auto const &&[a, b] = f();", format("auto const && [a, b] = f();")); + EXPECT_EQ("const auto &[a, b] = f();", format("const auto & [a, b] = f();")); + EXPECT_EQ("const auto volatile &&[a, b] = f();", + format("const auto volatile &&[a, b] = f();")); + EXPECT_EQ("volatile const auto &&[a, b] = f();", + format("volatile const auto &&[a, b] = f();")); + EXPECT_EQ("const auto &&[a, b] = f();", format("const auto && [a, b] = f();")); + + // Make sure we don't mistake structured bindings for lambdas. + FormatStyle PointerMiddle = getLLVMStyle(); + PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat("auto [a1, b]{A * i};", getGoogleStyle()); + verifyFormat("auto [a2, b]{A * i};", getLLVMStyle()); + verifyFormat("auto [a3, b]{A * i};", PointerMiddle); + verifyFormat("auto const [a1, b]{A * i};", getGoogleStyle()); + verifyFormat("auto const [a2, b]{A * i};", getLLVMStyle()); + verifyFormat("auto const [a3, b]{A * i};", PointerMiddle); + verifyFormat("auto const& [a1, b]{A * i};", getGoogleStyle()); + verifyFormat("auto const &[a2, b]{A * i};", getLLVMStyle()); + verifyFormat("auto const & [a3, b]{A * i};", PointerMiddle); + verifyFormat("auto const&& [a1, b]{A * i};", getGoogleStyle()); + verifyFormat("auto const &&[a2, b]{A * i};", getLLVMStyle()); + verifyFormat("auto const && [a3, b]{A * i};", PointerMiddle); + + EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n}", + format("for (const auto && [a, b] : some_range) {\n}")); + EXPECT_EQ("for (const auto &[a, b] : some_range) {\n}", + format("for (const auto & [a, b] : some_range) {\n}")); + EXPECT_EQ("for (const auto [a, b] : some_range) {\n}", + format("for (const auto[a, b] : some_range) {\n}")); + EXPECT_EQ("auto [x, y](expr);", format("auto[x,y] (expr);")); + EXPECT_EQ("auto &[x, y](expr);", format("auto & [x,y] (expr);")); + EXPECT_EQ("auto &&[x, y](expr);", format("auto && [x,y] (expr);")); + EXPECT_EQ("auto const &[x, y](expr);", format("auto const & [x,y] (expr);")); + EXPECT_EQ("auto const &&[x, y](expr);", format("auto const && [x,y] (expr);")); + EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y] {expr};")); + EXPECT_EQ("auto const &[x, y]{expr};", format("auto const & [x,y] {expr};")); + EXPECT_EQ("auto const &&[x, y]{expr};", format("auto const && [x,y] {expr};")); + + format::FormatStyle Spaces = format::getLLVMStyle(); + Spaces.SpacesInSquareBrackets = true; + verifyFormat("auto [ a, b ] = f();", Spaces); + verifyFormat("auto &&[ a, b ] = f();", Spaces); + verifyFormat("auto &[ a, b ] = f();", Spaces); + verifyFormat("auto const &&[ a, b ] = f();", Spaces); + verifyFormat("auto const &[ a, b ] = f();", Spaces); +} + } // end namespace } // end namespace format } // end namespace clang |