diff options
author | Daniel Jasper <djasper@google.com> | 2013-02-14 09:58:41 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-02-14 09:58:41 +0000 |
commit | c78c6b35d398b4c9414e7c5c7e413e28a66c8c5f (patch) | |
tree | 4757f448fd63b2e78128cbb5a11942786f956368 | |
parent | c5cfa490a1fa4eb1a3a17803c6125b42abd73455 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175152 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Format/Format.cpp | 34 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 4 |
2 files changed, 25 insertions, 13 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index f03b77853c..c50bfb0a70 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -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)) diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index e99aad7a8c..232cd6b98a 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -162,6 +162,10 @@ TEST_F(FormatTest, OnlyGeneratesNecessaryReplacements) { 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. //===----------------------------------------------------------------------===// |