forked from OSchip/llvm-project
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. llvm-svn: 175152
This commit is contained in:
parent
66e9dee707
commit
2457010b1c
|
@ -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))
|
||||
|
|
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue