From: Alexander Kornienko Date: Mon, 16 Dec 2013 14:35:51 +0000 (+0000) Subject: Always break before the colon in constructor initializers, when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=74a1c67f646da8f72d8a5c7552b19e518cc11823;p=clang Always break before the colon in constructor initializers, when BreakConstructorInitializersBeforeComma is true. This option is used in WebKit style, so this also ensures initializer lists are not put on a single line, as per the WebKit coding guidelines. Patch by Florian Sowade! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197386 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index e63f72d65e..e8dc8d4a7f 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -183,9 +183,12 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { Current.LongestObjCSelectorName == 0 && State.Stack.back().BreakBeforeParameter) return true; - if ((Current.Type == TT_CtorInitializerColon || - (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0 && - !Current.isTrailingComment()))) + if (Current.Type == TT_CtorInitializerColon && + (!Style.AllowShortFunctionsOnASingleLine || + Style.BreakConstructorInitializersBeforeComma || Style.ColumnLimit != 0)) + return true; + if (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0 && + !Current.isTrailingComment()) return true; if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) && diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 87c2fd70ae..86619270b3 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -455,13 +455,12 @@ public: /// \brief Formats the line starting at \p State, simply keeping all of the /// input's line breaking decisions. - void format(unsigned FirstIndent, const AnnotatedLine *Line, - bool LineIsMerged) { + void format(unsigned FirstIndent, const AnnotatedLine *Line) { LineState State = Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false); while (State.NextToken != NULL) { bool Newline = - (!LineIsMerged && Indenter->mustBreak(State)) || + Indenter->mustBreak(State) || (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0); Indenter->addTokenToState(State, Newline, /*DryRun=*/false); } @@ -728,8 +727,7 @@ public: // FIXME: Implement nested blocks for ColumnLimit = 0. NoColumnLimitFormatter Formatter(Indenter); if (!DryRun) - Formatter.format(Indent, &TheLine, - /*LineIsMerged=*/MergedLines > 0); + Formatter.format(Indent, &TheLine); } else { Penalty += format(TheLine, Indent, DryRun); } diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 19759afc85..e2615dbb6a 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -1407,7 +1407,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, Right.Previous->MatchingParen->NestingLevel == 0 && Style.AlwaysBreakTemplateDeclarations) { return true; - } else if (Right.Type == TT_CtorInitializerComma && + } else if ((Right.Type == TT_CtorInitializerComma || + Right.Type == TT_CtorInitializerColon) && Style.BreakConstructorInitializersBeforeComma && !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) { return true; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index bd9d108357..5e38f5974a 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -7524,7 +7524,38 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) { " , b(b)\n" " , c(c) {}", Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a) {}", + Style); + + Style.ColumnLimit = 0; + verifyFormat("SomeClass::Constructor()\n" + " : a(a) {}", + Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a)\n" + " , b(b)\n" + " , c(c) {}", + Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a) {\n" + " foo();\n" + " bar();\n" + "}", + Style); + + Style.AllowShortFunctionsOnASingleLine = false; + verifyFormat("SomeClass::Constructor()\n" + " : a(a)\n" + " , b(b)\n" + " , c(c) {\n}", + Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a) {\n}", + Style); + Style.ColumnLimit = 80; + Style.AllowShortFunctionsOnASingleLine = true; Style.ConstructorInitializerIndentWidth = 2; verifyFormat("SomeClass::Constructor()\n" " : a(a)\n" @@ -7541,6 +7572,10 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) { Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true; Style.ConstructorInitializerIndentWidth = 4; + verifyFormat("SomeClass::Constructor() : aaaaaaaa(aaaaaaaa) {}", Style); + verifyFormat( + "SomeClass::Constructor() : aaaaa(aaaaa), aaaaa(aaaaa), aaaaa(aaaaa)\n", + Style); verifyFormat( "SomeClass::Constructor()\n" " : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa) {}", @@ -7600,18 +7635,27 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) { // Constructor initializers are formatted one per line with the "," on the // new line. - EXPECT_EQ( - "Constructor()\n" - " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" - " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" - " aaaaaaaaaaaaaa)\n" - " , aaaaaaaaaaaaaaaaaaaaaaa() {}", - format("Constructor()\n" - " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" - " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" - " aaaaaaaaaaaaaa)\n" - " , aaaaaaaaaaaaaaaaaaaaaaa() {}", - Style)); + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" + " aaaaaaaaaaaaaa)\n" + " , aaaaaaaaaaaaaaaaaaaaaaa() {}", + Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a) {}", + Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a)\n" + " , b(b)\n" + " , c(c) {}", + Style); + verifyFormat("SomeClass::Constructor()\n" + " : a(a)\n" + "{\n" + " foo();\n" + " bar();\n" + "}", + Style); // Access specifiers should be aligned left. verifyFormat("class C {\n"