aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2013-02-14 09:58:41 +0000
committerDaniel Jasper <djasper@google.com>2013-02-14 09:58:41 +0000
commitc78c6b35d398b4c9414e7c5c7e413e28a66c8c5f (patch)
tree4757f448fd63b2e78128cbb5a11942786f956368
parentc5cfa490a1fa4eb1a3a17803c6125b42abd73455 (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.cpp34
-rw-r--r--unittests/Format/FormatTest.cpp4
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.
//===----------------------------------------------------------------------===//