[clang] e71c537 - [clang-format] Fix line lengths w/ comments in align

via cfe-commits cfe-commits at lists.llvm.org
Tue May 19 23:22:28 PDT 2020


Author: mydeveloperday
Date: 2020-05-20T07:22:01+01:00
New Revision: e71c537a487cacaa00265e1acb765235943d5172

URL: https://github.com/llvm/llvm-project/commit/e71c537a487cacaa00265e1acb765235943d5172
DIFF: https://github.com/llvm/llvm-project/commit/e71c537a487cacaa00265e1acb765235943d5172.diff

LOG: [clang-format] Fix line lengths w/ comments in align

Summary:
https://bugs.llvm.org/show_bug.cgi?id=43845

When a '//comment' trails a consecutive alignment, it adds a whitespace
replacement within the comment token. This wasn't handled correctly in
the alignment code, which treats it as a whole token and thus double
counts it.

This can wrongly trigger the "line too long, it'll wrap" alignment-break
condition with specific lengths, causing the alignment to break for
seemingly no reason.

Patch By:  JakeMerdichAMD

Reviewed By: MyDeveloperDay

Subscribers: kostyakozko, cfe-commits

Tags: #clang, #clang-format

Differential Revision: https://reviews.llvm.org/D79465

Added: 
    

Modified: 
    clang/lib/Format/WhitespaceManager.cpp
    clang/unittests/Format/FormatTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 000141a7a1b0..fd1d74933925 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -445,8 +445,16 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
 
     unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
     int LineLengthAfter = Changes[i].TokenLength;
-    for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j)
-      LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
+    for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) {
+      LineLengthAfter += Changes[j].Spaces;
+      // Changes are generally 1:1 with the tokens, but a change could also be
+      // inside of a token, in which case it's counted more than once: once for
+      // the whitespace surrounding the token (!IsInsideToken) and once for
+      // each whitespace change within it (IsInsideToken).
+      // Therefore, changes inside of a token should only count the space.
+      if (!Changes[j].IsInsideToken)
+        LineLengthAfter += Changes[j].TokenLength;
+    }
     unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
 
     // If we are restricted by the maximum column width, end the sequence.

diff  --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a0b1dc7331e1..5eefe99214b2 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12010,6 +12010,16 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
                "  x = 1;\n"
                "y = 1;\n",
                Alignment);
+
+  Alignment.ReflowComments = true;
+  Alignment.ColumnLimit = 50;
+  EXPECT_EQ("int x   = 0;\n"
+            "int yy  = 1; /// specificlennospace\n"
+            "int zzz = 2;\n",
+            format("int x   = 0;\n"
+                   "int yy  = 1; ///specificlennospace\n"
+                   "int zzz = 2;\n",
+                   Alignment));
 }
 
 TEST_F(FormatTest, AlignConsecutiveDeclarations) {


        


More information about the cfe-commits mailing list