**AccessModifierOffset** (``int``)
The extra indent or outdent of access modifiers, e.g. ``public:``.
+**AlignAfterOpenBracket** (``bool``)
+ If ``true``, horizontally aligns arguments after an open bracket.
+
+ This applies to round brackets (parentheses), angle brackets and square
+ brackets. This will result in formattings like
+ \code
+ someLongFunction(argument1,
+ argument2);
+ \endcode
+
**AlignEscapedNewlinesLeft** (``bool``)
If ``true``, aligns escaped newlines as far left as possible.
Otherwise puts them into the right-most column.
+**AlignOperands** (``bool``)
+ If ``true``, horizontally align operands of binary and ternary
+ expressions.
+
**AlignTrailingComments** (``bool``)
If ``true``, aligns trailing comments.
Never merge functions into a single line.
* ``SFS_Inline`` (in configuration: ``Inline``)
Only merge functions defined inside a class.
+ * ``SFS_Empty`` (in configuration: ``Empty``)
+ Only merge empty functions.
* ``SFS_All`` (in configuration: ``All``)
Merge all functions fitting on a single line.
**DerivePointerAlignment** (``bool``)
If ``true``, analyze the formatted file for the most common
- alignment of & and \*. ``PointerAlignment`` is then used only as fallback.
+ alignment of & and *. ``PointerAlignment`` is then used only as fallback.
**DisableFormat** (``bool``)
Disables formatting at all.
/// \endcode
bool AlignAfterOpenBracket;
+ /// \brief If \c true, horizontally align operands of binary and ternary
+ /// expressions.
+ bool AlignOperands;
+
/// \brief If \c true, aligns trailing comments.
bool AlignTrailingComments;
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
+ AlignOperands == R.AlignOperands &&
AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
// expression itself as otherwise, the line breaks seem superfluous.
// We need special cases for ">>" which we have split into two ">" while
// lexing in order to make template parsing easier.
- //
- // FIXME: We'll need something similar for styles that break before binary
- // operators.
bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
Previous.getPrecedence() == prec::Equality) &&
Previous.Previous &&
Previous.getPrecedence() != prec::Assignment &&
State.Stack.back().BreakBeforeParameter)
return true;
+ } else {
+ if (Current.is(TT_BinaryOperator) && Previous.EndsBinaryExpression &&
+ State.Stack.back().BreakBeforeParameter)
+ return true;
}
+
// Same as above, but for the first "<<" operator.
if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
State.Stack.back().BreakBeforeParameter &&
// is special cased.
bool SkipFirstExtraIndent =
(Previous && (Previous->opensScope() || Previous->is(tok::kw_return) ||
- Previous->getPrecedence() == prec::Assignment ||
+ (Previous->getPrecedence() == prec::Assignment &&
+ Style.AlignOperands) ||
Previous->is(TT_ObjCMethodExpr)));
for (SmallVectorImpl<prec::Level>::const_reverse_iterator
I = Current.FakeLParens.rbegin(),
// a builder type call after 'return' or, if the alignment after opening
// brackets is disabled.
if (!Current.isTrailingComment() &&
+ (Style.AlignOperands || *I < prec::Assignment) &&
(!Previous || Previous->isNot(tok::kw_return) ||
(Style.Language != FormatStyle::LK_Java && *I > 0)) &&
(Style.AlignAfterOpenBracket || *I != prec::Comma ||
IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
+ IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
Style.AllowAllParametersOfDeclarationOnNextLine);
LLVMStyle.AccessModifierOffset = -2;
LLVMStyle.AlignEscapedNewlinesLeft = false;
LLVMStyle.AlignAfterOpenBracket = true;
+ LLVMStyle.AlignOperands = true;
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
if (Language == FormatStyle::LK_Java) {
GoogleStyle.AlignAfterOpenBracket = false;
+ GoogleStyle.AlignOperands = false;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
GoogleStyle.ColumnLimit = 100;
FormatStyle Style = getLLVMStyle();
Style.AccessModifierOffset = -4;
Style.AlignAfterOpenBracket = false;
+ Style.AlignOperands = false;
Style.AlignTrailingComments = false;
Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
" // comment\n"
" + b;",
Style);
+ verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + cc;",
+ Style);
// Forced by comments.
verifyFormat(
Style);
}
+TEST_F(FormatTest, NoOperandAlignment) {
+ FormatStyle Style = getLLVMStyle();
+ Style.AlignOperands = false;
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
+ verifyFormat(
+ "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " > ccccccccccccccccccccccccccccccccccccccccc;",
+ Style);
+
+ verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + cc;",
+ Style);
+ verifyFormat("int a = aa\n"
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " * cccccccccccccccccccccccccccccccccccc;",
+ Style);
+}
+
TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) {
FormatStyle Style = getLLVMStyle();
Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
- " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", Style);
-
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;",
+ Style);
}
TEST_F(FormatTest, ConstructorInitializers) {
Style);
}
+TEST_F(FormatTest, ParenthesesAndOperandAlignment) {
+ FormatStyle Style = getLLVMStyleWithColumns(40);
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+ Style.AlignAfterOpenBracket = true;
+ Style.AlignOperands = false;
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+ Style.AlignAfterOpenBracket = false;
+ Style.AlignOperands = true;
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+ Style.AlignAfterOpenBracket = false;
+ Style.AlignOperands = false;
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+}
+
TEST_F(FormatTest, BreaksConditionalExpressions) {
verifyFormat(
"aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
TEST_F(FormatTest, ParsesConfigurationBools) {
FormatStyle Style = {};
Style.Language = FormatStyle::LK_Cpp;
+ CHECK_PARSE_BOOL(AlignAfterOpenBracket);
CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
+ CHECK_PARSE_BOOL(AlignOperands);
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
"double b; // align comments.",
Style);
+ // Do not align operands.
+ EXPECT_EQ("ASSERT(aaaa\n"
+ " || bbbb);",
+ format("ASSERT ( aaaa\n||bbbb);", Style));
+
// Accept input's line breaks.
EXPECT_EQ("if (aaaaaaaaaaaaaaa\n"
" || bbbbbbbbbbbbbbb) {\n"
TEST_F(FormatTestJava, StringConcatenation) {
verifyFormat("String someString = \"abc\"\n"
- " + \"cde\";");
+ " + \"cde\";");
}
TEST_F(FormatTestJava, TryCatchFinally) {