-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang-format] Add ApplyAlwaysOnePerLineToTemplateArguments option #137544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1259,6 +1259,45 @@ struct FormatStyle { | |
/// \version 3.7 | ||
BinPackParametersStyle BinPackParameters; | ||
|
||
/// If ``BinPackParameters`` is set to ``AlwaysOnePerLine``, specifies whether | ||
/// template argument lists should also be split across multiple lines. | ||
/// | ||
/// When set to ``true``, each template argument will be placed on its own | ||
/// line. When set to ``false``, template argument lists remain compact even | ||
/// when function parameters are broken one per line. | ||
/// | ||
/// \code | ||
/// true: | ||
/// template <typename T, int N> | ||
/// struct Foo { | ||
/// T mData[N]; | ||
/// | ||
/// Foo<T, | ||
/// N> | ||
/// operator+(const Foo<T, | ||
/// N> &other) const {} | ||
/// | ||
/// Foo<T, | ||
/// N> | ||
/// bar(const Foo<T, | ||
/// N> &other, | ||
/// float t) const {} | ||
/// }; | ||
/// | ||
/// false: | ||
/// template <typename T, int N> | ||
/// struct Foo { | ||
/// T mData[N]; | ||
/// | ||
/// Foo<T, N> operator+(const Foo<T, N> &other) const {} | ||
/// | ||
/// Foo<T, N> bar(const Foo<T, N> &other, | ||
/// float t) const {} | ||
/// }; | ||
/// \endcode | ||
/// \version 21 | ||
bool ApplyAlwaysOnePerLineToTemplateArguments; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please sort alphabetically. |
||
|
||
/// Styles for adding spacing around ``:`` in bitfield definitions. | ||
enum BitFieldColonSpacingStyle : int8_t { | ||
/// Add one space on each side of the ``:`` | ||
|
@@ -5326,6 +5365,8 @@ struct FormatStyle { | |
BinPackArguments == R.BinPackArguments && | ||
BinPackLongBracedList == R.BinPackLongBracedList && | ||
BinPackParameters == R.BinPackParameters && | ||
ApplyAlwaysOnePerLineToTemplateArguments == | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also sorting. |
||
R.ApplyAlwaysOnePerLineToTemplateArguments && | ||
BitFieldColonSpacing == R.BitFieldColonSpacing && | ||
BracedInitializerIndentWidth == R.BracedInitializerIndentWidth && | ||
BreakAdjacentStringLiterals == R.BreakAdjacentStringLiterals && | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1007,6 +1007,8 @@ template <> struct MappingTraits<FormatStyle> { | |
IO.mapOptional("BinPackArguments", Style.BinPackArguments); | ||
IO.mapOptional("BinPackLongBracedList", Style.BinPackLongBracedList); | ||
IO.mapOptional("BinPackParameters", Style.BinPackParameters); | ||
IO.mapOptional("ApplyAlwaysOnePerLineToTemplateArguments", | ||
Style.ApplyAlwaysOnePerLineToTemplateArguments); | ||
IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing); | ||
IO.mapOptional("BracedInitializerIndentWidth", | ||
Style.BracedInitializerIndentWidth); | ||
|
@@ -1521,6 +1523,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { | |
LLVMStyle.BinPackArguments = true; | ||
LLVMStyle.BinPackLongBracedList = true; | ||
LLVMStyle.BinPackParameters = FormatStyle::BPPS_BinPack; | ||
LLVMStyle.ApplyAlwaysOnePerLineToTemplateArguments = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the current behavior? is this the correct default? |
||
LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both; | ||
LLVMStyle.BracedInitializerIndentWidth = -1; | ||
LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1977,6 +1977,19 @@ class AnnotatingParser { | |
return Type; | ||
} | ||
|
||
void markTokenAsTemplateArgumentInLine() { | ||
int TemplateDepth = 0; | ||
for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next) { | ||
if (Tok->is(TT_TemplateCloser)) | ||
--TemplateDepth; | ||
|
||
Tok->InTemplateArgumentList = (TemplateDepth > 0); | ||
|
||
if (Tok->is(TT_TemplateOpener)) | ||
++TemplateDepth; | ||
} | ||
} | ||
|
||
public: | ||
LineType parseLine() { | ||
if (!CurrentToken) | ||
|
@@ -2074,6 +2087,7 @@ class AnnotatingParser { | |
if (ctx.ContextType == Context::StructArrayInitializer) | ||
return LT_ArrayOfStructInitializer; | ||
|
||
markTokenAsTemplateArgumentInLine(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you want this before the preceding loop. And can you get it into the first pass of the line? Just going through all tokens again doesn't seem nice. |
||
return LT_Other; | ||
} | ||
|
||
|
@@ -5619,6 +5633,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, | |
// BreakFunctionDefinitionParameters or AlignAfterOpenBracket. | ||
if (Style.BinPackParameters == FormatStyle::BPPS_AlwaysOnePerLine && | ||
Line.MightBeFunctionDecl && !Left.opensScope() && | ||
(Style.ApplyAlwaysOnePerLineToTemplateArguments || | ||
!Left.InTemplateArgumentList) && | ||
startsNextParameter(Right, Style)) { | ||
return true; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,6 +186,9 @@ class AnnotatedLine { | |
bool MightBeFunctionDecl; | ||
bool IsMultiVariableDeclStmt; | ||
|
||
/// \c True if this token is part o a template declaration. | ||
bool InTemplateDecl = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A leftover? |
||
|
||
/// \c True if this line contains a macro call for which an expansion exists. | ||
bool ContainsMacroCall = false; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9024,6 +9024,55 @@ TEST_F(FormatTest, FormatsDeclarationBreakAlways) { | |
BreakAlways); | ||
} | ||
|
||
TEST_F(FormatTest, ApplyAlwaysOnePerLineToTemplateArguments) { | ||
FormatStyle Style = getGoogleStyle(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why google style? |
||
Style.BinPackParameters = FormatStyle::BPPS_AlwaysOnePerLine; | ||
|
||
// Case 1: Template arguments split by AlwaysOnePerLine | ||
Style.ApplyAlwaysOnePerLineToTemplateArguments = true; | ||
verifyFormat("template <typename T, int N>\n" | ||
"struct Foo {\n" | ||
" T mData[N];\n" | ||
" Foo<T,\n" | ||
" N>\n" | ||
" operator+(const Foo<T,\n" | ||
" N> &other) const {}\n" | ||
" Foo<T,\n" | ||
" N>\n" | ||
" bar(const Foo<T,\n" | ||
" N> &other,\n" | ||
" float t) const {}\n" | ||
"};\n", | ||
Style); | ||
|
||
// Case 2: Template arguments not split by The | ||
// ApplyAlwaysOnePerLineToTemplateArguments | ||
Style.ApplyAlwaysOnePerLineToTemplateArguments = false; | ||
verifyFormat("template <typename T, int N>\n" | ||
"struct Foo {\n" | ||
" T mData[N];\n" | ||
" Foo<T, N> operator+(const Foo<T, N> &other) const {}\n" | ||
" Foo<T, N> bar(const Foo<T, N> &other,\n" | ||
" float t) const {}\n" | ||
"};\n", | ||
Style); | ||
|
||
// Case 3: Template arguments not split by the | ||
// ApplyAlwaysOnePerLineToTemplateArguments but using the | ||
// BreakFunctionDefinitionParameters flag | ||
Style.BreakFunctionDefinitionParameters = true; | ||
verifyFormat("template <typename T, int N>\n" | ||
"struct Foo {\n" | ||
" T mData[N];\n" | ||
" Foo<T, N> operator+(\n" | ||
" const Foo<T, N> &other) const {}\n" | ||
" Foo<T, N> bar(\n" | ||
" const Foo<T, N> &other,\n" | ||
" float t) const {}\n" | ||
"};\n", | ||
Style); | ||
} | ||
|
||
TEST_F(FormatTest, FormatsDefinitionBreakAlways) { | ||
FormatStyle BreakAlways = getGoogleStyle(); | ||
BreakAlways.BinPackParameters = FormatStyle::BPPS_AlwaysOnePerLine; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -444,6 +444,66 @@ TEST_F(FormatTestComments, UnderstandsBlockComments) { | |
" int jjj; /*b*/"); | ||
} | ||
|
||
TEST_F(FormatTestComments, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's your reason for this test? You didn't change anything comment related, right? |
||
AlwaysOnePerLineRespectsTemplateArgumentsFlagWithComments) { | ||
FormatStyle Style = getGoogleStyle(); | ||
Style.BinPackParameters = FormatStyle::BPPS_AlwaysOnePerLine; | ||
|
||
// Case 1: Template arguments split by AlwaysOnePerLine | ||
Style.ApplyAlwaysOnePerLineToTemplateArguments = true; | ||
verifyFormat("template <typename T, // comment\n" | ||
" int N> // comment\n" | ||
"struct Foo {\n" | ||
" T mData[N];\n" | ||
" Foo<T,\n" | ||
" N>\n" | ||
" operator+(const Foo<T,\n" | ||
" N> &other) const { // comment\n" | ||
" }\n" | ||
" Foo<T,\n" | ||
" N>\n" | ||
" bar(const Foo<T,\n" | ||
" N> &other, // comment\n" | ||
" float t) const { // comment\n" | ||
" }\n" | ||
"};\n", | ||
Style); | ||
|
||
// Case 2: Template arguments not split by The | ||
// ApplyAlwaysOnePerLineToTemplateArguments | ||
Style.ApplyAlwaysOnePerLineToTemplateArguments = false; | ||
verifyFormat( | ||
"template <typename T, // comment\n" | ||
" int N> // comment\n" | ||
"struct Foo {\n" | ||
" T mData[N];\n" | ||
" Foo<T, N> operator+(const Foo<T, N> &other) const { // comment\n" | ||
" }\n" | ||
" Foo<T, N> bar(const Foo<T, N> &other, // comment\n" | ||
" float t) const { // comment\n" | ||
" }\n" | ||
"};\n", | ||
Style); | ||
|
||
// Case 3: Template arguments not split by the | ||
// ApplyAlwaysOnePerLineToTemplateArguments but using the | ||
// BreakFunctionDefinitionParameters flag | ||
Style.BreakFunctionDefinitionParameters = true; | ||
verifyFormat("template <typename T, // comment\n" | ||
" int N> // comment\n" | ||
"struct Foo {\n" | ||
" T mData[N];\n" | ||
" Foo<T, N> operator+(\n" | ||
" const Foo<T, N> &other) const { // comment\n" | ||
" }\n" | ||
" Foo<T, N> bar(\n" | ||
" const Foo<T, N> &other, // comment\n" | ||
" float t) const { // comment\n" | ||
" }\n" | ||
"};\n", | ||
Style); | ||
} | ||
|
||
TEST_F(FormatTestComments, AlignsBlockComments) { | ||
EXPECT_EQ("/*\n" | ||
" * Really multi-line\n" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a reference on
BinPackParameters
to this one.