From: Daniel Jasper Date: Mon, 4 May 2015 07:39:00 +0000 (+0000) Subject: clang-format: Force aligning different brackets relative to each other. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c95b0129763897bfd3d9f28f81396c4d17b0086e;p=clang clang-format: Force aligning different brackets relative to each other. Before: void SomeFunction(vector< // break int> v); After: void SomeFunction(vector< // break int> v); git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236412 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 9e1014e567..44b86a76ef 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -814,6 +814,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, unsigned NewIndent; unsigned NewIndentLevel = State.Stack.back().IndentLevel; + unsigned LastSpace = State.Stack.back().LastSpace; bool AvoidBinPacking; bool BreakBeforeParameter = false; if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) { @@ -833,6 +834,18 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, NewIndent = Style.ContinuationIndentWidth + std::max(State.Stack.back().LastSpace, State.Stack.back().StartOfFunctionCall); + + // Ensure that different different brackets force relative alignment, e.g.: + // void SomeFunction(vector< // break + // int> v); + // FIXME: We likely want to do this for more combinations of brackets. + // Verify that it is wanted for ObjC, too. + if (Current.Tok.getKind() == tok::less && + Current.ParentBracket == tok::l_paren) { + NewIndent = std::max(NewIndent, State.Stack.back().Indent); + LastSpace = std::max(LastSpace, State.Stack.back().Indent); + } + AvoidBinPacking = (State.Line->MustBeDeclaration && !Style.BinPackParameters) || (!State.Line->MustBeDeclaration && !Style.BinPackArguments) || @@ -866,8 +879,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, State.Stack.back().ContainsUnwrappedBuilder); unsigned NestedBlockIndent = std::max(State.Stack.back().StartOfFunctionCall, State.Stack.back().NestedBlockIndent); - State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, - State.Stack.back().LastSpace, + State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace, AvoidBinPacking, NoLineBreak)); State.Stack.back().NestedBlockIndent = NestedBlockIndent; State.Stack.back().BreakBeforeParameter = BreakBeforeParameter; diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h index 5e8730c71e..aeb9ef578f 100644 --- a/lib/Format/FormatToken.h +++ b/lib/Format/FormatToken.h @@ -111,7 +111,7 @@ struct FormatToken { IsFirst(false), MustBreakBefore(false), IsUnterminatedLiteral(false), BlockKind(BK_Unknown), Type(TT_Unknown), SpacesRequiredBefore(0), CanBreakBefore(false), ClosesTemplateDeclaration(false), - ParameterCount(0), BlockParameterCount(0), + ParameterCount(0), BlockParameterCount(0), ParentBracket(tok::unknown), PackingKind(PPK_Inconclusive), TotalLength(0), UnbreakableTailLength(0), BindingStrength(0), NestingLevel(0), SplitPenalty(0), LongestObjCSelectorName(0), FakeRParens(0), @@ -204,6 +204,10 @@ struct FormatToken { /// if this is "(", "[" or "<". unsigned BlockParameterCount; + /// \brief If this is a bracket ("<", "(", "[" or "{"), contains the kind of + /// the surrounding bracket. + tok::TokenKind ParentBracket; + /// \brief A token can have a special role that can carry extra information /// about the token's formatting. std::unique_ptr Role; diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 00348a2c9f..15f9fba04c 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -43,8 +43,9 @@ private: bool parseAngle() { if (!CurrentToken) return false; - ScopedContextCreator ContextCreator(*this, tok::less, 10); FormatToken *Left = CurrentToken->Previous; + Left->ParentBracket = Contexts.back().ContextKind; + ScopedContextCreator ContextCreator(*this, tok::less, 10); Contexts.back().IsExpression = false; // If there's a template keyword before the opening angle bracket, this is a // template parameter, not an argument. @@ -92,6 +93,8 @@ private: bool parseParens(bool LookForDecls = false) { if (!CurrentToken) return false; + FormatToken *Left = CurrentToken->Previous; + Left->ParentBracket = Contexts.back().ContextKind; ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); // FIXME: This is a bit of a hack. Do better. @@ -99,7 +102,6 @@ private: Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; bool StartsObjCMethodExpr = false; - FormatToken *Left = CurrentToken->Previous; if (CurrentToken->is(tok::caret)) { // (^ can start a block type. Left->Type = TT_ObjCBlockLParen; @@ -245,6 +247,7 @@ private: // ')' or ']'), it could be the start of an Objective-C method // expression, or it could the the start of an Objective-C array literal. FormatToken *Left = CurrentToken->Previous; + Left->ParentBracket = Contexts.back().ContextKind; FormatToken *Parent = Left->getPreviousNonComment(); bool StartsObjCMethodExpr = Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) && @@ -324,6 +327,7 @@ private: bool parseBrace() { if (CurrentToken) { FormatToken *Left = CurrentToken->Previous; + Left->ParentBracket = Contexts.back().ContextKind; if (Contexts.back().CaretFound) Left->Type = TT_ObjCBlockLBrace; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index e2db4d10b9..a1817ea192 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -5803,6 +5803,13 @@ TEST_F(FormatTest, BreaksLongDeclarations) { verifyFormat("typedef size_t (*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n" " const aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " *aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " vector\n" + " aaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " vector>\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); } TEST_F(FormatTest, FormatsArrays) {