yvvan updated this revision to Diff 199150. yvvan added a comment. Sorry for unrelated formatting changes - that's clang-format's work :)
I've removed the extra executable. I don't know how to force that behavior only for the given line (for that I need someone who can help) but in our usecase we should not care if we apply the rule to the whole file or only to the current line since we are only interested in one single Replacement which we can anyways filter afterwards. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D53072/new/ https://reviews.llvm.org/D53072 Files: clang/include/clang/Format/Format.h clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/Format.cpp clang/lib/Format/FormatInternal.h clang/lib/Format/TokenAnalyzer.cpp clang/lib/Format/TokenAnalyzer.h clang/lib/Format/UnwrappedLineFormatter.cpp clang/lib/Format/UnwrappedLineFormatter.h clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/UnwrappedLineParser.h clang/tools/clang-format/ClangFormat.cpp clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -29,21 +29,18 @@ class FormatTest : public ::testing::Test { protected: - enum StatusCheck { - SC_ExpectComplete, - SC_ExpectIncomplete, - SC_DoNotCheck - }; + enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; - std::string format(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - StatusCheck CheckComplete = SC_ExpectComplete) { + std::string + format(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle(), + StatusCheck CheckComplete = SC_ExpectComplete, + ExtraFormattingOptions ExtraOptions = ExtraFormattingOptions::None) { LLVM_DEBUG(llvm::errs() << "---\n"); LLVM_DEBUG(llvm::errs() << Code << "\n\n"); std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); FormattingAttemptStatus Status; tooling::Replacements Replaces = - reformat(Style, Code, Ranges, "<stdin>", &Status); + reformat(Style, ExtraOptions, Code, Ranges, "<stdin>", &Status); if (CheckComplete != SC_DoNotCheck) { bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) @@ -332,13 +329,15 @@ format("namespace {\n" "int i;\n" "\n" - "}", LLVMWithNoNamespaceFix)); + "}", + LLVMWithNoNamespaceFix)); EXPECT_EQ("namespace {\n" "int i;\n" "}", format("namespace {\n" "int i;\n" - "}", LLVMWithNoNamespaceFix)); + "}", + LLVMWithNoNamespaceFix)); EXPECT_EQ("namespace {\n" "int i;\n" "\n" @@ -346,13 +345,15 @@ format("namespace {\n" "int i;\n" "\n" - "};", LLVMWithNoNamespaceFix)); + "};", + LLVMWithNoNamespaceFix)); EXPECT_EQ("namespace {\n" "int i;\n" "};", format("namespace {\n" "int i;\n" - "};", LLVMWithNoNamespaceFix)); + "};", + LLVMWithNoNamespaceFix)); EXPECT_EQ("namespace {\n" "int i;\n" "\n" @@ -395,6 +396,25 @@ Style)); } +TEST_F(FormatTest, KeepsLineBreaks) { + FormatStyle Style = getLLVMStyle(); + EXPECT_EQ("if (a\n" + " && b) {\n" + "}", + format("if (a\n" + " && b) {\n" + "}", + Style, SC_ExpectComplete, + ExtraFormattingOptions::KeepLineBreaksForNonEmptyLines)); + + EXPECT_EQ("[]() {\n" + " foo(); }", + format("[]() {\n" + "foo(); }", + Style, SC_ExpectComplete, + ExtraFormattingOptions::KeepLineBreaksForNonEmptyLines)); +} + TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) { verifyFormat("x = (a) and (b);"); verifyFormat("x = (a) or (b);"); @@ -854,7 +874,8 @@ verifyFormat("for (Foo *x = 0; x != in; x++) {\n}"); verifyFormat("Foo *x;\nfor (x = 0; x != in; x++) {\n}"); verifyFormat("Foo *x;\nfor (x in y) {\n}"); - verifyFormat("for (const Foo<Bar> &baz = in.value(); !baz.at_end(); ++baz) {\n}"); + verifyFormat( + "for (const Foo<Bar> &baz = in.value(); !baz.at_end(); ++baz) {\n}"); FormatStyle NoBinPacking = getLLVMStyle(); NoBinPacking.BinPackParameters = false; @@ -1246,20 +1267,26 @@ "#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" "}", + 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" + "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" + " 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" + "case 0: return; /* long long long long long long long long " + "long long long long comment line */\n" "}", Style)); verifyFormat("switch (a) {\n" @@ -1523,7 +1550,7 @@ TEST_F(FormatTest, BreakInheritanceStyle) { FormatStyle StyleWithInheritanceBreakBeforeComma = getLLVMStyle(); StyleWithInheritanceBreakBeforeComma.BreakInheritanceList = - FormatStyle::BILS_BeforeComma; + FormatStyle::BILS_BeforeComma; verifyFormat("class MyClass : public X {};", StyleWithInheritanceBreakBeforeComma); verifyFormat("class MyClass\n" @@ -1541,7 +1568,7 @@ FormatStyle StyleWithInheritanceBreakAfterColon = getLLVMStyle(); StyleWithInheritanceBreakAfterColon.BreakInheritanceList = - FormatStyle::BILS_AfterColon; + FormatStyle::BILS_AfterColon; verifyFormat("class MyClass : public X {};", StyleWithInheritanceBreakAfterColon); verifyFormat("class MyClass : public X, public Y {};", @@ -1805,8 +1832,7 @@ // 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 {};", - LLVMWithNoNamespaceFix); + verifyFormat("namespace {};", LLVMWithNoNamespaceFix); verifyFormat("namespace {\n" "class A {};\n" "};", @@ -1875,8 +1901,8 @@ Style.CompactNamespaces = true; verifyFormat("namespace A { namespace B {\n" - "}} // namespace A::B", - Style); + "}} // namespace A::B", + Style); EXPECT_EQ("namespace out { namespace in {\n" "}} // namespace out::in", @@ -2720,7 +2746,8 @@ "{\n" "}", format("void f() try {\n" - "}", Style)); + "}", + Style)); EXPECT_EQ("class SomeClass {\n" "public:\n" " SomeClass() EXCLUSIVE_LOCK_FUNCTION(mu_);\n" @@ -3505,16 +3532,19 @@ Style.MacroBlockEnd = "^[A-Z_]+_END$"; verifyFormat("FOO_BEGIN\n" " FOO_ENTRY\n" - "FOO_END", Style); + "FOO_END", + Style); verifyFormat("FOO_BEGIN\n" " NESTED_FOO_BEGIN\n" " NESTED_FOO_ENTRY\n" " NESTED_FOO_END\n" - "FOO_END", Style); + "FOO_END", + Style); verifyFormat("FOO_BEGIN(Foo, Bar)\n" " int x;\n" " x = 1;\n" - "FOO_END(Baz)", Style); + "FOO_END(Baz)", + Style); } //===----------------------------------------------------------------------===// @@ -3770,7 +3800,9 @@ EXPECT_EQ("return someVeryVeryLongConditionThatBarelyFitsOnALine\n" "\t&& (someOtherLongishConditionPart1\n" "\t\t|| someOtherEvenLongerNestedConditionPart2);", - format("return someVeryVeryLongConditionThatBarelyFitsOnALine && (someOtherLongishConditionPart1 || someOtherEvenLongerNestedConditionPart2);", + format("return someVeryVeryLongConditionThatBarelyFitsOnALine && " + "(someOtherLongishConditionPart1 || " + "someOtherEvenLongerNestedConditionPart2);", Style)); } @@ -4214,28 +4246,28 @@ "SomeClass::Constructor() :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" " aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", - Style); + Style); verifyFormat("Constructor(aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n" " aaaaaaaaaa(aaaaaa) {}", - Style); + Style); verifyFormat("Constructor() :\n" " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" " aaaaaaaaaaaaaaaaaaaaaaa() {}", - Style); + Style); verifyFormat("Constructor() :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", - Style); + Style); verifyFormat("Constructor(int Parameter = 0) :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa),\n" " aaaaaaaaaaaa(aaaaaaaaaaaaaaaaa) {}", - Style); + Style); verifyFormat("Constructor() :\n" " aaaaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbbbbb(b) {\n" "}", @@ -4243,7 +4275,7 @@ verifyFormat("Constructor() :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}", - Style); + Style); // Here a line could be saved by splitting the second initializer onto two // lines, but that is not desirable. @@ -4251,7 +4283,7 @@ " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n" " aaaaaaaaaaa(aaaaaaaaaaa),\n" " aaaaaaaaaaaaaaaaaaaaat(aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", - Style); + Style); FormatStyle OnePerLine = Style; OnePerLine.ConstructorInitializerAllOnOneLineOrOnePerLine = true; @@ -4283,12 +4315,11 @@ " aaaaaaaaaaaaaaaaaaaaaa) {}", OnePerLine); OnePerLine.BinPackParameters = false; - verifyFormat( - "Constructor() :\n" - " aaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaa().aaa(),\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", - OnePerLine); + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaa().aaa(),\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", + OnePerLine); OnePerLine.ColumnLimit = 60; verifyFormat("Constructor() :\n" " aaaaaaaaaaaaaaaaaaaa(a),\n" @@ -4301,7 +4332,7 @@ format("Constructor() :\n" " // Comment forcing unwanted break.\n" " aaaa(aaaa) {}", - Style)); + Style)); Style.ColumnLimit = 0; verifyFormat("SomeClass::Constructor() :\n" @@ -4311,7 +4342,7 @@ " a(a) {}", Style); verifyFormat("SomeClass::Constructor() :\n" - " a(a), b(b), c(c) {}", + " a(a), b(b), c(c) {}", Style); verifyFormat("SomeClass::Constructor() :\n" " a(a) {\n" @@ -4322,40 +4353,43 @@ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; verifyFormat("SomeClass::Constructor() :\n" - " a(a), b(b), c(c) {\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() : a(a), b(b), c(c) {}", Style); verifyFormat("SomeClass::Constructor() :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}", Style); - // `ConstructorInitializerIndentWidth` actually applies to InheritanceList as well + // `ConstructorInitializerIndentWidth` actually applies to InheritanceList as + // well Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon; - verifyFormat("class SomeClass\n" - " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", - Style); + verifyFormat( + "class SomeClass\n" + " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", + Style); Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma; - verifyFormat("class SomeClass\n" - " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " , public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", - Style); + verifyFormat( + "class SomeClass\n" + " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " , public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", + Style); Style.BreakInheritanceList = FormatStyle::BILS_AfterColon; - verifyFormat("class SomeClass :\n" - " public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", - Style); + verifyFormat( + "class SomeClass :\n" + " public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", + Style); } #ifndef EXPENSIVE_CHECKS @@ -4541,11 +4575,10 @@ "typename aaaaaaaaaa<aaaaaa>::aaaaaaaaaaa\n" "aaaaaaaaaa<aaaaaa>::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " bool *aaaaaaaaaaaaaaaaaa, bool *aa) {}"); - verifyGoogleFormat( - "template <typename T>\n" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - "aaaaaaaaaaaaaaaaaaaaaaa<T>::aaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa);"); + verifyGoogleFormat("template <typename T>\n" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + "aaaaaaaaaaaaaaaaaaaaaaa<T>::aaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa);"); FormatStyle Style = getLLVMStyle(); Style.PointerAlignment = FormatStyle::PAS_Left; @@ -4918,11 +4951,10 @@ verifyFormat("return aaaaaaaaaaaaaaaaa->aaaaa().aaaaaaaaaaaaa().aaaaaa() <\n" " aaaaaaaaaaaaaaa->aaaaa().aaaaaaaaaaaaa().aaaaaa();"); - verifyFormat( - "aaaaaaa->aaaaaaa\n" - " ->aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" - " ->aaaaaaaa(aaaaaaaaaaaaaaa);"); + verifyFormat("aaaaaaa->aaaaaaa\n" + " ->aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " ->aaaaaaaa(aaaaaaaaaaaaaaa);"); verifyFormat( "aaaaaaa->aaaaaaa\n" " ->aaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" @@ -5279,10 +5311,9 @@ verifyFormat( "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); - verifyFormat( - "aaaa(aaaaaaaaa, aaaaaaaaa,\n" - " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("aaaa(aaaaaaaaa, aaaaaaaaa,\n" + " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa ? aaaa(aaaaaa)\n" " : aaaaaaaaaaaaa);"); @@ -5424,11 +5455,10 @@ "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", Style); - verifyFormat( - "aaaa(aaaaaaaa, aaaaaaaaaa,\n" - " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", - Style); + verifyFormat("aaaa(aaaaaaaa, aaaaaaaaaa,\n" + " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", + Style); verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa ? aaaa(aaaaaa) :\n" " aaaaaaaaaaaaa);", @@ -6231,7 +6261,8 @@ verifyFormat("template <typename T> class C {};", NeverBreak); verifyFormat("template <typename T> void f();", NeverBreak); verifyFormat("template <typename T> void f() {}", NeverBreak); - verifyFormat("template <typename T>\nvoid foo(aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb) {}", + verifyFormat("template <typename T>\nvoid foo(aaaaaaaaaaaaaaaaaaaaaaaaaa " + "bbbbbbbbbbbbbbbbbbbb) {}", NeverBreak); verifyFormat("void aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbb>(\n" @@ -6247,9 +6278,11 @@ verifyFormat("template <enum E> class A {\n" "public:\n" " E *f();\n" - "};", NeverBreak); + "};", + NeverBreak); NeverBreak.PenaltyBreakTemplateDeclaration = 100; - verifyFormat("template <typename T> void\nfoo(aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb) {}", + verifyFormat("template <typename T> void\nfoo(aaaaaaaaaaaaaaaaaaaaaaaaaa " + "bbbbbbbbbbbbbbbbbbbb) {}", NeverBreak); } @@ -6324,22 +6357,24 @@ Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; - verifyFormat( - "template <typename... a> struct s {};\n" - "extern s<\n" - " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa>\n" - " y;", - Style); + verifyFormat("template <typename... a> struct s {};\n" + "extern s<\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " + "aaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " + "aaaaaaaaaaaaaaaaaaaaaa>\n" + " y;", + Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; - verifyFormat( - "template <typename... a> struct t {};\n" - "extern t<\n" - " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa>\n" - " y;", - Style); + verifyFormat("template <typename... a> struct t {};\n" + "extern t<\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " + "aaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " + "aaaaaaaaaaaaaaaaaaaaaa>\n" + " y;", + Style); } TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) { @@ -6366,12 +6401,11 @@ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaa);"); - verifyFormat( - "aaaaaaaaaaaaaaaaaa(aaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaa);", - getLLVMStyleWithColumns(74)); + verifyFormat("aaaaaaaaaaaaaaaaaa(aaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaa);", + getLLVMStyleWithColumns(74)); verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" @@ -6620,7 +6654,8 @@ Spaces.SpacesInCStyleCastParentheses = false; Spaces.SpacesInParentheses = true; verifyFormat("Deleted &operator=( const Deleted & ) & = default;", Spaces); - verifyFormat("SomeType MemberFunction( const Deleted & ) & = delete;", Spaces); + verifyFormat("SomeType MemberFunction( const Deleted & ) & = delete;", + Spaces); verifyFormat("Deleted &operator=( const Deleted & ) &;", Spaces); verifyFormat("SomeType MemberFunction( const Deleted & ) &;", Spaces); } @@ -6823,14 +6858,13 @@ " (sizeof(T) > 1 || sizeof(T) < 8)>::type>\n" "void F();", getLLVMStyleWithColumns(70)); - verifyFormat( - "template <class T,\n" - " class = typename std::enable_if<\n" - " std::is_integral<T>::value &&\n" - " (sizeof(T) > 1 || sizeof(T) < 8)>::type,\n" - " class U>\n" - "void F();", - getLLVMStyleWithColumns(70)); + verifyFormat("template <class T,\n" + " class = typename std::enable_if<\n" + " std::is_integral<T>::value &&\n" + " (sizeof(T) > 1 || sizeof(T) < 8)>::type,\n" + " class U>\n" + "void F();", + getLLVMStyleWithColumns(70)); verifyFormat( "template <class T,\n" " class = typename ::std::enable_if<\n" @@ -7543,13 +7577,14 @@ // Binpacking only if there is no trailing comma verifyFormat("const Aaaaaa aaaaa = {aaaaaaaaaa, bbbbbbbbbb,\n" " cccccccccc, dddddddddd};", - getLLVMStyleWithColumns(50)); + getLLVMStyleWithColumns(50)); verifyFormat("const Aaaaaa aaaaa = {\n" " aaaaaaaaaaa,\n" " bbbbbbbbbbb,\n" " ccccccccccc,\n" " ddddddddddd,\n" - "};", getLLVMStyleWithColumns(50)); + "};", + getLLVMStyleWithColumns(50)); // Cases where distinguising braced lists and blocks is hard. verifyFormat("vector<int> v{12} GUARDED_BY(mutex);"); @@ -8207,7 +8242,7 @@ "{\n" "} Foo_t;", Style); - //typedef struct Bar {} Bar_t; + // typedef struct Bar {} Bar_t; } TEST_F(FormatTest, SplitEmptyUnion) { @@ -8590,7 +8625,6 @@ verifyGoogleFormat("- foo:(int)foo;"); } - TEST_F(FormatTest, BreaksStringLiterals) { EXPECT_EQ("\"some text \"\n" "\"other\";", @@ -8713,14 +8747,13 @@ // Verify that splitting the strings understands // Style::AlwaysBreakBeforeMultilineStrings. - EXPECT_EQ( - "aaaaaaaaaaaa(\n" - " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa \"\n" - " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa\");", - format("aaaaaaaaaaaa(\"aaaaaaaaaaaaaaaaaaaaaaaaaa " - "aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa " - "aaaaaaaaaaaaaaaaaaaaaa\");", - getGoogleStyle())); + EXPECT_EQ("aaaaaaaaaaaa(\n" + " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa \"\n" + " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa\");", + format("aaaaaaaaaaaa(\"aaaaaaaaaaaaaaaaaaaaaaaaaa " + "aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa " + "aaaaaaaaaaaaaaaaaaaaaa\");", + getGoogleStyle())); EXPECT_EQ("return \"aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa \"\n" " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa\";", format("return \"aaaaaaaaaaaaaaaaaaaaaa " @@ -8857,10 +8890,10 @@ TEST_F(FormatTest, BreaksStringLiteralOperands) { // In a function call with two operands, the second can be broken with no line // break before it. - EXPECT_EQ("func(a, \"long long \"\n" - " \"long long\");", - format("func(a, \"long long long long\");", - getLLVMStyleWithColumns(24))); + EXPECT_EQ( + "func(a, \"long long \"\n" + " \"long long\");", + format("func(a, \"long long long long\");", getLLVMStyleWithColumns(24))); // In a function call with three operands, the second must be broken with a // line break before it. EXPECT_EQ("func(a,\n" @@ -8889,22 +8922,21 @@ // break before it. EXPECT_EQ("a << \"line line \"\n" " \"line\";", - format("a << \"line line line\";", - getLLVMStyleWithColumns(20))); + format("a << \"line line line\";", getLLVMStyleWithColumns(20))); // In a chain of << with three operands, the second can be broken with no line // break before it. - EXPECT_EQ("abcde << \"line \"\n" - " \"line line\"\n" - " << c;", - format("abcde << \"line line line\" << c;", - getLLVMStyleWithColumns(20))); + EXPECT_EQ( + "abcde << \"line \"\n" + " \"line line\"\n" + " << c;", + format("abcde << \"line line line\" << c;", getLLVMStyleWithColumns(20))); // In a chain of << with three operands, the third must be broken with a line // break before it. - EXPECT_EQ("a << b\n" - " << \"line line \"\n" - " \"line\";", - format("a << b << \"line line line\";", - getLLVMStyleWithColumns(20))); + EXPECT_EQ( + "a << b\n" + " << \"line line \"\n" + " \"line\";", + format("a << b << \"line line line\";", getLLVMStyleWithColumns(20))); // In a chain of << with three operands, the second can be broken with no line // break before it and the third must be broken with a line break before it. EXPECT_EQ("abcd << \"line line \"\n" @@ -8915,10 +8947,10 @@ getLLVMStyleWithColumns(20))); // In a chain of binary operators with two operands, the second can be broken // with no line break before it. - EXPECT_EQ("abcd + \"line line \"\n" - " \"line line\";", - format("abcd + \"line line line line\";", - getLLVMStyleWithColumns(20))); + EXPECT_EQ( + "abcd + \"line line \"\n" + " \"line line\";", + format("abcd + \"line line line line\";", getLLVMStyleWithColumns(20))); // In a chain of binary operators with three operands, the second must be // broken with a line break before it. EXPECT_EQ("abcd +\n" @@ -11169,7 +11201,8 @@ Style)); verifyFormat("int a; // the\n" - " // comment", Style); + " // comment", + Style); EXPECT_EQ("int a; /* first line\n" " * second\n" " * line third\n" @@ -11259,11 +11292,11 @@ // Make sure we do not keep protruding characters if strict mode reflow is // cheaper than keeping protruding characters. Style.ColumnLimit = 21; - EXPECT_EQ("// foo foo foo foo\n" - "// foo foo foo foo\n" - "// foo foo foo foo\n", - format("// foo foo foo foo foo foo foo foo foo foo foo foo\n", - Style)); + EXPECT_EQ( + "// foo foo foo foo\n" + "// foo foo foo foo\n" + "// foo foo foo foo\n", + format("// foo foo foo foo foo foo foo foo foo foo foo foo\n", Style)); EXPECT_EQ("int a = /* long block\n" " comment */\n" @@ -11273,8 +11306,8 @@ #define EXPECT_ALL_STYLES_EQUAL(Styles) \ for (size_t i = 1; i < Styles.size(); ++i) \ - EXPECT_EQ(Styles[0], Styles[i]) << "Style #" << i << " of " << Styles.size() \ - << " differs from Style #0" + EXPECT_EQ(Styles[0], Styles[i]) \ + << "Style #" << i << " of " << Styles.size() << " differs from Style #0" TEST_F(FormatTest, GetsPredefinedStyleByName) { SmallVector<FormatStyle, 3> Styles; @@ -11466,8 +11499,7 @@ 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("PenaltyBreakAssignment: 1234", PenaltyBreakAssignment, 1234u); CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234", PenaltyBreakBeforeFirstCallParameter, 1234u); CHECK_PARSE("PenaltyBreakTemplateDeclaration: 1234", @@ -11528,15 +11560,15 @@ BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma); Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon; - CHECK_PARSE("BreakInheritanceList: BeforeComma", - BreakInheritanceList, FormatStyle::BILS_BeforeComma); - CHECK_PARSE("BreakInheritanceList: AfterColon", - BreakInheritanceList, FormatStyle::BILS_AfterColon); - CHECK_PARSE("BreakInheritanceList: BeforeColon", - BreakInheritanceList, FormatStyle::BILS_BeforeColon); + CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList, + FormatStyle::BILS_BeforeComma); + CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList, + FormatStyle::BILS_AfterColon); + CHECK_PARSE("BreakInheritanceList: BeforeColon", BreakInheritanceList, + FormatStyle::BILS_BeforeColon); // For backward compatibility: - CHECK_PARSE("BreakBeforeInheritanceComma: true", - BreakInheritanceList, FormatStyle::BILS_BeforeComma); + CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList, + FormatStyle::BILS_BeforeComma); Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, @@ -11640,16 +11672,16 @@ FormatStyle::RTBS_TopLevelDefinitions); Style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; - CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", AlwaysBreakTemplateDeclarations, - FormatStyle::BTDS_No); - CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine", AlwaysBreakTemplateDeclarations, - FormatStyle::BTDS_MultiLine); - CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", AlwaysBreakTemplateDeclarations, - FormatStyle::BTDS_Yes); - CHECK_PARSE("AlwaysBreakTemplateDeclarations: false", AlwaysBreakTemplateDeclarations, - FormatStyle::BTDS_MultiLine); - CHECK_PARSE("AlwaysBreakTemplateDeclarations: true", AlwaysBreakTemplateDeclarations, - FormatStyle::BTDS_Yes); + CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", + AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_No); + CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine", + AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_MultiLine); + CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", + AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_Yes); + CHECK_PARSE("AlwaysBreakTemplateDeclarations: false", + AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_MultiLine); + CHECK_PARSE("AlwaysBreakTemplateDeclarations: true", + AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_Yes); Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None", @@ -12035,17 +12067,17 @@ "SomeLongTemplateVariableName<\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>", Style); - verifyFormat( - "bool smaller = 1 < bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", - Style); + verifyFormat("bool smaller = 1 < " + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" + " " + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", + Style); Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; - verifyFormat( - "SomeClass::Constructor() :\n" - "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa),\n" - "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa) {}", - Style); + verifyFormat("SomeClass::Constructor() :\n" + "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa),\n" + "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa) {}", + Style); } TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) { @@ -12311,15 +12343,17 @@ verifyFormat("void f() {\n" " other.other.other.other.other(\n" " x.begin(), x.end(),\n" - " [something, rather](int, int, int, int, int, int, int) { return 1; });\n" - "}\n"); - verifyFormat("void f() {\n" - " other.other.other.other.other(\n" - " x.begin(), x.end(),\n" - " [something, rather](int, int, int, int, int, int, int) {\n" - " //\n" - " });\n" + " [something, rather](int, int, int, int, int, int, int) { " + "return 1; });\n" "}\n"); + verifyFormat( + "void f() {\n" + " other.other.other.other.other(\n" + " x.begin(), x.end(),\n" + " [something, rather](int, int, int, int, int, int, int) {\n" + " //\n" + " });\n" + "}\n"); verifyFormat("SomeFunction([]() { // A cool function...\n" " return 43;\n" "});"); @@ -12371,9 +12405,10 @@ verifyFormat("SomeFunction({[&] {\n" " // comment\n" "}});"); - verifyFormat("virtual aaaaaaaaaaaaaaaa(\n" - " std::function<bool()> bbbbbbbbbbbb = [&]() { return true; },\n" - " aaaaa aaaaaaaaa);"); + verifyFormat( + "virtual aaaaaaaaaaaaaaaa(\n" + " std::function<bool()> bbbbbbbbbbbb = [&]() { return true; },\n" + " aaaaa aaaaaaaaa);"); // Lambdas with return types. verifyFormat("int c = []() -> int { return 2; }();\n"); @@ -12404,77 +12439,77 @@ verifyFormat("[]() -> foo<5 < 2> { return {}; };"); verifyFormat("[]() -> foo<2 ? 1 : 0> { return {}; };"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 + 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 + 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 - 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 - 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 / 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 / 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 * 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 * 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 % 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 % 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 << 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 << 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<!5> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<!5> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<~5> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<~5> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 | 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 | 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 || 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 || 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 & 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 & 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 && 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 && 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 == 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 == 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 != 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 != 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 >= 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 >= 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 <= 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 <= 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<5 < 2> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<5 < 2> { return {}; }};\n" + "} // namespace bar"); verifyFormat("namespace bar {\n" - "// broken:\n" - "auto foo{[]() -> foo<2 ? 1 : 0> { return {}; }};\n" - "} // namespace bar"); + "// broken:\n" + "auto foo{[]() -> foo<2 ? 1 : 0> { return {}; }};\n" + "} // namespace bar"); verifyFormat("[]() -> a<1> {};"); verifyFormat("[]() -> a<1> { ; };"); verifyFormat("[]() -> a<1> { ; }();"); @@ -12522,8 +12557,8 @@ " },\n" " 1);\n"); - // A multi-line lambda passed as arg1 forces arg0 to be pushed out, just like the arg0 - // case above. + // A multi-line lambda passed as arg1 forces arg0 to be pushed out, just like + // the arg0 case above. auto Style = getGoogleStyle(); Style.BinPackArguments = false; verifyFormat("SomeFunction(\n" @@ -12542,23 +12577,25 @@ // A lambda with a very long line forces arg0 to be pushed out irrespective of // the BinPackArguments value (as long as the code is wide enough). - verifyFormat("something->SomeFunction(\n" - " a,\n" - " [this] {\n" - " D0000000000000000000000000000000000000000000000000000000000001();\n" - " },\n" - " b);\n"); + verifyFormat( + "something->SomeFunction(\n" + " a,\n" + " [this] {\n" + " " + "D0000000000000000000000000000000000000000000000000000000000001();\n" + " },\n" + " b);\n"); - // A multi-line lambda is pulled up as long as the introducer fits on the previous - // line and there are no further args. + // A multi-line lambda is pulled up as long as the introducer fits on the + // previous line and there are no further args. verifyFormat("function(1, [this, that] {\n" " //\n" "});\n"); verifyFormat("function([this, that] {\n" " //\n" "});\n"); - // FIXME: this format is not ideal and we should consider forcing the first arg - // onto its own line. + // FIXME: this format is not ideal and we should consider forcing the first + // arg onto its own line. verifyFormat("function(a, b, c, //\n" " d, [this, that] {\n" " //\n" @@ -13123,24 +13160,23 @@ " int k;")); // Don't reflow comments within disabled regions. - EXPECT_EQ( - "// clang-format off\n" - "// long long long long long long line\n" - "/* clang-format on */\n" - "/* long long long\n" - " * long long long\n" - " * line */\n" - "int i;\n" - "/* clang-format off */\n" - "/* long long long long long long line */\n", - format("// clang-format off\n" - "// long long long long long long line\n" - "/* clang-format on */\n" - "/* long long long long long long line */\n" - "int i;\n" - "/* clang-format off */\n" - "/* long long long long long long line */\n", - getLLVMStyleWithColumns(20))); + EXPECT_EQ("// clang-format off\n" + "// long long long long long long line\n" + "/* clang-format on */\n" + "/* long long long\n" + " * long long long\n" + " * line */\n" + "int i;\n" + "/* clang-format off */\n" + "/* long long long long long long line */\n", + format("// clang-format off\n" + "// long long long long long long line\n" + "/* clang-format on */\n" + "/* long long long long long long line */\n" + "int i;\n" + "/* clang-format off */\n" + "/* long long long long long long line */\n", + getLLVMStyleWithColumns(20))); } TEST_F(FormatTest, DoNotCrashOnInvalidInput) { @@ -13174,9 +13210,7 @@ format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces)); } -TEST_F(FormatTest, NoSpaceAfterSuper) { - verifyFormat("__super::FooBar();"); -} +TEST_F(FormatTest, NoSpaceAfterSuper) { verifyFormat("__super::FooBar();"); } TEST(FormatStyle, GetStyleWithEmptyFileName) { llvm::vfs::InMemoryFileSystem FS; @@ -13331,7 +13365,8 @@ EXPECT_EQ("using std::cin;\n" "using std::cout;", format("using std::cout;\n" - "using std::cin;", getGoogleStyle())); + "using std::cin;", + getGoogleStyle())); } TEST_F(FormatTest, UTF8CharacterLiteralCpp03) { @@ -13348,10 +13383,8 @@ } TEST_F(FormatTest, DoNotFormatLikelyXml) { - EXPECT_EQ("<!-- ;> -->", - format("<!-- ;> -->", getGoogleStyle())); - EXPECT_EQ(" <!-- >; -->", - format(" <!-- >; -->", getGoogleStyle())); + EXPECT_EQ("<!-- ;> -->", format("<!-- ;> -->", getGoogleStyle())); + EXPECT_EQ(" <!-- >; -->", format(" <!-- >; -->", getGoogleStyle())); } TEST_F(FormatTest, StructuredBindings) { @@ -13371,13 +13404,16 @@ 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("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();")); + 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(); @@ -13404,11 +13440,15 @@ 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 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};")); + 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; @@ -13424,7 +13464,8 @@ EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.m", "")); EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.mm", "")); EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "")); - EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.h", "@interface Foo\n@end\n")); + EXPECT_EQ(FormatStyle::LK_ObjC, + guessLanguage("foo.h", "@interface Foo\n@end\n")); EXPECT_EQ( FormatStyle::LK_ObjC, guessLanguage("foo.h", "#define TRY(x, y) @try { x; } @finally { y; }")); @@ -13432,7 +13473,8 @@ guessLanguage("foo.h", "#define AVAIL(x) @available(x, *))")); EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.h", "@class Foo;")); EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo", "")); - EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo", "@interface Foo\n@end\n")); + EXPECT_EQ(FormatStyle::LK_ObjC, + guessLanguage("foo", "@interface Foo\n@end\n")); EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.h", "int DoStuff(CGRect rect);\n")); EXPECT_EQ( @@ -13494,36 +13536,36 @@ } TEST_F(FormatTest, GuessedLanguageWithInlineAsmClobbers) { - EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", - "void f() {\n" - " asm (\"mov %[e], %[d]\"\n" - " : [d] \"=rm\" (d)\n" - " [e] \"rm\" (*e));\n" - "}")); - EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", - "void f() {\n" - " _asm (\"mov %[e], %[d]\"\n" - " : [d] \"=rm\" (d)\n" - " [e] \"rm\" (*e));\n" - "}")); - EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", - "void f() {\n" - " __asm (\"mov %[e], %[d]\"\n" - " : [d] \"=rm\" (d)\n" - " [e] \"rm\" (*e));\n" - "}")); - EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", - "void f() {\n" - " __asm__ (\"mov %[e], %[d]\"\n" - " : [d] \"=rm\" (d)\n" - " [e] \"rm\" (*e));\n" - "}")); - EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", - "void f() {\n" - " asm (\"mov %[e], %[d]\"\n" - " : [d] \"=rm\" (d),\n" - " [e] \"rm\" (*e));\n" - "}")); + EXPECT_EQ(FormatStyle::LK_Cpp, + guessLanguage("foo.h", "void f() {\n" + " asm (\"mov %[e], %[d]\"\n" + " : [d] \"=rm\" (d)\n" + " [e] \"rm\" (*e));\n" + "}")); + EXPECT_EQ(FormatStyle::LK_Cpp, + guessLanguage("foo.h", "void f() {\n" + " _asm (\"mov %[e], %[d]\"\n" + " : [d] \"=rm\" (d)\n" + " [e] \"rm\" (*e));\n" + "}")); + EXPECT_EQ(FormatStyle::LK_Cpp, + guessLanguage("foo.h", "void f() {\n" + " __asm (\"mov %[e], %[d]\"\n" + " : [d] \"=rm\" (d)\n" + " [e] \"rm\" (*e));\n" + "}")); + EXPECT_EQ(FormatStyle::LK_Cpp, + guessLanguage("foo.h", "void f() {\n" + " __asm__ (\"mov %[e], %[d]\"\n" + " : [d] \"=rm\" (d)\n" + " [e] \"rm\" (*e));\n" + "}")); + EXPECT_EQ(FormatStyle::LK_Cpp, + guessLanguage("foo.h", "void f() {\n" + " asm (\"mov %[e], %[d]\"\n" + " : [d] \"=rm\" (d),\n" + " [e] \"rm\" (*e));\n" + "}")); EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "void f() {\n" " asm volatile (\"mov %[e], %[d]\"\n" Index: clang/tools/clang-format/ClangFormat.cpp =================================================================== --- clang/tools/clang-format/ClangFormat.cpp +++ clang/tools/clang-format/ClangFormat.cpp @@ -51,13 +51,14 @@ "Can only be used with one input file."), cl::cat(ClangFormatCategory)); static cl::list<std::string> -LineRanges("lines", cl::desc("<start line>:<end line> - format a range of\n" - "lines (both 1-based).\n" - "Multiple ranges can be formatted by specifying\n" - "several -lines arguments.\n" - "Can't be used with -offset and -length.\n" - "Can only be used with one input file."), - cl::cat(ClangFormatCategory)); + LineRanges("lines", + cl::desc("<start line>:<end line> - format a range of\n" + "lines (both 1-based).\n" + "Multiple ranges can be formatted by specifying\n" + "several -lines arguments.\n" + "Can't be used with -offset and -length.\n" + "Can only be used with one input file."), + cl::cat(ClangFormatCategory)); static cl::opt<std::string> Style("style", cl::desc(clang::format::StyleOptionHelpDescription), cl::init(clang::format::DefaultFormatStyle), @@ -72,12 +73,12 @@ cl::init(clang::format::DefaultFallbackStyle), cl::cat(ClangFormatCategory)); -static cl::opt<std::string> -AssumeFileName("assume-filename", - cl::desc("When reading from stdin, clang-format assumes this\n" - "filename to look for a style config file (with\n" - "-style=file) and to determine the language."), - cl::init("<stdin>"), cl::cat(ClangFormatCategory)); +static cl::opt<std::string> AssumeFileName( + "assume-filename", + cl::desc("When reading from stdin, clang-format assumes this\n" + "filename to look for a style config file (with\n" + "-style=file) and to determine the language."), + cl::init("<stdin>"), cl::cat(ClangFormatCategory)); static cl::opt<bool> Inplace("i", cl::desc("Inplace edit <file>s, if specified."), @@ -107,6 +108,11 @@ Verbose("verbose", cl::desc("If set, shows the list of processed files"), cl::cat(ClangFormatCategory)); +static cl::opt<bool> + KeepLineBreaks("keep-line-breaks", + cl::desc("If set, keeps all existing line breaks"), + cl::cat(ClangFormatCategory)); + static cl::list<std::string> FileNames(cl::Positional, cl::desc("[<file> ...]"), cl::cat(ClangFormatCategory)); @@ -240,7 +246,9 @@ } // Returns true on error. -static bool format(StringRef FileName) { +static bool +format(StringRef FileName, + ExtraFormattingOptions ExtraOptions = ExtraFormattingOptions::None) { if (!OutputXML && Inplace && FileName == "-") { errs() << "error: cannot use -i when reading from stdin.\n"; return false; @@ -248,8 +256,8 @@ // On Windows, overwriting a file with an open file mapping doesn't work, // so read the whole file into memory when formatting in-place. ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = - !OutputXML && Inplace ? MemoryBuffer::getFileAsStream(FileName) : - MemoryBuffer::getFileOrSTDIN(FileName); + !OutputXML && Inplace ? MemoryBuffer::getFileAsStream(FileName) + : MemoryBuffer::getFileOrSTDIN(FileName); if (std::error_code EC = CodeOrErr.getError()) { errs() << EC.message() << "\n"; return true; @@ -263,20 +271,21 @@ // https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding // for more information. StringRef BufStr = Code->getBuffer(); - const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr) - .StartsWith(llvm::StringLiteral::withInnerNUL("\x00\x00\xFE\xFF"), - "UTF-32 (BE)") - .StartsWith(llvm::StringLiteral::withInnerNUL("\xFF\xFE\x00\x00"), - "UTF-32 (LE)") - .StartsWith("\xFE\xFF", "UTF-16 (BE)") - .StartsWith("\xFF\xFE", "UTF-16 (LE)") - .StartsWith("\x2B\x2F\x76", "UTF-7") - .StartsWith("\xF7\x64\x4C", "UTF-1") - .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC") - .StartsWith("\x0E\xFE\xFF", "SCSU") - .StartsWith("\xFB\xEE\x28", "BOCU-1") - .StartsWith("\x84\x31\x95\x33", "GB-18030") - .Default(nullptr); + const char *InvalidBOM = + llvm::StringSwitch<const char *>(BufStr) + .StartsWith(llvm::StringLiteral::withInnerNUL("\x00\x00\xFE\xFF"), + "UTF-32 (BE)") + .StartsWith(llvm::StringLiteral::withInnerNUL("\xFF\xFE\x00\x00"), + "UTF-32 (LE)") + .StartsWith("\xFE\xFF", "UTF-16 (BE)") + .StartsWith("\xFF\xFE", "UTF-16 (LE)") + .StartsWith("\x2B\x2F\x76", "UTF-7") + .StartsWith("\xF7\x64\x4C", "UTF-1") + .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC") + .StartsWith("\x0E\xFE\xFF", "SCSU") + .StartsWith("\xFB\xEE\x28", "BOCU-1") + .StartsWith("\x84\x31\x95\x33", "GB-18030") + .Default(nullptr); if (InvalidBOM) { errs() << "error: encoding with unsupported byte order mark \"" @@ -312,8 +321,9 @@ // Get new affected ranges after sorting `#includes`. Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); FormattingAttemptStatus Status; - Replacements FormatChanges = reformat(*FormatStyle, *ChangedCode, Ranges, - AssumedFileName, &Status); + Replacements FormatChanges = + reformat(*FormatStyle, ExtraOptions, *ChangedCode, Ranges, + AssumedFileName, &Status); Replaces = Replaces.merge(FormatChanges); if (OutputXML) { outs() << "<?xml version='1.0'?>\n<replacements " @@ -360,8 +370,8 @@ return false; } -} // namespace format -} // namespace clang +} // namespace format +} // namespace clang static void PrintVersion(raw_ostream &OS) { OS << clang::getClangToolFullVersion("clang-format") << '\n'; @@ -418,12 +428,21 @@ return 0; } + clang::format::ExtraFormattingOptions ExtraOptions = + clang::format::ExtraFormattingOptions::None; + if (KeepLineBreaks.getNumOccurrences() != 0) { + ExtraOptions = + ExtraOptions | + clang::format::ExtraFormattingOptions::KeepLineBreaksForNonEmptyLines; + } + bool Error = false; if (FileNames.empty()) { Error = clang::format::format("-"); return Error ? 1 : 0; } - if (FileNames.size() != 1 && (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty())) { + if (FileNames.size() != 1 && + (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty())) { errs() << "error: -offset, -length and -lines can only be used for " "single file.\n"; return 1; @@ -431,7 +450,7 @@ for (const auto &FileName : FileNames) { if (Verbose) errs() << "Formatting " << FileName << "\n"; - Error |= clang::format::format(FileName); + Error |= clang::format::format(FileName, ExtraOptions); } return Error ? 1 : 0; } Index: clang/lib/Format/UnwrappedLineParser.h =================================================================== --- clang/lib/Format/UnwrappedLineParser.h +++ clang/lib/Format/UnwrappedLineParser.h @@ -77,7 +77,8 @@ UnwrappedLineParser(const FormatStyle &Style, const AdditionalKeywords &Keywords, unsigned FirstStartColumn, ArrayRef<FormatToken *> Tokens, - UnwrappedLineConsumer &Callback); + UnwrappedLineConsumer &Callback, + ExtraFormattingOptions FormattingOptions); void parse(); @@ -274,6 +275,8 @@ // does not start at the beginning of the file. unsigned FirstStartColumn; + ExtraFormattingOptions FormattingOptions; + friend class ScopedLineState; friend class CompoundStatementIndenter; }; Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -222,11 +222,10 @@ } // end anonymous namespace -UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style, - const AdditionalKeywords &Keywords, - unsigned FirstStartColumn, - ArrayRef<FormatToken *> Tokens, - UnwrappedLineConsumer &Callback) +UnwrappedLineParser::UnwrappedLineParser( + const FormatStyle &Style, const AdditionalKeywords &Keywords, + unsigned FirstStartColumn, ArrayRef<FormatToken *> Tokens, + UnwrappedLineConsumer &Callback, ExtraFormattingOptions FormattingOptions) : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), CurrentLines(&Lines), Style(Style), Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr), @@ -234,7 +233,8 @@ IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None ? IG_Rejected : IG_Inited), - IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn) {} + IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn), + FormattingOptions(FormattingOptions) {} void UnwrappedLineParser::reset() { PPBranchLevel = -1; @@ -2613,6 +2613,10 @@ else readTokenWithJavaScriptASI(); FormatTok->Previous = Previous; + + + if (FormatTok->NewlinesBefore && alwaysKeepLineBreaks(FormattingOptions)) + FormatTok->MustBreakBefore = true; } void UnwrappedLineParser::distributeComments( Index: clang/lib/Format/UnwrappedLineFormatter.h =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.h +++ clang/lib/Format/UnwrappedLineFormatter.h @@ -32,9 +32,11 @@ const FormatStyle &Style, const AdditionalKeywords &Keywords, const SourceManager &SourceMgr, + ExtraFormattingOptions FormattingOptions, FormattingAttemptStatus *Status) : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), - Keywords(Keywords), SourceMgr(SourceMgr), Status(Status) {} + Keywords(Keywords), SourceMgr(SourceMgr), + FormattingOptions(FormattingOptions), Status(Status) {} /// Format the current block and return the penalty. unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, @@ -67,6 +69,7 @@ const FormatStyle &Style; const AdditionalKeywords &Keywords; const SourceManager &SourceMgr; + ExtraFormattingOptions FormattingOptions; FormattingAttemptStatus *Status; }; } // end namespace format Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -682,11 +682,12 @@ /// Base class for classes that format one \c AnnotatedLine. class LineFormatter { public: - LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, - const FormatStyle &Style, - UnwrappedLineFormatter *BlockFormatter) + LineFormatter( + ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, + const FormatStyle &Style, UnwrappedLineFormatter *BlockFormatter, + ExtraFormattingOptions FormattingOptions = ExtraFormattingOptions::None) : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), - BlockFormatter(BlockFormatter) {} + BlockFormatter(BlockFormatter), FormattingOptions(FormattingOptions) {} virtual ~LineFormatter() {} /// Formats an \c AnnotatedLine and returns the penalty. @@ -726,7 +727,8 @@ // assert so that we can simply call this function for all tokens. return true; - if (NewLine) { + if (NewLine || (Previous.Children[0]->First->MustBreakBefore && + alwaysKeepLineBreaks(FormattingOptions))) { int AdditionalIndent = State.Stack.back().Indent - Previous.Children[0]->Level * Style.IndentWidth; @@ -776,6 +778,7 @@ WhitespaceManager *Whitespaces; const FormatStyle &Style; UnwrappedLineFormatter *BlockFormatter; + ExtraFormattingOptions FormattingOptions; }; /// Formatter that keeps the existing line breaks. @@ -784,8 +787,10 @@ NoColumnLimitLineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, const FormatStyle &Style, - UnwrappedLineFormatter *BlockFormatter) - : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} + UnwrappedLineFormatter *BlockFormatter, + ExtraFormattingOptions FormattingOptions) + : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter, + FormattingOptions) {} /// Formats the line, simply keeping all of the input's line breaking /// decisions. @@ -821,7 +826,8 @@ LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun); while (State.NextToken) { - formatChildren(State, /*Newline=*/false, DryRun, Penalty); + bool Newline = false; + formatChildren(State, Newline, DryRun, Penalty); Indenter->addTokenToState( State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun); } @@ -1076,8 +1082,9 @@ !Style.JavaScriptWrapImports)) || (Style.isCSharp() && TheLine.InPPDirective); // don't split #regions in C# - if (Style.ColumnLimit == 0) - NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this) + if (Style.ColumnLimit == 0 || alwaysKeepLineBreaks(FormattingOptions)) + NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this, + FormattingOptions) .formatLine(TheLine, NextStartColumn + Indent, FirstLine ? FirstStartColumn : 0, DryRun); else if (FitsIntoOneLine) Index: clang/lib/Format/TokenAnalyzer.h =================================================================== --- clang/lib/Format/TokenAnalyzer.h +++ clang/lib/Format/TokenAnalyzer.h @@ -79,7 +79,9 @@ class TokenAnalyzer : public UnwrappedLineConsumer { public: - TokenAnalyzer(const Environment &Env, const FormatStyle &Style); + TokenAnalyzer( + const Environment &Env, const FormatStyle &Style, + ExtraFormattingOptions FormattingOptions = ExtraFormattingOptions::None); std::pair<tooling::Replacements, unsigned> process(); @@ -100,6 +102,7 @@ AffectedRangeManager AffectedRangeMgr; SmallVector<SmallVector<UnwrappedLine, 16>, 2> UnwrappedLines; encoding::Encoding Encoding; + ExtraFormattingOptions FormattingOptions; }; } // end namespace format Index: clang/lib/Format/TokenAnalyzer.cpp =================================================================== --- clang/lib/Format/TokenAnalyzer.cpp +++ clang/lib/Format/TokenAnalyzer.cpp @@ -48,12 +48,14 @@ } } -TokenAnalyzer::TokenAnalyzer(const Environment &Env, const FormatStyle &Style) +TokenAnalyzer::TokenAnalyzer(const Environment &Env, const FormatStyle &Style, + ExtraFormattingOptions FormattingOptions) : Style(Style), Env(Env), AffectedRangeMgr(Env.getSourceManager(), Env.getCharRanges()), UnwrappedLines(1), Encoding(encoding::detectEncoding( - Env.getSourceManager().getBufferData(Env.getFileID()))) { + Env.getSourceManager().getBufferData(Env.getFileID()))), + FormattingOptions(FormattingOptions) { LLVM_DEBUG( llvm::dbgs() << "File encoding: " << (Encoding == encoding::Encoding_UTF8 ? "UTF8" : "unknown") @@ -68,7 +70,8 @@ Env.getFirstStartColumn(), Style, Encoding); UnwrappedLineParser Parser(Style, Tokens.getKeywords(), - Env.getFirstStartColumn(), Tokens.lex(), *this); + Env.getFirstStartColumn(), Tokens.lex(), *this, + FormattingOptions); Parser.parse(); assert(UnwrappedLines.rbegin()->empty()); unsigned Penalty = 0; Index: clang/lib/Format/FormatInternal.h =================================================================== --- clang/lib/Format/FormatInternal.h +++ clang/lib/Format/FormatInternal.h @@ -73,6 +73,7 @@ reformat(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, + ExtraFormattingOptions FormattingOptions, FormattingAttemptStatus *Status); } // namespace internal Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -605,8 +605,8 @@ return Style; FormatStyle Expanded = Style; Expanded.BraceWrapping = {false, false, false, false, false, false, - false, false, false, false, false, - false, false, true, true, true}; + false, false, false, false, false, false, + false, true, true, true}; switch (Style.BreakBeforeBraces) { case FormatStyle::BS_Linux: Expanded.BraceWrapping.AfterClass = true; @@ -683,8 +683,8 @@ LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; LLVMStyle.BraceWrapping = {false, false, false, false, false, false, - false, false, false, false, false, - false, false, true, true, true}; + false, false, false, false, false, false, + false, true, true, true}; LLVMStyle.BreakAfterJavaFieldAnnotations = false; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; @@ -1239,8 +1239,9 @@ class Formatter : public TokenAnalyzer { public: Formatter(const Environment &Env, const FormatStyle &Style, + ExtraFormattingOptions FormattingOptions, FormattingAttemptStatus *Status) - : TokenAnalyzer(Env, Style), Status(Status) {} + : TokenAnalyzer(Env, Style, FormattingOptions), Status(Status) {} std::pair<tooling::Replacements, unsigned> analyze(TokenAnnotator &Annotator, @@ -1263,7 +1264,7 @@ unsigned Penalty = UnwrappedLineFormatter(&Indenter, &Whitespaces, Style, Tokens.getKeywords(), Env.getSourceManager(), - Status) + FormattingOptions, Status) .format(AnnotatedLines, /*DryRun=*/false, /*AdditionalIndent=*/0, /*FixBadIndentation=*/false, @@ -1769,8 +1770,8 @@ static void sortCppIncludes(const FormatStyle &Style, const SmallVectorImpl<IncludeDirective> &Includes, ArrayRef<tooling::Range> Ranges, StringRef FileName, - StringRef Code, - tooling::Replacements &Replaces, unsigned *Cursor) { + StringRef Code, tooling::Replacements &Replaces, + unsigned *Cursor) { unsigned IncludesBeginOffset = Includes.front().Offset; unsigned IncludesEndOffset = Includes.back().Offset + Includes.back().Text.size(); @@ -2247,6 +2248,7 @@ reformat(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, + ExtraFormattingOptions FormattingOptions, FormattingAttemptStatus *Status) { FormatStyle Expanded = expandPresets(Style); if (Expanded.DisableFormat) @@ -2280,7 +2282,7 @@ }); Passes.emplace_back([&](const Environment &Env) { - return Formatter(Env, Expanded, Status).process(); + return Formatter(Env, Expanded, FormattingOptions, Status).process(); }); auto Env = @@ -2317,7 +2319,21 @@ return internal::reformat(Style, Code, Ranges, /*FirstStartColumn=*/0, /*NextStartColumn=*/0, - /*LastStartColumn=*/0, FileName, Status) + /*LastStartColumn=*/0, FileName, + ExtraFormattingOptions::None, Status) + .first; +} + +tooling::Replacements reformat(const FormatStyle &Style, + ExtraFormattingOptions FormattingOptions, + StringRef Code, ArrayRef<tooling::Range> Ranges, + StringRef FileName, + FormattingAttemptStatus *Status) { + return internal::reformat(Style, Code, Ranges, + /*FirstStartColumn=*/0, + /*NextStartColumn=*/0, + /*LastStartColumn=*/0, FileName, FormattingOptions, + Status) .first; } Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -1573,6 +1573,7 @@ std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat( RawStringStyle, RawText, {tooling::Range(0, RawText.size())}, FirstStartColumn, NextStartColumn, LastStartColumn, "<stdin>", + ExtraFormattingOptions::None, /*Status=*/nullptr); auto NewCode = applyAllReplacements(RawText, Fixes.first); Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -449,38 +449,38 @@ /// Different ways to break after the template declaration. enum BreakTemplateDeclarationsStyle { - /// Do not force break before declaration. - /// ``PenaltyBreakTemplateDeclaration`` is taken into account. - /// \code - /// template <typename T> T foo() { - /// } - /// template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa, - /// int bbbbbbbbbbbbbbbbbbbbb) { - /// } - /// \endcode - BTDS_No, - /// Force break after template declaration only when the following - /// declaration spans multiple lines. - /// \code - /// template <typename T> T foo() { - /// } - /// template <typename T> - /// T foo(int aaaaaaaaaaaaaaaaaaaaa, - /// int bbbbbbbbbbbbbbbbbbbbb) { - /// } - /// \endcode - BTDS_MultiLine, - /// Always break after template declaration. - /// \code - /// template <typename T> - /// T foo() { - /// } - /// template <typename T> - /// T foo(int aaaaaaaaaaaaaaaaaaaaa, - /// int bbbbbbbbbbbbbbbbbbbbb) { - /// } - /// \endcode - BTDS_Yes + /// Do not force break before declaration. + /// ``PenaltyBreakTemplateDeclaration`` is taken into account. + /// \code + /// template <typename T> T foo() { + /// } + /// template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa, + /// int bbbbbbbbbbbbbbbbbbbbb) { + /// } + /// \endcode + BTDS_No, + /// Force break after template declaration only when the following + /// declaration spans multiple lines. + /// \code + /// template <typename T> T foo() { + /// } + /// template <typename T> + /// T foo(int aaaaaaaaaaaaaaaaaaaaa, + /// int bbbbbbbbbbbbbbbbbbbbb) { + /// } + /// \endcode + BTDS_MultiLine, + /// Always break after template declaration. + /// \code + /// template <typename T> + /// T foo() { + /// } + /// template <typename T> + /// T foo(int aaaaaaaaaaaaaaaaaaaaa, + /// int bbbbbbbbbbbbbbbbbbbbb) { + /// } + /// \endcode + BTDS_Yes }; /// The template declaration breaking style to use. @@ -1062,7 +1062,8 @@ /// \code /// true: /// SomeClass::Constructor() - /// : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) { + /// : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), + /// aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) { /// return 0; /// } /// @@ -1174,9 +1175,9 @@ /// Indent case labels one level from the switch statement. /// - /// When ``false``, use the same indentation level as for the switch statement. - /// Switch statement body is always indented one level more than case labels. - /// \code + /// When ``false``, use the same indentation level as for the switch + /// statement. Switch statement body is always indented one level more than + /// case labels. \code /// false: true: /// switch (fool) { vs. switch (fool) { /// case 1: case 1: @@ -1315,7 +1316,8 @@ /// } from 'some/module.js' /// /// false: - /// import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" + /// import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, + /// VeryLongImportsAreAnnoying,} from "some/module.js" /// \endcode bool JavaScriptWrapImports; @@ -1602,13 +1604,17 @@ /// If ``true``, clang-format will attempt to re-flow comments. /// \code /// false: - /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information - /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */ + /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty + /// of information + /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with + /// plenty of information */ /// /// true: - /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of + /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty + /// of /// // information - /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of + /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with + /// plenty of /// * information */ /// \endcode bool ReflowComments; @@ -2089,6 +2095,31 @@ unsigned Line = 0; }; +enum class ExtraFormattingOptions { + None = 0x0, + KeepLineBreaksForNonEmptyLines = 0x1 +}; + +inline ExtraFormattingOptions operator|(ExtraFormattingOptions lhs, + ExtraFormattingOptions rhs) { + using T = std::underlying_type_t<ExtraFormattingOptions>; + return static_cast<ExtraFormattingOptions>(static_cast<T>(lhs) | + static_cast<T>(rhs)); +} + +inline ExtraFormattingOptions operator&(ExtraFormattingOptions lhs, + ExtraFormattingOptions rhs) { + using T = std::underlying_type_t<ExtraFormattingOptions>; + return static_cast<ExtraFormattingOptions>(static_cast<T>(lhs) & + static_cast<T>(rhs)); +} + +inline bool alwaysKeepLineBreaks(ExtraFormattingOptions FormattingOptions) { + return (FormattingOptions & + ExtraFormattingOptions::KeepLineBreaksForNonEmptyLines) != + ExtraFormattingOptions::None; +} + /// Reformats the given \p Ranges in \p Code. /// /// Each range is extended on either end to its next bigger logic unit, i.e. @@ -2110,8 +2141,13 @@ /// a non-recoverable syntax error. tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, - StringRef FileName, - bool *IncompleteFormat); + StringRef FileName, bool *IncompleteFormat); + +tooling::Replacements reformat(const FormatStyle &Style, + ExtraFormattingOptions FormattingOptions, + StringRef Code, ArrayRef<tooling::Range> Ranges, + StringRef FileName = "<stdin>", + FormattingAttemptStatus *Status = nullptr); /// Clean up any erroneous/redundant code in the given \p Ranges in \p /// Code. @@ -2222,6 +2258,6 @@ namespace std { template <> struct is_error_code_enum<clang::format::ParseError> : std::true_type {}; -} +} // namespace std #endif // LLVM_CLANG_FORMAT_FORMAT_H
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits