Prefer similar line breaks.

This adds a penalty for clang-format for each break that occurs in
a set of parentheses (including fake parenthesis that determine
the range of certain operator precendences) that have not yet been
broken. Thereby, clang-format prefers similar line breaks.

This fixes llvm.org/PR15506.

Before:
const int kTrackingOptions =
    NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited |
    NSTrackingActiveAlways;

After:
const int kTrackingOptions = NSTrackingMouseMoved |
                             NSTrackingMouseEnteredAndExited |
                             NSTrackingActiveAlways;

Also removed ParenState::ForFakeParenthesis which has become unused.

llvm-svn: 185822
This commit is contained in:
Daniel Jasper 2013-07-08 14:25:23 +00:00
parent 2db29ef467
commit ee7539a387
2 changed files with 33 additions and 20 deletions

View File

@ -140,7 +140,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.PenaltyBreakComment = 45; LLVMStyle.PenaltyBreakComment = 45;
LLVMStyle.PenaltyBreakString = 1000; LLVMStyle.PenaltyBreakString = 1000;
LLVMStyle.PenaltyExcessCharacter = 1000000; LLVMStyle.PenaltyExcessCharacter = 1000000;
LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 75; LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
LLVMStyle.PointerBindsToType = false; LLVMStyle.PointerBindsToType = false;
LLVMStyle.SpacesBeforeTrailingComments = 1; LLVMStyle.SpacesBeforeTrailingComments = 1;
LLVMStyle.SpacesInBracedLists = true; LLVMStyle.SpacesInBracedLists = true;
@ -320,7 +320,7 @@ private:
AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false), AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0), NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
NestedNameSpecifierContinuation(0), CallContinuation(0), NestedNameSpecifierContinuation(0), CallContinuation(0),
VariablePos(0), ForFakeParenthesis(false) {} VariablePos(0), ContainsLineBreak(false) {}
/// \brief The position to which a specific parenthesis level needs to be /// \brief The position to which a specific parenthesis level needs to be
/// indented. /// indented.
@ -379,12 +379,12 @@ private:
/// Used to align further variables if necessary. /// Used to align further variables if necessary.
unsigned VariablePos; unsigned VariablePos;
/// \brief \c true if this \c ParenState was created for a fake parenthesis. /// \brief \c true if this \c ParenState already contains a line-break.
/// ///
/// Does not need to be considered for memoization / the comparison function /// The first line break in a certain \c ParenState causes extra penalty so
/// as otherwise identical states will have the same fake/non-fake /// that clang-format prefers similar breaks, i.e. breaks in the same
/// \c ParenStates. /// parenthesis.
bool ForFakeParenthesis; bool ContainsLineBreak;
bool operator<(const ParenState &Other) const { bool operator<(const ParenState &Other) const {
if (Indent != Other.Indent) if (Indent != Other.Indent)
@ -411,6 +411,8 @@ private:
return CallContinuation < Other.CallContinuation; return CallContinuation < Other.CallContinuation;
if (VariablePos != Other.VariablePos) if (VariablePos != Other.VariablePos)
return VariablePos < Other.VariablePos; return VariablePos < Other.VariablePos;
if (ContainsLineBreak != Other.ContainsLineBreak)
return ContainsLineBreak < Other.ContainsLineBreak;
return false; return false;
} }
}; };
@ -510,6 +512,7 @@ private:
unsigned ContinuationIndent = unsigned ContinuationIndent =
std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4; std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4;
if (Newline) { if (Newline) {
State.Stack.back().ContainsLineBreak = true;
if (Current.is(tok::r_brace)) { if (Current.is(tok::r_brace)) {
State.Column = Line.Level * Style.IndentWidth; State.Column = Line.Level * Style.IndentWidth;
} else if (Current.is(tok::string_literal) && } else if (Current.is(tok::string_literal) &&
@ -728,7 +731,7 @@ private:
E = Current.FakeLParens.rend(); E = Current.FakeLParens.rend();
I != E; ++I) { I != E; ++I) {
ParenState NewParenState = State.Stack.back(); ParenState NewParenState = State.Stack.back();
NewParenState.ForFakeParenthesis = true; NewParenState.ContainsLineBreak = false;
NewParenState.Indent = NewParenState.Indent =
std::max(std::max(State.Column, NewParenState.Indent), std::max(std::max(State.Column, NewParenState.Indent),
State.Stack.back().LastSpace); State.Stack.back().LastSpace);
@ -1013,8 +1016,11 @@ private:
return; return;
if (!NewLine && mustBreak(PreviousNode->State)) if (!NewLine && mustBreak(PreviousNode->State))
return; return;
if (NewLine) if (NewLine) {
if (!PreviousNode->State.Stack.back().ContainsLineBreak)
Penalty += 15;
Penalty += PreviousNode->State.NextToken->SplitPenalty; Penalty += PreviousNode->State.NextToken->SplitPenalty;
}
StateNode *Node = new (Allocator.Allocate()) StateNode *Node = new (Allocator.Allocate())
StateNode(PreviousNode->State, NewLine, PreviousNode); StateNode(PreviousNode->State, NewLine, PreviousNode);

View File

@ -773,11 +773,11 @@ TEST_F(FormatTest, UnderstandsBlockComments) {
EXPECT_EQ( EXPECT_EQ(
"void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaa) { /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaa */\n" " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
"}", "}",
format("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" format("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaa ,\n" " aaaaaaaaaaaaaaaaaa ,\n"
" aaaaaaaaaaaaaaaaaa) { /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaa */\n" " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
"}")); "}"));
FormatStyle NoBinPacking = getLLVMStyle(); FormatStyle NoBinPacking = getLLVMStyle();
@ -2558,6 +2558,12 @@ TEST_F(FormatTest, BreaksDesireably) {
" x, y);", " x, y);",
format("f(g(h(a, // comment\n" format("f(g(h(a, // comment\n"
" b, c), d, e), x, y);")); " b, c), d, e), x, y);"));
// Prefer breaking similar line breaks.
verifyFormat(
"const int kTrackingOptions = NSTrackingMouseMoved |\n"
" NSTrackingMouseEnteredAndExited |\n"
" NSTrackingActiveAlways;");
} }
TEST_F(FormatTest, FormatsOneParameterPerLineIfNecessary) { TEST_F(FormatTest, FormatsOneParameterPerLineIfNecessary) {
@ -2696,9 +2702,10 @@ TEST_F(FormatTest, AlignsAfterAssignments) {
verifyFormat( verifyFormat(
"int Result = (aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" "int Result = (aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n"
" aaaaaaaaaaaaaaaaaaaaaaaaa);"); " aaaaaaaaaaaaaaaaaaaaaaaaa);");
verifyFormat("double LooooooooooooooooooooooooongResult =\n" verifyFormat(
" aaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaa +\n" "double LooooooooooooooooooooooooongResult = aaaaaaaaaaaaaaaaaaaaaaaa +\n"
" aaaaaaaaaaaaaaaaaaaaaaaa;"); " aaaaaaaaaaaaaaaaaaaaaaaa +\n"
" aaaaaaaaaaaaaaaaaaaaaaaa;");
} }
TEST_F(FormatTest, AlignsAfterReturn) { TEST_F(FormatTest, AlignsAfterReturn) {
@ -2723,9 +2730,9 @@ TEST_F(FormatTest, AlignsAfterReturn) {
TEST_F(FormatTest, BreaksConditionalExpressions) { TEST_F(FormatTest, BreaksConditionalExpressions) {
verifyFormat( verifyFormat(
"aaaa(aaaaaaaaaaaaaaaaaaaa,\n" "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
verifyFormat( verifyFormat(
"aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
@ -3000,9 +3007,9 @@ TEST_F(FormatTest, WrapsAtFunctionCallsIfNecessary) {
verifyFormat( verifyFormat(
"aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" "aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
" .aaaaaaaaaaaaaaa(\n" " .aaaaaaaaaaaaaaa(aa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" aa(aaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); " aaaaaaaaaaaaaaaaaaaaaaaaaaa));");
verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"