llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-format Author: Iuri Chaer (ichaer) <details> <summary>Changes</summary> * Convert `ReflowComments` from boolean into a new `enum` which can take on the value `RCS_Never`, `RCS_IndentOnly`, or `RCS_Always`. The first one is equivalent to the old `false`, the third one is `true`, and the middle one means that multiline comments should only have their indentation corrected, which is what Doxygen users will want. * Preserve backward compatibility while parsing `ReflowComments`. --- Full diff: https://github.com/llvm/llvm-project/pull/96804.diff 8 Files Affected: - (modified) clang/include/clang/Format/Format.h (+14-3) - (modified) clang/lib/Format/BreakableToken.cpp (+10-4) - (modified) clang/lib/Format/ContinuationIndenter.cpp (+2-2) - (modified) clang/lib/Format/Format.cpp (+11-1) - (modified) clang/lib/Format/UnwrappedLineParser.cpp (+9-9) - (modified) clang/unittests/Format/ConfigParseTest.cpp (+10-1) - (modified) clang/unittests/Format/FormatTest.cpp (+3-3) - (modified) clang/unittests/Format/FormatTestComments.cpp (+19-3) ``````````diff diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 7d257be10af42..971e9347df127 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -3749,23 +3749,34 @@ struct FormatStyle { /// \version 13 ReferenceAlignmentStyle ReferenceAlignment; + enum ReflowCommentsStyle : int8_t { RCS_Never, RCS_IndentOnly, RCS_Always }; // clang-format off /// If ``true``, clang-format will attempt to re-flow comments. That is it /// will touch a comment and *reflow* long comments into new lines, trying to /// obey the ``ColumnLimit``. /// \code - /// false: + /// RCS_Never: /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */ + /// /* third veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information + /// * and a misaligned second line */ /// - /// true: + /// RCS_IndentOnly: + /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information + /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */ + /// /* third veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information + /// * and a misaligned second line */ + /// + /// RCS_Always: /// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of /// // information /// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of /// * information */ + /// /* third veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of + /// * information and a misaligned second line */ /// \endcode /// \version 3.8 - bool ReflowComments; + ReflowCommentsStyle ReflowComments; // clang-format on /// Remove optional braces of control statements (``if``, ``else``, ``for``, diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 75304908dc650..0ccc8a690c208 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -420,8 +420,10 @@ BreakableComment::getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, unsigned ContentStartColumn, const llvm::Regex &CommentPragmasRegex) const { // Don't break lines matching the comment pragmas regex. - if (CommentPragmasRegex.match(Content[LineIndex])) + if (Style.ReflowComments != FormatStyle::RCS_Always || + CommentPragmasRegex.match(Content[LineIndex])) { return Split(StringRef::npos, 0); + } return getCommentSplit(Content[LineIndex].substr(TailOffset), ContentStartColumn, ColumnLimit, Style.TabWidth, Encoding, Style); @@ -608,8 +610,10 @@ BreakableToken::Split BreakableBlockComment::getSplit( unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, unsigned ContentStartColumn, const llvm::Regex &CommentPragmasRegex) const { // Don't break lines matching the comment pragmas regex. - if (CommentPragmasRegex.match(Content[LineIndex])) + if (Style.ReflowComments != FormatStyle::RCS_Always || + CommentPragmasRegex.match(Content[LineIndex])) { return Split(StringRef::npos, 0); + } return getCommentSplit(Content[LineIndex].substr(TailOffset), ContentStartColumn, ColumnLimit, Style.TabWidth, Encoding, Style, Decoration.ends_with("*")); @@ -855,7 +859,8 @@ bool BreakableBlockComment::mayReflow( StringRef IndentContent = Content[LineIndex]; if (Lines[LineIndex].ltrim(Blanks).starts_with("*")) IndentContent = Lines[LineIndex].ltrim(Blanks).substr(1); - return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) && + return LineIndex > 0 && Style.ReflowComments == FormatStyle::RCS_Always && + !CommentPragmasRegex.match(IndentContent) && mayReflowContent(Content[LineIndex]) && !Tok.Finalized && !switchesFormatting(tokenAt(LineIndex)); } @@ -1160,7 +1165,8 @@ bool BreakableLineCommentSection::mayReflow( // // text that protrudes // // into text with different indent // We do reflow in that case in block comments. - return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) && + return LineIndex > 0 && Style.ReflowComments == FormatStyle::RCS_Always && + !CommentPragmasRegex.match(IndentContent) && mayReflowContent(Content[LineIndex]) && !Tok.Finalized && !switchesFormatting(tokenAt(LineIndex)) && OriginalPrefix[LineIndex] == OriginalPrefix[LineIndex - 1]; diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b07360425ca6e..7d592a31bc0eb 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -2400,7 +2400,7 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current, State.Line->InPPDirective, Encoding, Style); } } else if (Current.is(TT_BlockComment)) { - if (!Style.ReflowComments || + if (Style.ReflowComments == FormatStyle::RCS_Never || // If a comment token switches formatting, like // /* clang-format on */, we don't want to break it further, // but we may still want to adjust its indentation. @@ -2421,7 +2421,7 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current, } return true; }(); - if (!Style.ReflowComments || + if (Style.ReflowComments == FormatStyle::RCS_Never || CommentPragmasRegex.match(Current.TokenText.substr(2)) || switchesFormatting(Current) || !RegularComments) { return nullptr; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index cd21fbb2221ac..ee1f5651b4f98 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -497,6 +497,16 @@ template <> struct MappingTraits<FormatStyle::RawStringFormat> { } }; +template <> struct ScalarEnumerationTraits<FormatStyle::ReflowCommentsStyle> { + static void enumeration(IO &IO, FormatStyle::ReflowCommentsStyle &Value) { + IO.enumCase(Value, "Never", FormatStyle::RCS_Never); + IO.enumCase(Value, "IndentOnly", FormatStyle::RCS_IndentOnly); + IO.enumCase(Value, "Always", FormatStyle::RCS_Always); + IO.enumCase(Value, "false", FormatStyle::RCS_Never); + IO.enumCase(Value, "true", FormatStyle::RCS_Always); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> { static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) { @@ -1534,7 +1544,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.PPIndentWidth = -1; LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave; LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; - LLVMStyle.ReflowComments = true; + LLVMStyle.ReflowComments = FormatStyle::RCS_Always; LLVMStyle.RemoveBracesLLVM = false; LLVMStyle.RemoveParentheses = FormatStyle::RPS_Leave; LLVMStyle.RemoveSemicolon = false; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index d406a531a5c0c..0e239c9362027 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -4588,11 +4588,11 @@ bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) { // Checks if \p FormatTok is a line comment that continues the line comment // section on \p Line. -static bool -continuesLineCommentSection(const FormatToken &FormatTok, - const UnwrappedLine &Line, - const llvm::Regex &CommentPragmasRegex) { - if (Line.Tokens.empty()) +static bool continuesLineCommentSection( + const FormatToken &FormatTok, const UnwrappedLine &Line, + const FormatStyle::ReflowCommentsStyle ReflowCommentsStyle, + const llvm::Regex &CommentPragmasRegex) { + if (Line.Tokens.empty() || ReflowCommentsStyle != FormatStyle::RCS_Always) return false; StringRef IndentContent = FormatTok.TokenText; @@ -4704,8 +4704,8 @@ void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { // // FIXME: Consider putting separate line comment sections as children to the // unwrapped line instead. - Tok->ContinuesLineCommentSection = - continuesLineCommentSection(*Tok, *Line, CommentPragmasRegex); + Tok->ContinuesLineCommentSection = continuesLineCommentSection( + *Tok, *Line, Style.ReflowComments, CommentPragmasRegex); if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection) addUnwrappedLine(); pushToken(Tok); @@ -4778,8 +4778,8 @@ void UnwrappedLineParser::distributeComments( if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) { FormatTok->ContinuesLineCommentSection = false; } else { - FormatTok->ContinuesLineCommentSection = - continuesLineCommentSection(*FormatTok, *Line, CommentPragmasRegex); + FormatTok->ContinuesLineCommentSection = continuesLineCommentSection( + *FormatTok, *Line, Style.ReflowComments, CommentPragmasRegex); } if (!FormatTok->ContinuesLineCommentSection && (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) { diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index aded3ed2a6596..a8a985f8fa94b 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -183,7 +183,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(ObjCSpaceAfterProperty); CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); CHECK_PARSE_BOOL(Cpp11BracedListStyle); - CHECK_PARSE_BOOL(ReflowComments); CHECK_PARSE_BOOL(RemoveBracesLLVM); CHECK_PARSE_BOOL(RemoveSemicolon); CHECK_PARSE_BOOL(SkipMacroDefinitionBody); @@ -372,6 +371,16 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment, FormatStyle::PAS_Middle); + Style.ReflowComments = FormatStyle::RCS_Always; + CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never); + CHECK_PARSE("ReflowComments: IndentOnly", ReflowComments, + FormatStyle::RCS_IndentOnly); + CHECK_PARSE("ReflowComments: Always", ReflowComments, + FormatStyle::RCS_Always); + // For backward compatibility: + CHECK_PARSE("ReflowComments: false", ReflowComments, FormatStyle::RCS_Never); + CHECK_PARSE("ReflowComments: true", ReflowComments, FormatStyle::RCS_Always); + Style.Standard = FormatStyle::LS_Auto; CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03); CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index db1decb20d626..80d4958806f19 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -17851,7 +17851,7 @@ TEST_F(FormatTest, AlignConsecutiveMacros) { // Test across comments Style.MaxEmptyLinesToKeep = 10; - Style.ReflowComments = false; + Style.ReflowComments = FormatStyle::RCS_Never; Style.AlignConsecutiveMacros.AcrossComments = true; verifyFormat("#define a 3\n" "// line comment\n" @@ -18598,7 +18598,7 @@ TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLinesAndComments) { "y = 1;", Alignment); - Alignment.ReflowComments = true; + Alignment.ReflowComments = FormatStyle::RCS_Always; Alignment.ColumnLimit = 50; verifyFormat("int x = 0;\n" "int yy = 1; /// specificlennospace\n" @@ -18996,7 +18996,7 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { "y = 1;", Alignment); - EXPECT_EQ(Alignment.ReflowComments, true); + EXPECT_EQ(Alignment.ReflowComments, FormatStyle::RCS_Always); Alignment.ColumnLimit = 50; verifyFormat("int x = 0;\n" "int yy = 1; /// specificlennospace\n" diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 3e75707a9faec..a89016758719c 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -493,9 +493,25 @@ TEST_F(FormatTestComments, AlignsBlockComments) { TEST_F(FormatTestComments, CommentReflowingCanBeTurnedOff) { FormatStyle Style = getLLVMStyleWithColumns(20); - Style.ReflowComments = false; - verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style); - verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style); + Style.ReflowComments = FormatStyle::RCS_Never; + verifyNoChange("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\naaaaaaaaa*/", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n aaaaaaaaa*/", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n * aaaaaaaaa*/", + Style); +} + +TEST_F(FormatTestComments, CommentReflowingCanApplyOnlyToIndents) { + FormatStyle Style = getLLVMStyleWithColumns(20); + Style.ReflowComments = FormatStyle::RCS_IndentOnly; + verifyNoChange("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\naaaaaaaaa*/", Style); + verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n aaaaaaaaa*/", Style); + verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n * aaaaaaaaa*/", + "/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n * aaaaaaaaa*/", + Style); } TEST_F(FormatTestComments, CorrectlyHandlesLengthOfBlockComments) { `````````` </details> https://github.com/llvm/llvm-project/pull/96804 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits