From 0de1c4d152b5fbf0b383e9fa8396e334f029c716 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Tue, 9 Jul 2013 09:06:29 +0000 Subject: [PATCH] Fix alignment of closing brace in braced initializers. Before: someFunction(OtherParam, BracedList{ // comment 1 (Forcing intersting break) param1, param2, // comment 2 param3, param4 }); After: someFunction(OtherParam, BracedList{ // comment 1 (Forcing intersting break) param1, param2, // comment 2 param3, param4 }); To do so, the UnwrappedLineParser now stores the information about the kind of brace in the FormatToken. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185914 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/Format.cpp | 5 ++++- lib/Format/FormatToken.h | 19 +++++++++++++---- lib/Format/UnwrappedLineParser.cpp | 33 +++++++++++++++--------------- lib/Format/UnwrappedLineParser.h | 12 ----------- unittests/Format/FormatTest.cpp | 7 +++++++ 5 files changed, 43 insertions(+), 33 deletions(-) diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 23f6f5b3e8..34ed8ea07c 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -514,7 +514,10 @@ private: if (Newline) { State.Stack.back().ContainsLineBreak = true; if (Current.is(tok::r_brace)) { - State.Column = Line.Level * Style.IndentWidth; + if (Current.BlockKind == BK_BracedInit) + State.Column = State.Stack[State.Stack.size() - 2].LastSpace; + else + State.Column = Line.Level * Style.IndentWidth; } else if (Current.is(tok::string_literal) && State.StartOfStringLiteral != 0) { State.Column = State.StartOfStringLiteral; diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h index 69afaac965..e77ac016be 100644 --- a/lib/Format/FormatToken.h +++ b/lib/Format/FormatToken.h @@ -56,16 +56,24 @@ enum TokenType { TT_Unknown }; +// Represents what type of block a set of braces open. +enum BraceBlockKind { + BK_Unknown, + BK_Block, + BK_BracedInit +}; + /// \brief A wrapper around a \c Token storing information about the /// whitespace characters preceeding it. struct FormatToken { FormatToken() : NewlinesBefore(0), HasUnescapedNewline(false), LastNewlineOffset(0), CodePointCount(0), IsFirst(false), MustBreakBefore(false), - Type(TT_Unknown), SpacesRequiredBefore(0), CanBreakBefore(false), - ClosesTemplateDeclaration(false), ParameterCount(0), TotalLength(0), - UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0), - LongestObjCSelectorName(0), FakeRParens(0), LastInChainOfCalls(false), + BlockKind(BK_Unknown), Type(TT_Unknown), SpacesRequiredBefore(0), + CanBreakBefore(false), ClosesTemplateDeclaration(false), + ParameterCount(0), TotalLength(0), UnbreakableTailLength(0), + BindingStrength(0), SplitPenalty(0), LongestObjCSelectorName(0), + FakeRParens(0), LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false), MatchingParen(NULL), Previous(NULL), Next(NULL) {} @@ -117,6 +125,9 @@ struct FormatToken { /// escaped newlines. StringRef TokenText; + /// \brief Contains the kind of block if this token is a brace. + BraceBlockKind BlockKind; + TokenType Type; unsigned SpacesRequiredBefore; diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 98a5a8ae07..77f98bffda 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -183,9 +183,7 @@ UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style, UnwrappedLineConsumer &Callback) : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), CurrentLines(&Lines), StructuralError(false), Style(Style), Tokens(NULL), - Callback(Callback), AllTokens(Tokens) { - LBraces.resize(Tokens.size(), BS_Unknown); -} + Callback(Callback), AllTokens(Tokens) {} bool UnwrappedLineParser::parse() { DEBUG(llvm::dbgs() << "----\n"); @@ -252,7 +250,7 @@ void UnwrappedLineParser::calculateBraceTypes() { // Keep a stack of positions of lbrace tokens. We will // update information about whether an lbrace starts a // braced init list or a different block during the loop. - SmallVector LBraceStack; + SmallVector LBraceStack; assert(Tok->Tok.is(tok::l_brace)); do { // Get next none-comment token. @@ -265,11 +263,11 @@ void UnwrappedLineParser::calculateBraceTypes() { switch (Tok->Tok.getKind()) { case tok::l_brace: - LBraceStack.push_back(Position); + LBraceStack.push_back(Tok); break; case tok::r_brace: if (!LBraceStack.empty()) { - if (LBraces[LBraceStack.back()] == BS_Unknown) { + if (LBraceStack.back()->BlockKind == BK_Unknown) { // If there is a comma, semicolon or right paren after the closing // brace, we assume this is a braced initializer list. @@ -279,10 +277,13 @@ void UnwrappedLineParser::calculateBraceTypes() { // brace blocks inside it braced init list. That works good enough // for now, but we will need to fix it to correctly handle lambdas. if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren, - tok::l_brace, tok::colon)) - LBraces[LBraceStack.back()] = BS_BracedInit; - else - LBraces[LBraceStack.back()] = BS_Block; + tok::l_brace, tok::colon)) { + Tok->BlockKind = BK_BracedInit; + LBraceStack.back()->BlockKind = BK_BracedInit; + } else { + Tok->BlockKind = BK_Block; + LBraceStack.back()->BlockKind = BK_Block; + } } LBraceStack.pop_back(); } @@ -294,7 +295,7 @@ void UnwrappedLineParser::calculateBraceTypes() { case tok::kw_switch: case tok::kw_try: if (!LBraceStack.empty()) - LBraces[LBraceStack.back()] = BS_Block; + LBraceStack.back()->BlockKind = BK_Block; break; default: break; @@ -304,8 +305,8 @@ void UnwrappedLineParser::calculateBraceTypes() { } while (Tok->Tok.isNot(tok::eof)); // Assume other blocks for all unclosed opening braces. for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { - if (LBraces[LBraceStack[i]] == BS_Unknown) - LBraces[LBraceStack[i]] = BS_Block; + if (LBraceStack[i]->BlockKind == BK_Unknown) + LBraceStack[i]->BlockKind = BK_Block; } FormatTok = Tokens->setPosition(StoredPosition); } @@ -632,10 +633,10 @@ void UnwrappedLineParser::parseStructuralElement() { } bool UnwrappedLineParser::tryToParseBracedList() { - if (LBraces[Tokens->getPosition()] == BS_Unknown) + if (FormatTok->BlockKind == BK_Unknown) calculateBraceTypes(); - assert(LBraces[Tokens->getPosition()] != BS_Unknown); - if (LBraces[Tokens->getPosition()] == BS_Block) + assert(FormatTok->BlockKind != BK_Unknown); + if (FormatTok->BlockKind == BK_Block) return false; parseBracedList(); return true; diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index fb65078c33..0624c4fd15 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -102,13 +102,6 @@ private: void calculateBraceTypes(); void pushPPConditional(); - // Represents what type of block a left brace opens. - enum LBraceState { - BS_Unknown, - BS_Block, - BS_BracedInit - }; - // FIXME: We are constantly running into bugs where Line.Level is incorrectly // subtracted from beyond 0. Introduce a method to subtract from Line.Level // and use that everywhere in the Parser. @@ -153,11 +146,6 @@ private: // owned outside of and handed into the UnwrappedLineParser. ArrayRef AllTokens; - // FIXME: Currently we cannot store attributes with tokens, as we treat - // them as read-only; thus, we now store the brace state indexed by the - // position of the token in the stream (see \c AllTokens). - SmallVector LBraces; - // Represents preprocessor branch type, so we can find matching // #if/#else/#endif directives. enum PPBranchKind { diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 6c70ebb11a..417c50cd2c 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -3785,6 +3785,13 @@ TEST_F(FormatTest, LayoutCxx11ConstructorBraceInitializers) { " bbbbbbbbbbbbbbbbbbbb, bbbbb };"); verifyFormat("DoSomethingWithVector({} /* No data */);"); verifyFormat("DoSomethingWithVector({ {} /* No data */ }, { { 1, 2 } });"); + verifyFormat( + "someFunction(OtherParam, BracedList{\n" + " // comment 1 (Forcing intersting break)\n" + " param1, param2,\n" + " // comment 2\n" + " param3, param4\n" + " });"); FormatStyle NoSpaces = getLLVMStyle(); NoSpaces.SpacesInBracedLists = false; -- 2.40.0