oleg.smolsky updated this revision to Diff 167611.
oleg.smolsky marked an inline comment as done.
oleg.smolsky added a comment.

Tweaked if/else/return structure, added comments. No functional changes.


Repository:
  rC Clang

https://reviews.llvm.org/D52676

Files:
  lib/Format/ContinuationIndenter.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -11785,6 +11785,60 @@
                "      return j;\n"
                "    });");
 
+  // A lambda passed as arg0 is always pushed to the next line.
+  verifyFormat("void f() {\n"
+               "  something->Method1(\n"
+               "      [this] {\n"
+               "        Do1();\n"
+               "        Do2();\n"
+               "      },\n"
+               "      1);\n"
+               "}\n");
+
+  // A lambda passed as arg1 forces arg0 to be pushed out when
+  // BinPackArguments=false.
+  {
+    auto Style = getGoogleStyle();
+    Style.BinPackArguments = false;
+    verifyFormat("void f() {\n"
+                 "  something->Method2s(\n"
+                 "      1,\n"
+                 "      [this] {\n"
+                 "        Do1();\n"
+                 "        Do2();\n"
+                 "      },\n"
+                 "      1);\n"
+                 "}\n",
+                 Style);
+  }
+
+  // A lambda with a very long line forces arg0 to be pushed out irrespective of
+  // the BinPackArguments value.
+  verifyFormat("void f() {\n"
+               "  something->Method2l(\n"
+               "      1,\n"
+               "      [this] {\n"
+               "        Do1();\n"
+               "        D0000000000000000000000000000000000000000000000000000000001();\n"
+               "      },\n"
+               "      1);\n"
+               "}\n");
+
+  // Multiple lambdas are treated correctly even when there is a short arg0.
+  verifyFormat("void f() {\n"
+               "  something->Method3(\n"
+               "      1,\n"
+               "      [this] {\n"
+               "        Do1();\n"
+               "        Do2();\n"
+               "      },\n"
+               "      [this] {\n"
+               "        Do1();\n"
+               "        Do2();\n"
+               "      },\n"
+               "      1);\n"
+               "}\n");
+
   // More complex introducers.
   verifyFormat("return [i, args...] {};");
 
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -988,18 +988,17 @@
       Path.push_front(Best);
       Best = Best->Previous;
     }
-    for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();
-         I != E; ++I) {
+    for (auto I = Path.begin(), E = Path.end(); I != E; ++I) {
       unsigned Penalty = 0;
       formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty);
       Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false);
 
       LLVM_DEBUG({
         printLineState((*I)->Previous->State);
         if ((*I)->NewLine) {
           llvm::dbgs() << "Penalty for placing "
-                       << (*I)->Previous->State.NextToken->Tok.getName() << ": "
-                       << Penalty << "\n";
+                       << (*I)->Previous->State.NextToken->Tok.getName()
+                       << " on a new line: " << Penalty << "\n";
         }
       });
     }
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -3043,6 +3043,22 @@
       return true;
   }
 
+  // Deal with lambda arguments in C++ - we want consistent line breaks whether
+  // they happen to be at arg0, arg1 or argN. The selection is a bit nuanced
+  // as aggressive line breaks only make sense when the user had set
+  // Style.BinPackArguments to 'false'.
+  if ((Style.Language == FormatStyle::LK_Cpp ||
+       Style.Language == FormatStyle::LK_ObjC) &&
+      Left.is(tok::l_paren) && Left.BlockParameterCount > 0 &&
+      !Right.isOneOf(tok::l_paren, TT_LambdaLSquare)) {
+    // Always break lines in the "multiple lumbdas" case.
+    if (Left.BlockParameterCount > 1)
+      return true;
+    // Break lines with a lambda when the style disallows arg packing.
+    if (!Style.BinPackArguments)
+      return true;
+  }
+
   return false;
 }
 
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -1135,7 +1135,8 @@
   //   }, a, b, c);
   if (Current.isNot(tok::comment) && Previous &&
       Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
-      !Previous->is(TT_DictLiteral) && State.Stack.size() > 1) {
+      !Previous->is(TT_DictLiteral) && State.Stack.size() > 1 &&
+      !State.Stack.back().HasMultipleNestedBlocks) {
     if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
       for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
         State.Stack[i].NoLineBreak = true;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to