From: Daniel Jasper Date: Mon, 15 Sep 2014 11:11:00 +0000 (+0000) Subject: clang-format: Add option to break before non-assignment operators. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=742a11d58333485592e2e44cdfcf3c210f1aae72;p=clang clang-format: Add option to break before non-assignment operators. This will allow: int aaaaaaaaaaaaaa = bbbbbbbbbbbbbb + ccccccccccccccc; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217757 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index e0793e80a7..84b3fc8202 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -191,8 +191,18 @@ the configuration (without a prefix: ``Auto``). If ``false``, a function call's or function definition's parameters will either all be on the same line or will have one line each. -**BreakBeforeBinaryOperators** (``bool``) - If ``true``, binary operators will be placed after line breaks. +**BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) + The way to wrap binary operators. + + Possible values: + + * ``BOS_None`` (in configuration: ``None``) + Break after operators. + * ``BOS_NonAssignment`` (in configuration: ``NonAssignment``) + Break before operators that aren't assignments. + * ``BOS_All`` (in configuration: ``All``) + Break before operators. + **BreakBeforeBraces** (``BraceBreakingStyle``) The brace breaking style to use. @@ -260,7 +270,7 @@ the configuration (without a prefix: ``Auto``). **DerivePointerAlignment** (``bool``) If ``true``, analyze the formatted file for the most common - alignment of & and ``*``. ``PointerAlignment`` is then used only as fallback. + alignment of & and *. ``PointerAlignment`` is then used only as fallback. **DisableFormat** (``bool``) Disables formatting at all. diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index abf505922e..22a9ef606e 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -266,8 +266,18 @@ struct FormatStyle { /// \brief The way to use tab characters in the resulting file. UseTabStyle UseTab; - /// \brief If \c true, binary operators will be placed after line breaks. - bool BreakBeforeBinaryOperators; + /// \brief The style of breaking before or after binary operators. + enum BinaryOperatorStyle { + /// Break after operators. + BOS_None, + /// Break before operators that aren't assignments. + BOS_NonAssignment, + /// Break before operators. + BOS_All, + }; + + /// \brief The way to wrap binary operators. + BinaryOperatorStyle BreakBeforeBinaryOperators; /// \brief If \c true, ternary operators will be placed after line breaks. bool BreakBeforeTernaryOperators; diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 36d0f62a85..5f9536dac8 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -76,6 +76,16 @@ template <> struct ScalarEnumerationTraits { } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) { + IO.enumCase(Value, "All", FormatStyle::BOS_All); + IO.enumCase(Value, "true", FormatStyle::BOS_All); + IO.enumCase(Value, "None", FormatStyle::BOS_None); + IO.enumCase(Value, "false", FormatStyle::BOS_None); + IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) { IO.enumCase(Value, "Attach", FormatStyle::BS_Attach); @@ -322,7 +332,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; LLVMStyle.AlwaysBreakTemplateDeclarations = false; LLVMStyle.BinPackParameters = true; - LLVMStyle.BreakBeforeBinaryOperators = false; + LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; LLVMStyle.BreakConstructorInitializersBeforeComma = false; @@ -438,7 +448,7 @@ FormatStyle getWebKitStyle() { FormatStyle Style = getLLVMStyle(); Style.AccessModifierOffset = -4; Style.AlignTrailingComments = false; - Style.BreakBeforeBinaryOperators = true; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; Style.BreakConstructorInitializersBeforeComma = true; Style.Cpp11BracedListStyle = false; @@ -454,7 +464,7 @@ FormatStyle getWebKitStyle() { FormatStyle getGNUStyle() { FormatStyle Style = getLLVMStyle(); Style.AlwaysBreakAfterDefinitionReturnType = true; - Style.BreakBeforeBinaryOperators = true; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; Style.BreakBeforeBraces = FormatStyle::BS_GNU; Style.BreakBeforeTernaryOperators = true; Style.Cpp11BracedListStyle = false; diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 4f3ec0b199..4c18b72d3c 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -1851,16 +1851,21 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Left.is(tok::greater) && Right.is(tok::greater) && Left.Type != TT_TemplateCloser) return false; - if (Right.Type == TT_BinaryOperator && Style.BreakBeforeBinaryOperators) + if (Right.Type == TT_BinaryOperator && + Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None && + (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All || + Right.getPrecedence() != prec::Assignment)) return true; if (Left.Type == TT_ArrayInitializerLSquare) return true; if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const)) return true; - return (Left.isBinaryOperator() && - !Left.isOneOf(tok::arrowstar, tok::lessless) && - !Style.BreakBeforeBinaryOperators) || - Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, + if (Left.isBinaryOperator() && !Left.isOneOf(tok::arrowstar, tok::lessless) && + Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All && + (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None || + Left.getPrecedence() == prec::Assignment)) + return true; + return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, tok::kw_class, tok::kw_struct) || Right.isMemberAccess() || Right.isOneOf(tok::lessless, tok::colon, tok::l_square, tok::at) || diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index dfa31085a9..2e358b4a3c 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -3171,7 +3171,7 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { // everything until something with the same indent as the operator is found. // FIXME: Is this a good system? FormatStyle Style = getLLVMStyle(); - Style.BreakBeforeBinaryOperators = true; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; verifyFormat( "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" @@ -3224,6 +3224,15 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { Style); } +TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; + verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", Style); + +} + TEST_F(FormatTest, ConstructorInitializers) { verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}"); verifyFormat("Constructor() : Inttializer(FitsOnTheLine) {}", @@ -8368,7 +8377,6 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(AlwaysBreakAfterDefinitionReturnType); CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations); CHECK_PARSE_BOOL(BinPackParameters); - CHECK_PARSE_BOOL(BreakBeforeBinaryOperators); CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma); CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine); @@ -8415,9 +8423,12 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u); Style.PointerAlignment = FormatStyle::PAS_Middle; - CHECK_PARSE("PointerAlignment: Left", PointerAlignment, FormatStyle::PAS_Left); - CHECK_PARSE("PointerAlignment: Right", PointerAlignment, FormatStyle::PAS_Right); - CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, FormatStyle::PAS_Middle); + CHECK_PARSE("PointerAlignment: Left", PointerAlignment, + FormatStyle::PAS_Left); + CHECK_PARSE("PointerAlignment: Right", PointerAlignment, + FormatStyle::PAS_Right); + CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, + FormatStyle::PAS_Middle); Style.Standard = FormatStyle::LS_Auto; CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03); @@ -8426,6 +8437,18 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11); CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto); + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; + CHECK_PARSE("BreakBeforeBinaryOperators: false", BreakBeforeBinaryOperators, + FormatStyle::BOS_None); + CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment", + BreakBeforeBinaryOperators, FormatStyle::BOS_NonAssignment); + CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators, + FormatStyle::BOS_All); + CHECK_PARSE("BreakBeforeBinaryOperators: None", BreakBeforeBinaryOperators, + FormatStyle::BOS_None); + CHECK_PARSE("BreakBeforeBinaryOperators: All", BreakBeforeBinaryOperators, + FormatStyle::BOS_All); + Style.UseTab = FormatStyle::UT_ForIndentation; CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never); CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);