[clang-format] Add LeaveAll to the BreakAfterAttributes option (#187204)
Closes #163537
This commit is contained in:
parent
f554fcfd0b
commit
79042e701b
@ -2727,7 +2727,7 @@ the configuration (without a prefix: ``Auto``).
|
||||
Possible values:
|
||||
|
||||
* ``ABS_Always`` (in configuration: ``Always``)
|
||||
Always break after attributes.
|
||||
Always break after the last attribute of the group.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@ -2758,7 +2758,7 @@ the configuration (without a prefix: ``Auto``).
|
||||
}
|
||||
|
||||
* ``ABS_Leave`` (in configuration: ``Leave``)
|
||||
Leave the line breaking after attributes as is.
|
||||
Leave the line breaking after the last attribute of the group as is.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@ -2784,8 +2784,24 @@ the configuration (without a prefix: ``Auto``).
|
||||
return;
|
||||
}
|
||||
|
||||
* ``ABS_LeaveAll`` (in configuration: ``LeaveAll``)
|
||||
Same as ``Leave`` except that it applies to all attributes of the group.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
[[deprecated("Don't use this version")]]
|
||||
[[nodiscard]]
|
||||
bool foo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[deprecated("Don't use this version")]]
|
||||
[[nodiscard]] bool bar() {
|
||||
return true;
|
||||
}
|
||||
|
||||
* ``ABS_Never`` (in configuration: ``Never``)
|
||||
Never break after attributes.
|
||||
Never break after the last attribute of the group.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
|
||||
@ -1717,9 +1717,10 @@ struct FormatStyle {
|
||||
/// \version 18
|
||||
bool BreakAdjacentStringLiterals;
|
||||
|
||||
/// Different ways to break after attributes.
|
||||
/// Different ways to break after the last attribute of a group before a
|
||||
/// declaration or control statement.
|
||||
enum AttributeBreakingStyle : int8_t {
|
||||
/// Always break after attributes.
|
||||
/// Always break after the last attribute of the group.
|
||||
/// \code
|
||||
/// [[maybe_unused]]
|
||||
/// const int i;
|
||||
@ -1748,7 +1749,7 @@ struct FormatStyle {
|
||||
/// }
|
||||
/// \endcode
|
||||
ABS_Always,
|
||||
/// Leave the line breaking after attributes as is.
|
||||
/// Leave the line breaking after the last attribute of the group as is.
|
||||
/// \code
|
||||
/// [[maybe_unused]] const int i;
|
||||
/// [[gnu::const]] [[maybe_unused]]
|
||||
@ -1773,7 +1774,21 @@ struct FormatStyle {
|
||||
/// }
|
||||
/// \endcode
|
||||
ABS_Leave,
|
||||
/// Never break after attributes.
|
||||
/// Same as ``Leave`` except that it applies to all attributes of the group.
|
||||
/// \code
|
||||
/// [[deprecated("Don't use this version")]]
|
||||
/// [[nodiscard]]
|
||||
/// bool foo() {
|
||||
/// return true;
|
||||
/// }
|
||||
///
|
||||
/// [[deprecated("Don't use this version")]]
|
||||
/// [[nodiscard]] bool bar() {
|
||||
/// return true;
|
||||
/// }
|
||||
/// \endcode
|
||||
ABS_LeaveAll,
|
||||
/// Never break after the last attribute of the group.
|
||||
/// \code
|
||||
/// [[maybe_unused]] const int i;
|
||||
/// [[gnu::const]] [[maybe_unused]] int j;
|
||||
|
||||
@ -121,6 +121,7 @@ struct ScalarEnumerationTraits<FormatStyle::AttributeBreakingStyle> {
|
||||
static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value) {
|
||||
IO.enumCase(Value, "Always", FormatStyle::ABS_Always);
|
||||
IO.enumCase(Value, "Leave", FormatStyle::ABS_Leave);
|
||||
IO.enumCase(Value, "LeaveAll", FormatStyle::ABS_LeaveAll);
|
||||
IO.enumCase(Value, "Never", FormatStyle::ABS_Never);
|
||||
}
|
||||
};
|
||||
|
||||
@ -28,10 +28,10 @@ static bool mustBreakAfterAttributes(const FormatToken &Tok,
|
||||
switch (Style.BreakAfterAttributes) {
|
||||
case FormatStyle::ABS_Always:
|
||||
return true;
|
||||
case FormatStyle::ABS_Leave:
|
||||
return Tok.NewlinesBefore > 0;
|
||||
default:
|
||||
case FormatStyle::ABS_Never:
|
||||
return false;
|
||||
default: // ABS_Leave and ABS_LeaveAll
|
||||
return Tok.NewlinesBefore > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4121,6 +4121,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
|
||||
}
|
||||
|
||||
if (!LineIsFunctionDeclaration) {
|
||||
Line.ReturnTypeWrapped = false;
|
||||
// Annotate */&/&& in `operator` function calls as binary operators.
|
||||
for (const auto *Tok = FirstNonComment; Tok; Tok = Tok->Next) {
|
||||
if (Tok->isNot(tok::kw_operator))
|
||||
@ -5706,7 +5707,7 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) {
|
||||
Tok.isNoneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
|
||||
}
|
||||
|
||||
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
|
||||
bool TokenAnnotator::mustBreakBefore(AnnotatedLine &Line,
|
||||
const FormatToken &Right) const {
|
||||
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
|
||||
(!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
|
||||
@ -6183,6 +6184,12 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Style.BreakAfterAttributes == FormatStyle::ABS_LeaveAll &&
|
||||
Left.is(TT_AttributeRSquare) && Right.NewlinesBefore > 0) {
|
||||
Line.ReturnTypeWrapped = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -247,8 +247,7 @@ private:
|
||||
bool spaceRequiredBefore(const AnnotatedLine &Line,
|
||||
const FormatToken &Right) const;
|
||||
|
||||
bool mustBreakBefore(const AnnotatedLine &Line,
|
||||
const FormatToken &Right) const;
|
||||
bool mustBreakBefore(AnnotatedLine &Line, const FormatToken &Right) const;
|
||||
|
||||
bool canBreakBefore(const AnnotatedLine &Line,
|
||||
const FormatToken &Right) const;
|
||||
|
||||
@ -1196,6 +1196,8 @@ TEST(ConfigParseTest, ParsesConfiguration) {
|
||||
FormatStyle::ABS_Always);
|
||||
CHECK_PARSE("BreakAfterAttributes: Leave", BreakAfterAttributes,
|
||||
FormatStyle::ABS_Leave);
|
||||
CHECK_PARSE("BreakAfterAttributes: LeaveAll", BreakAfterAttributes,
|
||||
FormatStyle::ABS_LeaveAll);
|
||||
CHECK_PARSE("BreakAfterAttributes: Never", BreakAfterAttributes,
|
||||
FormatStyle::ABS_Never);
|
||||
|
||||
|
||||
@ -28321,6 +28321,19 @@ TEST_F(FormatTest, BreakAfterAttributes) {
|
||||
EXPECT_EQ(Style.BreakAfterAttributes, FormatStyle::ABS_Leave);
|
||||
verifyNoChange(Code, Style);
|
||||
|
||||
Style.BreakAfterAttributes = FormatStyle::ABS_LeaveAll;
|
||||
verifyNoChange("[[deprecated(\"Don't use this version\")]]\n"
|
||||
"[[nodiscard]]\n"
|
||||
"bool foo() {\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"[[deprecated(\"Don't use this version\")]]\n"
|
||||
"[[nodiscard]] bool bar() {\n"
|
||||
" return true;\n"
|
||||
"}",
|
||||
Style);
|
||||
|
||||
Style.BreakAfterAttributes = FormatStyle::ABS_Never;
|
||||
verifyFormat("[[maybe_unused]] const int i;\n"
|
||||
"[[foo([[]])]] [[maybe_unused]] int j;\n"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user