================
@@ -1318,281 +1343,253 @@ void 
WhitespaceManager::alignArrayInitializers(unsigned Start, unsigned End) {
 
 void WhitespaceManager::alignArrayInitializersRightJustified(
     CellDescriptions &&CellDescs) {
-  if (!CellDescs.isRectangular())
+
+  // If there are less than two rows, there is nothing to align.
+  if (CellDescs.Rows.size() < 2)
+    return;
+
+  // If there are less than 2 columns, there is nothing to align.
+  const int ColumnCount = CellDescs.ColumnStartingCellIndices.size();
+  if (ColumnCount < 2)
     return;
 
   const int BracePadding = Style.Cpp11BracedListStyle ? 0 : 1;
+  auto &ColumnStartingIndices = CellDescs.ColumnStartingCellIndices;
   auto &Cells = CellDescs.Cells;
-  // Now go through and fixup the spaces.
-  auto *CellIter = Cells.begin();
-  for (auto i = 0U; i < CellDescs.CellCounts[0]; ++i, ++CellIter) {
-    unsigned NetWidth = 0U;
-    if (isSplitCell(*CellIter))
-      NetWidth = getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
-    auto CellWidth = getMaximumCellWidth(CellIter, NetWidth);
-
-    if (Changes[CellIter->Index].Tok->is(tok::r_brace)) {
-      // So in here we want to see if there is a brace that falls
-      // on a line that was split. If so on that line we make sure that
-      // the spaces in front of the brace are enough.
-      const auto *Next = CellIter;
-      do {
-        const FormatToken *Previous = Changes[Next->Index].Tok->Previous;
-        if (Previous && Previous->isNot(TT_LineComment)) {
-          Changes[Next->Index].Spaces = BracePadding;
-          Changes[Next->Index].NewlinesBefore = 0;
-        }
-        Next = Next->NextColumnElement;
-      } while (Next);
-      // Unless the array is empty, we need the position of all the
-      // immediately adjacent cells
-      if (CellIter != Cells.begin()) {
-        auto ThisNetWidth =
-            getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
-        auto MaxNetWidth = getMaximumNetWidth(
-            Cells.begin(), CellIter, CellDescs.InitialSpaces,
-            CellDescs.CellCounts[0], CellDescs.CellCounts.size());
-        if (ThisNetWidth < MaxNetWidth)
-          Changes[CellIter->Index].Spaces = (MaxNetWidth - ThisNetWidth);
-        auto RowCount = 1U;
-        auto Offset = std::distance(Cells.begin(), CellIter);
-        for (const auto *Next = CellIter->NextColumnElement; Next;
-             Next = Next->NextColumnElement) {
-          if (RowCount >= CellDescs.CellCounts.size())
-            break;
-          auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
-          auto *End = Start + Offset;
-          ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
-          if (ThisNetWidth < MaxNetWidth)
-            Changes[Next->Index].Spaces = (MaxNetWidth - ThisNetWidth);
-          ++RowCount;
-        }
-      }
-    } else {
-      auto ThisWidth =
-          calculateCellWidth(CellIter->Index, CellIter->EndIndex, true) +
-          NetWidth;
-      if (Changes[CellIter->Index].NewlinesBefore == 0) {
-        Changes[CellIter->Index].Spaces = (CellWidth - (ThisWidth + NetWidth));
-        Changes[CellIter->Index].Spaces += (i > 0) ? 1 : BracePadding;
-      }
-      alignToStartOfCell(CellIter->Index, CellIter->EndIndex);
-      for (const auto *Next = CellIter->NextColumnElement; Next;
-           Next = Next->NextColumnElement) {
-        ThisWidth =
-            calculateCellWidth(Next->Index, Next->EndIndex, true) + NetWidth;
-        if (Changes[Next->Index].NewlinesBefore == 0) {
-          Changes[Next->Index].Spaces = (CellWidth - ThisWidth);
-          Changes[Next->Index].Spaces += (i > 0) ? 1 : BracePadding;
-        }
-        alignToStartOfCell(Next->Index, Next->EndIndex);
-      }
+
+  // Calculate column widths.
+  SmallVector<unsigned> ColumnWidths;       // Widths from the previous column
+  SmallVector<unsigned> SummedColumnWidths; // Widths from the start of the row
+
+  unsigned CurrentWidth = 0;
+  for (unsigned CellIndex : ColumnStartingIndices) {
+    const CellDescription *current = &Cells[CellIndex];
+
+    unsigned MaxWidth = 0;
+    while (current != nullptr) {
+      unsigned CellWidth = calculateCellWidth(*current);
+
+      // +1 for the space after the comma in the previous column in all but
+      // the first column which has brace padding from the opening
+      // brace instead.
+      CellWidth += (current->Cell > 0) ? 1 : BracePadding;
+
+      MaxWidth = std::max(MaxWidth, CellWidth);
+      current = current->NextColumnElement;
     }
+
+    ColumnWidths.push_back(MaxWidth);
+
+    CurrentWidth += MaxWidth;
+    SummedColumnWidths.push_back(CurrentWidth);
+
+    // +1 for the comma between cells.
+    CurrentWidth++;
+  }
+
+  // Fixup spaces.
+  for (RowDescription &Row : CellDescs.Rows) {
+    unsigned WidthSoFarInRow = 0;
+    for (unsigned i = Row.StartCellIndex; i < Row.EndCellIndex; i++) {
+      const CellDescription &Cell = Cells[i];
+
+      const unsigned CellWidth = calculateCellWidth(Cell);
+      const unsigned AlignmentSpaces = ColumnWidths[Cell.Cell] - CellWidth;
+      setChangeSpaces(Cell.Index, AlignmentSpaces);
+      Changes[Cell.Index].IsWhitespaceAligned = true;
+
+      WidthSoFarInRow = SummedColumnWidths[Cell.Cell];
+
+      // +1 for the comma after columns in all but the last column
+      // Note: this can't check Cell.Cell because a row may not have a full
+      // set of columns.
+      if (i < Row.EndCellIndex - 1)
+        WidthSoFarInRow++;
+    }
+
+    // Align the end brace.
+    const unsigned AlignmentSpaces =
+        (SummedColumnWidths.back() - WidthSoFarInRow) + BracePadding;
+    setChangeSpaces(Row.ClosingBraceChangeIndex, AlignmentSpaces);
+    Changes[Row.ClosingBraceChangeIndex].IsWhitespaceAligned = true;
   }
 }
 
 void WhitespaceManager::alignArrayInitializersLeftJustified(
     CellDescriptions &&CellDescs) {
 
-  if (!CellDescs.isRectangular())
+  // If there are less than two rows, there is nothing to align.
+  if (CellDescs.Rows.size() < 2)
+    return;
+
+  // If there are less than 2 columns, there is nothing to align.
+  const unsigned ColumnCount = CellDescs.ColumnStartingCellIndices.size();
+  if (ColumnCount < 2)
     return;
 
+  const unsigned LastColumnIndex = ColumnCount - 1;
   const int BracePadding = Style.Cpp11BracedListStyle ? 0 : 1;
-  auto &Cells = CellDescs.Cells;
-  // Now go through and fixup the spaces.
-  auto *CellIter = Cells.begin();
-  // The first cell of every row needs to be against the left brace.
-  for (const auto *Next = CellIter; Next; Next = Next->NextColumnElement) {
-    auto &Change = Changes[Next->Index];
-    Change.Spaces =
-        Change.NewlinesBefore == 0 ? BracePadding : CellDescs.InitialSpaces;
-  }
-  ++CellIter;
-  for (auto i = 1U; i < CellDescs.CellCounts[0]; i++, ++CellIter) {
-    auto MaxNetWidth = getMaximumNetWidth(
-        Cells.begin(), CellIter, CellDescs.InitialSpaces,
-        CellDescs.CellCounts[0], CellDescs.CellCounts.size());
-    auto ThisNetWidth =
-        getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
-    if (Changes[CellIter->Index].NewlinesBefore == 0) {
-      Changes[CellIter->Index].Spaces =
-          MaxNetWidth - ThisNetWidth +
-          (Changes[CellIter->Index].Tok->isNot(tok::r_brace) ? 1
-                                                             : BracePadding);
-    }
-    auto RowCount = 1U;
-    auto Offset = std::distance(Cells.begin(), CellIter);
-    for (const auto *Next = CellIter->NextColumnElement; Next;
-         Next = Next->NextColumnElement) {
-      if (RowCount >= CellDescs.CellCounts.size())
-        break;
-      auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
-      auto *End = Start + Offset;
-      auto ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
-      if (Changes[Next->Index].NewlinesBefore == 0) {
-        Changes[Next->Index].Spaces =
-            MaxNetWidth - ThisNetWidth +
-            (Changes[Next->Index].Tok->isNot(tok::r_brace) ? 1 : BracePadding);
-      }
-      ++RowCount;
+  const auto &ColumnStartingIndices = CellDescs.ColumnStartingCellIndices;
+  const auto &Cells = CellDescs.Cells;
+
+  // Calculate column starting widths.
+  SmallVector<unsigned> StartWidths;
+
+  // The first column starts after the opening brace's padding.
+  StartWidths.push_back(BracePadding);
+
+  for (unsigned i = 0; i < ColumnCount; i++) {
+    const CellDescription *current = &Cells[ColumnStartingIndices[i]];
+
+    unsigned MaxWidth = 0;
+    while (current != nullptr) {
+      // calculateCellWidth returns relative column count from the previous
+      // cell, but we want it relative to the opening brace so we add
+      // starting width for this cell.
+      unsigned CellWidth = calculateCellWidth(*current) + StartWidths[i];
+
+      // +1 for the comma after the cell if it exists.
+      if (Changes[current->EndIndex].Tok->is(tok::comma))
+        CellWidth++;
+
+      // +1 for the space after the column if this is not the last column.
+      if (i < LastColumnIndex)
+        CellWidth++;
+
+      MaxWidth = std::max(MaxWidth, CellWidth);
+      current = current->NextColumnElement;
     }
+
+    // If this is the last column, add the brace padding to the width so that
+    // the end brace gets the necessary padding.
+    if (i == LastColumnIndex)
+      MaxWidth += BracePadding;
+
+    StartWidths.push_back(MaxWidth);
   }
-}
 
-bool WhitespaceManager::isSplitCell(const CellDescription &Cell) {
-  if (Cell.HasSplit)
-    return true;
-  for (const auto *Next = Cell.NextColumnElement; Next;
-       Next = Next->NextColumnElement) {
-    if (Next->HasSplit)
-      return true;
+  // Fixup spaces.
+  for (RowDescription &Row : CellDescs.Rows) {
+    unsigned WidthSoFarInRow = 0;
+
+    for (unsigned i = Row.StartCellIndex; i < Row.EndCellIndex; i++) {
+      const CellDescription &Cell = Cells[i];
+
+      Change &Change = Changes[Cell.Index];
+      const unsigned AlignmentSpaces = StartWidths[Cell.Cell] - 
WidthSoFarInRow;
+      setChangeSpaces(Cell.Index, AlignmentSpaces);
+      Change.IsWhitespaceAligned = true;
+
+      WidthSoFarInRow += calculateCellWidth(Cell) + Change.Spaces;
+
+      // +1 for the comma after columns in all but the last column
+      // Note: this can't check Cell.Cell because a row may not have a full
+      // set of columns.
+      if (i < Row.EndCellIndex - 1)
+        WidthSoFarInRow += 1;
+    }
+
+    // Align the end brace.
+    const unsigned AlignmentSpaces = StartWidths.back() - WidthSoFarInRow;
+    setChangeSpaces(Row.ClosingBraceChangeIndex, AlignmentSpaces);
+    Changes[Row.ClosingBraceChangeIndex].IsWhitespaceAligned = true;
   }
-  return false;
 }
 
 WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
                                                                 unsigned End) {
-
   unsigned Depth = 0;
   unsigned Cell = 0;
-  SmallVector<unsigned> CellCounts;
-  unsigned InitialSpaces = 0;
-  unsigned InitialTokenLength = 0;
-  unsigned EndSpaces = 0;
   SmallVector<CellDescription> Cells;
+  SmallVector<RowDescription> Rows;
+  SmallVector<unsigned> StartingCellIndices;
   const FormatToken *MatchingParen = nullptr;
+  RowDescription CurrentRow;
+  bool SkipCurrentRow = false;
   for (unsigned i = Start; i < End; ++i) {
     auto &C = Changes[i];
+
     if (C.Tok->is(tok::l_brace))
       ++Depth;
     else if (C.Tok->is(tok::r_brace))
       --Depth;
+
     if (Depth == 2) {
       if (C.Tok->is(tok::l_brace)) {
         Cell = 0;
+        SkipCurrentRow = false;
+        CurrentRow = RowDescription{unsigned(Cells.size()), 0, 0,
+                                    C.StartOfTokenColumn + C.TokenLength};
         MatchingParen = C.Tok->MatchingParen;
-        if (InitialSpaces == 0) {
-          InitialSpaces = C.Spaces + C.TokenLength;
-          InitialTokenLength = C.TokenLength;
-          auto j = i - 1;
-          for (; Changes[j].NewlinesBefore == 0 && j > Start; --j) {
-            InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
-            InitialTokenLength += Changes[j].TokenLength;
-          }
-          if (C.NewlinesBefore == 0) {
-            InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
-            InitialTokenLength += Changes[j].TokenLength;
-          }
-        }
       } else if (C.Tok->is(tok::comma)) {
         if (!Cells.empty())
           Cells.back().EndIndex = i;
+
         if (const auto *Next = C.Tok->getNextNonComment();
             Next && Next->isNot(tok::r_brace)) { // dangling comma
           ++Cell;
         }
       }
     } else if (Depth == 1) {
       if (C.Tok == MatchingParen) {
-        if (!Cells.empty())
-          Cells.back().EndIndex = i;
-        Cells.push_back(CellDescription{i, ++Cell, i + 1, false, nullptr});
-        CellCounts.push_back(C.Tok->Previous->isNot(tok::comma) ? Cell + 1
-                                                                : Cell);
-        // Go to the next non-comment and ensure there is a break in front
-        const auto *NextNonComment = C.Tok->getNextNonComment();
-        while (NextNonComment && NextNonComment->is(tok::comma))
-          NextNonComment = NextNonComment->getNextNonComment();
-        auto j = i;
-        while (j < End && Changes[j].Tok != NextNonComment)
-          ++j;
-        if (j < End && Changes[j].NewlinesBefore == 0 &&
-            Changes[j].Tok->isNot(tok::r_brace)) {
-          Changes[j].NewlinesBefore = 1;
-          // Account for the added token lengths
-          Changes[j].Spaces = InitialSpaces - InitialTokenLength;
+        // Rows with trailing commas are not aligned because they have each 
cell
+        // on a separate line
+        if (C.Tok->getPreviousNonComment()->is(tok::comma))
+          SkipCurrentRow = true;
+
+        if (SkipCurrentRow) {
+          // If we are skipping this row, we also need to remove the cells. We
+          // may have added cells before we found out the row needed to be
+          // skipped, so we just remove them at the end of the row for
+          // simplicity.
+          Cells.pop_back_n(Cells.size() - CurrentRow.StartCellIndex);
+        } else {
+          CurrentRow.ClosingBraceChangeIndex = i;
+          CurrentRow.EndCellIndex = Cells.size();
+          Rows.push_back(CurrentRow);
+
+          // If this is an empty row, just push back the cell.
+          if (Cell == 0) {
+            Cells.push_back(CellDescription{i, Cell, i + 1, nullptr});
+          } else {
+            if (!Cells.empty())
+              Cells.back().EndIndex = i;
+            Cells.push_back(CellDescription{i, ++Cell, i + 1, nullptr});
+          }
         }
-      } else if (C.Tok->is(tok::comment) && C.Tok->NewlinesBefore == 0) {
-        // Trailing comments stay at a space past the last token
-        C.Spaces = Changes[i - 1].Tok->is(tok::comma) ? 1 : 2;
-      } else if (C.Tok->is(tok::l_brace)) {
-        // We need to make sure that the ending braces is aligned to the
-        // start of our initializer
-        auto j = i - 1;
-        for (; j > 0 && !Changes[j].Tok->ArrayInitializerLineStart; --j)
-          ; // Nothing the loop does the work
-        EndSpaces = Changes[j].Spaces;
       }
-    } else if (Depth == 0 && C.Tok->is(tok::r_brace)) {
-      C.NewlinesBefore = 1;
-      C.Spaces = EndSpaces;
     }
+
     if (C.Tok->StartsColumn) {
-      // This gets us past tokens that have been split over multiple
-      // lines
-      bool HasSplit = false;
-      if (Changes[i].NewlinesBefore > 0) {
-        // So if we split a line previously and the tail line + this token is
-        // less then the column limit we remove the split here and just put
-        // the column start at a space past the comma
-        //
-        // FIXME This if branch covers the cases where the column is not
-        // the first column. This leads to weird pathologies like the 
formatting
-        // auto foo = Items{
-        //     Section{
-        //             0, bar(),
-        //     }
-        // };
-        // Well if it doesn't lead to that it's indicative that the line
-        // breaking should be revisited. Unfortunately alot of other options
-        // interact with this
-        auto j = i - 1;
-        if ((j - 1) > Start && Changes[j].Tok->is(tok::comma) &&
-            Changes[j - 1].NewlinesBefore > 0) {
-          --j;
-          auto LineLimit = Changes[j].Spaces + Changes[j].TokenLength;
-          if (LineLimit < Style.ColumnLimit) {
-            Changes[i].NewlinesBefore = 0;
-            Changes[i].Spaces = 1;
-          }
-        }
-      }
-      while (Changes[i].NewlinesBefore > 0 && Changes[i].Tok == C.Tok) {
-        Changes[i].Spaces = InitialSpaces;
-        ++i;
-        HasSplit = true;
+      if (C.NewlinesBefore > 0) {
+        SkipCurrentRow = true;
+      } else {
+        if (Cell >= StartingCellIndices.size())
+          StartingCellIndices.push_back(Cells.size());
+
+        Cells.push_back(CellDescription{i, Cell, i, nullptr});
       }
-      if (Changes[i].Tok != C.Tok)
-        --i;
-      Cells.push_back(CellDescription{i, Cell, i, HasSplit, nullptr});
     }
   }
 
-  return linkCells({Cells, CellCounts, InitialSpaces});
+  return linkCells({Cells, Rows, StartingCellIndices});
 }
 
-unsigned WhitespaceManager::calculateCellWidth(unsigned Start, unsigned End,
-                                               bool WithSpaces) const {
+unsigned
+WhitespaceManager::calculateCellWidth(const CellDescription &Cell) const {
   unsigned CellWidth = 0;
-  for (auto i = Start; i < End; i++) {
+  for (auto i = Cell.Index; i < Cell.EndIndex; i++) {
     if (Changes[i].NewlinesBefore > 0)
       CellWidth = 0;
+
+    if (CellWidth != 0)
+      CellWidth += Changes[i].Spaces;
+
     CellWidth += Changes[i].TokenLength;
-    CellWidth += (WithSpaces ? Changes[i].Spaces : 0);
   }
   return CellWidth;
 }
 
-void WhitespaceManager::alignToStartOfCell(unsigned Start, unsigned End) {
----------------
bdunkin wrote:

This function is no longer used.

https://github.com/llvm/llvm-project/pull/143781
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to