From: Alexander Kornienko Date: Tue, 12 Nov 2013 17:50:13 +0000 (+0000) Subject: Remove extra whitespace instead of breaking the line in comments when possible. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a7462b8ce22a3f754bf51eeeb01adafc42b32cea;p=clang Remove extra whitespace instead of breaking the line in comments when possible. Summary: Solves the problem described in http://llvm.org/PR17756 Reviewers: klimek Reviewed By: klimek CC: cfe-commits, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D2131 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194493 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp index 97475780f4..d720ce990b 100644 --- a/lib/Format/BreakableToken.cpp +++ b/lib/Format/BreakableToken.cpp @@ -215,7 +215,16 @@ void BreakableLineComment::insertBreak(unsigned LineIndex, unsigned TailOffset, WhitespaceManager &Whitespaces) { Whitespaces.replaceWhitespaceInToken( Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second, - Postfix, Prefix, InPPDirective, 1, IndentLevel, StartColumn); + Postfix, Prefix, InPPDirective, /*Newlines=*/1, IndentLevel, StartColumn); +} + +void BreakableLineComment::replaceWhitespace(unsigned LineIndex, + unsigned TailOffset, Split Split, + WhitespaceManager &Whitespaces) { + Whitespaces.replaceWhitespaceInToken( + Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second, "", + "", /*InPPDirective=*/false, /*Newlines=*/0, /*IndentLevel=*/0, + /*Spaces=*/1); } void @@ -223,7 +232,9 @@ BreakableLineComment::replaceWhitespaceBefore(unsigned LineIndex, WhitespaceManager &Whitespaces) { if (OriginalPrefix != Prefix) { Whitespaces.replaceWhitespaceInToken(Tok, OriginalPrefix.size(), 0, "", "", - false, 0, /*IndentLevel=*/0, 1); + /*InPPDirective=*/false, + /*Newlines=*/0, /*IndentLevel=*/0, + /*Spaces=*/1); } } @@ -374,6 +385,18 @@ void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset, IndentLevel, IndentAtLineBreak - Decoration.size()); } +void BreakableBlockComment::replaceWhitespace(unsigned LineIndex, + unsigned TailOffset, Split Split, + WhitespaceManager &Whitespaces) { + StringRef Text = Lines[LineIndex].substr(TailOffset); + unsigned BreakOffsetInToken = + Text.data() - Tok.TokenText.data() + Split.first; + unsigned CharsToRemove = Split.second; + Whitespaces.replaceWhitespaceInToken( + Tok, BreakOffsetInToken, CharsToRemove, "", "", /*InPPDirective=*/false, + /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1); +} + void BreakableBlockComment::replaceWhitespaceBefore(unsigned LineIndex, WhitespaceManager &Whitespaces) { diff --git a/lib/Format/BreakableToken.h b/lib/Format/BreakableToken.h index 132301c9f6..b965190d54 100644 --- a/lib/Format/BreakableToken.h +++ b/lib/Format/BreakableToken.h @@ -61,6 +61,12 @@ public: virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) = 0; + /// \brief Replaces the whitespace range described by \p Split with a single + /// space. + virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, + Split Split, + WhitespaceManager &Whitespaces) = 0; + /// \brief Replaces the whitespace between \p LineIndex-1 and \p LineIndex. virtual void replaceWhitespaceBefore(unsigned LineIndex, WhitespaceManager &Whitespaces) {} @@ -121,6 +127,9 @@ public: unsigned ColumnLimit) const; virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces); + virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, + Split Split, + WhitespaceManager &Whitespaces) {} }; class BreakableLineComment : public BreakableSingleLineToken { @@ -137,6 +146,9 @@ public: unsigned ColumnLimit) const; virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces); + virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, + Split Split, + WhitespaceManager &Whitespaces); virtual void replaceWhitespaceBefore(unsigned LineIndex, WhitespaceManager &Whitespaces); @@ -166,6 +178,9 @@ public: unsigned ColumnLimit) const; virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces); + virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, + Split Split, + WhitespaceManager &Whitespaces); virtual void replaceWhitespaceBefore(unsigned LineIndex, WhitespaceManager &Whitespaces); diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 1e10ce3492..971acc2b7a 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -813,6 +813,15 @@ unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, assert(Split.first != 0); unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit( LineIndex, TailOffset + Split.first + Split.second, StringRef::npos); + + // We can remove extra whitespace instead of breaking the line. + if (RemainingTokenColumns + 1 - Split.second <= RemainingSpace) { + RemainingTokenColumns = 0; + if (!DryRun) + Token->replaceWhitespace(LineIndex, TailOffset, Split, Whitespaces); + break; + } + assert(NewRemainingTokenColumns < RemainingTokenColumns); if (!DryRun) Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 9f05619bb1..f2ac3ba94f 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -985,6 +985,11 @@ TEST_F(FormatTest, SplitsLongCxxComments) { format("//Even if it makes the line exceed the column limit", getLLVMStyleWithColumns(51))); EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle())); + + EXPECT_EQ("// aa bb cc dd", + format("// aa bb cc dd ", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("// A comment before\n" "// a macro\n" "// definition\n" @@ -1252,6 +1257,17 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { " \n" " \n" " */\n")); + + EXPECT_EQ("/* a a */", + format("/* a a */", getLLVMStyleWithColumns(15))); + EXPECT_EQ("/* a a bc */", + format("/* a a bc */", getLLVMStyleWithColumns(15))); + EXPECT_EQ("/* aaa aaa\n" + " * aaaaa */", + format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); + EXPECT_EQ("/* aaa aaa\n" + " * aaaaa */", + format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); } TEST_F(FormatTest, SplitsLongLinesInCommentsInPreprocessor) {