forked from OSchip/llvm-project
clang-format: Use nested block special case for all languages.
Previously this was only used for JavaScript. Before: functionCall({ int i; int j; }, aaaa, bbbb, cccc); After: functionCall({ int i; int j; }, aaaa, bbbb, cccc); llvm-svn: 222531
This commit is contained in:
parent
45bac8d4e8
commit
4b444495ed
|
@ -117,9 +117,8 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
|
|||
|
||||
// Don't create a 'hanging' indent if there are multiple blocks in a single
|
||||
// statement.
|
||||
if (Style.Language == FormatStyle::LK_JavaScript &&
|
||||
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
|
||||
State.Stack[State.Stack.size() - 2].JSFunctionInlined &&
|
||||
if (Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
|
||||
State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
|
||||
State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks)
|
||||
return false;
|
||||
|
||||
|
@ -453,11 +452,10 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
|
|||
|
||||
// Any break on this level means that the parent level has been broken
|
||||
// and we need to avoid bin packing there.
|
||||
bool JavaScriptFormat = Style.Language == FormatStyle::LK_JavaScript &&
|
||||
Current.is(tok::r_brace) &&
|
||||
State.Stack.size() > 1 &&
|
||||
State.Stack[State.Stack.size() - 2].JSFunctionInlined;
|
||||
if (!JavaScriptFormat) {
|
||||
bool NestedBlockSpecialCase =
|
||||
Current.is(tok::r_brace) && State.Stack.size() > 1 &&
|
||||
State.Stack[State.Stack.size() - 2].NestedBlockInlined;
|
||||
if (!NestedBlockSpecialCase) {
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
|
||||
State.Stack[i].BreakBeforeParameter = true;
|
||||
}
|
||||
|
@ -520,7 +518,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
|
|||
: State.Stack.back().Indent;
|
||||
if (Current.isOneOf(tok::r_brace, tok::r_square)) {
|
||||
if (State.Stack.size() > 1 &&
|
||||
State.Stack[State.Stack.size() - 2].JSFunctionInlined)
|
||||
State.Stack[State.Stack.size() - 2].NestedBlockInlined)
|
||||
return State.FirstIndent;
|
||||
if (Current.closesBlockTypeList(Style) ||
|
||||
(Current.MatchingParen &&
|
||||
|
@ -666,22 +664,21 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
|
|||
// foo();
|
||||
// bar();
|
||||
// }, a, b, c);
|
||||
if (Style.Language == FormatStyle::LK_JavaScript) {
|
||||
if (Current.isNot(tok::comment) && Previous && Previous->is(tok::l_brace) &&
|
||||
State.Stack.size() > 1) {
|
||||
if (State.Stack[State.Stack.size() - 2].JSFunctionInlined && Newline) {
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
|
||||
State.Stack[i].NoLineBreak = true;
|
||||
}
|
||||
if (Current.isNot(tok::comment) && Previous && Previous->is(tok::l_brace) &&
|
||||
State.Stack.size() > 1) {
|
||||
if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline) {
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
|
||||
State.Stack[i].NoLineBreak = true;
|
||||
}
|
||||
State.Stack[State.Stack.size() - 2].JSFunctionInlined = false;
|
||||
}
|
||||
if (Current.is(Keywords.kw_function))
|
||||
State.Stack.back().JSFunctionInlined =
|
||||
!Newline && Previous && Previous->Type != TT_DictLiteral &&
|
||||
// If the unnamed function is the only parameter to another function,
|
||||
// we can likely inline it and come up with a good format.
|
||||
(Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1);
|
||||
State.Stack[State.Stack.size() - 2].NestedBlockInlined = false;
|
||||
}
|
||||
if (Previous && (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) ||
|
||||
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) &&
|
||||
!Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
|
||||
State.Stack.back().NestedBlockInlined =
|
||||
!Newline &&
|
||||
(Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1) && !Newline;
|
||||
}
|
||||
|
||||
moveStatePastFakeLParens(State, Newline);
|
||||
|
|
|
@ -155,7 +155,7 @@ struct ParenState {
|
|||
NestedNameSpecifierContinuation(0), CallContinuation(0), VariablePos(0),
|
||||
ContainsLineBreak(false), ContainsUnwrappedBuilder(0),
|
||||
AlignColons(true), ObjCSelectorNameFound(false),
|
||||
HasMultipleNestedBlocks(false), JSFunctionInlined(false) {}
|
||||
HasMultipleNestedBlocks(false), NestedBlockInlined(false) {}
|
||||
|
||||
/// \brief The position to which a specific parenthesis level needs to be
|
||||
/// indented.
|
||||
|
@ -256,9 +256,9 @@ struct ParenState {
|
|||
/// the same token.
|
||||
bool HasMultipleNestedBlocks;
|
||||
|
||||
// \brief The previous JavaScript 'function' keyword is not wrapped to a new
|
||||
// line.
|
||||
bool JSFunctionInlined;
|
||||
// \brief The start of a nested block (e.g. lambda introducer in C++ or
|
||||
// "function" in JavaScript) is not wrapped to a new line.
|
||||
bool NestedBlockInlined;
|
||||
|
||||
bool operator<(const ParenState &Other) const {
|
||||
if (Indent != Other.Indent)
|
||||
|
@ -293,8 +293,8 @@ struct ParenState {
|
|||
return ContainsLineBreak < Other.ContainsLineBreak;
|
||||
if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
|
||||
return ContainsUnwrappedBuilder < Other.ContainsUnwrappedBuilder;
|
||||
if (JSFunctionInlined != Other.JSFunctionInlined)
|
||||
return JSFunctionInlined < Other.JSFunctionInlined;
|
||||
if (NestedBlockInlined != Other.NestedBlockInlined)
|
||||
return NestedBlockInlined < Other.NestedBlockInlined;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1285,7 +1285,7 @@ private:
|
|||
int AdditionalIndent =
|
||||
State.FirstIndent - State.Line->Level * Style.IndentWidth;
|
||||
if (State.Stack.size() < 2 ||
|
||||
!State.Stack[State.Stack.size() - 2].JSFunctionInlined) {
|
||||
!State.Stack[State.Stack.size() - 2].NestedBlockInlined) {
|
||||
AdditionalIndent = State.Stack.back().Indent -
|
||||
Previous.Children[0]->Level * Style.IndentWidth;
|
||||
}
|
||||
|
|
|
@ -2900,11 +2900,19 @@ TEST_F(FormatTest, LayoutBlockInsideParens) {
|
|||
"});",
|
||||
format(" functionCall ( {int i;int j;} );"));
|
||||
EXPECT_EQ("functionCall({\n"
|
||||
" int i;\n"
|
||||
" int j;\n"
|
||||
" },\n"
|
||||
" aaaa, bbbb, cccc);",
|
||||
" int i;\n"
|
||||
" int j;\n"
|
||||
"}, aaaa, bbbb, cccc);",
|
||||
format(" functionCall ( {int i;int j;}, aaaa, bbbb, cccc);"));
|
||||
EXPECT_EQ("functionCall(\n"
|
||||
" {\n"
|
||||
" int i;\n"
|
||||
" int j;\n"
|
||||
" },\n"
|
||||
" aaaa, bbbb, // comment\n"
|
||||
" cccc);",
|
||||
format(" functionCall ( {int i;int j;}, aaaa, bbbb, // comment\n"
|
||||
"cccc);"));
|
||||
EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });",
|
||||
format(" functionCall (aaaa, bbbb, {int i;});"));
|
||||
EXPECT_EQ("functionCall(aaaa, bbbb, {\n"
|
||||
|
@ -2915,7 +2923,8 @@ TEST_F(FormatTest, LayoutBlockInsideParens) {
|
|||
EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });",
|
||||
format(" functionCall (aaaa, bbbb, {int i;});"));
|
||||
verifyFormat(
|
||||
"Aaa({\n"
|
||||
"Aaa(\n" // FIXME: There shouldn't be a linebreak here.
|
||||
" {\n"
|
||||
" int i; // break\n"
|
||||
" },\n"
|
||||
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
|
||||
|
@ -2997,10 +3006,9 @@ TEST_F(FormatTest, LayoutNestedBlocks) {
|
|||
FormatStyle Style = getGoogleStyle();
|
||||
Style.ColumnLimit = 45;
|
||||
verifyFormat("Debug(aaaaa, {\n"
|
||||
" if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"
|
||||
" return;\n"
|
||||
" },\n"
|
||||
" a);", Style);
|
||||
" if (aaaaaaaaaaaaaaaaaaaaaaaa) return;\n"
|
||||
"}, a);",
|
||||
Style);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) {
|
||||
|
@ -7687,11 +7695,10 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
|
|||
Tab);
|
||||
verifyFormat("{\n"
|
||||
"\tQ({\n"
|
||||
"\t\t int a;\n"
|
||||
"\t\t someFunction(aaaaaaaaaa,\n"
|
||||
"\t\t bbbbbbbbb);\n"
|
||||
"\t },\n"
|
||||
"\t p);\n"
|
||||
"\t\tint a;\n"
|
||||
"\t\tsomeFunction(aaaaaaaa,\n"
|
||||
"\t\t bbbbbbb);\n"
|
||||
"\t}, p);\n"
|
||||
"}",
|
||||
Tab);
|
||||
EXPECT_EQ("{\n"
|
||||
|
@ -9278,14 +9285,15 @@ TEST_F(FormatTest, FormatsLambdas) {
|
|||
"};");
|
||||
|
||||
// Multiple lambdas in the same parentheses change indentation rules.
|
||||
verifyFormat("SomeFunction([]() {\n"
|
||||
" int i = 42;\n"
|
||||
" return i;\n"
|
||||
" },\n"
|
||||
" []() {\n"
|
||||
" int j = 43;\n"
|
||||
" return j;\n"
|
||||
" });");
|
||||
verifyFormat("SomeFunction(\n"
|
||||
" []() {\n"
|
||||
" int i = 42;\n"
|
||||
" return i;\n"
|
||||
" },\n"
|
||||
" []() {\n"
|
||||
" int j = 43;\n"
|
||||
" return j;\n"
|
||||
" });");
|
||||
|
||||
// More complex introducers.
|
||||
verifyFormat("return [i, args...] {};");
|
||||
|
|
|
@ -319,6 +319,29 @@ TEST_F(FormatTestJava, NeverAlignAfterReturn) {
|
|||
getStyleWithColumns(40));
|
||||
}
|
||||
|
||||
TEST_F(FormatTestJava, FormatsInnerBlocks) {
|
||||
verifyFormat("someObject.someFunction(new Runnable() {\n"
|
||||
" @Override\n"
|
||||
" public void run() {\n"
|
||||
" System.out.println(42);\n"
|
||||
" }\n"
|
||||
"}, someOtherParameter);");
|
||||
verifyFormat("someObject.someFunction(\n"
|
||||
" new Runnable() {\n"
|
||||
" @Override\n"
|
||||
" public void run() {\n"
|
||||
" System.out.println(42);\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" new Runnable() {\n"
|
||||
" @Override\n"
|
||||
" public void run() {\n"
|
||||
" System.out.println(43);\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" someOtherParameter);");
|
||||
}
|
||||
|
||||
TEST_F(FormatTestJava, FormatsLambdas) {
|
||||
verifyFormat("(aaaaaaaaaa, bbbbbbbbbb) -> aaaaaaaaaa + bbbbbbbbbb;");
|
||||
verifyFormat("(aaaaaaaaaa, bbbbbbbbbb)\n"
|
||||
|
|
Loading…
Reference in New Issue