r236992 - clang-format: Improve column layout.

Daniel Jasper djasper at google.com
Mon May 11 06:35:41 PDT 2015


Author: djasper
Date: Mon May 11 08:35:40 2015
New Revision: 236992

URL: http://llvm.org/viewvc/llvm-project?rev=236992&view=rev
Log:
clang-format: Improve column layout.

Specifically, calculate the deviation between the shortest and longest
element (which is used to prevent excessive whitespace) per column, not
overall. This automatically handles the corner cases of a single column
and a single row so that the actualy implementation becomes simpler.

Before:
  vector<int> x = {1,
                   aaaaaaaaaaaaaaaaaaaaaa,
                   2,
                   bbbbbbbbbbbbbbbbbbbbbb,
                   3,
                   cccccccccccccccccccccc};

After:
  vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa,
                   2, bbbbbbbbbbbbbbbbbbbbbb,
                   3, cccccccccccccccccccccc};

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

Modified: cfe/trunk/lib/Format/FormatToken.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.cpp?rev=236992&r1=236991&r2=236992&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.cpp (original)
+++ cfe/trunk/lib/Format/FormatToken.cpp Mon May 11 08:35:40 2015
@@ -150,9 +150,6 @@ void CommaSeparatedList::precomputeForma
   // trailing comments which are otherwise ignored for column alignment.
   SmallVector<unsigned, 8> EndOfLineItemLength;
 
-  unsigned MinItemLength = Style.ColumnLimit;
-  unsigned MaxItemLength = 0;
-
   for (unsigned i = 0, e = Commas.size() + 1; i != e; ++i) {
     // Skip comments on their own line.
     while (ItemBegin->HasUnescapedNewline && ItemBegin->isTrailingComment())
@@ -179,8 +176,6 @@ void CommaSeparatedList::precomputeForma
       ItemEnd = Commas[i];
       // The comma is counted as part of the item when calculating the length.
       ItemLengths.push_back(CodePointsBetween(ItemBegin, ItemEnd));
-      MinItemLength = std::min(MinItemLength, ItemLengths.back());
-      MaxItemLength = std::max(MaxItemLength, ItemLengths.back());
 
       // Consume trailing comments so the are included in EndOfLineItemLength.
       if (ItemEnd->Next && !ItemEnd->Next->HasUnescapedNewline &&
@@ -197,19 +192,17 @@ void CommaSeparatedList::precomputeForma
 
   // If this doesn't have a nested list, we require at least 6 elements in order
   // create a column layout. If it has a nested list, column layout ensures one
-  // list element per line. If the difference between the shortest and longest
-  // element is too large, column layout would create too much whitespace.
+  // list element per line.
   if (Commas.size() < 5 || Token->NestingLevel != 0)
     return;
 
   // We can never place more than ColumnLimit / 3 items in a row (because of the
   // spaces and the comma).
-  unsigned MaxColumns =
-      MaxItemLength - MinItemLength > 10 ? 1 : Style.ColumnLimit / 3;
-  for (unsigned Columns = 1; Columns <= MaxColumns; ++Columns) {
+  for (unsigned Columns = 1; Columns <= Style.ColumnLimit / 3; ++Columns) {
     ColumnFormat Format;
     Format.Columns = Columns;
     Format.ColumnSizes.resize(Columns);
+    std::vector<unsigned> MinSizeInColumn(Columns, UINT_MAX);
     Format.LineCount = 1;
     bool HasRowWithSufficientColumns = false;
     unsigned Column = 0;
@@ -221,9 +214,10 @@ void CommaSeparatedList::precomputeForma
       }
       if (Column == Columns - 1)
         HasRowWithSufficientColumns = true;
-      unsigned length =
+      unsigned Length =
           (Column == Columns - 1) ? EndOfLineItemLength[i] : ItemLengths[i];
-      Format.ColumnSizes[Column] = std::max(Format.ColumnSizes[Column], length);
+      Format.ColumnSizes[Column] = std::max(Format.ColumnSizes[Column], Length);
+      MinSizeInColumn[Column] = std::min(MinSizeInColumn[Column], Length);
       ++Column;
     }
     // If all rows are terminated early (e.g. by trailing comments), we don't
@@ -231,9 +225,19 @@ void CommaSeparatedList::precomputeForma
     if (!HasRowWithSufficientColumns)
       break;
     Format.TotalWidth = Columns - 1; // Width of the N-1 spaces.
-    for (unsigned i = 0; i < Columns; ++i) {
+
+    for (unsigned i = 0; i < Columns; ++i)
       Format.TotalWidth += Format.ColumnSizes[i];
-    }
+
+    // Don't use this Format, if the difference between the longest and shortest
+    // element in a column exceeds a threshold to avoid excessive spaces.
+    if ([&] {
+          for (unsigned i = 0; i < Columns - 1; ++i)
+            if (Format.ColumnSizes[i] - MinSizeInColumn[i] > 10)
+              return true;
+          return false;
+        }())
+      continue;
 
     // Ignore layouts that are bound to violate the column limit.
     if (Format.TotalWidth > Style.ColumnLimit)

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=236992&r1=236991&r2=236992&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Mon May 11 08:35:40 2015
@@ -6305,6 +6305,11 @@ TEST_F(FormatTest, FormatsBracedListsInC
                "    \"aaaaaaaaaaaa\",\n"
                "    \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n"
                "};");
+  verifyFormat("vector<int> x = {1, 2, 3, 4, aaaaaaaaaaaaaaaaa, 6};");
+  verifyFormat("vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa,\n"
+               "                 2, bbbbbbbbbbbbbbbbbbbbbb,\n"
+               "                 3, cccccccccccccccccccccc};",
+               getLLVMStyleWithColumns(60));
 
   // Trailing commas.
   verifyFormat("vector<int> x = {\n"





More information about the cfe-commits mailing list