r297274 - [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
Krasimir Georgiev via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 8 04:54:51 PST 2017
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"
More information about the cfe-commits
mailing list