Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -245,44 +245,43 @@ } else if (Style.Language == FormatStyle::LK_JavaScript && (Line.startsWith(Keywords.kw_type, tok::identifier) || Line.startsWith(tok::kw_export, Keywords.kw_type, - tok::identifier))) { + tok::identifier))) // type X = (...); // export type X = (...); Contexts.back().IsExpression = false; - } else if (Left->Previous && - (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_while, - tok::l_paren, tok::comma) || - Left->Previous->isIf() || - Left->Previous->is(TT_BinaryOperator))) { + else if (Left->Previous && + (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_while, + tok::l_paren, tok::comma) || + Left->Previous->isIf() || Left->Previous->is(TT_BinaryOperator))) // static_assert, if and while usually contain expressions. Contexts.back().IsExpression = true; - } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && - (Left->Previous->is(Keywords.kw_function) || - (Left->Previous->endsSequence(tok::identifier, - Keywords.kw_function)))) { + else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && + (Left->Previous->is(Keywords.kw_function) || + (Left->Previous->endsSequence(tok::identifier, + Keywords.kw_function)))) // function(...) or function f(...) Contexts.back().IsExpression = false; - } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && - Left->Previous->is(TT_JsTypeColon)) { + else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && + Left->Previous->is(TT_JsTypeColon)) // let x: (SomeType); Contexts.back().IsExpression = false; - } else if (isLambdaParameterList(Left)) { + else if (isLambdaParameterList(Left)) // This is a parameter list of a lambda expression. Contexts.back().IsExpression = false; - } else if (Line.InPPDirective && - (!Left->Previous || !Left->Previous->is(tok::identifier))) { + else if (Line.InPPDirective && + (!Left->Previous || !Left->Previous->is(tok::identifier))) Contexts.back().IsExpression = true; - } else if (Contexts[Contexts.size() - 2].CaretFound) { + else if (Contexts[Contexts.size() - 2].CaretFound) // This is the parameter list of an ObjC block. Contexts.back().IsExpression = false; - } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) { + else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) { // The first argument to a foreach macro is a declaration. Contexts.back().IsForEachMacro = true; Contexts.back().IsExpression = false; } else if (Left->Previous && Left->Previous->MatchingParen && - Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) { + Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) Contexts.back().IsExpression = false; - } else if (!Line.MustBeDeclaration && !Line.InPPDirective) { + else if (!Line.MustBeDeclaration && !Line.InPPDirective) { bool IsForOrCatch = Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch); Contexts.back().IsExpression = !IsForOrCatch; @@ -364,11 +363,10 @@ // Detect the case where macros are used to generate lambdas or // function bodies, e.g.: // auto my_lambda = MACRO((Type *type, int i) { .. body .. }); - for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) { + for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) if (Tok->is(TT_BinaryOperator) && Tok->isOneOf(tok::star, tok::amp, tok::ampamp)) Tok->setType(TT_PointerOrReference); - } } if (StartsObjCMethodExpr) { @@ -467,9 +465,8 @@ return false; // Move along the tokens inbetween the '[' and ']' e.g. [STAThread]. - while (AttrTok && AttrTok->isNot(tok::r_square)) { + while (AttrTok && AttrTok->isNot(tok::r_square)) AttrTok = AttrTok->Next; - } if (!AttrTok) return false; @@ -482,9 +479,8 @@ // Limit this to being an access modifier that follows. if (AttrTok->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected, tok::comment, tok::kw_class, tok::kw_static, - tok::l_square, Keywords.kw_internal)) { + tok::l_square, Keywords.kw_internal)) return true; - } // incase its a [XXX] retval func(.... if (AttrTok->Next && @@ -498,9 +494,9 @@ if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square)) return false; // The first square bracket is part of an ObjC array literal - if (Tok.Previous && Tok.Previous->is(tok::at)) { + if (Tok.Previous && Tok.Previous->is(tok::at)) return false; - } + const FormatToken *AttrTok = Tok.Next->Next; if (!AttrTok) return false; @@ -572,29 +568,29 @@ bool ColonFound = false; unsigned BindingIncrease = 1; - if (IsCppStructuredBinding) { + if (IsCppStructuredBinding) Left->setType(TT_StructuredBindingLSquare); - } else if (Left->is(TT_Unknown)) { + else if (Left->is(TT_Unknown)) { if (StartsObjCMethodExpr) { Left->setType(TT_ObjCMethodExpr); - } else if (InsideInlineASM) { + } else if (InsideInlineASM) Left->setType(TT_InlineASMSymbolicNameLSquare); - } else if (IsCpp11AttributeSpecifier) { + else if (IsCpp11AttributeSpecifier) Left->setType(TT_AttributeSquare); - } else if (Style.Language == FormatStyle::LK_JavaScript && Parent && - Contexts.back().ContextKind == tok::l_brace && - Parent->isOneOf(tok::l_brace, tok::comma)) { + else if (Style.Language == FormatStyle::LK_JavaScript && Parent && + Contexts.back().ContextKind == tok::l_brace && + Parent->isOneOf(tok::l_brace, tok::comma)) Left->setType(TT_JsComputedPropertyName); - } else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace && - Parent && Parent->isOneOf(tok::l_brace, tok::comma)) { + else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace && + Parent && Parent->isOneOf(tok::l_brace, tok::comma)) Left->setType(TT_DesignatedInitializerLSquare); - } else if (IsCSharpAttributeSpecifier) { + else if (IsCSharpAttributeSpecifier) Left->setType(TT_AttributeSquare); - } else if (CurrentToken->is(tok::r_square) && Parent && - Parent->is(TT_TemplateCloser)) { + else if (CurrentToken->is(tok::r_square) && Parent && + Parent->is(TT_TemplateCloser)) Left->setType(TT_ArraySubscriptLSquare); - } else if (Style.Language == FormatStyle::LK_Proto || - Style.Language == FormatStyle::LK_TextProto) { + else if (Style.Language == FormatStyle::LK_Proto || + Style.Language == FormatStyle::LK_TextProto) { // Square braces in LK_Proto can either be message field attributes: // // optional Aaa aaa = 1 [ @@ -635,9 +631,9 @@ tok::comma, tok::l_paren, tok::l_square, tok::question, tok::colon, tok::kw_return, // Should only be relevant to JavaScript: - tok::kw_default)) { + tok::kw_default)) Left->setType(TT_ArrayInitializerLSquare); - } else { + else { BindingIncrease = 10; Left->setType(TT_ArraySubscriptLSquare); } @@ -701,10 +697,10 @@ Previous->ObjCSelectorNameParts = 1; Contexts.back().FirstObjCSelectorName = Previous; } - } else { + } else Left->ParameterCount = Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; - } + if (Contexts.back().FirstObjCSelectorName) { Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = Contexts.back().LongestObjCSelectorName; @@ -753,10 +749,10 @@ const auto End = std::next(Contexts.rbegin(), 2); auto Last = Contexts.rbegin(); unsigned Depth = 0; - for (; Last != End; ++Last) { + for (; Last != End; ++Last) if (Last->ContextKind == tok::l_brace) ++Depth; - } + return Depth == 2 && Last->ContextKind != tok::l_brace; } @@ -784,9 +780,8 @@ CurrentToken->MatchingParen = Left; if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) { if (Left->ParentBracket == tok::l_brace && - couldBeInStructArrayInitializer() && CommaCount > 0) { + couldBeInStructArrayInitializer() && CommaCount > 0) Contexts.back().InStructArrayInitializer = true; - } } next(); return true; @@ -834,9 +829,8 @@ if (!Left->Role) Left->Role.reset(new CommaSeparatedList(Style)); Left->Role->CommaFound(Current); - } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) { + } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) Left->ParameterCount = 1; - } } bool parseConditional() { @@ -938,13 +932,13 @@ Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; } - } else if (Contexts.back().ColonIsForRangeExpr) { + } else if (Contexts.back().ColonIsForRangeExpr) Tok->setType(TT_RangeBasedForLoopColon); - } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) { + else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) Tok->setType(TT_BitFieldColon); - } else if (Contexts.size() == 1 && - !Line.First->isOneOf(tok::kw_enum, tok::kw_case, - tok::kw_default)) { + else if (Contexts.size() == 1 && + !Line.First->isOneOf(tok::kw_enum, tok::kw_case, + tok::kw_default)) { FormatToken *Prev = Tok->getPreviousNonComment(); if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept)) Tok->setType(TT_CtorInitializerColon); @@ -962,9 +956,9 @@ // This handles a special macro in ObjC code where selectors including // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); - } else if (Contexts.back().ContextKind == tok::l_paren) { + } else if (Contexts.back().ContextKind == tok::l_paren) Tok->setType(TT_InlineASMColon); - } + break; case tok::pipe: case tok::amp: @@ -1142,9 +1136,9 @@ break; case tok::identifier: if (Tok->isOneOf(Keywords.kw___has_include, - Keywords.kw___has_include_next)) { + Keywords.kw___has_include_next)) parseHasInclude(); - } + if (Style.isCSharp() && Tok->is(Keywords.kw_where) && Tok->Next && Tok->Next->isNot(tok::l_paren)) { Tok->setType(TT_CSharpGenericTypeConstraint); @@ -1180,9 +1174,8 @@ } else if (CurrentToken->is(tok::colon)) { CurrentToken->setType(TT_CSharpGenericTypeConstraintColon); next(); - } else { + } else next(); - } } } @@ -1518,37 +1511,36 @@ } } } else if (Current.is(tok::lessless) && - (!Current.Previous || !Current.Previous->is(tok::kw_operator))) { + (!Current.Previous || !Current.Previous->is(tok::kw_operator))) Contexts.back().IsExpression = true; - } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) { + else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) Contexts.back().IsExpression = true; - } else if (Current.is(TT_TrailingReturnArrow)) { + else if (Current.is(TT_TrailingReturnArrow)) Contexts.back().IsExpression = false; - } else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) { + else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java; - } else if (Current.Previous && - Current.Previous->is(TT_CtorInitializerColon)) { + else if (Current.Previous && + Current.Previous->is(TT_CtorInitializerColon)) { Contexts.back().IsExpression = true; Contexts.back().InCtorInitializer = true; - } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) { + } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) Contexts.back().InInheritanceList = true; - } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { + else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { for (FormatToken *Previous = Current.Previous; Previous && Previous->isOneOf(tok::star, tok::amp); Previous = Previous->Previous) Previous->setType(TT_PointerOrReference); if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer) Contexts.back().IsExpression = false; - } else if (Current.is(tok::kw_new)) { + } else if (Current.is(tok::kw_new)) Contexts.back().CanBeExpression = false; - } else if (Current.is(tok::semi) || - (Current.is(tok::exclaim) && Current.Previous && - !Current.Previous->is(tok::kw_operator))) { + else if (Current.is(tok::semi) || + (Current.is(tok::exclaim) && Current.Previous && + !Current.Previous->is(tok::kw_operator))) // This should be the condition or increment in a for-loop. // But not operator !() (can't use TT_OverloadedOperator here as its not // been annotated yet). Contexts.back().IsExpression = true; - } } static FormatToken *untilMatchingParen(FormatToken *Current) { @@ -1575,10 +1567,10 @@ int NestingLevel = 0; while (TemplateCloser) { // Skip over an expressions in parens A<(3 < 2)>; - if (TemplateCloser->is(tok::l_paren)) { + if (TemplateCloser->is(tok::l_paren)) // No Matching Paren yet so skip to matching paren TemplateCloser = untilMatchingParen(TemplateCloser); - } + if (TemplateCloser->is(tok::less)) NestingLevel++; if (TemplateCloser->is(tok::greater)) @@ -1648,63 +1640,62 @@ // Line.MightBeFunctionDecl can only be true after the parentheses of a // function declaration have been found. In this case, 'Current' is a // trailing token of this declaration and thus cannot be a name. - if (Current.is(Keywords.kw_instanceof)) { + if (Current.is(Keywords.kw_instanceof)) Current.setType(TT_BinaryOperator); - } else if (isStartOfName(Current) && - (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) { + else if (isStartOfName(Current) && + (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) { Contexts.back().FirstStartOfName = &Current; Current.setType(TT_StartOfName); - } else if (Current.is(tok::semi)) { + } else if (Current.is(tok::semi)) // Reset FirstStartOfName after finding a semicolon so that a for loop // with multiple increment statements is not confused with a for loop // having multiple variable declarations. Contexts.back().FirstStartOfName = nullptr; - } else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) { + else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) AutoFound = true; - } else if (Current.is(tok::arrow) && - Style.Language == FormatStyle::LK_Java) { + else if (Current.is(tok::arrow) && Style.Language == FormatStyle::LK_Java) Current.setType(TT_LambdaArrow); - } else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration && - Current.NestingLevel == 0 && - !Current.Previous->is(tok::kw_operator)) { + else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration && + Current.NestingLevel == 0 && + !Current.Previous->is(tok::kw_operator)) // not auto operator->() -> xxx; Current.setType(TT_TrailingReturnArrow); - } else if (Current.is(tok::arrow) && Current.Previous && - Current.Previous->is(tok::r_brace)) { + else if (Current.is(tok::arrow) && Current.Previous && + Current.Previous->is(tok::r_brace)) // Concept implicit conversion constraint needs to be treated like // a trailing return type ... } -> . Current.setType(TT_TrailingReturnArrow); - } else if (isDeductionGuide(Current)) { + else if (isDeductionGuide(Current)) // Deduction guides trailing arrow " A(...) -> A;". Current.setType(TT_TrailingReturnArrow); - } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) { + else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) Current.setType(determineStarAmpUsage( Current, Contexts.back().CanBeExpression && Contexts.back().IsExpression, Contexts.back().InTemplateArgument)); - } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { + else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { Current.setType(determinePlusMinusCaretUsage(Current)); if (Current.is(TT_UnaryOperator) && Current.is(tok::caret)) Contexts.back().CaretFound = true; - } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { + } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) Current.setType(determineIncrementUsage(Current)); - } else if (Current.isOneOf(tok::exclaim, tok::tilde)) { + else if (Current.isOneOf(tok::exclaim, tok::tilde)) Current.setType(TT_UnaryOperator); - } else if (Current.is(tok::question)) { + else if (Current.is(tok::question)) { if (Style.Language == FormatStyle::LK_JavaScript && Line.MustBeDeclaration && !Contexts.back().IsExpression) { // In JavaScript, `interface X { foo?(): bar; }` is an optional method // on the interface, not a ternary expression. Current.setType(TT_JsTypeOptionalQuestion); - } else { + } else Current.setType(TT_ConditionalExpr); - } + } else if (Current.isBinaryOperator() && (!Current.Previous || Current.Previous->isNot(tok::l_square)) && (!Current.is(tok::greater) && - Style.Language != FormatStyle::LK_TextProto)) { + Style.Language != FormatStyle::LK_TextProto)) Current.setType(TT_BinaryOperator); - } else if (Current.is(tok::comment)) { + else if (Current.is(tok::comment)) { if (Current.TokenText.startswith("/*")) { if (Current.TokenText.endswith("*/")) Current.setType(TT_BlockComment); @@ -1725,7 +1716,7 @@ tok::coloncolon)) if (FormatToken *AfterParen = Current.MatchingParen->Next) { // Make sure this isn't the return type of an Obj-C block declaration - if (AfterParen->Tok.isNot(tok::caret)) { + if (AfterParen->Tok.isNot(tok::caret)) if (FormatToken *BeforeParen = Current.MatchingParen->Previous) if (BeforeParen->is(tok::identifier) && !BeforeParen->is(TT_TypenameMacro) && @@ -1733,7 +1724,6 @@ (!BeforeParen->Previous || BeforeParen->Previous->ClosesTemplateDeclaration)) Current.setType(TT_FunctionAnnotationRParen); - } } } else if (Current.is(tok::at) && Current.Next && Style.Language != FormatStyle::LK_JavaScript && @@ -1769,22 +1759,22 @@ Current.Previous->MatchingParen && Current.Previous->MatchingParen->Previous && Current.Previous->MatchingParen->Previous->is( - TT_ObjCMethodSpecifier)) { + TT_ObjCMethodSpecifier)) // This is the first part of an Objective-C selector name. (If there's no // colon after this, this is the only place which annotates the identifier // as a selector.) Current.setType(TT_SelectorName); - } else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept, - tok::kw_requires) && - Current.Previous && - !Current.Previous->isOneOf(tok::equal, tok::at) && - Line.MightBeFunctionDecl && Contexts.size() == 1) { + else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept, + tok::kw_requires) && + Current.Previous && + !Current.Previous->isOneOf(tok::equal, tok::at) && + Line.MightBeFunctionDecl && Contexts.size() == 1) // Line.MightBeFunctionDecl can only be true after the parentheses of a // function declaration have been found. Current.setType(TT_TrailingAnnotation); - } else if ((Style.Language == FormatStyle::LK_Java || - Style.Language == FormatStyle::LK_JavaScript) && - Current.Previous) { + else if ((Style.Language == FormatStyle::LK_Java || + Style.Language == FormatStyle::LK_JavaScript) && + Current.Previous) { if (Current.Previous->is(tok::at) && Current.isNot(Keywords.kw_interface)) { const FormatToken &AtToken = *Current.Previous; @@ -1964,11 +1954,10 @@ return true; // Look for a cast `( x ) (`. - if (Tok.Next->is(tok::l_paren) && Tok.Previous && Tok.Previous->Previous) { + if (Tok.Next->is(tok::l_paren) && Tok.Previous && Tok.Previous->Previous) if (Tok.Previous->is(tok::identifier) && Tok.Previous->Previous->is(tok::l_paren)) return true; - } if (!Tok.Next->Next) return false; @@ -1983,10 +1972,10 @@ return false; // Search for unexpected tokens. for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen; - Prev = Prev->Previous) { + Prev = Prev->Previous) if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon)) return false; - } + return true; } @@ -2175,9 +2164,8 @@ (Current->MatchingParen || Current->is(TT_TemplateString))) || (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) || (CurrentPrecedence == prec::Conditional && - Precedence == prec::Assignment && Current->is(tok::colon))) { + Precedence == prec::Assignment && Current->is(tok::colon))) break; - } // Consume scopes: (), [], <> and {} if (Current->opensScope()) { @@ -2206,9 +2194,8 @@ if (Precedence == PrecedenceArrowAndPeriod) { // Call expressions don't have a binary operator precedence. addFakeParenthesis(Start, prec::Unknown); - } else { + } else addFakeParenthesis(Start, prec::Level(Precedence)); - } } } @@ -2287,9 +2274,9 @@ } void parseConditionalExpr() { - while (Current && Current->isTrailingComment()) { + while (Current && Current->isTrailingComment()) next(); - } + FormatToken *Start = Current; parse(prec::LogicalOr); if (!Current || !Current->is(tok::question)) @@ -2338,7 +2325,7 @@ if (NextNonCommentLine && CommentLine && NextNonCommentLine->First->NewlinesBefore <= 1 && NextNonCommentLine->First->OriginalColumn == - (*I)->First->OriginalColumn) { + (*I)->First->OriginalColumn) // Align comments for preprocessor lines with the # in column 0 if // preprocessor lines are not indented. Otherwise, align with the next // line. @@ -2348,9 +2335,8 @@ NextNonCommentLine->Type == LT_ImportStatement)) ? 0 : NextNonCommentLine->Level; - } else { + else NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr; - } setCommentLineLevels((*I)->Children); } @@ -2366,9 +2352,9 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { for (SmallVectorImpl::iterator I = Line.Children.begin(), E = Line.Children.end(); - I != E; ++I) { + I != E; ++I) annotate(**I); - } + AnnotatingParser Parser(Style, Line, Keywords); Line.Type = Parser.parseLine(); @@ -2444,9 +2430,9 @@ if (!Current.is(TT_StartOfName) || Current.NestingLevel != 0) return false; for (; Next; Next = Next->Next) { - if (Next->is(TT_TemplateOpener)) { + if (Next->is(TT_TemplateOpener)) Next = Next->MatchingParen; - } else if (Next->is(tok::coloncolon)) { + else if (Next->is(tok::coloncolon)) { Next = Next->Next; if (!Next) return false; @@ -2456,11 +2442,10 @@ } if (!Next->is(tok::identifier)) return false; - } else if (Next->is(tok::l_paren)) { + } else if (Next->is(tok::l_paren)) break; - } else { + else return false; - } } } @@ -2535,9 +2520,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { for (SmallVectorImpl::iterator I = Line.Children.begin(), E = Line.Children.end(); - I != E; ++I) { + I != E; ++I) calculateFormattingInformation(**I); - } Line.First->TotalLength = Line.First->IsMultiline ? Style.ColumnLimit @@ -2582,9 +2566,8 @@ } } } else if (Current->SpacesRequiredBefore == 0 && - spaceRequiredBefore(Line, *Current)) { + spaceRequiredBefore(Line, *Current)) Current->SpacesRequiredBefore = 1; - } Current->MustBreakBefore = Current->MustBreakBefore || mustBreakBefore(Line, *Current); @@ -2625,12 +2608,11 @@ // expression is a part of other expression). Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl); if (Style.Language == FormatStyle::LK_ObjC && - Current->is(TT_SelectorName) && Current->ParameterIndex > 0) { + Current->is(TT_SelectorName) && Current->ParameterIndex > 0) if (Current->ParameterIndex == 1) Current->SplitPenalty += 5 * Current->BindingStrength; - } else { - Current->SplitPenalty += 20 * Current->BindingStrength; - } + else + Current->SplitPenalty += 20 * Current->BindingStrength; Current = Current->Next; } @@ -2661,18 +2643,18 @@ if (Current->CanBreakBefore || Current->isOneOf(tok::comment, tok::string_literal)) { UnbreakableTailLength = 0; - } else { + } else UnbreakableTailLength += Current->ColumnWidth + Current->SpacesRequiredBefore; - } + Current = Current->Previous; } } void TokenAnnotator::calculateArrayInitializerColumnList(AnnotatedLine &Line) { - if (Line.First == Line.Last) { + if (Line.First == Line.Last) return; - } + auto *CurrentToken = Line.First; CurrentToken->ArrayInitializerLineStart = true; unsigned Depth = 0; @@ -2683,9 +2665,8 @@ CurrentToken->Next->MustBreakBefore = true; CurrentToken = calculateInitializerColumnList(Line, CurrentToken->Next, Depth + 1); - } else { + } else CurrentToken = CurrentToken->Next; - } } } @@ -2783,7 +2764,7 @@ TT_CtorInitializerColon)) return 2; - if (Right.isMemberAccess()) { + if (Right.isMemberAccess()) // Breaking before the "./->" of a chained call/member access is reasonably // cheap, as formatting those with one call per line is generally // desirable. In particular, it should be cheaper to break before the call @@ -2806,7 +2787,6 @@ return !Right.NextOperator || !Right.NextOperator->Previous->closesScope() ? 150 : 35; - } if (Right.is(TT_TrailingAnnotation) && (!Right.Next || Right.Next->isNot(tok::l_paren))) { @@ -3244,184 +3224,185 @@ // and "%d %d" if (Left.is(tok::numeric_constant) && Right.is(tok::percent)) return HasExistingWhitespace(); - } else if (Style.isJson()) { + } else if (Style.isJson()) if (Right.is(tok::colon)) return false; - } else if (Style.isCSharp()) { - // Require spaces around '{' and before '}' unless they appear in - // interpolated strings. Interpolated strings are merged into a single token - // so cannot have spaces inserted by this function. + else if (Style.isCSharp()) { + // Require spaces around '{' and before '}' unless they appear in + // interpolated strings. Interpolated strings are merged into a single + // token so cannot have spaces inserted by this function. - // No space between 'this' and '[' - if (Left.is(tok::kw_this) && Right.is(tok::l_square)) - return false; + // No space between 'this' and '[' + if (Left.is(tok::kw_this) && Right.is(tok::l_square)) + return false; - // No space between 'new' and '(' - if (Left.is(tok::kw_new) && Right.is(tok::l_paren)) - return false; + // No space between 'new' and '(' + if (Left.is(tok::kw_new) && Right.is(tok::l_paren)) + return false; - // Space before { (including space within '{ {'). - if (Right.is(tok::l_brace)) - return true; + // Space before { (including space within '{ {'). + if (Right.is(tok::l_brace)) + return true; - // Spaces inside braces. - if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace)) - return true; + // Spaces inside braces. + if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace)) + return true; - if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace)) - return true; + if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace)) + return true; - // Spaces around '=>'. - if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow)) - return true; + // Spaces around '=>'. + if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow)) + return true; - // No spaces around attribute target colons - if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon)) - return false; + // No spaces around attribute target colons + if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon)) + return false; - // space between type and variable e.g. Dictionary foo; - if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName)) - return true; + // space between type and variable e.g. Dictionary foo; + if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName)) + return true; - // spaces inside square brackets. - if (Left.is(tok::l_square) || Right.is(tok::r_square)) - return Style.SpacesInSquareBrackets; + // spaces inside square brackets. + if (Left.is(tok::l_square) || Right.is(tok::r_square)) + return Style.SpacesInSquareBrackets; - // No space before ? in nullable types. - if (Right.is(TT_CSharpNullable)) - return false; + // No space before ? in nullable types. + if (Right.is(TT_CSharpNullable)) + return false; - // No space before null forgiving '!'. - if (Right.is(TT_NonNullAssertion)) - return false; + // No space before null forgiving '!'. + if (Right.is(TT_NonNullAssertion)) + return false; - // No space between consecutive commas '[,,]'. - if (Left.is(tok::comma) && Right.is(tok::comma)) - return false; + // No space between consecutive commas '[,,]'. + if (Left.is(tok::comma) && Right.is(tok::comma)) + return false; - // space after var in `var (key, value)` - if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren)) - return true; + // space after var in `var (key, value)` + if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren)) + return true; - // space between keywords and paren e.g. "using (" - if (Right.is(tok::l_paren)) - if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when, - Keywords.kw_lock)) - return Style.SpaceBeforeParens == FormatStyle::SBPO_ControlStatements || - spaceRequiredBeforeParens(Right); - - // space between method modifier and opening parenthesis of a tuple return - // type - if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected, - tok::kw_virtual, tok::kw_extern, tok::kw_static, - Keywords.kw_internal, Keywords.kw_abstract, - Keywords.kw_sealed, Keywords.kw_override, - Keywords.kw_async, Keywords.kw_unsafe) && - Right.is(tok::l_paren)) - return true; - } else if (Style.Language == FormatStyle::LK_JavaScript) { - if (Left.is(TT_FatArrow)) - return true; - // for await ( ... - if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous && - Left.Previous->is(tok::kw_for)) - return true; - if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) && - Right.MatchingParen) { - const FormatToken *Next = Right.MatchingParen->getNextNonComment(); - // An async arrow function, for example: `x = async () => foo();`, - // as opposed to calling a function called async: `x = async();` - if (Next && Next->is(TT_FatArrow)) + // space between keywords and paren e.g. "using (" + if (Right.is(tok::l_paren)) + if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when, + Keywords.kw_lock)) + return Style.SpaceBeforeParens == + FormatStyle::SBPO_ControlStatements || + spaceRequiredBeforeParens(Right); + + // space between method modifier and opening parenthesis of a tuple return + // type + if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected, + tok::kw_virtual, tok::kw_extern, tok::kw_static, + Keywords.kw_internal, Keywords.kw_abstract, + Keywords.kw_sealed, Keywords.kw_override, + Keywords.kw_async, Keywords.kw_unsafe) && + Right.is(tok::l_paren)) return true; - } - if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) || - (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) - return false; - // In tagged template literals ("html`bar baz`"), there is no space between - // the tag identifier and the template string. - if (Keywords.IsJavaScriptIdentifier(Left, - /* AcceptIdentifierName= */ false) && - Right.is(TT_TemplateString)) - return false; - if (Right.is(tok::star) && - Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) - return false; - if (Right.isOneOf(tok::l_brace, tok::l_square) && - Left.isOneOf(Keywords.kw_function, Keywords.kw_yield, - Keywords.kw_extends, Keywords.kw_implements)) - return true; - if (Right.is(tok::l_paren)) { - // JS methods can use some keywords as names (e.g. `delete()`). - if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo()) + } else if (Style.Language == FormatStyle::LK_JavaScript) { + if (Left.is(TT_FatArrow)) + return true; + // for await ( ... + if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && + Left.Previous && Left.Previous->is(tok::kw_for)) + return true; + if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) && + Right.MatchingParen) { + const FormatToken *Next = Right.MatchingParen->getNextNonComment(); + // An async arrow function, for example: `x = async () => foo();`, + // as opposed to calling a function called async: `x = async();` + if (Next && Next->is(TT_FatArrow)) + return true; + } + if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) || + (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) return false; - // Valid JS method names can include keywords, e.g. `foo.delete()` or - // `bar.instanceof()`. Recognize call positions by preceding period. - if (Left.Previous && Left.Previous->is(tok::period) && - Left.Tok.getIdentifierInfo()) + // In tagged template literals ("html`bar baz`"), there is no space + // between the tag identifier and the template string. + if (Keywords.IsJavaScriptIdentifier(Left, + /* AcceptIdentifierName= */ false) && + Right.is(TT_TemplateString)) return false; - // Additional unary JavaScript operators that need a space after. - if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof, - tok::kw_void)) + if (Right.is(tok::star) && + Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) + return false; + if (Right.isOneOf(tok::l_brace, tok::l_square) && + Left.isOneOf(Keywords.kw_function, Keywords.kw_yield, + Keywords.kw_extends, Keywords.kw_implements)) + return true; + if (Right.is(tok::l_paren)) { + // JS methods can use some keywords as names (e.g. `delete()`). + if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo()) + return false; + // Valid JS method names can include keywords, e.g. `foo.delete()` or + // `bar.instanceof()`. Recognize call positions by preceding period. + if (Left.Previous && Left.Previous->is(tok::period) && + Left.Tok.getIdentifierInfo()) + return false; + // Additional unary JavaScript operators that need a space after. + if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof, + tok::kw_void)) + return true; + } + // `foo as const;` casts into a const type. + if (Left.endsSequence(tok::kw_const, Keywords.kw_as)) + return false; + + if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, + tok::kw_const) || + // "of" is only a keyword if it appears after another identifier + // (e.g. as "const x of y" in a for loop), or after a destructuring + // operation (const [x, y] of z, const {a, b} of c). + (Left.is(Keywords.kw_of) && Left.Previous && + (Left.Previous->Tok.is(tok::identifier) || + Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) && + (!Left.Previous || !Left.Previous->is(tok::period))) + return true; + if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous && + Left.Previous->is(tok::period) && Right.is(tok::l_paren)) + return false; + if (Left.is(Keywords.kw_as) && + Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) + return true; + if (Left.is(tok::kw_default) && Left.Previous && + Left.Previous->is(tok::kw_export)) + return true; + if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace)) + return true; + if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion)) + return false; + if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator)) + return false; + if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) && + Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) + return false; + if (Left.is(tok::ellipsis)) + return false; + if (Left.is(TT_TemplateCloser) && + !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square, + Keywords.kw_implements, Keywords.kw_extends)) + // Type assertions ('expr') are not followed by whitespace. Other + // locations that should have whitespace following are identified by the + // above set of follower tokens. + return false; + if (Right.is(TT_NonNullAssertion)) + return false; + if (Left.is(TT_NonNullAssertion) && + Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) + return true; // "x! as string", "x! in y" + } else if (Style.Language == FormatStyle::LK_Java) { + if (Left.is(tok::r_square) && Right.is(tok::l_brace)) + return true; + if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) + return Style.SpaceBeforeParens != FormatStyle::SBPO_Never; + if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private, + tok::kw_protected) || + Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract, + Keywords.kw_native)) && + Right.is(TT_TemplateOpener)) return true; } - // `foo as const;` casts into a const type. - if (Left.endsSequence(tok::kw_const, Keywords.kw_as)) { - return false; - } - if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, - tok::kw_const) || - // "of" is only a keyword if it appears after another identifier - // (e.g. as "const x of y" in a for loop), or after a destructuring - // operation (const [x, y] of z, const {a, b} of c). - (Left.is(Keywords.kw_of) && Left.Previous && - (Left.Previous->Tok.is(tok::identifier) || - Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) && - (!Left.Previous || !Left.Previous->is(tok::period))) - return true; - if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous && - Left.Previous->is(tok::period) && Right.is(tok::l_paren)) - return false; - if (Left.is(Keywords.kw_as) && - Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) - return true; - if (Left.is(tok::kw_default) && Left.Previous && - Left.Previous->is(tok::kw_export)) - return true; - if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace)) - return true; - if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion)) - return false; - if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator)) - return false; - if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) && - Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) - return false; - if (Left.is(tok::ellipsis)) - return false; - if (Left.is(TT_TemplateCloser) && - !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square, - Keywords.kw_implements, Keywords.kw_extends)) - // Type assertions ('expr') are not followed by whitespace. Other - // locations that should have whitespace following are identified by the - // above set of follower tokens. - return false; - if (Right.is(TT_NonNullAssertion)) - return false; - if (Left.is(TT_NonNullAssertion) && - Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) - return true; // "x! as string", "x! in y" - } else if (Style.Language == FormatStyle::LK_Java) { - if (Left.is(tok::r_square) && Right.is(tok::l_brace)) - return true; - if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) - return Style.SpaceBeforeParens != FormatStyle::SBPO_Never; - if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private, - tok::kw_protected) || - Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract, - Keywords.kw_native)) && - Right.is(TT_TemplateOpener)) - return true; - } if (Left.is(TT_ImplicitStringLiteral)) return HasExistingWhitespace(); if (Line.Type == LT_ObjCMethodDecl) { @@ -3687,18 +3668,17 @@ (Left.NestingLevel == 0 && Line.Level == 0 && Style.AllowShortFunctionsOnASingleLine & FormatStyle::SFS_InlineOnly); - } else if (Style.Language == FormatStyle::LK_Java) { + } else if (Style.Language == FormatStyle::LK_Java) if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next && Right.Next->is(tok::string_literal)) return true; - } else if (Style.Language == FormatStyle::LK_Cpp || + else if (Style.Language == FormatStyle::LK_Cpp || Style.Language == FormatStyle::LK_ObjC || Style.Language == FormatStyle::LK_Proto || Style.Language == FormatStyle::LK_TableGen || - Style.Language == FormatStyle::LK_TextProto) { - if (Left.isStringLiteral() && Right.isStringLiteral()) - return true; - } + Style.Language == FormatStyle::LK_TextProto) + if (Left.isStringLiteral() && Right.isStringLiteral()) + return true; // Basic JSON newline processing. if (Style.isJson()) { @@ -3792,11 +3772,11 @@ if ((Right.Previous->is(tok::l_brace) || (Right.Previous->is(tok::less) && Right.Previous->Previous && Right.Previous->Previous->is(tok::equal))) && - Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) { + Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) // Don't put enums or option definitions onto single lines in protocol // buffers. return true; - } + if (Right.is(TT_InlineASMBrace)) return Right.HasUnescapedNewline; @@ -3845,9 +3825,8 @@ } if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace) && - Left.isOneOf(tok::star, tok::amp, tok::ampamp, TT_TemplateCloser)) { + Left.isOneOf(tok::star, tok::amp, tok::ampamp, TT_TemplateCloser)) return true; - } // Put multiple Java annotation on a new line. if ((Style.Language == FormatStyle::LK_Java || @@ -3919,7 +3898,7 @@ ((LBrace->is(tok::l_brace) && (LBrace->is(TT_DictLiteral) || (LBrace->Next && LBrace->Next->is(tok::r_brace)))) || - LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) { + LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) // If Left.ParameterCount is 0, then this submessage entry is not the // first in its parent submessage, and we want to break before this entry. // If Left.ParameterCount is greater than 0, then its parent submessage @@ -3928,11 +3907,10 @@ // detecting and breaking before the next entry in the parent submessage. if (Left.ParameterCount == 0) return true; - // However, if this submessage is the first entry in its parent - // submessage, Left.ParameterCount might be 1 in some cases. - // We deal with this case later by detecting an entry - // following a closing paren of this submessage. - } + // However, if this submessage is the first entry in its parent + // submessage, Left.ParameterCount might be 1 in some cases. + // We deal with this case later by detecting an entry + // following a closing paren of this submessage. // If this is an entry immediately following a submessage, it will be // preceded by a closing paren of that submessage, like in: @@ -4041,12 +4019,12 @@ return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None; if (Right.is(Keywords.kw_as)) return false; // must not break before as in 'x as type' casts - if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) { + if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) // extends and infer can appear as keywords in conditional types: // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types // do not break before them, as the expressions are subject to ASI. return false; - } + if (Left.is(Keywords.kw_as)) return true; if (Left.is(TT_NonNullAssertion)) @@ -4066,9 +4044,9 @@ return false; // Don't split tagged template literal so there is a break between the tag // identifier and template string. - if (Left.is(tok::identifier) && Right.is(TT_TemplateString)) { + if (Left.is(tok::identifier) && Right.is(TT_TemplateString)) return false; - } + if (Left.is(TT_TemplateString) && Left.opensScope()) return true; }