Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -228,6 +228,15 @@
/// Foo instead of \c Foo.
bool ObjCSpaceBeforeProtocolList;
+ /// \brief If \c true, horizontally aligns arguments after an open bracket.
+ ///
+ /// This will result in formattings like
+ /// \code
+ /// someLongFunction(argument1,
+ /// argument2);
+ /// \endcode
+ bool AlignAfterOpenBracket;
+
/// \brief If \c true, aligns trailing comments.
bool AlignTrailingComments;
@@ -394,6 +403,7 @@
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
+ AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -301,6 +301,9 @@
}
if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr &&
+ !(!Style.AlignAfterOpenBracket && Previous.is(tok::l_paren) &&
+ Previous.getPreviousNonComment() &&
+ Previous.getPreviousNonComment()->Type == TT_FunctionDeclarationName) &&
(Current.Type != TT_LineComment || Previous.BlockKind == BK_BracedInit))
State.Stack.back().Indent = State.Column + Spaces;
if (State.Stack.back().AvoidBinPacking && startsNextParameter(Current, Style))
@@ -735,11 +738,26 @@
ParenState NewParenState = State.Stack.back();
NewParenState.ContainsLineBreak = false;
- // Indent from 'LastSpace' unless this the fake parentheses encapsulating a
- // builder type call after 'return'. If such a call is line-wrapped, we
- // commonly just want to indent from the start of the line.
+ bool PreviousIsFunctionDeclParen =
+ Previous && Previous->is(tok::l_paren) &&
+ Previous->getPreviousNonComment() &&
+ Previous->getPreviousNonComment()->Type == TT_FunctionDeclarationName &&
+ *I == prec::Comma;
+
+ // We can disable alignment after an open bracket by not allowing line
+ // breaks within a scope unless we broke immediately after the scope opener.
+ if (!Style.AlignAfterOpenBracket && Previous && Previous->opensScope() &&
+ !PreviousIsFunctionDeclParen && !Newline && canBreak(State))
+ NewParenState.NoLineBreak = true;
+
+ // Indent from 'LastSpace' unless this is the fake parenthesis encapsulating
+ // a builder type call after 'return' or, if the alignment after opening
+ // brackets is disabled, a left paren of a method declaration argument list.
+ // If such a call is line-wrapped, we commonly just want to indent from the
+ // start of the line.
if (!Current.isTrailingComment() &&
- (!Previous || Previous->isNot(tok::kw_return) || *I > 0))
+ (!Previous || Previous->isNot(tok::kw_return) || *I > 0) &&
+ (Style.AlignAfterOpenBracket || !PreviousIsFunctionDeclParen))
NewParenState.Indent =
std::max(std::max(State.Column, NewParenState.Indent),
State.Stack.back().LastSpace);
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -170,6 +170,7 @@
}
IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
+ IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
@@ -324,6 +325,7 @@
LLVMStyle.Language = FormatStyle::LK_Cpp;
LLVMStyle.AccessModifierOffset = -2;
LLVMStyle.AlignEscapedNewlinesLeft = false;
+ LLVMStyle.AlignAfterOpenBracket = true;
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
@@ -411,6 +413,7 @@
GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
if (Language == FormatStyle::LK_Java) {
+ GoogleStyle.AlignAfterOpenBracket = false;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
GoogleStyle.ColumnLimit = 100;
@@ -458,6 +461,7 @@
FormatStyle getWebKitStyle() {
FormatStyle Style = getLLVMStyle();
Style.AccessModifierOffset = -4;
+ Style.AlignAfterOpenBracket = false;
Style.AlignTrailingComments = false;
Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1452,8 +1452,10 @@
return 1;
if (Right.is(Keywords.kw_implements))
return 2;
- if (Left.is(tok::comma) && Left.NestingLevel == 0)
+ if (Left.is(tok::comma))
return 3;
+ if (Left.is(tok::l_paren) && InFunctionDecl)
+ return 1;
}
if (Left.is(tok::comma) || (Right.is(tok::identifier) && Right.Next &&
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -4026,6 +4026,32 @@
" code == a || code == b;");
}
+TEST_F(FormatTest, AlignsAfterOpenBracket) {
+ verifyFormat(
+ "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaa aaaaaaaa,\n"
+ " aaaaaaaaa aaaaaaa) {}");
+ verifyFormat(
+ "SomeLongVariableName->someVeryLongFunctionName(aaaaaaaaaaa aaaaaaaaa,\n"
+ " aaaaaaaaaaa aaaaaaaaa);");
+ verifyFormat(
+ "SomeLongVariableName->someFunction(foooooooo(aaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaa));");
+ FormatStyle Style = getLLVMStyle();
+ Style.AlignAfterOpenBracket = false;
+ verifyFormat(
+ "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaa aaaaaaaa,\n"
+ " aaaaaaaaa aaaaaaa) {}",
+ Style);
+ verifyFormat(
+ "SomeLongVariableName->someVeryLongFunctionName(\n"
+ " aaaaaaaaaaa aaaaaaaaa, aaaaaaaaaaa aaaaaaaaa);",
+ Style);
+ verifyFormat(
+ "SomeLongVariableName->someFunction(\n"
+ " foooooooo(aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaa));",
+ Style);
+}
+
TEST_F(FormatTest, BreaksConditionalExpressions) {
verifyFormat(
"aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
Index: unittests/Format/FormatTestJava.cpp
===================================================================
--- unittests/Format/FormatTestJava.cpp
+++ unittests/Format/FormatTestJava.cpp
@@ -261,5 +261,16 @@
getStyleWithColumns(50));
}
+TEST_F(FormatTestJava, MethodDeclarations) {
+ verifyFormat("void methodName(Object arg1,\n"
+ " Object arg2, Object arg3) {\n"
+ "}",
+ getStyleWithColumns(40));
+ verifyFormat("void methodName(\n"
+ " Object arg1, Object arg2) {\n"
+ "}",
+ getStyleWithColumns(40));
+}
+
} // end namespace tooling
} // end namespace clang