Fixes layout of right braces.

We now decide whether a newline should go before the closing brace
depending on whether a newline was inserted after the opening brace.

For example, we now insert a newline before '};' in:
static SomeClass WithALoooooooooooooooooooongName = {
  100000000, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"
};
... while not inserting a newline here:
static SomeClass = { a, b, c, d, e, f, g, h, i, j,
                     looooooooooooooooooooooooooooooooooongname,
                     looooooooooooooooooooooooooooooong };

Also fixes the formating of (column limit 25):
int x = {
  avariable,
  b(alongervariable)
};

llvm-svn: 172076
This commit is contained in:
Manuel Klimek 2013-01-10 15:58:26 +00:00
parent 92465285ab
commit 0ddd57a17b
2 changed files with 29 additions and 5 deletions

View File

@ -154,6 +154,7 @@ public:
State.Indent.push_back(Indent + 4); State.Indent.push_back(Indent + 4);
State.LastSpace.push_back(Indent); State.LastSpace.push_back(Indent);
State.FirstLessLess.push_back(0); State.FirstLessLess.push_back(0);
State.BreakBeforeClosingBrace.push_back(false);
State.ForLoopVariablePos = 0; State.ForLoopVariablePos = 0;
State.LineContainsContinuedForLoopSection = false; State.LineContainsContinuedForLoopSection = false;
State.StartOfLineLevel = 1; State.StartOfLineLevel = 1;
@ -223,6 +224,13 @@ private:
/// on a level. /// on a level.
std::vector<unsigned> FirstLessLess; std::vector<unsigned> FirstLessLess;
/// \brief Whether a newline needs to be inserted before the block's closing
/// brace.
///
/// We only want to insert a newline before the closing brace if there also
/// was a newline after the beginning left brace.
std::vector<bool> BreakBeforeClosingBrace;
/// \brief The column of the first variable in a for-loop declaration. /// \brief The column of the first variable in a for-loop declaration.
/// ///
/// Used to align the second variable if necessary. /// Used to align the second variable if necessary.
@ -262,6 +270,8 @@ private:
if (Other.LineContainsContinuedForLoopSection != if (Other.LineContainsContinuedForLoopSection !=
LineContainsContinuedForLoopSection) LineContainsContinuedForLoopSection)
return LineContainsContinuedForLoopSection; return LineContainsContinuedForLoopSection;
if (Other.BreakBeforeClosingBrace != BreakBeforeClosingBrace)
return Other.BreakBeforeClosingBrace > BreakBeforeClosingBrace;
return false; return false;
} }
}; };
@ -346,7 +356,7 @@ private:
if (Previous.is(tok::l_paren) || if (Previous.is(tok::l_paren) ||
Previous.is(tok::l_brace) || Previous.is(tok::l_brace) ||
State.NextToken->Parent->Type == TT_TemplateOpener) State.NextToken->Parent->Type == TT_TemplateOpener)
State.Indent[ParenLevel] = State.Column; State.Indent[ParenLevel] = State.Column + Spaces;
// Top-level spaces that are not part of assignments are exempt as that // Top-level spaces that are not part of assignments are exempt as that
// mostly leads to better results. // mostly leads to better results.
@ -356,6 +366,9 @@ private:
State.LastSpace[ParenLevel] = State.Column; State.LastSpace[ParenLevel] = State.Column;
} }
moveStateToNextToken(State); moveStateToNextToken(State);
if (Newline && Previous.is(tok::l_brace)) {
State.BreakBeforeClosingBrace.back() = true;
}
} }
/// \brief Mark the next token as consumed in \p State and modify its stacks /// \brief Mark the next token as consumed in \p State and modify its stacks
@ -383,6 +396,7 @@ private:
} }
State.LastSpace.push_back(State.LastSpace.back()); State.LastSpace.push_back(State.LastSpace.back());
State.FirstLessLess.push_back(0); State.FirstLessLess.push_back(0);
State.BreakBeforeClosingBrace.push_back(false);
} }
// If we encounter a closing ), ], } or >, we can remove a level from our // If we encounter a closing ), ], } or >, we can remove a level from our
@ -393,6 +407,7 @@ private:
State.Indent.pop_back(); State.Indent.pop_back();
State.LastSpace.pop_back(); State.LastSpace.pop_back();
State.FirstLessLess.pop_back(); State.FirstLessLess.pop_back();
State.BreakBeforeClosingBrace.pop_back();
} }
if (State.NextToken->Children.empty()) if (State.NextToken->Children.empty())
@ -460,6 +475,9 @@ private:
return UINT_MAX; return UINT_MAX;
if (NewLine && !State.NextToken->CanBreakBefore) if (NewLine && !State.NextToken->CanBreakBefore)
return UINT_MAX; return UINT_MAX;
if (!NewLine && State.NextToken->is(tok::r_brace) &&
State.BreakBeforeClosingBrace.back())
return UINT_MAX;
if (!NewLine && State.NextToken->Parent->is(tok::semi) && if (!NewLine && State.NextToken->Parent->is(tok::semi) &&
State.LineContainsContinuedForLoopSection) State.LineContainsContinuedForLoopSection)
return UINT_MAX; return UINT_MAX;
@ -485,7 +503,6 @@ private:
if (StopAt <= CurrentPenalty) if (StopAt <= CurrentPenalty)
return UINT_MAX; return UINT_MAX;
StopAt -= CurrentPenalty; StopAt -= CurrentPenalty;
StateMap::iterator I = Memory.find(State); StateMap::iterator I = Memory.find(State);
if (I != Memory.end()) { if (I != Memory.end()) {
// If this state has already been examined, we can safely return the // If this state has already been examined, we can safely return the
@ -1129,7 +1146,7 @@ private:
Right.is(tok::arrow) || Right.is(tok::period) || Right.is(tok::arrow) || Right.is(tok::period) ||
Right.is(tok::colon) || Left.is(tok::semi) || Right.is(tok::colon) || Left.is(tok::semi) ||
Left.is(tok::l_brace) || Left.is(tok::question) || Left.is(tok::l_brace) || Left.is(tok::question) ||
Left.Type == TT_ConditionalExpr || Right.is(tok::r_brace) || Left.Type == TT_ConditionalExpr ||
(Left.is(tok::l_paren) && !Right.is(tok::r_paren)); (Left.is(tok::l_paren) && !Right.is(tok::r_paren));
} }

View File

@ -430,7 +430,13 @@ TEST_F(FormatTest, StaticInitializers) {
// FIXME: Format like enums if the static initializer does not fit on a line. // FIXME: Format like enums if the static initializer does not fit on a line.
verifyFormat( verifyFormat(
"static SomeClass WithALoooooooooooooooooooongName = {\n" "static SomeClass WithALoooooooooooooooooooongName = {\n"
" 100000000, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" };"); " 100000000, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
"};");
verifyFormat(
"static SomeClass = { a, b, c, d, e, f, g, h, i, j,\n"
" looooooooooooooooooooooooooooooooooongname,\n"
" looooooooooooooooooooooooooooooong };");
} }
TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) { TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) {
@ -1121,7 +1127,8 @@ TEST_F(FormatTest, LayoutCallsInsideBraceInitializers) {
verifyFormat( verifyFormat(
"int x = {\n" "int x = {\n"
" avariable,\n" " avariable,\n"
" b(alongervariable) };", getLLVMStyleWithColumns(25)); " b(alongervariable)\n"
"};", getLLVMStyleWithColumns(25));
} }
TEST_F(FormatTest, LayoutTokensFollowingBlockInParentheses) { TEST_F(FormatTest, LayoutTokensFollowingBlockInParentheses) {