clang-format: Split up moveStateToNextToken.
authorDaniel Jasper <djasper@google.com>
Mon, 26 May 2014 13:10:39 +0000 (13:10 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 26 May 2014 13:10:39 +0000 (13:10 +0000)
No functional changes intended.

llvm-svn: 209626

clang/lib/Format/ContinuationIndenter.cpp
clang/lib/Format/ContinuationIndenter.h

index e1a559d..7485e0d 100644 (file)
@@ -559,8 +559,8 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
 
 unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
                                                     bool DryRun, bool Newline) {
-  const FormatToken &Current = *State.NextToken;
   assert(State.Stack.size());
+  const FormatToken &Current = *State.NextToken;
 
   if (Current.Type == TT_InheritanceColon)
     State.Stack.back().AvoidBinPacking = true;
@@ -633,6 +633,44 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
       State.Stack.back().JSFunctionInlined = !Newline;
   }
 
+  moveStatePastFakeLParens(State, Newline);
+  moveStatePastScopeOpener(State, Newline);
+  moveStatePastScopeCloser(State);
+  moveStatePastFakeRParens(State);
+
+  if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
+    State.StartOfStringLiteral = State.Column;
+  } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
+             !Current.isStringLiteral()) {
+    State.StartOfStringLiteral = 0;
+  }
+
+  State.Column += Current.ColumnWidth;
+  State.NextToken = State.NextToken->Next;
+  unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
+  if (State.Column > getColumnLimit(State)) {
+    unsigned ExcessCharacters = State.Column - getColumnLimit(State);
+    Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
+  }
+
+  if (Current.Role)
+    Current.Role->formatFromToken(State, this, DryRun);
+  // If the previous has a special role, let it consume tokens as appropriate.
+  // It is necessary to start at the previous token for the only implemented
+  // role (comma separated list). That way, the decision whether or not to break
+  // after the "{" is already done and both options are tried and evaluated.
+  // FIXME: This is ugly, find a better way.
+  if (Previous && Previous->Role)
+    Penalty += Previous->Role->formatAfterToken(State, this, DryRun);
+
+  return Penalty;
+}
+
+void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
+                                                    bool Newline) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken *Previous = Current.getPreviousNonComment();
+
   // Don't add extra indentation for the first fake parenthesis after
   // 'return', assignments or opening <({[. The indentation for these cases
   // is special cased.
@@ -696,97 +734,91 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
     State.Stack.push_back(NewParenState);
     SkipFirstExtraIndent = false;
   }
+}
 
