[clang] [clang-format] Add per-operator granularity for BreakBinaryOperations (PR #181051)
Sergey Subbotin via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 15 14:23:13 PST 2026
================
@@ -28625,6 +28627,89 @@ TEST_F(FormatTest, BreakBinaryOperations) {
Style);
}
+TEST_F(FormatTest, BreakBinaryOperationsPerOperator) {
+ auto Style = getLLVMStyleWithColumns(60);
+
+ // Per-operator override: && and || are OnePerLine, rest is Never (default).
+ FormatStyle::BinaryOperationBreakRule LogicalRule;
+ LogicalRule.Operators = {"&&", "||"};
+ LogicalRule.Style = FormatStyle::BBO_OnePerLine;
+ LogicalRule.MinChainLength = 0;
+
+ Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+ Style.BreakBinaryOperations.PerOperator = {LogicalRule};
+
+ // Logical operators break one-per-line when line is too long.
+ verifyFormat("bool x = loooooooooooooongcondition1 &&\n"
+ " loooooooooooooongcondition2 &&\n"
+ " loooooooooooooongcondition3;",
+ Style);
+
+ // Arithmetic operators stay with default (Never) — no forced break.
+ verifyFormat("int x = loooooooooooooongop1 + looooooooongop2 +\n"
+ " loooooooooooooooooooooongop3;",
+ Style);
+
+ // Short logical chain that fits on one line stays on one line.
+ verifyFormat("bool x = a && b && c;", Style);
+
+ // Multiple PerOperator groups: && and || plus | operators.
+ FormatStyle::BinaryOperationBreakRule BitwiseOrRule;
+ BitwiseOrRule.Operators = {"|"};
+ BitwiseOrRule.Style = FormatStyle::BBO_OnePerLine;
+ BitwiseOrRule.MinChainLength = 0;
+
+ Style.BreakBinaryOperations.PerOperator = {LogicalRule, BitwiseOrRule};
+
+ // | operators should break one-per-line.
+ verifyFormat("int x = loooooooooooooooooongval1 |\n"
+ " loooooooooooooooooongval2 |\n"
+ " loooooooooooooooooongval3;",
+ Style);
+
+ // && still works in multi-group configuration.
+ verifyFormat("bool x = loooooooooooooongcondition1 &&\n"
+ " loooooooooooooongcondition2 &&\n"
+ " loooooooooooooongcondition3;",
+ Style);
+
+ // + operators stay with default (Never) even with multi-group.
+ verifyFormat("int x = loooooooooooooongop1 + looooooooongop2 +\n"
+ " loooooooooooooooooooooongop3;",
+ Style);
+}
+
+TEST_F(FormatTest, BreakBinaryOperationsMinChainLength) {
+ auto Style = getLLVMStyleWithColumns(60);
+
+ // MinChainLength = 3: chains shorter than 3 don't force breaks.
+ FormatStyle::BinaryOperationBreakRule LogicalRule;
+ LogicalRule.Operators = {"&&", "||"};
+ LogicalRule.Style = FormatStyle::BBO_OnePerLine;
+ LogicalRule.MinChainLength = 3;
+
+ Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+ Style.BreakBinaryOperations.PerOperator = {LogicalRule};
+
+ // Chain of 2 — should NOT force one-per-line (below MinChainLength).
+ verifyFormat("bool x = loooooooooooooongcondition1 &&\n"
----------------
ssubbotin wrote:
Good point — replaced `loooooong` names with realistic ones in commit 258f4f3. Tests now use names like `isConnectionReady()`, `isSessionNotExpired()`, `hasRequiredPermission()`, `unitBasePrice`, `shippingCostPerItem`, `OPTION_VERBOSE_OUTPUT`, etc.
https://github.com/llvm/llvm-project/pull/181051
More information about the cfe-commits
mailing list