diff options
| author | Krasimir Georgiev <krasimir@google.com> | 2017-02-02 14:36:50 +0000 |
|---|---|---|
| committer | Krasimir Georgiev <krasimir@google.com> | 2017-02-02 14:36:50 +0000 |
| commit | b6ccd38deecfcdb62280491553ad558efe5db6ec (patch) | |
| tree | a6033a370a4e6ca79d5d8ac645d4a646f37ac845 | |
| parent | 98075fe1815252ad52dbeded432f37908f294057 (diff) | |
| download | bcm5719-llvm-b6ccd38deecfcdb62280491553ad558efe5db6ec.tar.gz bcm5719-llvm-b6ccd38deecfcdb62280491553ad558efe5db6ec.zip | |
[clang-format] Fix breaking of comment sections in unwrapped lines containing newlines.
Summary:
The breaking of line comment sections was misaligning the case where the first comment line is on an unwrapped line containing newlines. In this case, the breaking column must be based on the source column of the last token that is preceded by a newline, not on the first token of the unwrapped line.
source:
```
enum A {
a, // line 1
// line 2
};
```
format before:
```
enum A {
a, // line 1
// line 2
};
```
format after:
```
enum A {
a, // line 1
// line 2
};
```
Reviewers: djasper
Reviewed By: djasper
Subscribers: cfe-commits, klimek
Differential Revision: https://reviews.llvm.org/D29444
llvm-svn: 293891
| -rw-r--r-- | clang/lib/Format/BreakableToken.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Format/FormatToken.h | 5 | ||||
| -rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 39 | ||||
| -rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 41 |
4 files changed, 83 insertions, 4 deletions
diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 09f17a35d07..e9dd253f3ec 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -695,7 +695,7 @@ BreakableLineCommentSection::BreakableLineCommentSection( Content[i] = Content[i].substr(0, EndOfLine); } LineTok = CurrentTok->Next; - if (CurrentTok->Next && CurrentTok->Next->NewlinesBefore > 1) { + if (CurrentTok->Next && !CurrentTok->Next->ContinuesLineCommentSection) { // A line comment section needs to broken by a line comment that is // preceded by at least two newlines. Note that we put this break here // instead of breaking at a previous stage during parsing, since that diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index c838cfbe1da..d6a2ff286ae 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -261,6 +261,11 @@ struct FormatToken { /// Only set if \c Type == \c TT_StartOfName. bool PartOfMultiVariableDeclStmt = false; + /// \brief Does this line comment continue a line comment section? + /// + /// Only set to true if \c Type == \c TT_LineComment. + bool ContinuesLineCommentSection = false; + /// \brief If this is a bracket, this points to the matching one. FormatToken *MatchingParen = nullptr; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index a96d4d9be3e..2c7b87ee014 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2066,31 +2066,58 @@ static bool continuesLineComment(const FormatToken &FormatTok, // original start column of the min column token of the line. // // For example, the second line comment continues the first in these cases: + // // // first line // // second line + // // and: + // // // first line // // second line + // // and: + // // int i; // first line // // second line + // // and: + // // do { // first line // // second line // int i; // } while (true); // + // and: + // + // enum { + // a, // first line + // // second line + // b + // }; + // // The second line comment doesn't continue the first in these cases: + // // // first line // // second line + // // and: + // // int i; // first line // // second line + // // and: + // // do { // first line // // second line // int i; // } while (true); + // + // and: + // + // enum { + // a, // first line + // // second line + // }; const FormatToken *MinColumnToken = Line.Tokens.front().Tok; // Scan for '{//'. If found, use the column of '{' as a min column for line @@ -2103,6 +2130,11 @@ static bool continuesLineComment(const FormatToken &FormatTok, break; } PreviousToken = Node.Tok; + + // Grab the last newline preceding a token in this unwrapped line. + if (Node.Tok->NewlinesBefore > 0) { + MinColumnToken = Node.Tok; + } } if (PreviousToken && PreviousToken->is(tok::l_brace)) { MinColumnToken = PreviousToken; @@ -2130,7 +2162,8 @@ void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { // // FIXME: Consider putting separate line comment sections as children to the // unwrapped line instead. - if (isOnNewLine(**I) && JustComments && !continuesLineComment(**I, *Line)) + (*I)->ContinuesLineCommentSection = continuesLineComment(**I, *Line); + if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection) addUnwrappedLine(); pushToken(*I); } @@ -2196,7 +2229,9 @@ void UnwrappedLineParser::readToken() { if (!FormatTok->Tok.is(tok::comment)) return; - if (!continuesLineComment(*FormatTok, *Line) && + FormatTok->ContinuesLineCommentSection = + continuesLineComment(*FormatTok, *Line); + if (!FormatTok->ContinuesLineCommentSection && (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) { CommentsInCurrentLine = false; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 497015bb095..1f81f5fbd2f 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -951,7 +951,46 @@ TEST_F(FormatTest, UnderstandsSingleLineComments) { " c\n" "};", getLLVMStyleWithColumns(20))); - + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + getLLVMStyleWithColumns(20))); verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment"); |