-  // If we encounter an opening (, [, { or <, we add a level to our stacks to
-  // prepare for the following tokens.
-  if (Current.opensScope()) {
-    unsigned NewIndent;
-    unsigned NewIndentLevel = State.Stack.back().IndentLevel;
-    bool AvoidBinPacking;
-    bool BreakBeforeParameter = false;
-    if (Current.is(tok::l_brace) ||
-        Current.Type == TT_ArrayInitializerLSquare) {
-      if (Current.MatchingParen && Current.BlockKind == BK_Block &&
-          State.Stack.back().LambdasFound <= 1) {
-        // If this is an l_brace starting a nested block, we pretend (wrt. to
-        // indentation) that we already consumed the corresponding r_brace.
-        // Thus, we remove all ParenStates caused by fake parentheses that end
-        // at the r_brace. The net effect of this is that we don't indent
-        // relative to the l_brace, if the nested block is the last parameter of
-        // a function. For example, this formats:
-        //
-        //   SomeFunction(a, [] {
-        //     f();  // break
-        //   });
-        //
-        // instead of:
-        //   SomeFunction(a, [] {
-        //                     f();  // break
-        //                   });
-        //
-        // If we have already found more than one lambda introducers on this
-        // level, we opt out of this because similarity between the lambdas is
-        // more important.
-        for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i) {
-          assert(State.Stack.size() > 1);
-          if (State.Stack.size() == 1) {
-            // Do not pop the last element.
-            break;
-          }
-          State.Stack.pop_back();
-        }
-        // For some reason, ObjC blocks are indented like continuations.
-        NewIndent =
-            State.Stack.back().LastSpace + (Current.Type == TT_ObjCBlockLBrace
-                                                ? Style.ContinuationIndentWidth
-                                                : Style.IndentWidth);
-        ++NewIndentLevel;
-        BreakBeforeParameter = true;
-      } else {
-        NewIndent = State.Stack.back().LastSpace;
-        if (Current.opensBlockTypeList(Style)) {
-          NewIndent += Style.IndentWidth;
-          NewIndent = std::min(State.Column + 2, NewIndent);
-          ++NewIndentLevel;
-        } else {
-          NewIndent += Style.ContinuationIndentWidth;
-          NewIndent = std::min(State.Column + 1, NewIndent);
-        }
+void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+
+  // Remove scopes created by fake parenthesis.
+  if (Current.isNot(tok::r_brace) ||
+      (Current.MatchingParen && Current.MatchingParen->BlockKind != BK_Block)) {
+    // Don't remove FakeRParens attached to r_braces that surround nested blocks
+    // as they will have been removed early (see above).
+    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
+      unsigned VariablePos = State.Stack.back().VariablePos;
+      assert(State.Stack.size() > 1);
+      if (State.Stack.size() == 1) {
+        // Do not pop the last element.
+        break;
       }
-      const FormatToken *NextNoComment = Current.getNextNonComment();
-      AvoidBinPacking = Current.BlockKind == BK_Block ||
-                        Current.Type == TT_ArrayInitializerLSquare ||
-                        Current.Type == TT_DictLiteral ||
-                        Style.Language == FormatStyle::LK_Proto ||
-                        !Style.BinPackParameters ||
-                        (NextNoComment &&
-                         NextNoComment->Type == TT_DesignatedInitializerPeriod);
-    } else {
-      NewIndent = Style.ContinuationIndentWidth +
-                  std::max(State.Stack.back().LastSpace,
-                           State.Stack.back().StartOfFunctionCall);
-      AvoidBinPacking = !Style.BinPackParameters ||
-                        (Style.ExperimentalAutoDetectBinPacking &&
-                         (Current.PackingKind == PPK_OnePerLine ||
-                          (!BinPackInconclusiveFunctions &&
-                           Current.PackingKind == PPK_Inconclusive)));
-      // If this '[' opens an ObjC call, determine whether all parameters fit
-      // into one line and put one per line if they don't.
-      if (Current.Type == TT_ObjCMethodExpr && Style.ColumnLimit != 0 &&
-          getLengthToMatchingParen(Current) + State.Column >
-              getColumnLimit(State))
-        BreakBeforeParameter = true;
+      State.Stack.pop_back();
+      State.Stack.back().VariablePos = VariablePos;
     }
+  }
+}
+
+void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
+                                                    bool Newline) {
+  const FormatToken &Current = *State.NextToken;
+  if (!Current.opensScope())
+    return;
 
-    bool NoLineBreak = State.Stack.back().NoLineBreak ||
-                       (Current.Type == TT_TemplateOpener &&
-                        State.Stack.back().ContainsUnwrappedBuilder);
-    State.Stack.push_back(ParenState(NewIndent, NewIndentLevel,
-                                     State.Stack.back().LastSpace,
-                                     AvoidBinPacking, NoLineBreak));
-    State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
+  if (Current.MatchingParen && Current.BlockKind == BK_Block) {
+    moveStateToNewBlock(State);
+    return;
   }
 
+  unsigned NewIndent;
+  unsigned NewIndentLevel = State.Stack.back().IndentLevel;
+  bool AvoidBinPacking;
+  bool BreakBeforeParameter = false;
+  if (Current.is(tok::l_brace) || Current.Type == TT_ArrayInitializerLSquare) {
+    NewIndent = State.Stack.back().LastSpace;
+    if (Current.opensBlockTypeList(Style)) {
+      NewIndent += Style.IndentWidth;
+      NewIndent = std::min(State.Column + 2, NewIndent);
+      ++NewIndentLevel;
+    } else {
+      NewIndent += Style.ContinuationIndentWidth;
+      NewIndent = std::min(State.Column + 1, NewIndent);
+    }
+    const FormatToken *NextNoComment = Current.getNextNonComment();
+    AvoidBinPacking = Current.Type == TT_ArrayInitializerLSquare ||
+                      Current.Type == TT_DictLiteral ||
+                      Style.Language == FormatStyle::LK_Proto ||
+                      !Style.BinPackParameters ||
+                      (NextNoComment &&
+                       NextNoComment->Type == TT_DesignatedInitializerPeriod);
+  } else {
+    NewIndent = Style.ContinuationIndentWidth +
+                std::max(State.Stack.back().LastSpace,
+                         State.Stack.back().StartOfFunctionCall);
+    AvoidBinPacking = !Style.BinPackParameters ||
+                      (Style.ExperimentalAutoDetectBinPacking &&
+                       (Current.PackingKind == PPK_OnePerLine ||
+                        (!BinPackInconclusiveFunctions &&
+                         Current.PackingKind == PPK_Inconclusive)));
+    // If this '[' opens an ObjC call, determine whether all parameters fit
+    // into one line and put one per line if they don't.
+    if (Current.Type == TT_ObjCMethodExpr && Style.ColumnLimit != 0 &&
+        getLengthToMatchingParen(Current) + State.Column >
+            getColumnLimit(State))
+      BreakBeforeParameter = true;
+  }
+  bool NoLineBreak = State.Stack.back().NoLineBreak ||
+                     (Current.Type == TT_TemplateOpener &&
+                      State.Stack.back().ContainsUnwrappedBuilder);
+  State.Stack.push_back(ParenState(NewIndent, NewIndentLevel,
+                                   State.Stack.back().LastSpace,
+                                   AvoidBinPacking, NoLineBreak));
+  State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
+}
+
+void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+  if (!Current.closesScope())
+    return;
+
   // If we encounter a closing ), ], } or >, we can remove a level from our
   // stacks.
   if (State.Stack.size() > 1 &&
@@ -801,50 +833,49 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
     if (NextNonComment && NextNonComment->isNot(tok::l_square))
       State.Stack.back().StartOfArraySubscripts = 0;
   }
+}
 
-  // Remove scopes created by fake parenthesis.
-  if (Current.isNot(tok::r_brace) ||
-      (Current.MatchingParen && Current.MatchingParen->BlockKind != BK_Block)) {
-    // Don't remove FakeRParens attached to r_braces that surround nested blocks
-    // as they will have been removed early (see above).
-    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
-      unsigned VariablePos = State.Stack.back().VariablePos;
+void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
+  // If this is an l_brace starting a nested block, we pretend (wrt. to
+  // indentation) that we already consumed the corresponding r_brace. Thus, we
+  // remove all ParenStates caused by fake parentheses that end at the r_brace.
+  // The net effect of this is that we don't indent relative to the l_brace, if
+  // the nested block is the last parameter of a function. For example, this
+  // formats:
+  //
+  //   SomeFunction(a, [] {
+  //     f();  // break
+  //   });
+  //
+  // instead of:
+  //   SomeFunction(a, [] {
+  //                     f();  // break
+  //                   });
+  //
+  // If we have already found more than one lambda introducers on this level, we
+  // opt out of this because similarity between the lambdas is more important.
+  if (State.Stack.back().LambdasFound <= 1) {
+    for (unsigned i = 0; i != State.NextToken->MatchingParen->FakeRParens;
+         ++i) {
       assert(State.Stack.size() > 1);
       if (State.Stack.size() == 1) {
         // Do not pop the last element.
         break;
       }
       State.Stack.pop_back();
-      State.Stack.back().VariablePos = VariablePos;
     }
   }
 
-  if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
-    State.StartOfStringLiteral = State.Column;
-  } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
-             !Current.isStringLiteral()) {
-    State.StartOfStringLiteral = 0;
-  }
-
-  State.Column += Current.ColumnWidth;
-  State.NextToken = State.NextToken->Next;
-  unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
-  if (State.Column > getColumnLimit(State)) {
-    unsigned ExcessCharacters = State.Column - getColumnLimit(State);
-    Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
-  }
-
-  if (Current.Role)
-    Current.Role->formatFromToken(State, this, DryRun);
-  // If the previous has a special role, let it consume tokens as appropriate.
-  // It is necessary to start at the previous token for the only implemented
-  // role (comma separated list). That way, the decision whether or not to break
-  // after the "{" is already done and both options are tried and evaluated.
-  // FIXME: This is ugly, find a better way.
-  if (Previous && Previous->Role)
-    Penalty += Previous->Role->formatAfterToken(State, this, DryRun);
-
-  return Penalty;
+  // For some reason, ObjC blocks are indented like continuations.
+  unsigned NewIndent = State.Stack.back().LastSpace +
+                       (State.NextToken->Type == TT_ObjCBlockLBrace
+                            ? Style.ContinuationIndentWidth
+                            : Style.IndentWidth);
+  State.Stack.push_back(ParenState(
+      NewIndent, /*NewIndentLevel=*/State.Stack.back().IndentLevel + 1,
+      State.Stack.back().LastSpace, /*AvoidBinPacking=*/true,
+      State.Stack.back().NoLineBreak));
+  State.Stack.back().BreakBeforeParameter = true;
 }
 
 unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,
index dc3e308..4733bda 100644 (file)
@@ -73,6 +73,18 @@ private:
   /// accordingly.
   unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
 
+  /// \brief Update 'State' according to the next token's fake left parentheses.
+  void moveStatePastFakeLParens(LineState &State, bool Newline);
+  /// \brief Update 'State' according to the next token's fake r_parens.
+  void moveStatePastFakeRParens(LineState &State);
+
+  /// \brief Update 'State' according to the next token being one of "(<{[".
+  void moveStatePastScopeOpener(LineState &State, bool Newline);
+  /// \brief Update 'State' according to the next token being one of ")>}]".
+  void moveStatePastScopeCloser(LineState &State);
+  /// \brief Update 'State' with the next token opening a nested block.
+  void moveStateToNewBlock(LineState &State);
+
   /// \brief If the current token sticks out over the end of the line, break
   /// it if possible.
   ///