@@ -131,7 +131,8 @@ static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok) {
131131// Returns \c true if \c Current starts a new parameter.
132132static bool startsNextParameter (const FormatToken &Current,
133133 const FormatStyle &Style) {
134- const FormatToken &Previous = *Current.Previous ;
134+ assert (Current.Previous );
135+ const auto &Previous = *Current.Previous ;
135136 if (Current.is (TT_CtorInitializerComma) &&
136137 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
137138 return true ;
@@ -146,6 +147,31 @@ static bool startsNextParameter(const FormatToken &Current,
146147 Style.BreakInheritanceList != FormatStyle::BILS_BeforeComma));
147148}
148149
150+ // Returns \c true if \c Token in an alignable binary operator
151+ static bool isAlignableBinaryOperator (const FormatToken &Token) {
152+ // No need to align binary operators that only have two operands.
153+ bool HasTwoOperands = Token.OperatorIndex == 0 && !Token.NextOperator ;
154+ return Token.is (TT_BinaryOperator) && !HasTwoOperands &&
155+ Token.getPrecedence () > prec::Conditional &&
156+ Token.getPrecedence () < prec::PointerToMember;
157+ }
158+
159+ // Returns \c true if \c Current starts the next operand in a binary operation.
160+ static bool startsNextOperand (const FormatToken &Current) {
161+ assert (Current.Previous );
162+ const auto &Previous = *Current.Previous ;
163+ return isAlignableBinaryOperator (Previous) && !Current.isTrailingComment ();
164+ }
165+
166+ // Returns \c true if \c Current is a binary operation that must break.
167+ static bool mustBreakBinaryOperation (const FormatToken &Current,
168+ const FormatStyle &Style) {
169+ return Style.BreakBinaryOperations != FormatStyle::BBO_Never &&
170+ (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None
171+ ? startsNextOperand
172+ : isAlignableBinaryOperator)(Current);
173+ }
174+
149175static bool opensProtoMessageField (const FormatToken &LessTok,
150176 const FormatStyle &Style) {
151177 if (LessTok.isNot (tok::less))
@@ -869,6 +895,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
869895 }
870896 if (CurrentState.AvoidBinPacking && startsNextParameter (Current, Style))
871897 CurrentState.NoLineBreak = true ;
898+ if (mustBreakBinaryOperation (Current, Style))
899+ CurrentState.NoLineBreak = true ;
900+
872901 if (startsSegmentOfBuilderTypeCall (Current) &&
873902 State.Column > getNewLineColumn (State)) {
874903 CurrentState.ContainsUnwrappedBuilder = true ;
@@ -1235,6 +1264,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
12351264 }
12361265 }
12371266
1267+ if (mustBreakBinaryOperation (Current, Style))
1268+ CurrentState.BreakBeforeParameter = true ;
1269+
12381270 return Penalty;
12391271}
12401272
0 commit comments