diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h --- a/clang/lib/Format/ContinuationIndenter.h +++ b/clang/lib/Format/ContinuationIndenter.h @@ -208,7 +208,8 @@ LastOperatorWrapped(true), ContainsLineBreak(false), ContainsUnwrappedBuilder(false), AlignColons(true), ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false), - NestedBlockInlined(false), IsInsideObjCArrayLiteral(false) {} + NestedBlockInlined(false), IsInsideObjCArrayLiteral(false), + IsChainedConditional(false) {} /// \brief The token opening this parenthesis level, or nullptr if this level /// is opened by fake parenthesis. @@ -329,6 +330,10 @@ /// array literal. bool IsInsideObjCArrayLiteral : 1; + /// \brief true if the current \c ParenState represents the false branch of + /// a chained conditional expression (e.g. else-if) + bool IsChainedConditional : 1; + bool operator<(const ParenState &Other) const { if (Indent != Other.Indent) return Indent < Other.Indent; @@ -366,6 +371,8 @@ return ContainsUnwrappedBuilder; if (NestedBlockInlined != Other.NestedBlockInlined) return NestedBlockInlined; + if (IsChainedConditional != Other.IsChainedConditional) + return IsChainedConditional; return false; } }; diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -356,6 +356,12 @@ State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() && !Current.isOneOf(tok::r_paren, tok::r_brace)) return true; + if (State.Stack.back().IsChainedConditional && + ((Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) && + Current.is(tok::colon)) || + (!Style.BreakBeforeTernaryOperators && Previous.is(TT_ConditionalExpr) && + Previous.is(tok::colon)))) + return true; if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) || (Previous.is(TT_ArrayInitializerLSquare) && Previous.ParameterCount > 1) || @@ -997,8 +1003,20 @@ if (State.Stack.back().QuestionColumn != 0 && ((NextNonComment->is(tok::colon) && NextNonComment->is(TT_ConditionalExpr)) || - Previous.is(TT_ConditionalExpr))) + Previous.is(TT_ConditionalExpr))) { + if ((NextNonComment->is(tok::colon) && NextNonComment->Next && + !NextNonComment->Next->FakeLParens.empty() && + NextNonComment->Next->FakeLParens.back() == prec::Conditional) || + (Previous.is(tok::colon) && !Current.FakeLParens.empty() && + Current.FakeLParens.back() == prec::Conditional)) { + //NOTE: we may tweak this slightly: + // * not remove the 'lead' ContinuationIndentWidth + // * always un-indent by the operator when BreakBeforeTernaryOperators=true + unsigned Indent = State.Stack.back().Indent - Style.ContinuationIndentWidth; + return Indent; + } return State.Stack.back().QuestionColumn; + } if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) return State.Stack.back().VariablePos; if ((PreviousNonComment && @@ -1243,6 +1261,7 @@ NewParenState.Tok = nullptr; NewParenState.ContainsLineBreak = false; NewParenState.LastOperatorWrapped = true; + NewParenState.IsChainedConditional = false; NewParenState.NoLineBreak = NewParenState.NoLineBreak || State.Stack.back().NoLineBreakInOperand; @@ -1275,14 +1294,19 @@ Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) NewParenState.StartOfFunctionCall = State.Column; - // Always indent conditional expressions. Never indent expression where - // the 'operator' is ',', ';' or an assignment (i.e. *I <= - // prec::Assignment) as those have different indentation rules. Indent - // other expression, unless the indentation needs to be skipped. - if (*I == prec::Conditional || - (!SkipFirstExtraIndent && *I > prec::Assignment && - !Current.isTrailingComment())) + // Indent conditional expressions, unless they are chained "else-if" + // conditionals. Never indent expression where the 'operator' is ',', ';' or + // an assignment (i.e. *I <= prec::Assignment) as those have different + // indentation rules. Indent other expression, unless the indentation needs + // to be skipped. + if (*I == prec::Conditional && Previous && Previous->is(tok::colon) && + Previous->is(TT_ConditionalExpr) && I == Current.FakeLParens.rbegin()) { + NewParenState.IsChainedConditional = true; + } else if (*I == prec::Conditional || + (!SkipFirstExtraIndent && *I > prec::Assignment && + !Current.isTrailingComment())) { NewParenState.Indent += Style.ContinuationIndentWidth; + } if ((Previous && !Previous->opensScope()) || *I != prec::Comma) NewParenState.BreakBeforeParameter = false; State.Stack.push_back(NewParenState); diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -19,6 +19,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include +#include namespace clang { namespace format { @@ -157,11 +158,16 @@ const Change *StartOfBlockComment; int IndentationOffset; - // A combination of indent level and nesting level, which are used in - // tandem to compute lexical scope, for the purposes of deciding + // Depth of conditionals. Computed from tracking fake parenthesis, except + // it does not increase the indent for "chained" conditionals. + int ConditionalsLevel; + + // A combination of indent, nesting and conditionals levels, which are used + // in tandem to compute lexical scope, for the purposes of deciding // when to stop consecutive alignment runs. - std::pair indentAndNestingLevel() const { - return std::make_pair(Tok->IndentLevel, Tok->NestingLevel); + std::tuple indentAndNestingLevel() const { + return std::make_tuple(Tok->IndentLevel, Tok->NestingLevel, + ConditionalsLevel); } }; @@ -180,6 +186,9 @@ /// Align consecutive declarations over all \c Changes. void alignConsecutiveDeclarations(); + /// Align consecutive declarations over all \c Changes. + void alignChainedConditionals(); + /// Align trailing comments over all \c Changes. void alignTrailingComments(); diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -94,6 +94,7 @@ alignConsecutiveMacros(); alignConsecutiveDeclarations(); alignConsecutiveAssignments(); + alignChainedConditionals(); alignTrailingComments(); alignEscapedNewlines(); generateChanges(); @@ -226,6 +227,32 @@ LastBlockComment = nullptr; } } + + // Compute conditional nesting level + // Level is increased for each conditional, unless this conditional continues + // a chain of conditional, i.e. starts immediately after the colon of another + // conditional. + SmallVector ScopeStack; + int ConditionalsLevel = 0; + for (auto &Change : Changes) { + for (unsigned i = 0, e = Change.Tok->FakeLParens.size(); i != e; ++i) { + bool isNestedConditional = + Change.Tok->FakeLParens[e - 1 - i] == prec::Conditional && + !(i == 0 && Change.Tok->Previous && + Change.Tok->Previous->is(TT_ConditionalExpr) && + Change.Tok->Previous->is(tok::colon)); + if (isNestedConditional) + ++ConditionalsLevel; + ScopeStack.push_back(isNestedConditional); + } + + Change.ConditionalsLevel = ConditionalsLevel; + + for (unsigned i = Change.Tok->FakeRParens; i > 0 && ScopeStack.size(); --i) { + if (ScopeStack.pop_back_val()) + --ConditionalsLevel; + } + } } // Align a single sequence of tokens, see AlignTokens below. @@ -247,6 +274,7 @@ // double z); // In the above example, we need to take special care to ensure that // 'double z' is indented along with it's owning function 'b'. + // Special handling is required for 'nested' ternary operators. SmallVector ScopeStack; for (unsigned i = Start; i != End; ++i) { @@ -287,7 +315,10 @@ unsigned ScopeStart = ScopeStack.back(); if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) || (ScopeStart > Start + 1 && - Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))) + Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) || + Changes[i].Tok->is(TT_ConditionalExpr) || + (Changes[i].Tok->Previous && + Changes[i].Tok->Previous->is(TT_ConditionalExpr))) Changes[i].Spaces += Shift; } @@ -340,7 +371,7 @@ // abort when we hit any token in a higher scope than the starting one. auto IndentAndNestingLevel = StartAt < Changes.size() ? Changes[StartAt].indentAndNestingLevel() - : std::pair(0, 0); + : std::tuple(); // Keep track of the number of commas before the matching tokens, we will only // align a sequence of matching tokens if they are preceded by the same number @@ -408,8 +439,8 @@ StartOfSequence = i; unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn; - int LineLengthAfter = -Changes[i].Spaces; - for (unsigned j = i; j != e && Changes[j].NewlinesBefore == 0; ++j) + int LineLengthAfter = Changes[i].TokenLength; + for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength; unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter; @@ -607,6 +638,52 @@ Changes, /*StartAt=*/0); } +void WhitespaceManager::alignChainedConditionals() +{ + if (Style.BreakBeforeTernaryOperators) { + AlignTokens(Style, + [](Change const &C) { + // Align question operators and last colon + return C.Tok->is(TT_ConditionalExpr) && + ((C.Tok->is(tok::question) && !C.NewlinesBefore) || + (C.Tok->is(tok::colon) && C.Tok->Next && + (C.Tok->Next->FakeLParens.size() == 0 || + C.Tok->Next->FakeLParens.back() != + prec::Conditional))); + }, + Changes, /*StartAt=*/0); + } else { + static auto AlignWrappedOperand = [](Change const &C) { + auto Previous = C.Tok->getPreviousNonComment();//Previous; + return C.NewlinesBefore && Previous && Previous->is(TT_ConditionalExpr) && + (Previous->is(tok::question) || + (Previous->is(tok::colon) && + (C.Tok->FakeLParens.size() == 0 || + C.Tok->FakeLParens.back() != prec::Conditional))); + }; + // Ensure we keep alignment of wrapped operands with non-wrapped operands + // Since we actually align the operators, the wrapped operands need the + // extra offset to be properly aligned. + for (Change & C: Changes) { + if (AlignWrappedOperand(C)) + C.StartOfTokenColumn -= 2; + } + AlignTokens(Style, + [this](Change const &C) { + // Align question operators if next operand is not wrapped, as + // well as wrapped operands after question operator or last + // colon in conditional sequence + return (C.Tok->is(TT_ConditionalExpr) && + C.Tok->is(tok::question) && + &C != &Changes.back() && + (&C + 1)->NewlinesBefore == 0 && + !(&C + 1)->IsTrailingComment) || + AlignWrappedOperand(C); + }, + Changes, /*StartAt=*/0); + } +} + void WhitespaceManager::alignTrailingComments() { unsigned MinColumn = 0; unsigned MaxColumn = UINT_MAX; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -5734,9 +5734,9 @@ getLLVMStyleWithColumns(60)); verifyFormat("bool aaaaaa = aaaaaaaaaaaaa //\n" " ? aaaaaaaaaaaaaaa\n" - " : bbbbbbbbbbbbbbb //\n" - " ? ccccccccccccccc\n" - " : ddddddddddddddd;"); + " : bbbbbbbbbbbbbbb //\n" + " ? ccccccccccccccc\n" + " : ddddddddddddddd;"); verifyFormat("bool aaaaaa = aaaaaaaaaaaaa //\n" " ? aaaaaaaaaaaaaaa\n" " : (bbbbbbbbbbbbbbb //\n" @@ -5798,6 +5798,113 @@ " // comment\n" " ? a = b\n" " : a;"); + + // Chained conditionals + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = 70; + Style.AlignOperands = true; + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbb ? 222222\n" + " : 333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : cccccccccccccc ? 3333333333333333\n" + " : 4444444444444444;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaa ? bbb : ccc)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : (aaa ? bbb : ccc);", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccccc)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccccc)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? a = (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : dddddddddddddddddd)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : dddddddddddddddddd)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : dddddddddddddddddd)\n", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccccc);", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : ccccccccccccccc ? dddddddddddddddddd\n" + " : eeeeeeeeeeeeeeeeee)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : ccccccccccccccc ? dddddddddddddddddd\n" + " : eeeeeeeeeeeeeeeeee)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccc ? dddddddddddddddddd\n" + " : eeeeeeeeeeeeeeeeee)\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccccc\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccc ? dddddddddddddddddd\n" + " : eeeeeeeeeeeeeeeeee\n" + " : bbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaaaaaaa\n" + " ? (aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccccc ? dddddddddddddddddd\n" + " : eeeeeeeeeeeeeeeeee)\n" + " : bbbbbbbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaa\n" + " ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" + " : cccccccccccccccc ? dddddddddddddddddd\n" + " : eeeeeeeeeeeeeeeeee\n" + " : bbbbbbbbbbbbbbbbbbbbbbb ? 2222222222222222\n" + " : 3333333333333333;", + Style); } TEST_F(FormatTest, BreaksConditionalExpressionsAfterOperator) { @@ -5885,9 +5992,9 @@ Style); verifyFormat("bool aaaaaa = aaaaaaaaaaaaa ? //\n" " aaaaaaaaaaaaaaa :\n" - " bbbbbbbbbbbbbbb ? //\n" - " ccccccccccccccc :\n" - " ddddddddddddddd;", + " bbbbbbbbbbbbbbb ? //\n" + " ccccccccccccccc :\n" + " ddddddddddddddd;", Style); verifyFormat("bool aaaaaa = aaaaaaaaaaaaa ? //\n" " aaaaaaaaaaaaaaa :\n" @@ -5903,6 +6010,110 @@ " aaaaa :\n" " bbbbbbbbbbbbbbb + cccccccccccccccc;", Style); + + // Chained conditionals + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 222222 :\n" + " 333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " cccccccccccccccc ? 3333333333333333 :\n" + " 4444444444444444;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaa ? bbb : ccc) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " (aaa ? bbb : ccc);", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccc) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccc) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? a = (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " dddddddddddddddddd) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " dddddddddddddddddd) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " dddddddddddddddddd)\n", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccc);", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " ccccccccccccccccc ? dddddddddddddddddd :\n" + " eeeeeeeeeeeeeeeeee) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " ccccccccccccc ? dddddddddddddddddd :\n" + " eeeeeeeeeeeeeeeeee) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " ccccccccccccccccc ? dddddddddddddddddd :\n" + " eeeeeeeeeeeeeeeeee) :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccc :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccc ? dddddddddddddddddd :\n" + " eeeeeeeeeeeeeeeeee :\n" + " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaaaaaaa ?\n" + " (aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccc ? dddddddddddddddddd :\n" + " eeeeeeeeeeeeeeeeee) :\n" + " bbbbbbbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); + verifyFormat("return aaaaaaaaaaaaaaaaaaaaa ?\n" + " aaaaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" + " cccccccccccccccccccc ? dddddddddddddddddd :\n" + " eeeeeeeeeeeeeeeeee :\n" + " bbbbbbbbbbbbbbbbbbbbb ? 2222222222222222 :\n" + " 3333333333333333;", + Style); } TEST_F(FormatTest, DeclarationsOfMultipleVariables) {