[cfe-commits] [PATCH] "<<" alignment for clang-format

Daniel Jasper djasper at google.com
Wed Dec 5 10:15:27 PST 2012


Hi klimek,

http://llvm-reviews.chandlerc.com/D177

Files:
  lib/Format/Format.cpp
  unittests/Format/FormatTest.cpp

Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -102,6 +102,7 @@
     //State.UsedIndent.push_back(Line.Level * 2);
     State.Indent.push_back(Indent + 4);
     State.LastSpace.push_back(Indent);
+    State.LessLessPos.push_back(0);
 
     // Start iterating at 1 as we have correctly formatted of Token #0 above.
     for (unsigned i = 1, n = Line.Tokens.size(); i != n; ++i) {
@@ -126,8 +127,19 @@
     /// indented.
     std::vector<unsigned> Indent;
 
+    /// \brief The position of the last space on each level.
+    ///
+    /// Used e.g. to break like:
+    /// functionCall(Parameter, otherCall(
+    ///                             OtherParameter));
     std::vector<unsigned> LastSpace;
 
+    /// \brief The position the first "<<" operator encountered on each level.
+    ///
+    /// Used to align "<<" operators. 0 if no such operator has been encountered
+    /// on a level.
+    std::vector<unsigned> LessLessPos;
+
     bool CtorInitializerOnNewLine;
     bool InCtorInitializer;
 
@@ -149,6 +161,12 @@
         if (Other.LastSpace[i] != LastSpace[i])
           return Other.LastSpace[i] > LastSpace[i];
       }
+      if (Other.LessLessPos.size() != LessLessPos.size())
+        return Other.LessLessPos.size() > LessLessPos.size();
+      for (int i = 0, e = LessLessPos.size(); i != e; ++i) {
+        if (Other.LessLessPos[i] != LessLessPos[i])
+          return Other.LessLessPos[i] > LessLessPos[i];
+      }
       return false;
     }
   };
@@ -171,6 +189,9 @@
       if (Current.Tok.is(tok::string_literal) &&
           Previous.Tok.is(tok::string_literal))
         State.Column = State.Column - Previous.Tok.getLength();
+      else if (Current.Tok.is(tok::lessless) &&
+               State.LessLessPos[ParenLevel] != 0)
+        State.Column = State.LessLessPos[ParenLevel];
       else if (Previous.Tok.is(tok::equal) && ParenLevel != 0)
         // Indent and extra 4 spaces after '=' as it continues an expression.
         // Don't do that on the top level, as we already indent 4 there.
@@ -217,21 +238,27 @@
   void moveStateToNextToken(IndentState &State) {
     unsigned Index = State.ConsumedTokens;
     const FormatToken &Current = Line.Tokens[Index];
+    unsigned ParenLevel = State.Indent.size() - 1;
+
+    if (Current.Tok.is(tok::lessless) && State.LessLessPos[ParenLevel] == 0)
+      State.LessLessPos[ParenLevel] = State.Column - 2;
 
     // If we encounter an opening (, [ or <, we add a level to our stacks to
     // prepare for the following tokens.
     if (Current.Tok.is(tok::l_paren) || Current.Tok.is(tok::l_square) ||
         Annotations[Index].Type == TokenAnnotation::TT_TemplateOpener) {
       State.Indent.push_back(4 + State.LastSpace.back());
       State.LastSpace.push_back(State.LastSpace.back());
+      State.LessLessPos.push_back(0);
     }
 
     // If we encounter a closing ), ] or >, we can remove a level from our
     // stacks.
     if (Current.Tok.is(tok::r_paren) || Current.Tok.is(tok::r_square) ||
         Annotations[Index].Type == TokenAnnotation::TT_TemplateCloser) {
       State.Indent.pop_back();
       State.LastSpace.pop_back();
+      State.LessLessPos.pop_back();
     }
 
     ++State.ConsumedTokens;
@@ -687,6 +714,8 @@
       return false;
     if (isBinaryOperator(Left))
       return true;
+    if (Right.Tok.is(tok::lessless))
+      return true;
     return Right.Tok.is(tok::colon) || Left.Tok.is(tok::comma) ||
         Left.Tok.is(tok::semi) || Left.Tok.is(tok::equal) ||
         Left.Tok.is(tok::ampamp) || Left.Tok.is(tok::pipepipe) ||
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -434,5 +434,26 @@
 
 }
 
+TEST_F(FormatTest, AlignsPipes) {
+  verifyFormat(
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+  verifyFormat(
+      "aaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaa\n"
+      "                     << aaaaaaaaaaaaaaaaaaaa;");
+  verifyFormat(
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                                 << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+  verifyFormat(
+      "llvm::outs() << \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
+      "                \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n"
+      "             << \"ccccccccccccccccccccccccccccccccccccccccccccccccc\";");
+  verifyFormat(
+      "aaaaaaaa << (aaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                                 << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+      "         << aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+}
+
 }  // end namespace tooling
 }  // end namespace clang
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D177.1.patch
Type: text/x-patch
Size: 5027 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121205/9477676b/attachment.bin>


More information about the cfe-commits mailing list