[clang-format] Fix bug in block comment reflow that joins * and /

Fixes PR41213

Differential Revision: https://reviews.llvm.org/D61276

llvm-svn: 359943
This commit is contained in:
Owen Pan 2019-05-03 23:15:40 +00:00
parent 3f796f974d
commit 3dcb892d2d
3 changed files with 39 additions and 2 deletions

View File

@ -65,7 +65,8 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment,
static BreakableToken::Split static BreakableToken::Split
getCommentSplit(StringRef Text, unsigned ContentStartColumn, getCommentSplit(StringRef Text, unsigned ContentStartColumn,
unsigned ColumnLimit, unsigned TabWidth, unsigned ColumnLimit, unsigned TabWidth,
encoding::Encoding Encoding, const FormatStyle &Style) { encoding::Encoding Encoding, const FormatStyle &Style,
bool DecorationEndsWithStar = false) {
LLVM_DEBUG(llvm::dbgs() << "Comment split: \"" << Text LLVM_DEBUG(llvm::dbgs() << "Comment split: \"" << Text
<< "\", Column limit: " << ColumnLimit << "\", Column limit: " << ColumnLimit
<< ", Content start: " << ContentStartColumn << "\n"); << ", Content start: " << ContentStartColumn << "\n");
@ -123,7 +124,10 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn,
if (SpaceOffset == 1 && Text[SpaceOffset - 1] == '*') if (SpaceOffset == 1 && Text[SpaceOffset - 1] == '*')
return BreakableToken::Split(StringRef::npos, 0); return BreakableToken::Split(StringRef::npos, 0);
StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks); StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks);
StringRef AfterCut = Text.substr(SpaceOffset).ltrim(Blanks); StringRef AfterCut = Text.substr(SpaceOffset);
// Don't trim the leading blanks if it would create a */ after the break.
if (!DecorationEndsWithStar || AfterCut.size() <= 1 || AfterCut[1] != '/')
AfterCut = AfterCut.ltrim(Blanks);
return BreakableToken::Split(BeforeCut.size(), return BreakableToken::Split(BeforeCut.size(),
AfterCut.begin() - BeforeCut.end()); AfterCut.begin() - BeforeCut.end());
} }
@ -452,6 +456,18 @@ BreakableBlockComment::BreakableBlockComment(
}); });
} }
BreakableToken::Split
BreakableBlockComment::getSplit(unsigned LineIndex, unsigned TailOffset,
unsigned ColumnLimit, unsigned ContentStartColumn,
llvm::Regex &CommentPragmasRegex) const {
// Don't break lines matching the comment pragmas regex.
if (CommentPragmasRegex.match(Content[LineIndex]))
return Split(StringRef::npos, 0);
return getCommentSplit(Content[LineIndex].substr(TailOffset),
ContentStartColumn, ColumnLimit, Style.TabWidth,
Encoding, Style, Decoration.endswith("*"));
}
void BreakableBlockComment::adjustWhitespace(unsigned LineIndex, void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
int IndentDelta) { int IndentDelta) {
// When in a preprocessor directive, the trailing backslash in a block comment // When in a preprocessor directive, the trailing backslash in a block comment

View File

@ -361,6 +361,9 @@ public:
bool InPPDirective, encoding::Encoding Encoding, bool InPPDirective, encoding::Encoding Encoding,
const FormatStyle &Style, bool UseCRLF); const FormatStyle &Style, bool UseCRLF);
Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
unsigned ContentStartColumn,
llvm::Regex &CommentPragmasRegex) const override;
unsigned getRangeLength(unsigned LineIndex, unsigned Offset, unsigned getRangeLength(unsigned LineIndex, unsigned Offset,
StringRef::size_type Length, StringRef::size_type Length,
unsigned StartColumn) const override; unsigned StartColumn) const override;

View File

@ -11150,6 +11150,24 @@ TEST_F(FormatTest, OptimizeBreakPenaltyVsExcess) {
FormatStyle Style = getLLVMStyle(); FormatStyle Style = getLLVMStyle();
Style.ColumnLimit = 20; Style.ColumnLimit = 20;
// See PR41213
EXPECT_EQ("/*\n"
" *\t9012345\n"
" * /8901\n"
" */",
format("/*\n"
" *\t9012345 /8901\n"
" */",
Style));
EXPECT_EQ("/*\n"
" *345678\n"
" *\t/8901\n"
" */",
format("/*\n"
" *345678\t/8901\n"
" */",
Style));
verifyFormat("int a; // the\n" verifyFormat("int a; // the\n"
" // comment", Style); " // comment", Style);
EXPECT_EQ("int a; /* first line\n" EXPECT_EQ("int a; /* first line\n"