russellmcc updated this revision to Diff 144269. russellmcc added a comment.
Responded to review feedback. Improved documentation comments for new options. While adding tests for the other constructor line break styles, I noticed an inconsistency with the way "after colon" behaved with `ConstructorInitializerAllOnOneLineOrOnePerLine`. Unlike the other two modes, "after colon" breaking would never allow all initializers on a single line. I've changed the behavior so the new `AllowAllConstructorInitializersOnNextLine` is honored even in break after colon mode. This does cause a slight change in behavior for default settings, as now in after colon mode it will be allowed to put all the initializers in one line with default settings. I've updated the unit tests for break after colon mode to address this. https://reviews.llvm.org/D40988 Files: include/clang/Format/Format.h lib/Format/ContinuationIndenter.cpp lib/Format/Format.cpp unittests/Format/FormatTest.cpp
Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -3433,6 +3433,154 @@ " aaaa(aaaa) {}")); } +TEST_F(FormatTest, AllowAllConstructorInitializersOnNextLine) { + FormatStyle Style = getLLVMStyle(); + Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; + Style.ColumnLimit = 60; + Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true; + Style.AllowAllConstructorInitializersOnNextLine = true; + Style.BinPackParameters = false; + + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + verifyFormat("Constructor() : a(a), b(b) {}", Style); + + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaa(a)\n" + " , bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + verifyFormat("Constructor() : a(a), b(b) {}", Style); + + Style.AllowAllParametersOfDeclarationOnNextLine = true; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb)\n" + " : aaaaaaaaaaaaaaaaaaaa(a)\n" + " , bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllConstructorInitializersOnNextLine = true; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbbb,\n" + " int cccccccccccccccc)\n" + " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllParametersOfDeclarationOnNextLine = false; + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbbb)\n" + " : aaaaaaaaaaaaaaaaaaaa(a)\n" + " , bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; + Style.AllowAllConstructorInitializersOnNextLine = true; + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllParametersOfDeclarationOnNextLine = true; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb)\n" + " : aaaaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllConstructorInitializersOnNextLine = true; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbbb,\n" + " int cccccccccccccccc)\n" + " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllParametersOfDeclarationOnNextLine = false; + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbbb)\n" + " : aaaaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; + Style.AllowAllConstructorInitializersOnNextLine = true; + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("Constructor() :\n" + " aaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllParametersOfDeclarationOnNextLine = true; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb) :\n" + " aaaaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllConstructorInitializersOnNextLine = true; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbbb,\n" + " int cccccccccccccccc) :\n" + " aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); + + Style.AllowAllParametersOfDeclarationOnNextLine = false; + Style.AllowAllConstructorInitializersOnNextLine = false; + verifyFormat("SomeClassWithALongName::Constructor(\n" + " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbbb) :\n" + " aaaaaaaaaaaaaaaaaaaa(a),\n" + " bbbbbbbbbbbbbbbbbbbbb(b) {}", + Style); +} + +TEST_F(FormatTest, AllowAllArgumentsOnNextLine) { + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = 60; + Style.BinPackArguments = false; + Style.AllowAllArgumentsOnNextLine = true; + verifyFormat("void foo() {\n" + " FunctionCallWithReallyLongName(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbb);\n" + "}", + Style); + Style.AllowAllArgumentsOnNextLine = false; + verifyFormat("void foo() {\n" + " FunctionCallWithReallyLongName(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " bbbbbbbbbbbb);\n" + "}", + Style); + + // This parameter should not affect declarations. + Style.BinPackParameters = false; + Style.AllowAllParametersOfDeclarationOnNextLine = true; + verifyFormat("void FunctionCallWithReallyLongName(\n" + " int aaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbb);", + Style); + Style.AllowAllParametersOfDeclarationOnNextLine = false; + verifyFormat("void FunctionCallWithReallyLongName(\n" + " int aaaaaaaaaaaaaaaaaaaaaaa,\n" + " int bbbbbbbbbbbb);", + Style); +} + TEST_F(FormatTest, BreakConstructorInitializersAfterColon) { FormatStyle Style = getLLVMStyle(); Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; @@ -3450,7 +3598,13 @@ verifyFormat("template <typename T>\n" "Constructor() : Initializer(FitsOnTheLine) {}", getStyleWithColumns(Style, 50)); + Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true; + verifyFormat( + "SomeClass::Constructor() :\n" + " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", + Style); + Style.ConstructorInitializerAllOnOneLineOrOnePerLine = false; verifyFormat( "SomeClass::Constructor() :\n" " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", @@ -3506,7 +3660,7 @@ FormatStyle OnePerLine = Style; OnePerLine.ConstructorInitializerAllOnOneLineOrOnePerLine = true; - OnePerLine.AllowAllParametersOfDeclarationOnNextLine = false; + OnePerLine.AllowAllConstructorInitializersOnNextLine = false; verifyFormat("SomeClass::Constructor() :\n" " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" @@ -10020,6 +10174,8 @@ CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AlignConsecutiveAssignments); CHECK_PARSE_BOOL(AlignConsecutiveDeclarations); + CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine); + CHECK_PARSE_BOOL(AllowAllConstructorInitializersOnNextLine); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -287,6 +287,10 @@ IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); IO.mapOptional("AlignOperands", Style.AlignOperands); IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); + IO.mapOptional("AllowAllArgumentsOnNextLine", + Style.AllowAllArgumentsOnNextLine); + IO.mapOptional("AllowAllConstructorInitializersOnNextLine", + Style.AllowAllConstructorInitializersOnNextLine); IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", Style.AllowAllParametersOfDeclarationOnNextLine); IO.mapOptional("AllowShortBlocksOnASingleLine", @@ -303,6 +307,7 @@ Style.AlwaysBreakAfterDefinitionReturnType); IO.mapOptional("AlwaysBreakAfterReturnType", Style.AlwaysBreakAfterReturnType); + // If AlwaysBreakAfterDefinitionReturnType was specified but // AlwaysBreakAfterReturnType was not, initialize the latter from the // former for backwards compatibility. @@ -575,6 +580,8 @@ LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = false; LLVMStyle.AlignConsecutiveDeclarations = false; + LLVMStyle.AllowAllArgumentsOnNextLine = true; + LLVMStyle.AllowAllConstructorInitializersOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; LLVMStyle.AllowShortBlocksOnASingleLine = false; Index: lib/Format/ContinuationIndenter.cpp =================================================================== --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -747,14 +747,30 @@ State.Stack.back().BreakBeforeClosingBrace = true; if (State.Stack.back().AvoidBinPacking) { - // If we are breaking after '(', '{', '<', this is not bin packing - // unless AllowAllParametersOfDeclarationOnNextLine is false or this is a - // dict/object literal. - if (!Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) || + // If we are breaking after '(', '{', '<', or this is the break after a ':' + // to start a member initializater list in a constructor, this should not + // be considered bin packing unless the relevant AllowAll option is false or + // this is a dict/object literal. + bool PreviousIsBreakingCtorInitializerColon = + Previous.is(TT_CtorInitializerColon) && + Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon; + if (!(Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) || + PreviousIsBreakingCtorInitializerColon) || (!Style.AllowAllParametersOfDeclarationOnNextLine && State.Line->MustBeDeclaration) || + (!Style.AllowAllArgumentsOnNextLine && + !State.Line->MustBeDeclaration) || + (!Style.AllowAllConstructorInitializersOnNextLine && + PreviousIsBreakingCtorInitializerColon) || Previous.is(TT_DictLiteral)) State.Stack.back().BreakBeforeParameter = true; + + // If we are breaking after a ':' to start a member initializer list, + // and we allow all arguments on the next line, we should not break + // before the next parameter. + if (PreviousIsBreakingCtorInitializerColon && + Style.AllowAllConstructorInitializersOnNextLine) + State.Stack.back().BreakBeforeParameter = false; } return Penalty; @@ -959,9 +975,13 @@ ? 0 : 2); State.Stack.back().NestedBlockIndent = State.Stack.back().Indent; - if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) + if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) { State.Stack.back().AvoidBinPacking = true; - State.Stack.back().BreakBeforeParameter = false; + State.Stack.back().BreakBeforeParameter = + !Style.AllowAllConstructorInitializersOnNextLine; + } else { + State.Stack.back().BreakBeforeParameter = false; + } } if (Current.is(TT_CtorInitializerColon) && Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) { Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -151,6 +151,38 @@ /// \endcode bool AlignTrailingComments; + /// \brief If a function call, braced initializer list, or template argument + /// list doesn't fit on a line, allow putting all arguments onto the next + /// line, even if ``BinPackArguments`` is ``false``. + /// \code + /// true: + /// callFunction( + /// a, b, c, d); + /// + /// false: + /// callFunction(a, + /// b, + /// c, + /// d); + /// \endcode + bool AllowAllArgumentsOnNextLine; + + /// \brief If a constructor definition with a member initializer list doesn't + /// fit on a single line, allow putting all member initializers onto the next + /// line, if ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is true. + /// Note that this parameter has no effect if + /// ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is false. + /// \code + /// true: + /// MyClass::MyClass() : + /// member0(0), member1(2) {} + /// + /// false: + /// MyClass::MyClass() : + /// member0(0), + /// member1(2) {} + bool AllowAllConstructorInitializersOnNextLine; + /// \brief If the function declaration doesn't fit on a line, /// allow putting all parameters of a function declaration onto /// the next line even if ``BinPackParameters`` is ``false``. @@ -1571,6 +1603,9 @@ AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && AlignTrailingComments == R.AlignTrailingComments && + AllowAllArgumentsOnNextLine == R.AllowAllArgumentsOnNextLine && + AllowAllConstructorInitializersOnNextLine == + R.AllowAllConstructorInitializersOnNextLine && AllowAllParametersOfDeclarationOnNextLine == R.AllowAllParametersOfDeclarationOnNextLine && AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine && @@ -1625,8 +1660,7 @@ ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && - PenaltyBreakAssignment == - R.PenaltyBreakAssignment && + PenaltyBreakAssignment == R.PenaltyBreakAssignment && PenaltyBreakBeforeFirstCallParameter == R.PenaltyBreakBeforeFirstCallParameter && PenaltyBreakComment == R.PenaltyBreakComment &&
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits