[cfe-commits] r170337 - in /cfe/trunk: lib/Format/Format.cpp unittests/Format/FormatTest.cpp

Daniel Jasper djasper at google.com
Mon Dec 17 06:34:14 PST 2012


Author: djasper
Date: Mon Dec 17 08:34:14 2012
New Revision: 170337

URL: http://llvm.org/viewvc/llvm-project?rev=170337&view=rev
Log:
Add basic support for splitting before function calls if it can't be
avoided.

This required a minor modification of the memoization as now the
"CurrentPenalty" depends on whether or not we break before the current
token. Therefore, the CurrentPenalty should not be memoized but added
after retrieving a value from memory. This should not affect the runtime
behavior.

Modified:
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=170337&r1=170336&r2=170337&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Mon Dec 17 08:34:14 2012
@@ -198,7 +198,9 @@
       else if (Current.Tok.is(tok::lessless) &&
                State.FirstLessLess[ParenLevel] != 0)
         State.Column = State.FirstLessLess[ParenLevel];
-      else if (Previous.Tok.is(tok::equal) && ParenLevel != 0)
+      else if (ParenLevel != 0 &&
+               (Previous.Tok.is(tok::equal) || Current.Tok.is(tok::arrow) ||
+                Current.Tok.is(tok::period)))
         // 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.
         State.Column = State.Indent[ParenLevel] + 4;
@@ -271,14 +273,23 @@
     ++State.ConsumedTokens;
   }
 
-  unsigned splitPenalty(const FormatToken &Token) {
-    if (Token.Tok.is(tok::semi))
+  /// \brief Calculate the panelty for splitting after the token at \p Index.
+  unsigned splitPenalty(unsigned Index) {
+    assert(Index < Line.Tokens.size() &&
+           "Tried to calculate penalty for splitting after the last token");
+    const FormatToken &Left = Line.Tokens[Index];
+    const FormatToken &Right = Line.Tokens[Index + 1];
+    if (Left.Tok.is(tok::semi))
       return 0;
-    if (Token.Tok.is(tok::comma))
+    if (Left.Tok.is(tok::comma))
       return 1;
-    if (Token.Tok.is(tok::equal) || Token.Tok.is(tok::l_paren) ||
-        Token.Tok.is(tok::pipepipe) || Token.Tok.is(tok::ampamp))
+    if (Left.Tok.is(tok::equal) || Left.Tok.is(tok::l_paren) ||
+        Left.Tok.is(tok::pipepipe) || Left.Tok.is(tok::ampamp))
       return 2;
+
+    if (Right.Tok.is(tok::arrow) || Right.Tok.is(tok::period))
+      return 200;
+
     return 3;
   }
 
@@ -313,8 +324,7 @@
     unsigned CurrentPenalty = 0;
     if (NewLine) {
       CurrentPenalty += Parameters.PenaltyIndentLevel * State.Indent.size() +
-          Parameters.PenaltyExtraLine +
-          splitPenalty(Line.Tokens[State.ConsumedTokens - 1]);
+          Parameters.PenaltyExtraLine + splitPenalty(State.ConsumedTokens - 1);
     }
 
     addTokenToState(NewLine, true, State);
@@ -335,17 +345,21 @@
       // - are now computing for a smaller or equal StopAt.
       unsigned SavedResult = I->second.first;
       unsigned SavedStopAt = I->second.second;
-      if (SavedResult != UINT_MAX || StopAt <= SavedStopAt)
-        return SavedResult;
+      if (SavedResult != UINT_MAX)
+        return SavedResult + CurrentPenalty;
+      else if (StopAt <= SavedStopAt)
+        return UINT_MAX;
     }
 
     unsigned NoBreak = calcPenalty(State, false, StopAt);
     unsigned WithBreak = calcPenalty(State, true, std::min(StopAt, NoBreak));
     unsigned Result = std::min(NoBreak, WithBreak);
-    if (Result != UINT_MAX)
-      Result += CurrentPenalty;
+
+    // We have to store 'Result' without adding 'CurrentPenalty' as the latter
+    // can depend on 'NewLine'.
     Memory[State] = std::pair<unsigned, unsigned>(Result, StopAt);
-    return Result;
+
+    return Result == UINT_MAX ? UINT_MAX : Result + CurrentPenalty;
   }
 
   /// \brief Replaces the whitespace in front of \p Tok. Only call once for
@@ -737,9 +751,8 @@
     if (Right.Tok.is(tok::r_paren) || Right.Tok.is(tok::l_brace) ||
         Right.Tok.is(tok::comment) || Right.Tok.is(tok::greater))
       return false;
-    if (isBinaryOperator(Left))
-      return true;
-    if (Right.Tok.is(tok::lessless))
+    if (isBinaryOperator(Left) || Right.Tok.is(tok::lessless) ||
+        Right.Tok.is(tok::arrow) || Right.Tok.is(tok::period))
       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) ||

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=170337&r1=170336&r2=170337&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Mon Dec 17 08:34:14 2012
@@ -444,6 +444,37 @@
                "        100000000 + 100000000) {\n}");
 }
 
+TEST_F(FormatTest, WrapsAtFunctionCallsIfNecessary) {
+  verifyFormat(
+      "LoooooooooooooooooooooooooooooooooooooongObject\n"
+      "    .looooooooooooooooooooooooooooooooooooooongFunction();");
+
+  verifyFormat(
+      "LoooooooooooooooooooooooooooooooooooooongObject\n"
+      "    ->looooooooooooooooooooooooooooooooooooooongFunction();");
+
+  verifyFormat(
+      "LooooooooooooooooooooooooooooooooongObject->shortFunction(Parameter1,\n"
+      "                                                          Parameter2);");
+
+  verifyFormat(
+      "ShortObject->shortFunction(\n"
+      "    LooooooooooooooooooooooooooooooooooooooooooooooongParameter1,\n"
+      "    LooooooooooooooooooooooooooooooooooooooooooooooongParameter2);");
+
+  verifyFormat("loooooooooooooongFunction(\n"
+               "    LoooooooooooooongObject->looooooooooooooooongFunction());");
+
+  verifyFormat(
+      "function(LoooooooooooooooooooooooooooooooooooongObject\n"
+      "             ->loooooooooooooooooooooooooooooooooooooooongFunction());");
+
+  verifyFormat(
+      "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaa) ||\n"
+      "    aaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
+      "}");
+}
+
 TEST_F(FormatTest, UnderstandsTemplateParameters) {
   verifyFormat("A<int> a;");
   verifyFormat("A<A<A<int> > > a;");





More information about the cfe-commits mailing list