diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index a28efa5dad0457..3458575119e276 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3335,43 +3335,6 @@ the configuration (without a prefix: ``Auto``). var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3]; f({a : 1, b : 2, c : 3}); f({a: 1, b: 2, c: 3}); -**SpacesInLineCommentPrefix** (``SpacesInLineComment``) - How many spaces are allowed at the start of a line comment. To disable the - maximum set it to ``-1``, apart from that the maximum takes precedence - over the minimum. - Minimum = 1 Maximum = -1 - // One space is forced - - // but more spaces are possible - - Minimum = 0 - Maximum = 0 - //Forces to start every comment directly after the slashes - - Note that in line comment sections the relative indent of the subsequent - lines is kept, that means the following: - - .. code-block:: c++ - - before: after: - Minimum: 1 - //if (b) { // if (b) { - // return true; // return true; - //} // } - - Maximum: 0 - /// List: ///List: - /// - Foo /// - Foo - /// - Bar /// - Bar - - Nested configuration flags: - - - * ``unsigned Minimum`` The minimum number of spaces at the start of the comment. - - * ``unsigned Maximum`` The maximum number of spaces at the start of the comment. - - **SpacesInParentheses** (``bool``) If ``true``, spaces will be inserted after ``(`` and before ``)``. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c5b93718b0a1c9..454355af4c41e7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -158,9 +158,6 @@ clang-format - ... -- Option ``SpacesInLineCommentPrefix`` has been added to control the - number of spaces in a line comments prefix. - libclang -------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 269707fedaac7a..96c2a74e97db87 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2894,43 +2894,6 @@ struct FormatStyle { /// \endcode bool SpacesInCStyleCastParentheses; - /// Control of spaces within a single line comment - struct SpacesInLineComment { - /// The minimum number of spaces at the start of the comment. - unsigned Minimum; - /// The maximum number of spaces at the start of the comment. - unsigned Maximum; - }; - - /// How many spaces are allowed at the start of a line comment. To disable the - /// maximum set it to ``-1``, apart from that the maximum takes precedence - /// over the minimum. - /// \code Minimum = 1 Maximum = -1 - /// // One space is forced - /// - /// // but more spaces are possible - /// - /// Minimum = 0 - /// Maximum = 0 - /// //Forces to start every comment directly after the slashes - /// \endcode - /// - /// Note that in line comment sections the relative indent of the subsequent - /// lines is kept, that means the following: - /// \code - /// before: after: - /// Minimum: 1 - /// //if (b) { // if (b) { - /// // return true; // return true; - /// //} // } - /// - /// Maximum: 0 - /// /// List: ///List: - /// /// - Foo /// - Foo - /// /// - Bar /// - Bar - /// \endcode - SpacesInLineComment SpacesInLineCommentPrefix; - /// If ``true``, spaces will be inserted after ``(`` and before ``)``. /// \code /// true: false: @@ -3182,10 +3145,6 @@ struct FormatStyle { SpacesInConditionalStatement == R.SpacesInConditionalStatement && SpacesInContainerLiterals == R.SpacesInContainerLiterals && SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses && - SpacesInLineCommentPrefix.Minimum == - R.SpacesInLineCommentPrefix.Minimum && - SpacesInLineCommentPrefix.Maximum == - R.SpacesInLineCommentPrefix.Maximum && SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && SpaceBeforeSquareBrackets == R.SpaceBeforeSquareBrackets && diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index c581a9727d315a..f179ac64de1756 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -757,9 +757,6 @@ BreakableLineCommentSection::BreakableLineCommentSection( assert(Tok.is(TT_LineComment) && "line comment section must start with a line comment"); FormatToken *LineTok = nullptr; - // How many spaces we changed in the first line of the section, this will be - // applied in all following lines - int FirstLineSpaceChange = 0; for (const FormatToken *CurrentTok = &Tok; CurrentTok && CurrentTok->is(TT_LineComment); CurrentTok = CurrentTok->Next) { @@ -771,71 +768,44 @@ BreakableLineCommentSection::BreakableLineCommentSection( TokenText.split(Lines, "\n"); Content.resize(Lines.size()); ContentColumn.resize(Lines.size()); - PrefixSpaceChange.resize(Lines.size()); + OriginalContentColumn.resize(Lines.size()); Tokens.resize(Lines.size()); Prefix.resize(Lines.size()); OriginalPrefix.resize(Lines.size()); for (size_t i = FirstLineIndex, e = Lines.size(); i < e; ++i) { Lines[i] = Lines[i].ltrim(Blanks); StringRef IndentPrefix = getLineCommentIndentPrefix(Lines[i], Style); - OriginalPrefix[i] = IndentPrefix; - const unsigned SpacesInPrefix = - std::count(IndentPrefix.begin(), IndentPrefix.end(), ' '); - - // On the first line of the comment section we calculate how many spaces - // are to be added or removed, all lines after that just get only the - // change and we will not look at the maximum anymore. Additionally to the - // actual first line, we calculate that when the non space Prefix changes, - // e.g. from "///" to "//". - if (i == 0 || OriginalPrefix[i].rtrim(Blanks) != - OriginalPrefix[i - 1].rtrim(Blanks)) { - if (SpacesInPrefix < Style.SpacesInLineCommentPrefix.Minimum && - Lines[i].size() > IndentPrefix.size() && - isAlphanumeric(Lines[i][IndentPrefix.size()])) { - FirstLineSpaceChange = - Style.SpacesInLineCommentPrefix.Minimum - SpacesInPrefix; - } else if (SpacesInPrefix > Style.SpacesInLineCommentPrefix.Maximum) { - FirstLineSpaceChange = - Style.SpacesInLineCommentPrefix.Maximum - SpacesInPrefix; - } else { - FirstLineSpaceChange = 0; - } - } - - if (Lines[i].size() != IndentPrefix.size()) { - PrefixSpaceChange[i] = FirstLineSpaceChange; - - if (SpacesInPrefix + PrefixSpaceChange[i] < - Style.SpacesInLineCommentPrefix.Minimum) { - PrefixSpaceChange[i] += Style.SpacesInLineCommentPrefix.Minimum - - (SpacesInPrefix + PrefixSpaceChange[i]); - } - - assert(Lines[i].size() > IndentPrefix.size()); - const auto FirstNonSpace = Lines[i][IndentPrefix.size()]; - const auto AllowsSpaceChange = - SpacesInPrefix != 0 || - (isAlphanumeric(FirstNonSpace) || FirstNonSpace == '}'); - - if (PrefixSpaceChange[i] > 0 && AllowsSpaceChange) { - Prefix[i] = IndentPrefix.str(); - Prefix[i].append(PrefixSpaceChange[i], ' '); - } else if (PrefixSpaceChange[i] < 0 && AllowsSpaceChange) { - Prefix[i] = IndentPrefix - .drop_back(std::min( - -PrefixSpaceChange[i], SpacesInPrefix)) - .str(); - } else { - Prefix[i] = IndentPrefix.str(); - } - } else { - // If the IndentPrefix is the whole line, there is no content and we - // drop just all space - Prefix[i] = IndentPrefix.drop_back(SpacesInPrefix).str(); + assert((TokenText.startswith("//") || TokenText.startswith("#")) && + "unsupported line comment prefix, '//' and '#' are supported"); + OriginalPrefix[i] = Prefix[i] = IndentPrefix; + if (Lines[i].size() > Prefix[i].size() && + isAlphanumeric(Lines[i][Prefix[i].size()])) { + if (Prefix[i] == "//") + Prefix[i] = "// "; + else if (Prefix[i] == "///") + Prefix[i] = "/// "; + else if (Prefix[i] == "//!") + Prefix[i] = "//! "; + else if (Prefix[i] == "///<") + Prefix[i] = "///< "; + else if (Prefix[i] == "//!<") + Prefix[i] = "//!< "; + else if (Prefix[i] == "#") + Prefix[i] = "# "; + else if (Prefix[i] == "##") + Prefix[i] = "## "; + else if (Prefix[i] == "###") + Prefix[i] = "### "; + else if (Prefix[i] == "####") + Prefix[i] = "#### "; } Tokens[i] = LineTok; Content[i] = Lines[i].substr(IndentPrefix.size()); + OriginalContentColumn[i] = + StartColumn + encoding::columnWidthWithTabs(OriginalPrefix[i], + StartColumn, + Style.TabWidth, Encoding); ContentColumn[i] = StartColumn + encoding::columnWidthWithTabs(Prefix[i], StartColumn, Style.TabWidth, Encoding); @@ -878,9 +848,10 @@ BreakableLineCommentSection::getRangeLength(unsigned LineIndex, unsigned Offset, Encoding); } -unsigned -BreakableLineCommentSection::getContentStartColumn(unsigned LineIndex, - bool /*Break*/) const { +unsigned BreakableLineCommentSection::getContentStartColumn(unsigned LineIndex, + bool Break) const { + if (Break) + return OriginalContentColumn[LineIndex]; return ContentColumn[LineIndex]; } @@ -893,10 +864,16 @@ void BreakableLineCommentSection::insertBreak( unsigned BreakOffsetInToken = Text.data() - tokenAt(LineIndex).TokenText.data() + Split.first; unsigned CharsToRemove = Split.second; + // Compute the size of the new indent, including the size of the new prefix of + // the newly broken line. + unsigned IndentAtLineBreak = OriginalContentColumn[LineIndex] + + Prefix[LineIndex].size() - + OriginalPrefix[LineIndex].size(); + assert(IndentAtLineBreak >= Prefix[LineIndex].size()); Whitespaces.replaceWhitespaceInToken( tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "", Prefix[LineIndex], InPPDirective, /*Newlines=*/1, - /*Spaces=*/ContentColumn[LineIndex] - Prefix[LineIndex].size()); + /*Spaces=*/IndentAtLineBreak - Prefix[LineIndex].size()); } BreakableComment::Split BreakableLineCommentSection::getReflowSplit( @@ -994,12 +971,14 @@ void BreakableLineCommentSection::adaptStartOfLine( } if (OriginalPrefix[LineIndex] != Prefix[LineIndex]) { // Adjust the prefix if necessary. - const auto SpacesToRemove = -std::min(PrefixSpaceChange[LineIndex], 0); - const auto SpacesToAdd = std::max(PrefixSpaceChange[LineIndex], 0); + + // Take care of the space possibly introduced after a decoration. + assert(Prefix[LineIndex] == (OriginalPrefix[LineIndex] + " ").str() && + "Expecting a line comment prefix to differ from original by at most " + "a space"); Whitespaces.replaceWhitespaceInToken( - tokenAt(LineIndex), OriginalPrefix[LineIndex].size() - SpacesToRemove, - /*ReplaceChars=*/SpacesToRemove, "", "", -/*InPPDirective=*/false, - /*Newlines=*/0, /*Spaces=*/SpacesToAdd); + tokenAt(LineIndex), OriginalPrefix[LineIndex].size(), 0, "", "", + /*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1); } } diff --git a/clang/lib/Format/BreakableToken.h b/clang/lib/Format/BreakableToken.h index 190144ad1be939..41b19f82e9dfd6 100644 --- a/clang/lib/Format/BreakableToken.h +++ b/clang/lib/Format/BreakableToken.h @@ -465,23 +465,15 @@ class BreakableLineCommentSection : public BreakableComment { // then the original prefix is "// ". SmallVector OriginalPrefix; - /// Prefix[i] + SpacesToAdd[i] contains the intended leading "//" with - /// trailing spaces to account for the indentation of content within the - /// comment at line i after formatting. It can be different than the original - /// prefix. - /// When the original line starts like this: - /// //content - /// Then the OriginalPrefix[i] is "//", but the Prefix[i] is "// " in the LLVM - /// style. - /// When the line starts like: - /// // content - /// And we want to remove the spaces the OriginalPrefix[i] is "// " and - /// Prefix[i] is "//". - SmallVector Prefix; - - /// How many spaces are added or removed from the OriginalPrefix to form - /// Prefix. - SmallVector PrefixSpaceChange; + // Prefix[i] contains the intended leading "//" with trailing spaces to + // account for the indentation of content within the comment at line i after + // formatting. It can be different than the original prefix when the original + // line starts like this: + // //content + // Then the original prefix is "//", but the prefix is "// ". + SmallVector Prefix; + + SmallVector OriginalContentColumn; /// The token to which the last line of this breakable token belongs /// to; nullptr if that token is the initial token. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 16a42f2d97c45d..5f5bb8585ac1e0 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -661,8 +661,6 @@ template <> struct MappingTraits { Style.SpacesInContainerLiterals); IO.mapOptional("SpacesInCStyleCastParentheses", Style.SpacesInCStyleCastParentheses); - IO.mapOptional("SpacesInLineCommentPrefix", - Style.SpacesInLineCommentPrefix); IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses); IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets); IO.mapOptional("SpaceBeforeSquareBrackets", @@ -712,20 +710,6 @@ template <> struct MappingTraits { } }; -template <> struct MappingTraits { - static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) { - // Transform the maximum to signed, to parse "-1" correctly - int signedMaximum = static_cast(Space.Maximum); - IO.mapOptional("Minimum", Space.Minimum); - IO.mapOptional("Maximum", signedMaximum); - Space.Maximum = static_cast(signedMaximum); - - if (Space.Maximum != -1u) { - Space.Minimum = std::min(Space.Minimum, Space.Maximum); - } - } -}; - // Allows to read vector while keeping default values. // IO.getContext() should contain a pointer to the FormatStyle structure, that // will be used to get default values for missing keys. @@ -1002,7 +986,6 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.SpaceInEmptyParentheses = false; LLVMStyle.SpacesInContainerLiterals = true; LLVMStyle.SpacesInCStyleCastParentheses = false; - LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u}; LLVMStyle.SpaceAfterCStyleCast = false; LLVMStyle.SpaceAfterLogicalNot = false; LLVMStyle.SpaceAfterTemplateKeyword = true; diff --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/clang/lib/Format/NamespaceEndCommentsFixer.cpp index c5bb6e9eab5d9e..97de45bd19659c 100644 --- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp +++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp @@ -66,10 +66,8 @@ std::string computeName(const FormatToken *NamespaceTok) { } std::string computeEndCommentText(StringRef NamespaceName, bool AddNewline, - const FormatToken *NamespaceTok, - unsigned SpacesToAdd) { - std::string text = "//"; - text.append(SpacesToAdd, ' '); + const FormatToken *NamespaceTok) { + std::string text = "// "; text += NamespaceTok->TokenText; if (NamespaceTok->is(TT_NamespaceMacro)) text += "("; @@ -280,8 +278,7 @@ std::pair NamespaceEndCommentsFixer::analyze( EndCommentNextTok->NewlinesBefore == 0 && EndCommentNextTok->isNot(tok::eof); const std::string EndCommentText = - computeEndCommentText(NamespaceName, AddNewline, NamespaceTok, - Style.SpacesInLineCommentPrefix.Minimum); + computeEndCommentText(NamespaceName, AddNewline, NamespaceTok); if (!hasEndComment(EndCommentPrevTok)) { bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1; if (!isShort) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 1090f0ca8ee216..c1f88b9ae17ad1 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -15994,26 +15994,6 @@ TEST_F(FormatTest, ParsesConfiguration) { " - 'CPPEVAL'\n" " CanonicalDelimiter: 'cc'", RawStringFormats, ExpectedRawStringFormats); - - CHECK_PARSE("SpacesInLineCommentPrefix:\n" - " Minimum: 0\n" - " Maximum: 0", - SpacesInLineCommentPrefix.Minimum, 0u); - EXPECT_EQ(Style.SpacesInLineCommentPrefix.Maximum, 0u); - Style.SpacesInLineCommentPrefix.Minimum = 1; - CHECK_PARSE("SpacesInLineCommentPrefix:\n" - " Minimum: 2", - SpacesInLineCommentPrefix.Minimum, 0u); - CHECK_PARSE("SpacesInLineCommentPrefix:\n" - " Maximum: -1", - SpacesInLineCommentPrefix.Maximum, -1u); - CHECK_PARSE("SpacesInLineCommentPrefix:\n" - " Minimum: 2", - SpacesInLineCommentPrefix.Minimum, 2u); - CHECK_PARSE("SpacesInLineCommentPrefix:\n" - " Maximum: 1", - SpacesInLineCommentPrefix.Maximum, 1u); - EXPECT_EQ(Style.SpacesInLineCommentPrefix.Minimum, 1u); } TEST_F(FormatTest, ParsesConfigurationWithLanguages) { diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 43869f7f5a67c6..457e7321ec7593 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -3144,7 +3144,7 @@ TEST_F(FormatTestComments, PythonStyleComments) { " # commen6\n" " # commen7", format("k:val#commen1 commen2\n" - " #commen3\n" + " # commen3\n" "# commen4\n" "a:1#commen5 commen6\n" " #commen7", @@ -3275,506 +3275,6 @@ TEST_F(FormatTestComments, IndentsLongJavadocAnnotatedLines) { JSStyle20)); } -TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { - FormatStyle Style = getLLVMStyle(); - StringRef NoTextInComment = " // \n" - "\n" - "void foo() {// \n" - "// \n" - "}"; - - EXPECT_EQ("//\n" - "\n" - "void foo() { //\n" - " //\n" - "}", - format(NoTextInComment, Style)); - - Style.SpacesInLineCommentPrefix.Minimum = 0; - EXPECT_EQ("//\n" - "\n" - "void foo() { //\n" - " //\n" - "}", - format(NoTextInComment, Style)); - - Style.SpacesInLineCommentPrefix.Minimum = 5; - EXPECT_EQ("//\n" - "\n" - "void foo() { //\n" - " //\n" - "}", - format(NoTextInComment, Style)); - - Style = getLLVMStyle(); - StringRef Code = - "//Free comment without space\n" - "\n" - "// Free comment with 3 spaces\n" - "\n" - "///Free Doxygen without space\n" - "\n" - "/// Free Doxygen with 3 spaces\n" - "\n" - "/// A Doxygen Comment with a nested list:\n" - "/// - Foo\n" - "/// - Bar\n" - "/// - Baz\n" - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "/// .\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///