From 0ddd57a17bf8e42cc6a8374d9859e86070716d4e Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Thu, 10 Jan 2013 15:58:26 +0000 Subject: [PATCH] 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 --- clang/lib/Format/Format.cpp | 23 ++++++++++++++++++++--- clang/unittests/Format/FormatTest.cpp | 11 +++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 09874bbd7787..de92b75b0bb0 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -154,6 +154,7 @@ public: State.Indent.push_back(Indent + 4); State.LastSpace.push_back(Indent); State.FirstLessLess.push_back(0); + State.BreakBeforeClosingBrace.push_back(false); State.ForLoopVariablePos = 0; State.LineContainsContinuedForLoopSection = false; State.StartOfLineLevel = 1; @@ -223,6 +224,13 @@ private: /// on a level. std::vector 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 BreakBeforeClosingBrace; + /// \brief The column of the first variable in a for-loop declaration. /// /// Used to align the second variable if necessary. @@ -262,6 +270,8 @@ private: if (Other.LineContainsContinuedForLoopSection != LineContainsContinuedForLoopSection) return LineContainsContinuedForLoopSection; + if (Other.BreakBeforeClosingBrace != BreakBeforeClosingBrace) + return Other.BreakBeforeClosingBrace > BreakBeforeClosingBrace; return false; } }; @@ -346,7 +356,7 @@ private: if (Previous.is(tok::l_paren) || Previous.is(tok::l_brace) || 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 // mostly leads to better results. @@ -356,6 +366,9 @@ private: State.LastSpace[ParenLevel] = State.Column; } 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 @@ -383,6 +396,7 @@ private: } State.LastSpace.push_back(State.LastSpace.back()); State.FirstLessLess.push_back(0); + State.BreakBeforeClosingBrace.push_back(false); } // If we encounter a closing ), ], } or >, we can remove a level from our @@ -393,6 +407,7 @@ private: State.Indent.pop_back(); State.LastSpace.pop_back(); State.FirstLessLess.pop_back(); + State.BreakBeforeClosingBrace.pop_back(); } if (State.NextToken->Children.empty()) @@ -460,6 +475,9 @@ private: return UINT_MAX; if (NewLine && !State.NextToken->CanBreakBefore) 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) && State.LineContainsContinuedForLoopSection) return UINT_MAX; @@ -485,7 +503,6 @@ private: if (StopAt <= CurrentPenalty) return UINT_MAX; StopAt -= CurrentPenalty; - StateMap::iterator I = Memory.find(State); if (I != Memory.end()) { // 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::colon) || Left.is(tok::semi) || 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)); } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 439568e4712b..1d9363dc2e4b 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -430,7 +430,13 @@ TEST_F(FormatTest, StaticInitializers) { // FIXME: Format like enums if the static initializer does not fit on a line. verifyFormat( "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) { @@ -1121,7 +1127,8 @@ TEST_F(FormatTest, LayoutCallsInsideBraceInitializers) { verifyFormat( "int x = {\n" " avariable,\n" - " b(alongervariable) };", getLLVMStyleWithColumns(25)); + " b(alongervariable)\n" + "};", getLLVMStyleWithColumns(25)); } TEST_F(FormatTest, LayoutTokensFollowingBlockInParentheses) {