Author: krasimir Date: Wed Mar 8 06:54:50 2017 New Revision: 297274 URL: http://llvm.org/viewvc/llvm-project?rev=297274&view=rev Log: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
Summary: This patch makes ContinuationIndenter call breakProtrudingToken only if NoLineBreak and NoLineBreakInOperand is false. Previously, clang-format required two runs to converge on the following example with 24 columns: Note that the second operand shouldn't be splitted according to NoLineBreakInOperand, but the token breaker doesn't take that into account: ``` func(a, "long long long long", c); ``` After first run: ``` func(a, "long long " "long long", c); ``` After second run, where NoLineBreakInOperand is taken into account: ``` func(a, "long long " "long long", c); ``` With the patch, clang-format now obtains in one run: ``` func(a, "long long long" "long", c); ``` which is a better token split overall. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D30575 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=297274&r1=297273&r2=297274&view=diff ============================================================================== --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Wed Mar 8 06:54:50 2017 @@ -848,6 +848,8 @@ unsigned ContinuationIndenter::moveState (Current.IsMultiline ? Current.LastLineColumnWidth : State.Column + Current.ColumnWidth) - strlen("${"); + bool CanBreakProtrudingToken = !State.Stack.back().NoLineBreak && + !State.Stack.back().NoLineBreakInOperand; moveStatePastScopeOpener(State, Newline); moveStatePastFakeRParens(State); @@ -861,7 +863,9 @@ unsigned ContinuationIndenter::moveState State.Column += Current.ColumnWidth; State.NextToken = State.NextToken->Next; - unsigned Penalty = breakProtrudingToken(Current, State, DryRun); + unsigned Penalty = 0; + if (CanBreakProtrudingToken) + Penalty = breakProtrudingToken(Current, State, DryRun); if (State.Column > getColumnLimit(State)) { unsigned ExcessCharacters = State.Column - getColumnLimit(State); Penalty += Style.PenaltyExcessCharacter * ExcessCharacters; Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=297274&r1=297273&r2=297274&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Mar 8 06:54:50 2017 @@ -6471,8 +6471,9 @@ TEST_F(FormatTest, BreaksStringLiteralsW "_T(\"aaaaaaaaaaaaaa\")\n" "_T(\"aaaaaaaaaaaa\")", format(" _T(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")", Style)); - EXPECT_EQ("f(x, _T(\"aaaaaaaaa\")\n" - " _T(\"aaaaaa\"),\n" + EXPECT_EQ("f(x,\n" + " _T(\"aaaaaaaaaaaa\")\n" + " _T(\"aaa\"),\n" " z);", format("f(x, _T(\"aaaaaaaaaaaaaaa\"), z);", Style)); @@ -6504,6 +6505,90 @@ TEST_F(FormatTest, BreaksStringLiteralsW "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));")); } +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))); + // In a function call with three operands, the second must be broken with a + // line break before it. + EXPECT_EQ("func(a,\n" + " \"long long long \"\n" + " \"long\",\n" + " c);", + format("func(a, \"long long long long\", c);", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the third must be broken with a + // line break before it. + EXPECT_EQ("func(a, b,\n" + " \"long long long \"\n" + " \"long\");", + format("func(a, b, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, both the second and the third must + // be broken with a line break before them. + EXPECT_EQ("func(a,\n" + " \"long long long \"\n" + " \"long\",\n" + " \"long long long \"\n" + " \"long\");", + format("func(a, \"long long long long\", \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a chain of << with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("a << \"line line \"\n" + " \"line\";", + 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))); + // 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))); + // 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" + " \"line\"\n" + " << \"line line \"\n" + " \"line\";", + format("abcd << \"line line line\" << \"line line line\";", + 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))); + // In a chain of binary operators with three operands, the second must be + // broken with a line break before it. + EXPECT_EQ("abcd +\n" + " \"line line \"\n" + " \"line line\" +\n" + " e;", + format("abcd + \"line line line line\" + e;", + getLLVMStyleWithColumns(20))); + // In a function call with two operands, with AlignAfterOpenBracket enabled, + // the first must be broken with a line break before it. + FormatStyle Style = getLLVMStyleWithColumns(25); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + EXPECT_EQ("someFunction(\n" + " \"long long long \"\n" + " \"long\",\n" + " a);", + format("someFunction(\"long long long long\", a);", Style)); +} + TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) { EXPECT_EQ( "aaaaaaaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits