r206159 - clang-format: Don't allow hanging indentation for operators on new lines

Daniel Jasper djasper at google.com
Mon Apr 14 04:08:45 PDT 2014


Author: djasper
Date: Mon Apr 14 06:08:45 2014
New Revision: 206159

URL: http://llvm.org/viewvc/llvm-project?rev=206159&view=rev
Log:
clang-format: Don't allow hanging indentation for operators on new lines

Before:
  if (aaaaaaaa && bbbbbbbbbbbbbbb // need to wrap
                  == cccccccccccccc) ...

After:
  if (aaaaaaaa
      && bbbbbbbbbbbbbbb // need to wrap
         == cccccccccccccc) ...

The same rule has already be implemented for BreakBeforeBinaryOperators
set to false in r205527.

Modified:
    cfe/trunk/lib/Format/ContinuationIndenter.cpp
    cfe/trunk/lib/Format/ContinuationIndenter.h
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=206159&r1=206158&r2=206159&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Mon Apr 14 06:08:45 2014
@@ -173,8 +173,7 @@ bool ContinuationIndenter::mustBreak(con
     if (Previous.Type == TT_BinaryOperator &&
         (!IsComparison || LHSIsBinaryExpr) &&
         Current.Type != TT_BinaryOperator && // For >>.
-        !Current.isTrailingComment() &&
-        !Previous.isOneOf(tok::lessless, tok::question) &&
+        !Current.isTrailingComment() && !Previous.is(tok::lessless) &&
         Previous.getPrecedence() != prec::Assignment &&
         State.Stack.back().BreakBeforeParameter)
       return true;
@@ -485,7 +484,8 @@ unsigned ContinuationIndenter::getNewLin
     }
   }
   if (State.Stack.back().QuestionColumn != 0 &&
-      (NextNonComment->Type == TT_ConditionalExpr ||
+      ((NextNonComment->is(tok::colon) &&
+        NextNonComment->Type == TT_ConditionalExpr) ||
        Previous.Type == TT_ConditionalExpr))
     return State.Stack.back().QuestionColumn;
   if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0)
@@ -547,9 +547,15 @@ unsigned ContinuationIndenter::moveState
 
   if (Current.Type == TT_InheritanceColon)
     State.Stack.back().AvoidBinPacking = true;
-  if (Current.is(tok::lessless) && Current.Type != TT_OverloadedOperator &&
-      State.Stack.back().FirstLessLess == 0)
-    State.Stack.back().FirstLessLess = State.Column;
+  if (Current.is(tok::lessless) && Current.Type != TT_OverloadedOperator) {
+    if (State.Stack.back().FirstLessLess == 0)
+      State.Stack.back().FirstLessLess = State.Column;
+    else
+      State.Stack.back().LastOperatorWrapped = Newline;
+  }
+  if ((Current.Type == TT_BinaryOperator && Current.isNot(tok::lessless)) ||
+      Current.Type == TT_ConditionalExpr)
+    State.Stack.back().LastOperatorWrapped = Newline;
   if (Current.Type == TT_ArraySubscriptLSquare &&
       State.Stack.back().StartOfArraySubscripts == 0)
     State.Stack.back().StartOfArraySubscripts = State.Column;
@@ -615,13 +621,19 @@ unsigned ContinuationIndenter::moveState
     // there is a line-break right after the operator.
     // Exclude relational operators, as there, it is always more desirable to
     // have the LHS 'left' of the RHS.
-    // FIXME: Implement this for '<<' and BreakBeforeBinaryOperators.
-    if (!Newline && Previous && Previous->Type == TT_BinaryOperator &&
-        !Previous->isOneOf(tok::lessless, tok::question, tok::colon) &&
-        Previous->getPrecedence() > prec::Assignment &&
-        Previous->getPrecedence() != prec::Relational &&
-        !Style.BreakBeforeBinaryOperators)
-      NewParenState.NoLineBreak = true;
+    if (Previous && Previous->getPrecedence() > prec::Assignment &&
+        (Previous->Type == TT_BinaryOperator ||
+         Previous->Type == TT_ConditionalExpr) &&
+        Previous->getPrecedence() != prec::Relational) {
+      bool BreakBeforeOperator = Previous->is(tok::lessless) ||
+                                 (Previous->Type == TT_BinaryOperator &&
+                                  Style.BreakBeforeBinaryOperators) ||
+                                 (Previous->Type == TT_ConditionalExpr &&
+                                  Style.BreakBeforeTernaryOperators);
+      if ((!Newline && !BreakBeforeOperator) ||
+          (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator))
+        NewParenState.NoLineBreak = true;
+    }
 
     // Do not indent relative to the fake parentheses inserted for "." or "->".
     // This is a special case to make the following to statements consistent:

Modified: cfe/trunk/lib/Format/ContinuationIndenter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.h?rev=206159&r1=206158&r2=206159&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.h (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.h Mon Apr 14 06:08:45 2014
@@ -135,11 +135,11 @@ struct ParenState {
       : Indent(Indent), IndentLevel(IndentLevel), LastSpace(LastSpace),
         FirstLessLess(0), BreakBeforeClosingBrace(false), QuestionColumn(0),
         AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
-        NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
-        StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
-        CallContinuation(0), VariablePos(0), ContainsLineBreak(false),
-        ContainsUnwrappedBuilder(0), AlignColons(true),
-        ObjCSelectorNameFound(false), LambdasFound(0) {}
+        NoLineBreak(NoLineBreak), LastOperatorWrapped(true), ColonPos(0),
+        StartOfFunctionCall(0), StartOfArraySubscripts(0),
+        NestedNameSpecifierContinuation(0), CallContinuation(0), VariablePos(0),
+        ContainsLineBreak(false), ContainsUnwrappedBuilder(0),
+        AlignColons(true), ObjCSelectorNameFound(false), LambdasFound(0) {}
 
   /// \brief The position to which a specific parenthesis level needs to be
   /// indented.
@@ -182,6 +182,10 @@ struct ParenState {
   /// \brief Line breaking in this context would break a formatting rule.
   bool NoLineBreak;
 
+  /// \brief True if the last binary operator on this level was wrapped to the
+  /// next line.
+  bool LastOperatorWrapped;
+
   /// \brief The position of the colon in an ObjC method declaration/call.
   unsigned ColonPos;
 
@@ -253,6 +257,8 @@ struct ParenState {
       return BreakBeforeParameter;
     if (NoLineBreak != Other.NoLineBreak)
       return NoLineBreak;
+    if (LastOperatorWrapped != Other.LastOperatorWrapped)
+      return LastOperatorWrapped;
     if (ColonPos != Other.ColonPos)
       return ColonPos < Other.ColonPos;
     if (StartOfFunctionCall != Other.StartOfFunctionCall)

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=206159&r1=206158&r2=206159&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon Apr 14 06:08:45 2014
@@ -735,6 +735,8 @@ private:
         Current.Type = determineIncrementUsage(Current);
       } else if (Current.is(tok::exclaim)) {
         Current.Type = TT_UnaryOperator;
+      } else if (Current.is(tok::question)) {
+        Current.Type = TT_ConditionalExpr;
       } else if (Current.isBinaryOperator() &&
                  (!Current.Previous ||
                   Current.Previous->isNot(tok::l_square))) {
@@ -858,6 +860,7 @@ private:
                            tok::comma, tok::semi, tok::kw_return, tok::colon,
                            tok::equal, tok::kw_delete, tok::kw_sizeof) ||
         PrevToken->Type == TT_BinaryOperator ||
+        PrevToken->Type == TT_ConditionalExpr ||
         PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
       return TT_UnaryOperator;
 
@@ -1494,7 +1497,8 @@ bool TokenAnnotator::spaceRequiredBefore
       Tok.getPrecedence() == prec::Assignment)
     return false;
   if ((Tok.Type == TT_BinaryOperator && !Tok.Previous->is(tok::l_paren)) ||
-      Tok.Previous->Type == TT_BinaryOperator)
+      Tok.Previous->Type == TT_BinaryOperator ||
+      Tok.Previous->Type == TT_ConditionalExpr)
     return true;
   if (Tok.Previous->Type == TT_TemplateCloser && Tok.is(tok::l_paren))
     return false;

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=206159&r1=206158&r2=206159&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Mon Apr 14 06:08:45 2014
@@ -2940,8 +2940,9 @@ TEST_F(FormatTest, ExpressionIndentation
                "       + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}",
                Style);
   verifyFormat("if () {\n"
-               "} else if (aaaaa && bbbbb // break\n"
-               "                    > ccccc) {\n"
+               "} else if (aaaaa\n"
+               "           && bbbbb // break\n"
+               "              > ccccc) {\n"
                "}",
                Style);
 
@@ -3697,6 +3698,12 @@ TEST_F(FormatTest, BreaksConditionalExpr
                "                  : (bbbbbbbbbbbbbbb //\n"
                "                         ? ccccccccccccccc\n"
                "                         : ddddddddddddddd);");
+  verifyFormat(
+      "int aaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                                      ? aaaaaaaaaaaaaaaaaaaaaaaaa +\n"
+      "                                            aaaaaaaaaaaaaaaaaaaaa +\n"
+      "                                            aaaaaaaaaaaaaaaaaaaaa\n"
+      "                                      : aaaaaaaaaa;");
 
   FormatStyle NoBinPacking = getLLVMStyle();
   NoBinPacking.BinPackParameters = false;
@@ -4000,6 +4007,8 @@ TEST_F(FormatTest, AlignsPipes) {
       "  llvm::outs() << \"aaaaaaaaaaaaaaaaaaaa: \"\n"
       "               << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n"
       "}");
+  verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n"
+               "             << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();");
 
   // Breaking before the first "<<" is generally not desirable.
   verifyFormat(





More information about the cfe-commits mailing list