]> granicus.if.org Git - clang/commitdiff
clang-format: Force aligning different brackets relative to each other.
authorDaniel Jasper <djasper@google.com>
Mon, 4 May 2015 07:39:00 +0000 (07:39 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 4 May 2015 07:39:00 +0000 (07:39 +0000)
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

lib/Format/ContinuationIndenter.cpp
lib/Format/FormatToken.h
lib/Format/TokenAnnotator.cpp
unittests/Format/FormatTest.cpp

index 9e1014e5670877da4a40af8aa89a0c07cae2ce83..44b86a76ef231b843047f8e28c2bf155ed36bf8e 100644 (file)
@@ -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;
index 5e8730c71e58f0685a01dfeaa02a199f1e9764a8..aeb9ef578feb375ea07d2b137389f9ab84ce2f54 100644 (file)
@@ -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<TokenRole> Role;
index 00348a2c9f53d8f09f8360dbc13d68121b94aa7c..15f9fba04ca2b8da72349e9a788af996ca536844 100644 (file)
@@ -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;
index e2db4d10b952abd8e964f2356ea5996d5bc3117d..a1817ea1926ce59b57a3b039a751d9fc2385ad6e 100644 (file)
@@ -5803,6 +5803,13 @@ TEST_F(FormatTest, BreaksLongDeclarations) {
   verifyFormat("typedef size_t (*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n"
                "    const aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
                "        *aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+  verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "    vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>\n"
+               "        aaaaaaaaaaaaaaaaaaaaaaaa);");
+  verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "    vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n"
+               "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>>\n"
+               "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
 }
 
 TEST_F(FormatTest, FormatsArrays) {