From: Daniel Jasper Date: Fri, 21 Nov 2014 13:38:53 +0000 (+0000) Subject: clang-format: Use nested block special case for all languages. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b444495ed95c433d8a4fa757ac4db37d6b71d4d;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 40b50dd..825a88e 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -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); diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h index 5abbe7e..004ddeb 100644 --- a/clang/lib/Format/ContinuationIndenter.h +++ b/clang/lib/Format/ContinuationIndenter.h @@ -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; } }; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index b96c17a..7c062d6 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -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; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c58ac0a..479919e 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -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...] {};"); diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp index 53df9af..8c9504b 100644 --- a/clang/unittests/Format/FormatTestJava.cpp +++ b/clang/unittests/Format/FormatTestJava.cpp @@ -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"