r175152 - Remove the trailing whitespace of formatted lines.

Daniel Jasper djasper at google.com
Thu Feb 14 01:58:42 PST 2013


Author: djasper
Date: Thu Feb 14 03:58:41 2013
New Revision: 175152

URL: http://llvm.org/viewvc/llvm-project?rev=175152&view=rev
Log:
Remove the trailing whitespace of formatted lines.

So far, clang-format has always assumed the whitespace belonging to the
subsequent token. This has the negative side-effect that when
clang-format formats a line, it does not remove its trailing whitespace,
as it belongs to the next token.

Thus, this patch fixes most of llvm.org/PR15062.

We are not zapping a file's trailing whitespace so far, as this does not
belong to any token we see during formatting. We need to fix this in a
subsequent patch.

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=175152&r1=175151&r2=175152&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Thu Feb 14 03:58:41 2013
@@ -960,16 +960,17 @@ public:
       Annotator.calculateFormattingInformation(AnnotatedLines[i]);
     }
     std::vector<int> IndentForLevel;
+    bool PreviousLineWasTouched = false;
     for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
                                               E = AnnotatedLines.end();
          I != E; ++I) {
       const AnnotatedLine &TheLine = *I;
-      int Offset = GetIndentOffset(TheLine.First);
+      int Offset = getIndentOffset(TheLine.First);
       while (IndentForLevel.size() <= TheLine.Level)
         IndentForLevel.push_back(-1);
       IndentForLevel.resize(TheLine.Level + 1);
       if (touchesRanges(TheLine) && TheLine.Type != LT_Invalid) {
-        unsigned LevelIndent = GetIndent(IndentForLevel, TheLine.Level);
+        unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);
         unsigned Indent = LevelIndent;
         if (static_cast<int>(Indent) + Offset >= 0)
           Indent += Offset;
@@ -987,15 +988,8 @@ public:
                                          StructuralError);
         PreviousEndOfLineColumn = Formatter.format();
         IndentForLevel[TheLine.Level] = LevelIndent;
+        PreviousLineWasTouched = true;
       } else {
-        // If we did not reformat this unwrapped line, the column at the end of
-        // the last token is unchanged - thus, we can calculate the end of the
-        // last token.
-        PreviousEndOfLineColumn =
-            SourceMgr.getSpellingColumnNumber(
-                TheLine.Last->FormatTok.Tok.getLocation()) +
-            Lex.MeasureTokenLength(TheLine.Last->FormatTok.Tok.getLocation(),
-                                   SourceMgr, Lex.getLangOpts()) - 1;
         if (TheLine.First.FormatTok.NewlinesBefore > 0 ||
             TheLine.First.FormatTok.IsFirst) {
           unsigned Indent = SourceMgr.getSpellingColumnNumber(
@@ -1004,7 +998,21 @@ public:
           if (static_cast<int>(LevelIndent) - Offset >= 0)
             LevelIndent -= Offset;
           IndentForLevel[TheLine.Level] = LevelIndent;
+
+          // Remove trailing whitespace of the previous line if it was touched.
+          if (PreviousLineWasTouched)
+            formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
+                             PreviousEndOfLineColumn);
         }
+        // If we did not reformat this unwrapped line, the column at the end of
+        // the last token is unchanged - thus, we can calculate the end of the
+        // last token.
+        PreviousEndOfLineColumn =
+            SourceMgr.getSpellingColumnNumber(
+                TheLine.Last->FormatTok.Tok.getLocation()) +
+            Lex.MeasureTokenLength(TheLine.Last->FormatTok.Tok.getLocation(),
+                                   SourceMgr, Lex.getLangOpts()) - 1;
+        PreviousLineWasTouched = false;
       }
     }
     return Whitespaces.generateReplacements();
@@ -1016,20 +1024,20 @@ private:
   /// \p IndentForLevel must contain the indent for the level \c l
   /// at \p IndentForLevel[l], or a value < 0 if the indent for
   /// that level is unknown.
-  unsigned GetIndent(const std::vector<int> IndentForLevel,
+  unsigned getIndent(const std::vector<int> IndentForLevel,
                      unsigned Level) {
     if (IndentForLevel[Level] != -1)
       return IndentForLevel[Level];
     if (Level == 0)
       return 0;
-    return GetIndent(IndentForLevel, Level - 1) + 2;
+    return getIndent(IndentForLevel, Level - 1) + 2;
   }
 
   /// \brief Get the offset of the line relatively to the level.
   ///
   /// For example, 'public:' labels in classes are offset by 1 or 2
   /// characters to the left from their level.
-  int GetIndentOffset(const AnnotatedToken &RootToken) {
+  int getIndentOffset(const AnnotatedToken &RootToken) {
     bool IsAccessModifier = false;
     if (RootToken.is(tok::kw_public) || RootToken.is(tok::kw_protected) ||
         RootToken.is(tok::kw_private))

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=175152&r1=175151&r2=175152&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Feb 14 03:58:41 2013
@@ -162,6 +162,10 @@ TEST_F(FormatTest, OnlyGeneratesNecessar
   EXPECT_EQ(0, ReplacementCount);
 }
 
+TEST_F(FormatTest, RemovesTrailingWhitespaceOfFormattedLine) {
+  EXPECT_EQ("int a;\nint b;", format("int a; \nint b;", 0, 0, getLLVMStyle()));
+}
+
 //===----------------------------------------------------------------------===//
 // Tests for control statements.
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list