[clang-format] Add BreakFunctionDefinitionParameters option (#84988)
This adds an option to break function definition parameters, putting them on the next line after the function's opening paren. This was a missing step towards allowing styles which require all function definition parameters be on their own lines. Closes #62963
This commit is contained in:
@@ -3295,6 +3295,21 @@ the configuration (without a prefix: ``Auto``).
|
||||
|
||||
|
||||
|
||||
.. _BreakFunctionDefinitionParameters:
|
||||
|
||||
**BreakFunctionDefinitionParameters** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ <BreakFunctionDefinitionParameters>`
|
||||
If ``true``, clang-format will always break before function definition
|
||||
parameters.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
true:
|
||||
void functionDefinition(
|
||||
int A, int B) {}
|
||||
|
||||
false:
|
||||
void functionDefinition(int A, int B) {}
|
||||
|
||||
.. _BreakInheritanceList:
|
||||
|
||||
**BreakInheritanceList** (``BreakInheritanceListStyle``) :versionbadge:`clang-format 7` :ref:`¶ <BreakInheritanceList>`
|
||||
|
||||
@@ -2223,6 +2223,20 @@ struct FormatStyle {
|
||||
/// \version 5
|
||||
BreakConstructorInitializersStyle BreakConstructorInitializers;
|
||||
|
||||
/// If ``true``, clang-format will always break before function definition
|
||||
/// parameters.
|
||||
/// \code
|
||||
/// true:
|
||||
/// void functionDefinition(
|
||||
/// int A, int B) {}
|
||||
///
|
||||
/// false:
|
||||
/// void functionDefinition(int A, int B) {}
|
||||
///
|
||||
/// \endcode
|
||||
/// \version 19
|
||||
bool BreakFunctionDefinitionParameters;
|
||||
|
||||
/// Break after each annotation on a field in Java files.
|
||||
/// \code{.java}
|
||||
/// true: false:
|
||||
@@ -4938,6 +4952,8 @@ struct FormatStyle {
|
||||
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
|
||||
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
|
||||
BreakConstructorInitializers == R.BreakConstructorInitializers &&
|
||||
BreakFunctionDefinitionParameters ==
|
||||
R.BreakFunctionDefinitionParameters &&
|
||||
BreakInheritanceList == R.BreakInheritanceList &&
|
||||
BreakStringLiterals == R.BreakStringLiterals &&
|
||||
BreakTemplateDeclarations == R.BreakTemplateDeclarations &&
|
||||
|
||||
@@ -955,6 +955,8 @@ template <> struct MappingTraits<FormatStyle> {
|
||||
Style.BreakBeforeTernaryOperators);
|
||||
IO.mapOptional("BreakConstructorInitializers",
|
||||
Style.BreakConstructorInitializers);
|
||||
IO.mapOptional("BreakFunctionDefinitionParameters",
|
||||
Style.BreakFunctionDefinitionParameters);
|
||||
IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
|
||||
IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
|
||||
IO.mapOptional("BreakTemplateDeclarations",
|
||||
@@ -1465,6 +1467,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
|
||||
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
|
||||
LLVMStyle.BreakBeforeTernaryOperators = true;
|
||||
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
|
||||
LLVMStyle.BreakFunctionDefinitionParameters = false;
|
||||
LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
|
||||
LLVMStyle.BreakStringLiterals = true;
|
||||
LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
|
||||
|
||||
@@ -574,6 +574,9 @@ public:
|
||||
/// Is optional and can be removed.
|
||||
bool Optional = false;
|
||||
|
||||
/// Might be function declaration open/closing paren.
|
||||
bool MightBeFunctionDeclParen = false;
|
||||
|
||||
/// Number of optional braces to be inserted after this token:
|
||||
/// -1: a single left brace
|
||||
/// 0: no braces
|
||||
|
||||
@@ -1550,6 +1550,7 @@ private:
|
||||
(!Previous->isAttribute() &&
|
||||
!Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) {
|
||||
Line.MightBeFunctionDecl = true;
|
||||
Tok->MightBeFunctionDeclParen = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -5392,6 +5393,12 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
|
||||
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
|
||||
return true;
|
||||
|
||||
if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
|
||||
Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
|
||||
Left.ParameterCount > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Style.isCSharp()) {
|
||||
if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&
|
||||
Style.BraceWrapping.AfterFunction) {
|
||||
|
||||
@@ -7976,6 +7976,43 @@ TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) {
|
||||
Input, Style);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, BreakFunctionDefinitionParameters) {
|
||||
FormatStyle Style = getLLVMStyle();
|
||||
EXPECT_FALSE(Style.BreakFunctionDefinitionParameters);
|
||||
StringRef Input = "void functionDecl(paramA, paramB, paramC);\n"
|
||||
"void emptyFunctionDefinition() {}\n"
|
||||
"void functionDefinition(int A, int B, int C) {}\n"
|
||||
"Class::Class(int A, int B) : m_A(A), m_B(B) {}\n";
|
||||
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
|
||||
"void emptyFunctionDefinition() {}\n"
|
||||
"void functionDefinition(int A, int B, int C) {}\n"
|
||||
"Class::Class(int A, int B) : m_A(A), m_B(B) {}\n"),
|
||||
Input, Style);
|
||||
Style.BreakFunctionDefinitionParameters = true;
|
||||
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
|
||||
"void emptyFunctionDefinition() {}\n"
|
||||
"void functionDefinition(\n"
|
||||
" int A, int B, int C) {}\n"
|
||||
"Class::Class(\n"
|
||||
" int A, int B)\n"
|
||||
" : m_A(A), m_B(B) {}\n"),
|
||||
Input, Style);
|
||||
// Test the style where all parameters are on their own lines
|
||||
Style.AllowAllParametersOfDeclarationOnNextLine = false;
|
||||
Style.BinPackParameters = false;
|
||||
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
|
||||
"void emptyFunctionDefinition() {}\n"
|
||||
"void functionDefinition(\n"
|
||||
" int A,\n"
|
||||
" int B,\n"
|
||||
" int C) {}\n"
|
||||
"Class::Class(\n"
|
||||
" int A,\n"
|
||||
" int B)\n"
|
||||
" : m_A(A), m_B(B) {}\n"),
|
||||
Input, Style);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, BreakBeforeInlineASMColon) {
|
||||
FormatStyle Style = getLLVMStyle();
|
||||
Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Never;
|
||||
|
||||
Reference in New Issue
Block a user