From: Daniel Jasper Date: Wed, 3 Jul 2013 10:34:47 +0000 (+0000) Subject: Don't insert confusing line breaks in comparisons. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6df7a2db6d74d41c4150b2c46b9a9e4e2db6c1dc;p=clang Don't insert confusing line breaks in comparisons. In general, clang-format breaks after an operator if the LHS spans multiple lines. Otherwise, this can lead to confusing effects and effectively hide the operator precendence, e.g. in if (aaaaaaaaaaaaaa == bbbbbbbbbbbbbb && c) { ... This patch removes this rule for comparisons, if the LHS is not a binary expression itself as many users were wondering why clang-format inserts an unnecessary linebreak. Before: if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) > 5) { ... After: if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) > 5) { ... In the long run, we might: - Want to do this for other binary expressions as well. - Do this only if the RHS is short or even only if it is a literal. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185530 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 9cfb04162e..ef871389fb 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -1066,9 +1066,23 @@ private: return true; // If we need to break somewhere inside the LHS of a binary expression, we - // should also break after the operator. + // should also break after the operator. Otherwise, the formatting would + // hide the operator precedence, e.g. in: + // if (aaaaaaaaaaaaaa == + // bbbbbbbbbbbbbb && c) {.. + // For comparisons, we only apply this rule, if the LHS is a binary + // expression itself as otherwise, the line breaks seem superfluous. + // We need special cases for ">>" which we have split into two ">" while + // lexing in order to make template parsing easier. + bool IsComparison = (Previous.getPrecedence() == prec::Relational || + Previous.getPrecedence() == prec::Equality) && + Previous.Previous && + Previous.Previous->Type != TT_BinaryOperator; // For >>. + bool LHSIsBinaryExpr = + Previous.Previous && Previous.Previous->FakeRParens > 0; if (Previous.Type == TT_BinaryOperator && - Current.Type != TT_BinaryOperator && // Special case for ">>". + (!IsComparison || LHSIsBinaryExpr) && + Current.Type != TT_BinaryOperator && // For >>. !Current.isTrailingComment() && !Previous.isOneOf(tok::lessless, tok::question) && Previous.getPrecedence() != prec::Assignment && diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index c5a02b614d..324f797e6d 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -2156,6 +2156,38 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) { " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaaaaaaa\n" " cccccc) {\n}"); + // If the LHS of a comparison is not a binary expression itself, the + // additional linebreak confuses many people. + verifyFormat( + "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) > 5) {\n" + "}"); + verifyFormat( + "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" + "}"); + // Even explicit parentheses stress the precedence enough to make the + // additional break unnecessary. + verifyFormat( + "if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" + "}"); + // This cases is borderline, but with the indentation it is still readable. + verifyFormat( + "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaa) > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" + "}", + getLLVMStyleWithColumns(75)); + + // If the LHS is a binary expression, we should still use the additional break + // as otherwise the formatting hides the operator precedence. + verifyFormat( + "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" + " 5) {\n" + "}"); + FormatStyle OnePerLine = getLLVMStyle(); OnePerLine.BinPackParameters = false; verifyFormat(