-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang-format] 'else if' clause not broken when using AlignAfterOpenBracket: BlockIndent #54663
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
Comments
@llvm/issue-subscribers-clang-format |
I noticed this as well on I would have never guessed that
void foo() {
if (thisIsRatherALongIfClause && thatIExpectToBeBroken
|| ontoMultipleLines && whenFormattedCorrectly) {}
if (false) {
} else if (
thisIsRatherALongIfClause && thatIExpectToBeBroken
|| ontoMultipleLines && whenFormattedCorrectly) {
}
} FWIW, +1 from me as well for a |
Bug is still present in |
I've noticed For example:
I spent a bit of time exploring the implementation and came up with the following workaround. It's probably imperfect. Unfortunately, I don't have time to further improve it. Maybe it will trigger some ideas in the community. diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 5991cf23d5dc..97e3904156d8 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4761,6 +4761,14 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
return true;
}
+ // We only break before r_paren if we're in a block indented context.
+ if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) {
+ if (Right.is(tok::r_paren))
+ return Right.MatchingParen;
+ if (Left.is(tok::l_paren))
+ return true;
+ }
+
if (Right.is(tok::colon) &&
!Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) {
return false;
@@ -4875,16 +4883,6 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::r_brace))
return Right.MatchingParen && Right.MatchingParen->is(BK_Block);
- // We only break before r_paren if we're in a block indented context.
- if (Right.is(tok::r_paren)) {
- if (Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent ||
- !Right.MatchingParen) {
- return false;
- }
- const FormatToken *Previous = Right.MatchingParen->Previous;
- return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf()));
- }
-
// Allow breaking after a trailing annotation, e.g. after a method
// declaration.
if (Left.is(TT_TrailingAnnotation)) { With it, the previous command produces: void foo() {
if (
thisIsRatherALongIfClause && thatIExpectToBeBroken ||
ontoMultipleLines && whenFormattedCorrectly
) {
}
if (false) {
} else if (
thisIsRatherALongIfClause && thatIExpectToBeBroken ||
ontoMultipleLines && whenFormattedCorrectly
) {
}
} which is good for my purposes. |
I have also seen this problem, involving
When the indent widths are 4, it works well, but when the indent widths are 2, things go badly wrong, with clang-format completely failing to format the
The condition is formatted this time, but not wrapped, even though it exceeds 80 chars. |
I have submitted a fix for this bug at https://reviews.llvm.org/D154755 |
A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this is intended. This patch preserves the AlwaysBreak behavior and supports BlockIndent on if clauses while fixing the bug. It may be reasonable to go the other way and create an explicit option for alignment of if (and loop) clauses intentionally. Fixes llvm#54663. Differential Revision: https://reviews.llvm.org/D154755
) A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this behavior is intended. This PR preserves the `AlwaysBreak` behavior on `if` clauses without supporting `BlockIndent` on `if` clauses to avoid regressions while fixing the bug. It may be reasonable to create an explicit option for alignment of if (and loop) clauses intentionally for both `AlwaysBreak` and `BlockIndent` Fixes #54663. Migrated from Differential Revision: https://reviews.llvm.org/D154755 See more discussion there. Addressed last open comment from the rev about refactoring the complex conditional logic involved with the `AlignAfterOpenBracket` line break behavior.
clang-format version:
Debian clang-format version 14.0.0-++20220329040358+3f43d803382d-1~exp1~20220329160446.105
Code:
Output with defaults:
Output with
AlignAfterOpenBracket: BlockIndent
Expected output:
First of all, I was intuitively expecting
BlockIndent
to break the if/else-if clause in a similar way to a function declaration:and my hope was that there would be a
BinPack...
option to place each part of the clause on each line just as one can with arguments and parameters, but that doesn't seem to be the case.If that's not possible and/or it's not a design goal for that option, then at the least I'd expect the
else if
clause to be broken, because currently it doesn't get wrapped at all when theBlockIndent
alignment style is used, which seems buggy.The text was updated successfully, but these errors were encountered: