forked from OSchip/llvm-project
[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 llvm-svn: 297274
This commit is contained in:
parent
f82d68ff53
commit
bc05ebaa5a
|
@ -848,6 +848,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
|
|||
(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::moveStateToNextToken(LineState &State,
|
|||
|
||||
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;
|
||||
|
|
|
@ -6471,8 +6471,9 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) {
|
|||
"_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, BreaksStringLiteralsWithin_TMacro) {
|
|||
"_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"
|
||||
|
|
Loading…
Reference in New Issue