1 //===--- TokenAnnotator.cpp - Format C++ code -----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief This file implements a token annotator, i.e. creates 12 /// \c AnnotatedTokens out of \c FormatTokens with required extra information. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "TokenAnnotator.h" 17 #include "clang/Basic/SourceManager.h" 18 #include "llvm/ADT/SmallPtrSet.h" 19 #include "llvm/Support/Debug.h" 20 21 #define DEBUG_TYPE "format-token-annotator" 22 23 namespace clang { 24 namespace format { 25 26 namespace { 27 28 /// \brief A parser that gathers additional information about tokens. 29 /// 30 /// The \c TokenAnnotator tries to match parenthesis and square brakets and 31 /// store a parenthesis levels. It also tries to resolve matching "<" and ">" 32 /// into template parameter lists. 33 class AnnotatingParser { 34 public: 35 AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line, 36 const AdditionalKeywords &Keywords) 37 : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false), 38 Keywords(Keywords) { 39 Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false)); 40 resetTokenMetadata(CurrentToken); 41 } 42 43 private: 44 bool parseAngle() { 45 if (!CurrentToken || !CurrentToken->Previous) 46 return false; 47 if (NonTemplateLess.count(CurrentToken->Previous)) 48 return false; 49 50 const FormatToken& Previous = *CurrentToken->Previous; 51 if (Previous.Previous) { 52 if (Previous.Previous->Tok.isLiteral()) 53 return false; 54 if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 && 55 (!Previous.Previous->MatchingParen || 56 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen))) 57 return false; 58 } 59 60 FormatToken *Left = CurrentToken->Previous; 61 Left->ParentBracket = Contexts.back().ContextKind; 62 ScopedContextCreator ContextCreator(*this, tok::less, 12); 63 64 // If this angle is in the context of an expression, we need to be more 65 // hesitant to detect it as opening template parameters. 66 bool InExprContext = Contexts.back().IsExpression; 67 68 Contexts.back().IsExpression = false; 69 // If there's a template keyword before the opening angle bracket, this is a 70 // template parameter, not an argument. 71 Contexts.back().InTemplateArgument = 72 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template); 73 74 if (Style.Language == FormatStyle::LK_Java && 75 CurrentToken->is(tok::question)) 76 next(); 77 78 while (CurrentToken) { 79 if (CurrentToken->is(tok::greater)) { 80 Left->MatchingParen = CurrentToken; 81 CurrentToken->MatchingParen = Left; 82 CurrentToken->Type = TT_TemplateCloser; 83 next(); 84 return true; 85 } 86 if (CurrentToken->is(tok::question) && 87 Style.Language == FormatStyle::LK_Java) { 88 next(); 89 continue; 90 } 91 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) || 92 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext)) 93 return false; 94 // If a && or || is found and interpreted as a binary operator, this set 95 // of angles is likely part of something like "a < b && c > d". If the 96 // angles are inside an expression, the ||/&& might also be a binary 97 // operator that was misinterpreted because we are parsing template 98 // parameters. 99 // FIXME: This is getting out of hand, write a decent parser. 100 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) && 101 CurrentToken->Previous->is(TT_BinaryOperator) && 102 Contexts[Contexts.size() - 2].IsExpression && 103 !Line.startsWith(tok::kw_template)) 104 return false; 105 updateParameterCount(Left, CurrentToken); 106 if (!consumeToken()) 107 return false; 108 } 109 return false; 110 } 111 112 bool parseParens(bool LookForDecls = false) { 113 if (!CurrentToken) 114 return false; 115 FormatToken *Left = CurrentToken->Previous; 116 Left->ParentBracket = Contexts.back().ContextKind; 117 ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); 118 119 // FIXME: This is a bit of a hack. Do better. 120 Contexts.back().ColonIsForRangeExpr = 121 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 122 123 bool StartsObjCMethodExpr = false; 124 if (CurrentToken->is(tok::caret)) { 125 // (^ can start a block type. 126 Left->Type = TT_ObjCBlockLParen; 127 } else if (FormatToken *MaybeSel = Left->Previous) { 128 // @selector( starts a selector. 129 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous && 130 MaybeSel->Previous->is(tok::at)) { 131 StartsObjCMethodExpr = true; 132 } 133 } 134 135 if (Left->is(TT_OverloadedOperatorLParen)) { 136 Contexts.back().IsExpression = false; 137 } else if (Style.Language == FormatStyle::LK_JavaScript && 138 (Line.startsWith(Keywords.kw_type, tok::identifier) || 139 Line.startsWith(tok::kw_export, Keywords.kw_type, 140 tok::identifier))) { 141 // type X = (...); 142 // export type X = (...); 143 Contexts.back().IsExpression = false; 144 } else if (Left->Previous && 145 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype, 146 tok::kw_if, tok::kw_while, tok::l_paren, 147 tok::comma) || 148 Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) || 149 Left->Previous->is(TT_BinaryOperator))) { 150 // static_assert, if and while usually contain expressions. 151 Contexts.back().IsExpression = true; 152 } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && 153 (Left->Previous->is(Keywords.kw_function) || 154 (Left->Previous->endsSequence(tok::identifier, 155 Keywords.kw_function)))) { 156 // function(...) or function f(...) 157 Contexts.back().IsExpression = false; 158 } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && 159 Left->Previous->is(TT_JsTypeColon)) { 160 // let x: (SomeType); 161 Contexts.back().IsExpression = false; 162 } else if (Left->Previous && Left->Previous->is(tok::r_square) && 163 Left->Previous->MatchingParen && 164 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) { 165 // This is a parameter list of a lambda expression. 166 Contexts.back().IsExpression = false; 167 } else if (Line.InPPDirective && 168 (!Left->Previous || !Left->Previous->is(tok::identifier))) { 169 Contexts.back().IsExpression = true; 170 } else if (Contexts[Contexts.size() - 2].CaretFound) { 171 // This is the parameter list of an ObjC block. 172 Contexts.back().IsExpression = false; 173 } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) { 174 Left->Type = TT_AttributeParen; 175 } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) { 176 // The first argument to a foreach macro is a declaration. 177 Contexts.back().IsForEachMacro = true; 178 Contexts.back().IsExpression = false; 179 } else if (Left->Previous && Left->Previous->MatchingParen && 180 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) { 181 Contexts.back().IsExpression = false; 182 } else if (!Line.MustBeDeclaration && !Line.InPPDirective) { 183 bool IsForOrCatch = 184 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch); 185 Contexts.back().IsExpression = !IsForOrCatch; 186 } 187 188 if (StartsObjCMethodExpr) { 189 Contexts.back().ColonIsObjCMethodExpr = true; 190 Left->Type = TT_ObjCMethodExpr; 191 } 192 193 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression; 194 bool ProbablyFunctionType = CurrentToken->isOneOf(tok::star, tok::amp); 195 bool HasMultipleLines = false; 196 bool HasMultipleParametersOnALine = false; 197 bool MightBeObjCForRangeLoop = 198 Left->Previous && Left->Previous->is(tok::kw_for); 199 while (CurrentToken) { 200 // LookForDecls is set when "if (" has been seen. Check for 201 // 'identifier' '*' 'identifier' followed by not '=' -- this 202 // '*' has to be a binary operator but determineStarAmpUsage() will 203 // categorize it as an unary operator, so set the right type here. 204 if (LookForDecls && CurrentToken->Next) { 205 FormatToken *Prev = CurrentToken->getPreviousNonComment(); 206 if (Prev) { 207 FormatToken *PrevPrev = Prev->getPreviousNonComment(); 208 FormatToken *Next = CurrentToken->Next; 209 if (PrevPrev && PrevPrev->is(tok::identifier) && 210 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) && 211 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) { 212 Prev->Type = TT_BinaryOperator; 213 LookForDecls = false; 214 } 215 } 216 } 217 218 if (CurrentToken->Previous->is(TT_PointerOrReference) && 219 CurrentToken->Previous->Previous->isOneOf(tok::l_paren, 220 tok::coloncolon)) 221 ProbablyFunctionType = true; 222 if (CurrentToken->is(tok::comma)) 223 MightBeFunctionType = false; 224 if (CurrentToken->Previous->is(TT_BinaryOperator)) 225 Contexts.back().IsExpression = true; 226 if (CurrentToken->is(tok::r_paren)) { 227 if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next && 228 (CurrentToken->Next->is(tok::l_paren) || 229 (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration))) 230 Left->Type = TT_FunctionTypeLParen; 231 Left->MatchingParen = CurrentToken; 232 CurrentToken->MatchingParen = Left; 233 234 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) && 235 Left->Previous && Left->Previous->is(tok::l_paren)) { 236 // Detect the case where macros are used to generate lambdas or 237 // function bodies, e.g.: 238 // auto my_lambda = MARCO((Type *type, int i) { .. body .. }); 239 for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) { 240 if (Tok->is(TT_BinaryOperator) && 241 Tok->isOneOf(tok::star, tok::amp, tok::ampamp)) 242 Tok->Type = TT_PointerOrReference; 243 } 244 } 245 246 if (StartsObjCMethodExpr) { 247 CurrentToken->Type = TT_ObjCMethodExpr; 248 if (Contexts.back().FirstObjCSelectorName) { 249 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 250 Contexts.back().LongestObjCSelectorName; 251 } 252 } 253 254 if (Left->is(TT_AttributeParen)) 255 CurrentToken->Type = TT_AttributeParen; 256 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation)) 257 CurrentToken->Type = TT_JavaAnnotation; 258 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation)) 259 CurrentToken->Type = TT_LeadingJavaAnnotation; 260 261 if (!HasMultipleLines) 262 Left->PackingKind = PPK_Inconclusive; 263 else if (HasMultipleParametersOnALine) 264 Left->PackingKind = PPK_BinPacked; 265 else 266 Left->PackingKind = PPK_OnePerLine; 267 268 next(); 269 return true; 270 } 271 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) 272 return false; 273 274 if (CurrentToken->is(tok::l_brace)) 275 Left->Type = TT_Unknown; // Not TT_ObjCBlockLParen 276 if (CurrentToken->is(tok::comma) && CurrentToken->Next && 277 !CurrentToken->Next->HasUnescapedNewline && 278 !CurrentToken->Next->isTrailingComment()) 279 HasMultipleParametersOnALine = true; 280 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) || 281 CurrentToken->Previous->isSimpleTypeSpecifier()) && 282 !CurrentToken->is(tok::l_brace)) 283 Contexts.back().IsExpression = false; 284 if (CurrentToken->isOneOf(tok::semi, tok::colon)) 285 MightBeObjCForRangeLoop = false; 286 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) 287 CurrentToken->Type = TT_ObjCForIn; 288 // When we discover a 'new', we set CanBeExpression to 'false' in order to 289 // parse the type correctly. Reset that after a comma. 290 if (CurrentToken->is(tok::comma)) 291 Contexts.back().CanBeExpression = true; 292 293 FormatToken *Tok = CurrentToken; 294 if (!consumeToken()) 295 return false; 296 updateParameterCount(Left, Tok); 297 if (CurrentToken && CurrentToken->HasUnescapedNewline) 298 HasMultipleLines = true; 299 } 300 return false; 301 } 302 303 bool parseSquare() { 304 if (!CurrentToken) 305 return false; 306 307 // A '[' could be an index subscript (after an identifier or after 308 // ')' or ']'), it could be the start of an Objective-C method 309 // expression, or it could the start of an Objective-C array literal. 310 FormatToken *Left = CurrentToken->Previous; 311 Left->ParentBracket = Contexts.back().ContextKind; 312 FormatToken *Parent = Left->getPreviousNonComment(); 313 314 // Cases where '>' is followed by '['. 315 // In C++, this can happen either in array of templates (foo<int>[10]) 316 // or when array is a nested template type (unique_ptr<type1<type2>[]>). 317 bool CppArrayTemplates = 318 Style.isCpp() && Parent && 319 Parent->is(TT_TemplateCloser) && 320 (Contexts.back().CanBeExpression || Contexts.back().IsExpression || 321 Contexts.back().InTemplateArgument); 322 323 bool StartsObjCMethodExpr = 324 !CppArrayTemplates && Style.isCpp() && 325 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) && 326 CurrentToken->isNot(tok::l_brace) && 327 (!Parent || 328 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, 329 tok::kw_return, tok::kw_throw) || 330 Parent->isUnaryOperator() || 331 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) || 332 getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown); 333 bool ColonFound = false; 334 335 unsigned BindingIncrease = 1; 336 if (Left->is(TT_Unknown)) { 337 if (StartsObjCMethodExpr) { 338 Left->Type = TT_ObjCMethodExpr; 339 } else if (Style.Language == FormatStyle::LK_JavaScript && Parent && 340 Contexts.back().ContextKind == tok::l_brace && 341 Parent->isOneOf(tok::l_brace, tok::comma)) { 342 Left->Type = TT_JsComputedPropertyName; 343 } else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace && 344 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) { 345 Left->Type = TT_DesignatedInitializerLSquare; 346 } else if (CurrentToken->is(tok::r_square) && Parent && 347 Parent->is(TT_TemplateCloser)) { 348 Left->Type = TT_ArraySubscriptLSquare; 349 } else if (Style.Language == FormatStyle::LK_Proto || 350 (!CppArrayTemplates && Parent && 351 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at, 352 tok::comma, tok::l_paren, tok::l_square, 353 tok::question, tok::colon, tok::kw_return, 354 // Should only be relevant to JavaScript: 355 tok::kw_default))) { 356 Left->Type = TT_ArrayInitializerLSquare; 357 } else { 358 BindingIncrease = 10; 359 Left->Type = TT_ArraySubscriptLSquare; 360 } 361 } 362 363 ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease); 364 Contexts.back().IsExpression = true; 365 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr; 366 367 while (CurrentToken) { 368 if (CurrentToken->is(tok::r_square)) { 369 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) && 370 Left->is(TT_ObjCMethodExpr)) { 371 // An ObjC method call is rarely followed by an open parenthesis. 372 // FIXME: Do we incorrectly label ":" with this? 373 StartsObjCMethodExpr = false; 374 Left->Type = TT_Unknown; 375 } 376 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) { 377 CurrentToken->Type = TT_ObjCMethodExpr; 378 // determineStarAmpUsage() thinks that '*' '[' is allocating an 379 // array of pointers, but if '[' starts a selector then '*' is a 380 // binary operator. 381 if (Parent && Parent->is(TT_PointerOrReference)) 382 Parent->Type = TT_BinaryOperator; 383 } 384 Left->MatchingParen = CurrentToken; 385 CurrentToken->MatchingParen = Left; 386 if (Contexts.back().FirstObjCSelectorName) { 387 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 388 Contexts.back().LongestObjCSelectorName; 389 if (Left->BlockParameterCount > 1) 390 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0; 391 } 392 next(); 393 return true; 394 } 395 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace)) 396 return false; 397 if (CurrentToken->is(tok::colon)) { 398 if (Left->isOneOf(TT_ArraySubscriptLSquare, 399 TT_DesignatedInitializerLSquare)) { 400 Left->Type = TT_ObjCMethodExpr; 401 StartsObjCMethodExpr = true; 402 Contexts.back().ColonIsObjCMethodExpr = true; 403 if (Parent && Parent->is(tok::r_paren)) 404 Parent->Type = TT_CastRParen; 405 } 406 ColonFound = true; 407 } 408 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) && 409 !ColonFound) 410 Left->Type = TT_ArrayInitializerLSquare; 411 FormatToken *Tok = CurrentToken; 412 if (!consumeToken()) 413 return false; 414 updateParameterCount(Left, Tok); 415 } 416 return false; 417 } 418 419 bool parseBrace() { 420 if (CurrentToken) { 421 FormatToken *Left = CurrentToken->Previous; 422 Left->ParentBracket = Contexts.back().ContextKind; 423 424 if (Contexts.back().CaretFound) 425 Left->Type = TT_ObjCBlockLBrace; 426 Contexts.back().CaretFound = false; 427 428 ScopedContextCreator ContextCreator(*this, tok::l_brace, 1); 429 Contexts.back().ColonIsDictLiteral = true; 430 if (Left->BlockKind == BK_BracedInit) 431 Contexts.back().IsExpression = true; 432 433 while (CurrentToken) { 434 if (CurrentToken->is(tok::r_brace)) { 435 Left->MatchingParen = CurrentToken; 436 CurrentToken->MatchingParen = Left; 437 next(); 438 return true; 439 } 440 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square)) 441 return false; 442 updateParameterCount(Left, CurrentToken); 443 if (CurrentToken->isOneOf(tok::colon, tok::l_brace)) { 444 FormatToken *Previous = CurrentToken->getPreviousNonComment(); 445 if (((CurrentToken->is(tok::colon) && 446 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) || 447 Style.Language == FormatStyle::LK_Proto) && 448 (Previous->Tok.getIdentifierInfo() || 449 Previous->is(tok::string_literal))) 450 Previous->Type = TT_SelectorName; 451 if (CurrentToken->is(tok::colon) || 452 Style.Language == FormatStyle::LK_JavaScript) 453 Left->Type = TT_DictLiteral; 454 } 455 if (CurrentToken->is(tok::comma) && 456 Style.Language == FormatStyle::LK_JavaScript) 457 Left->Type = TT_DictLiteral; 458 if (!consumeToken()) 459 return false; 460 } 461 } 462 return true; 463 } 464 465 void updateParameterCount(FormatToken *Left, FormatToken *Current) { 466 if (Current->is(tok::l_brace) && Current->BlockKind == BK_Block) 467 ++Left->BlockParameterCount; 468 if (Current->is(tok::comma)) { 469 ++Left->ParameterCount; 470 if (!Left->Role) 471 Left->Role.reset(new CommaSeparatedList(Style)); 472 Left->Role->CommaFound(Current); 473 } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) { 474 Left->ParameterCount = 1; 475 } 476 } 477 478 bool parseConditional() { 479 while (CurrentToken) { 480 if (CurrentToken->is(tok::colon)) { 481 CurrentToken->Type = TT_ConditionalExpr; 482 next(); 483 return true; 484 } 485 if (!consumeToken()) 486 return false; 487 } 488 return false; 489 } 490 491 bool parseTemplateDeclaration() { 492 if (CurrentToken && CurrentToken->is(tok::less)) { 493 CurrentToken->Type = TT_TemplateOpener; 494 next(); 495 if (!parseAngle()) 496 return false; 497 if (CurrentToken) 498 CurrentToken->Previous->ClosesTemplateDeclaration = true; 499 return true; 500 } 501 return false; 502 } 503 504 bool consumeToken() { 505 FormatToken *Tok = CurrentToken; 506 next(); 507 switch (Tok->Tok.getKind()) { 508 case tok::plus: 509 case tok::minus: 510 if (!Tok->Previous && Line.MustBeDeclaration) 511 Tok->Type = TT_ObjCMethodSpecifier; 512 break; 513 case tok::colon: 514 if (!Tok->Previous) 515 return false; 516 // Colons from ?: are handled in parseConditional(). 517 if (Style.Language == FormatStyle::LK_JavaScript) { 518 if (Contexts.back().ColonIsForRangeExpr || // colon in for loop 519 (Contexts.size() == 1 && // switch/case labels 520 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) || 521 Contexts.back().ContextKind == tok::l_paren || // function params 522 Contexts.back().ContextKind == tok::l_square || // array type 523 (Contexts.size() == 1 && 524 Line.MustBeDeclaration)) { // method/property declaration 525 Tok->Type = TT_JsTypeColon; 526 break; 527 } 528 } 529 if (Contexts.back().ColonIsDictLiteral || 530 Style.Language == FormatStyle::LK_Proto) { 531 Tok->Type = TT_DictLiteral; 532 } else if (Contexts.back().ColonIsObjCMethodExpr || 533 Line.startsWith(TT_ObjCMethodSpecifier)) { 534 Tok->Type = TT_ObjCMethodExpr; 535 const FormatToken *BeforePrevious = Tok->Previous->Previous; 536 if (!BeforePrevious || 537 !(BeforePrevious->is(TT_CastRParen) || 538 (BeforePrevious->is(TT_ObjCMethodExpr) && 539 BeforePrevious->is(tok::colon))) || 540 BeforePrevious->is(tok::r_square) || 541 Contexts.back().LongestObjCSelectorName == 0) { 542 Tok->Previous->Type = TT_SelectorName; 543 if (Tok->Previous->ColumnWidth > 544 Contexts.back().LongestObjCSelectorName) 545 Contexts.back().LongestObjCSelectorName = 546 Tok->Previous->ColumnWidth; 547 if (!Contexts.back().FirstObjCSelectorName) 548 Contexts.back().FirstObjCSelectorName = Tok->Previous; 549 } 550 } else if (Contexts.back().ColonIsForRangeExpr) { 551 Tok->Type = TT_RangeBasedForLoopColon; 552 } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) { 553 Tok->Type = TT_BitFieldColon; 554 } else if (Contexts.size() == 1 && 555 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) { 556 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren, 557 tok::kw_noexcept)) 558 Tok->Type = TT_CtorInitializerColon; 559 else 560 Tok->Type = TT_InheritanceColon; 561 } else if (Tok->Previous->is(tok::identifier) && Tok->Next && 562 Tok->Next->isOneOf(tok::r_paren, tok::comma)) { 563 // This handles a special macro in ObjC code where selectors including 564 // the colon are passed as macro arguments. 565 Tok->Type = TT_ObjCMethodExpr; 566 } else if (Contexts.back().ContextKind == tok::l_paren) { 567 Tok->Type = TT_InlineASMColon; 568 } 569 break; 570 case tok::pipe: 571 case tok::amp: 572 // | and & in declarations/type expressions represent union and 573 // intersection types, respectively. 574 if (Style.Language == FormatStyle::LK_JavaScript && 575 !Contexts.back().IsExpression) 576 Tok->Type = TT_JsTypeOperator; 577 break; 578 case tok::kw_if: 579 case tok::kw_while: 580 if (Tok->is(tok::kw_if) && CurrentToken && CurrentToken->is(tok::kw_constexpr)) 581 next(); 582 if (CurrentToken && CurrentToken->is(tok::l_paren)) { 583 next(); 584 if (!parseParens(/*LookForDecls=*/true)) 585 return false; 586 } 587 break; 588 case tok::kw_for: 589 if (Style.Language == FormatStyle::LK_JavaScript) { 590 if (Tok->Previous && Tok->Previous->is(tok::period)) 591 break; 592 // JS' for await ( ... 593 if (CurrentToken && CurrentToken->is(Keywords.kw_await)) 594 next(); 595 } 596 Contexts.back().ColonIsForRangeExpr = true; 597 next(); 598 if (!parseParens()) 599 return false; 600 break; 601 case tok::l_paren: 602 // When faced with 'operator()()', the kw_operator handler incorrectly 603 // marks the first l_paren as a OverloadedOperatorLParen. Here, we make 604 // the first two parens OverloadedOperators and the second l_paren an 605 // OverloadedOperatorLParen. 606 if (Tok->Previous && 607 Tok->Previous->is(tok::r_paren) && 608 Tok->Previous->MatchingParen && 609 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) { 610 Tok->Previous->Type = TT_OverloadedOperator; 611 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator; 612 Tok->Type = TT_OverloadedOperatorLParen; 613 } 614 615 if (!parseParens()) 616 return false; 617 if (Line.MustBeDeclaration && Contexts.size() == 1 && 618 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) && 619 (!Tok->Previous || 620 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute, 621 TT_LeadingJavaAnnotation))) 622 Line.MightBeFunctionDecl = true; 623 break; 624 case tok::l_square: 625 if (!parseSquare()) 626 return false; 627 break; 628 case tok::l_brace: 629 if (!parseBrace()) 630 return false; 631 break; 632 case tok::less: 633 if (parseAngle()) { 634 Tok->Type = TT_TemplateOpener; 635 } else { 636 Tok->Type = TT_BinaryOperator; 637 NonTemplateLess.insert(Tok); 638 CurrentToken = Tok; 639 next(); 640 } 641 break; 642 case tok::r_paren: 643 case tok::r_square: 644 return false; 645 case tok::r_brace: 646 // Lines can start with '}'. 647 if (Tok->Previous) 648 return false; 649 break; 650 case tok::greater: 651 Tok->Type = TT_BinaryOperator; 652 break; 653 case tok::kw_operator: 654 while (CurrentToken && 655 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) { 656 if (CurrentToken->isOneOf(tok::star, tok::amp)) 657 CurrentToken->Type = TT_PointerOrReference; 658 consumeToken(); 659 if (CurrentToken && 660 CurrentToken->Previous->isOneOf(TT_BinaryOperator, tok::comma)) 661 CurrentToken->Previous->Type = TT_OverloadedOperator; 662 } 663 if (CurrentToken) { 664 CurrentToken->Type = TT_OverloadedOperatorLParen; 665 if (CurrentToken->Previous->is(TT_BinaryOperator)) 666 CurrentToken->Previous->Type = TT_OverloadedOperator; 667 } 668 break; 669 case tok::question: 670 if (Style.Language == FormatStyle::LK_JavaScript && Tok->Next && 671 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren, 672 tok::r_brace)) { 673 // Question marks before semicolons, colons, etc. indicate optional 674 // types (fields, parameters), e.g. 675 // function(x?: string, y?) {...} 676 // class X { y?; } 677 Tok->Type = TT_JsTypeOptionalQuestion; 678 break; 679 } 680 // Declarations cannot be conditional expressions, this can only be part 681 // of a type declaration. 682 if (Line.MustBeDeclaration && !Contexts.back().IsExpression && 683 Style.Language == FormatStyle::LK_JavaScript) 684 break; 685 parseConditional(); 686 break; 687 case tok::kw_template: 688 parseTemplateDeclaration(); 689 break; 690 case tok::comma: 691 if (Contexts.back().InCtorInitializer) 692 Tok->Type = TT_CtorInitializerComma; 693 else if (Contexts.back().InInheritanceList) 694 Tok->Type = TT_InheritanceComma; 695 else if (Contexts.back().FirstStartOfName && 696 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) { 697 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true; 698 Line.IsMultiVariableDeclStmt = true; 699 } 700 if (Contexts.back().IsForEachMacro) 701 Contexts.back().IsExpression = true; 702 break; 703 case tok::identifier: 704 if (Tok->isOneOf(Keywords.kw___has_include, 705 Keywords.kw___has_include_next)) { 706 parseHasInclude(); 707 } 708 break; 709 default: 710 break; 711 } 712 return true; 713 } 714 715 void parseIncludeDirective() { 716 if (CurrentToken && CurrentToken->is(tok::less)) { 717 next(); 718 while (CurrentToken) { 719 // Mark tokens up to the trailing line comments as implicit string 720 // literals. 721 if (CurrentToken->isNot(tok::comment) && 722 !CurrentToken->TokenText.startswith("//")) 723 CurrentToken->Type = TT_ImplicitStringLiteral; 724 next(); 725 } 726 } 727 } 728 729 void parseWarningOrError() { 730 next(); 731 // We still want to format the whitespace left of the first token of the 732 // warning or error. 733 next(); 734 while (CurrentToken) { 735 CurrentToken->Type = TT_ImplicitStringLiteral; 736 next(); 737 } 738 } 739 740 void parsePragma() { 741 next(); // Consume "pragma". 742 if (CurrentToken && 743 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) { 744 bool IsMark = CurrentToken->is(Keywords.kw_mark); 745 next(); // Consume "mark". 746 next(); // Consume first token (so we fix leading whitespace). 747 while (CurrentToken) { 748 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator)) 749 CurrentToken->Type = TT_ImplicitStringLiteral; 750 next(); 751 } 752 } 753 } 754 755 void parseHasInclude() { 756 if (!CurrentToken || !CurrentToken->is(tok::l_paren)) 757 return; 758 next(); // '(' 759 parseIncludeDirective(); 760 next(); // ')' 761 } 762 763 LineType parsePreprocessorDirective() { 764 bool IsFirstToken = CurrentToken->IsFirst; 765 LineType Type = LT_PreprocessorDirective; 766 next(); 767 if (!CurrentToken) 768 return Type; 769 770 if (Style.Language == FormatStyle::LK_JavaScript && IsFirstToken) { 771 // JavaScript files can contain shebang lines of the form: 772 // #!/usr/bin/env node 773 // Treat these like C++ #include directives. 774 while (CurrentToken) { 775 // Tokens cannot be comments here. 776 CurrentToken->Type = TT_ImplicitStringLiteral; 777 next(); 778 } 779 return LT_ImportStatement; 780 } 781 782 if (CurrentToken->Tok.is(tok::numeric_constant)) { 783 CurrentToken->SpacesRequiredBefore = 1; 784 return Type; 785 } 786 // Hashes in the middle of a line can lead to any strange token 787 // sequence. 788 if (!CurrentToken->Tok.getIdentifierInfo()) 789 return Type; 790 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) { 791 case tok::pp_include: 792 case tok::pp_include_next: 793 case tok::pp_import: 794 next(); 795 parseIncludeDirective(); 796 Type = LT_ImportStatement; 797 break; 798 case tok::pp_error: 799 case tok::pp_warning: 800 parseWarningOrError(); 801 break; 802 case tok::pp_pragma: 803 parsePragma(); 804 break; 805 case tok::pp_if: 806 case tok::pp_elif: 807 Contexts.back().IsExpression = true; 808 parseLine(); 809 break; 810 default: 811 break; 812 } 813 while (CurrentToken) { 814 FormatToken *Tok = CurrentToken; 815 next(); 816 if (Tok->is(tok::l_paren)) 817 parseParens(); 818 else if (Tok->isOneOf(Keywords.kw___has_include, 819 Keywords.kw___has_include_next)) 820 parseHasInclude(); 821 } 822 return Type; 823 } 824 825 public: 826 LineType parseLine() { 827 NonTemplateLess.clear(); 828 if (CurrentToken->is(tok::hash)) 829 return parsePreprocessorDirective(); 830 831 // Directly allow to 'import <string-literal>' to support protocol buffer 832 // definitions (code.google.com/p/protobuf) or missing "#" (either way we 833 // should not break the line). 834 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo(); 835 if ((Style.Language == FormatStyle::LK_Java && 836 CurrentToken->is(Keywords.kw_package)) || 837 (Info && Info->getPPKeywordID() == tok::pp_import && 838 CurrentToken->Next && 839 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier, 840 tok::kw_static))) { 841 next(); 842 parseIncludeDirective(); 843 return LT_ImportStatement; 844 } 845 846 // If this line starts and ends in '<' and '>', respectively, it is likely 847 // part of "#define <a/b.h>". 848 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) { 849 parseIncludeDirective(); 850 return LT_ImportStatement; 851 } 852 853 // In .proto files, top-level options are very similar to import statements 854 // and should not be line-wrapped. 855 if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 && 856 CurrentToken->is(Keywords.kw_option)) { 857 next(); 858 if (CurrentToken && CurrentToken->is(tok::identifier)) 859 return LT_ImportStatement; 860 } 861 862 bool KeywordVirtualFound = false; 863 bool ImportStatement = false; 864 865 // import {...} from '...'; 866 if (Style.Language == FormatStyle::LK_JavaScript && 867 CurrentToken->is(Keywords.kw_import)) 868 ImportStatement = true; 869 870 while (CurrentToken) { 871 if (CurrentToken->is(tok::kw_virtual)) 872 KeywordVirtualFound = true; 873 if (Style.Language == FormatStyle::LK_JavaScript) { 874 // export {...} from '...'; 875 // An export followed by "from 'some string';" is a re-export from 876 // another module identified by a URI and is treated as a 877 // LT_ImportStatement (i.e. prevent wraps on it for long URIs). 878 // Just "export {...};" or "export class ..." should not be treated as 879 // an import in this sense. 880 if (Line.First->is(tok::kw_export) && 881 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next && 882 CurrentToken->Next->isStringLiteral()) 883 ImportStatement = true; 884 if (isClosureImportStatement(*CurrentToken)) 885 ImportStatement = true; 886 } 887 if (!consumeToken()) 888 return LT_Invalid; 889 } 890 if (KeywordVirtualFound) 891 return LT_VirtualFunctionDecl; 892 if (ImportStatement) 893 return LT_ImportStatement; 894 895 if (Line.startsWith(TT_ObjCMethodSpecifier)) { 896 if (Contexts.back().FirstObjCSelectorName) 897 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 898 Contexts.back().LongestObjCSelectorName; 899 return LT_ObjCMethodDecl; 900 } 901 902 return LT_Other; 903 } 904 905 private: 906 bool isClosureImportStatement(const FormatToken &Tok) { 907 // FIXME: Closure-library specific stuff should not be hard-coded but be 908 // configurable. 909 return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) && 910 Tok.Next->Next && (Tok.Next->Next->TokenText == "module" || 911 Tok.Next->Next->TokenText == "provide" || 912 Tok.Next->Next->TokenText == "require" || 913 Tok.Next->Next->TokenText == "setTestOnly" || 914 Tok.Next->Next->TokenText == "forwardDeclare") && 915 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren); 916 } 917 918 void resetTokenMetadata(FormatToken *Token) { 919 if (!Token) 920 return; 921 922 // Reset token type in case we have already looked at it and then 923 // recovered from an error (e.g. failure to find the matching >). 924 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro, 925 TT_FunctionLBrace, TT_ImplicitStringLiteral, 926 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow, 927 TT_OverloadedOperator, TT_RegexLiteral, 928 TT_TemplateString, TT_ObjCStringLiteral)) 929 CurrentToken->Type = TT_Unknown; 930 CurrentToken->Role.reset(); 931 CurrentToken->MatchingParen = nullptr; 932 CurrentToken->FakeLParens.clear(); 933 CurrentToken->FakeRParens = 0; 934 } 935 936 void next() { 937 if (CurrentToken) { 938 CurrentToken->NestingLevel = Contexts.size() - 1; 939 CurrentToken->BindingStrength = Contexts.back().BindingStrength; 940 modifyContext(*CurrentToken); 941 determineTokenType(*CurrentToken); 942 CurrentToken = CurrentToken->Next; 943 } 944 945 resetTokenMetadata(CurrentToken); 946 } 947 948 /// \brief A struct to hold information valid in a specific context, e.g. 949 /// a pair of parenthesis. 950 struct Context { 951 Context(tok::TokenKind ContextKind, unsigned BindingStrength, 952 bool IsExpression) 953 : ContextKind(ContextKind), BindingStrength(BindingStrength), 954 IsExpression(IsExpression) {} 955 956 tok::TokenKind ContextKind; 957 unsigned BindingStrength; 958 bool IsExpression; 959 unsigned LongestObjCSelectorName = 0; 960 bool ColonIsForRangeExpr = false; 961 bool ColonIsDictLiteral = false; 962 bool ColonIsObjCMethodExpr = false; 963 FormatToken *FirstObjCSelectorName = nullptr; 964 FormatToken *FirstStartOfName = nullptr; 965 bool CanBeExpression = true; 966 bool InTemplateArgument = false; 967 bool InCtorInitializer = false; 968 bool InInheritanceList = false; 969 bool CaretFound = false; 970 bool IsForEachMacro = false; 971 }; 972 973 /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 974 /// of each instance. 975 struct ScopedContextCreator { 976 AnnotatingParser &P; 977 978 ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind, 979 unsigned Increase) 980 : P(P) { 981 P.Contexts.push_back(Context(ContextKind, 982 P.Contexts.back().BindingStrength + Increase, 983 P.Contexts.back().IsExpression)); 984 } 985 986 ~ScopedContextCreator() { P.Contexts.pop_back(); } 987 }; 988 989 void modifyContext(const FormatToken &Current) { 990 if (Current.getPrecedence() == prec::Assignment && 991 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) && 992 // Type aliases use `type X = ...;` in TypeScript and can be exported 993 // using `export type ...`. 994 !(Style.Language == FormatStyle::LK_JavaScript && 995 (Line.startsWith(Keywords.kw_type, tok::identifier) || 996 Line.startsWith(tok::kw_export, Keywords.kw_type, 997 tok::identifier))) && 998 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) { 999 Contexts.back().IsExpression = true; 1000 if (!Line.startsWith(TT_UnaryOperator)) { 1001 for (FormatToken *Previous = Current.Previous; 1002 Previous && Previous->Previous && 1003 !Previous->Previous->isOneOf(tok::comma, tok::semi); 1004 Previous = Previous->Previous) { 1005 if (Previous->isOneOf(tok::r_square, tok::r_paren)) { 1006 Previous = Previous->MatchingParen; 1007 if (!Previous) 1008 break; 1009 } 1010 if (Previous->opensScope()) 1011 break; 1012 if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) && 1013 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) && 1014 Previous->Previous && Previous->Previous->isNot(tok::equal)) 1015 Previous->Type = TT_PointerOrReference; 1016 } 1017 } 1018 } else if (Current.is(tok::lessless) && 1019 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) { 1020 Contexts.back().IsExpression = true; 1021 } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) { 1022 Contexts.back().IsExpression = true; 1023 } else if (Current.is(TT_TrailingReturnArrow)) { 1024 Contexts.back().IsExpression = false; 1025 } else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) { 1026 Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java; 1027 } else if (Current.Previous && 1028 Current.Previous->is(TT_CtorInitializerColon)) { 1029 Contexts.back().IsExpression = true; 1030 Contexts.back().InCtorInitializer = true; 1031 } else if (Current.Previous && 1032 Current.Previous->is(TT_InheritanceColon)) { 1033 Contexts.back().InInheritanceList = true; 1034 } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { 1035 for (FormatToken *Previous = Current.Previous; 1036 Previous && Previous->isOneOf(tok::star, tok::amp); 1037 Previous = Previous->Previous) 1038 Previous->Type = TT_PointerOrReference; 1039 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer) 1040 Contexts.back().IsExpression = false; 1041 } else if (Current.is(tok::kw_new)) { 1042 Contexts.back().CanBeExpression = false; 1043 } else if (Current.isOneOf(tok::semi, tok::exclaim)) { 1044 // This should be the condition or increment in a for-loop. 1045 Contexts.back().IsExpression = true; 1046 } 1047 } 1048 1049 void determineTokenType(FormatToken &Current) { 1050 if (!Current.is(TT_Unknown)) 1051 // The token type is already known. 1052 return; 1053 1054 if (Style.Language == FormatStyle::LK_JavaScript) { 1055 if (Current.is(tok::exclaim)) { 1056 if (Current.Previous && 1057 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace, 1058 tok::r_paren, tok::r_square, 1059 tok::r_brace) || 1060 Current.Previous->Tok.isLiteral())) { 1061 Current.Type = TT_JsNonNullAssertion; 1062 return; 1063 } 1064 if (Current.Next && 1065 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) { 1066 Current.Type = TT_JsNonNullAssertion; 1067 return; 1068 } 1069 } 1070 } 1071 1072 // Line.MightBeFunctionDecl can only be true after the parentheses of a 1073 // function declaration have been found. In this case, 'Current' is a 1074 // trailing token of this declaration and thus cannot be a name. 1075 if (Current.is(Keywords.kw_instanceof)) { 1076 Current.Type = TT_BinaryOperator; 1077 } else if (isStartOfName(Current) && 1078 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) { 1079 Contexts.back().FirstStartOfName = &Current; 1080 Current.Type = TT_StartOfName; 1081 } else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) { 1082 AutoFound = true; 1083 } else if (Current.is(tok::arrow) && 1084 Style.Language == FormatStyle::LK_Java) { 1085 Current.Type = TT_LambdaArrow; 1086 } else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration && 1087 Current.NestingLevel == 0) { 1088 Current.Type = TT_TrailingReturnArrow; 1089 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) { 1090 Current.Type = 1091 determineStarAmpUsage(Current, Contexts.back().CanBeExpression && 1092 Contexts.back().IsExpression, 1093 Contexts.back().InTemplateArgument); 1094 } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { 1095 Current.Type = determinePlusMinusCaretUsage(Current); 1096 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret)) 1097 Contexts.back().CaretFound = true; 1098 } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { 1099 Current.Type = determineIncrementUsage(Current); 1100 } else if (Current.isOneOf(tok::exclaim, tok::tilde)) { 1101 Current.Type = TT_UnaryOperator; 1102 } else if (Current.is(tok::question)) { 1103 if (Style.Language == FormatStyle::LK_JavaScript && 1104 Line.MustBeDeclaration && !Contexts.back().IsExpression) { 1105 // In JavaScript, `interface X { foo?(): bar; }` is an optional method 1106 // on the interface, not a ternary expression. 1107 Current.Type = TT_JsTypeOptionalQuestion; 1108 } else { 1109 Current.Type = TT_ConditionalExpr; 1110 } 1111 } else if (Current.isBinaryOperator() && 1112 (!Current.Previous || Current.Previous->isNot(tok::l_square))) { 1113 Current.Type = TT_BinaryOperator; 1114 } else if (Current.is(tok::comment)) { 1115 if (Current.TokenText.startswith("/*")) { 1116 if (Current.TokenText.endswith("*/")) 1117 Current.Type = TT_BlockComment; 1118 else 1119 // The lexer has for some reason determined a comment here. But we 1120 // cannot really handle it, if it isn't properly terminated. 1121 Current.Tok.setKind(tok::unknown); 1122 } else { 1123 Current.Type = TT_LineComment; 1124 } 1125 } else if (Current.is(tok::r_paren)) { 1126 if (rParenEndsCast(Current)) 1127 Current.Type = TT_CastRParen; 1128 if (Current.MatchingParen && Current.Next && 1129 !Current.Next->isBinaryOperator() && 1130 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace, 1131 tok::comma, tok::period, tok::arrow, 1132 tok::coloncolon)) 1133 if (FormatToken *AfterParen = Current.MatchingParen->Next) { 1134 // Make sure this isn't the return type of an Obj-C block declaration 1135 if (AfterParen->Tok.isNot(tok::caret)) { 1136 if (FormatToken *BeforeParen = Current.MatchingParen->Previous) 1137 if (BeforeParen->is(tok::identifier) && 1138 BeforeParen->TokenText == BeforeParen->TokenText.upper() && 1139 (!BeforeParen->Previous || 1140 BeforeParen->Previous->ClosesTemplateDeclaration)) 1141 Current.Type = TT_FunctionAnnotationRParen; 1142 } 1143 } 1144 } else if (Current.is(tok::at) && Current.Next && 1145 Style.Language != FormatStyle::LK_JavaScript && 1146 Style.Language != FormatStyle::LK_Java) { 1147 // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it 1148 // marks declarations and properties that need special formatting. 1149 switch (Current.Next->Tok.getObjCKeywordID()) { 1150 case tok::objc_interface: 1151 case tok::objc_implementation: 1152 case tok::objc_protocol: 1153 Current.Type = TT_ObjCDecl; 1154 break; 1155 case tok::objc_property: 1156 Current.Type = TT_ObjCProperty; 1157 break; 1158 default: 1159 break; 1160 } 1161 } else if (Current.is(tok::period)) { 1162 FormatToken *PreviousNoComment = Current.getPreviousNonComment(); 1163 if (PreviousNoComment && 1164 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) 1165 Current.Type = TT_DesignatedInitializerPeriod; 1166 else if (Style.Language == FormatStyle::LK_Java && Current.Previous && 1167 Current.Previous->isOneOf(TT_JavaAnnotation, 1168 TT_LeadingJavaAnnotation)) { 1169 Current.Type = Current.Previous->Type; 1170 } 1171 } else if (Current.isOneOf(tok::identifier, tok::kw_const) && 1172 Current.Previous && 1173 !Current.Previous->isOneOf(tok::equal, tok::at) && 1174 Line.MightBeFunctionDecl && Contexts.size() == 1) { 1175 // Line.MightBeFunctionDecl can only be true after the parentheses of a 1176 // function declaration have been found. 1177 Current.Type = TT_TrailingAnnotation; 1178 } else if ((Style.Language == FormatStyle::LK_Java || 1179 Style.Language == FormatStyle::LK_JavaScript) && 1180 Current.Previous) { 1181 if (Current.Previous->is(tok::at) && 1182 Current.isNot(Keywords.kw_interface)) { 1183 const FormatToken &AtToken = *Current.Previous; 1184 const FormatToken *Previous = AtToken.getPreviousNonComment(); 1185 if (!Previous || Previous->is(TT_LeadingJavaAnnotation)) 1186 Current.Type = TT_LeadingJavaAnnotation; 1187 else 1188 Current.Type = TT_JavaAnnotation; 1189 } else if (Current.Previous->is(tok::period) && 1190 Current.Previous->isOneOf(TT_JavaAnnotation, 1191 TT_LeadingJavaAnnotation)) { 1192 Current.Type = Current.Previous->Type; 1193 } 1194 } 1195 } 1196 1197 /// \brief Take a guess at whether \p Tok starts a name of a function or 1198 /// variable declaration. 1199 /// 1200 /// This is a heuristic based on whether \p Tok is an identifier following 1201 /// something that is likely a type. 1202 bool isStartOfName(const FormatToken &Tok) { 1203 if (Tok.isNot(tok::identifier) || !Tok.Previous) 1204 return false; 1205 1206 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof, 1207 Keywords.kw_as)) 1208 return false; 1209 if (Style.Language == FormatStyle::LK_JavaScript && 1210 Tok.Previous->is(Keywords.kw_in)) 1211 return false; 1212 1213 // Skip "const" as it does not have an influence on whether this is a name. 1214 FormatToken *PreviousNotConst = Tok.getPreviousNonComment(); 1215 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const)) 1216 PreviousNotConst = PreviousNotConst->getPreviousNonComment(); 1217 1218 if (!PreviousNotConst) 1219 return false; 1220 1221 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) && 1222 PreviousNotConst->Previous && 1223 PreviousNotConst->Previous->is(tok::hash); 1224 1225 if (PreviousNotConst->is(TT_TemplateCloser)) 1226 return PreviousNotConst && PreviousNotConst->MatchingParen && 1227 PreviousNotConst->MatchingParen->Previous && 1228 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) && 1229 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template); 1230 1231 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen && 1232 PreviousNotConst->MatchingParen->Previous && 1233 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype)) 1234 return true; 1235 1236 return (!IsPPKeyword && 1237 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) || 1238 PreviousNotConst->is(TT_PointerOrReference) || 1239 PreviousNotConst->isSimpleTypeSpecifier(); 1240 } 1241 1242 /// \brief Determine whether ')' is ending a cast. 1243 bool rParenEndsCast(const FormatToken &Tok) { 1244 // C-style casts are only used in C++ and Java. 1245 if (!Style.isCpp() && Style.Language != FormatStyle::LK_Java) 1246 return false; 1247 1248 // Empty parens aren't casts and there are no casts at the end of the line. 1249 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen) 1250 return false; 1251 1252 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment(); 1253 if (LeftOfParens) { 1254 // If there is a closing parenthesis left of the current parentheses, 1255 // look past it as these might be chained casts. 1256 if (LeftOfParens->is(tok::r_paren)) { 1257 if (!LeftOfParens->MatchingParen || 1258 !LeftOfParens->MatchingParen->Previous) 1259 return false; 1260 LeftOfParens = LeftOfParens->MatchingParen->Previous; 1261 } 1262 1263 // If there is an identifier (or with a few exceptions a keyword) right 1264 // before the parentheses, this is unlikely to be a cast. 1265 if (LeftOfParens->Tok.getIdentifierInfo() && 1266 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case, 1267 tok::kw_delete)) 1268 return false; 1269 1270 // Certain other tokens right before the parentheses are also signals that 1271 // this cannot be a cast. 1272 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator, 1273 TT_TemplateCloser, tok::ellipsis)) 1274 return false; 1275 } 1276 1277 if (Tok.Next->is(tok::question)) 1278 return false; 1279 1280 // As Java has no function types, a "(" after the ")" likely means that this 1281 // is a cast. 1282 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren)) 1283 return true; 1284 1285 // If a (non-string) literal follows, this is likely a cast. 1286 if (Tok.Next->isNot(tok::string_literal) && 1287 (Tok.Next->Tok.isLiteral() || 1288 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof))) 1289 return true; 1290 1291 // Heuristically try to determine whether the parentheses contain a type. 1292 bool ParensAreType = 1293 !Tok.Previous || 1294 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) || 1295 Tok.Previous->isSimpleTypeSpecifier(); 1296 bool ParensCouldEndDecl = 1297 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater); 1298 if (ParensAreType && !ParensCouldEndDecl) 1299 return true; 1300 1301 // At this point, we heuristically assume that there are no casts at the 1302 // start of the line. We assume that we have found most cases where there 1303 // are by the logic above, e.g. "(void)x;". 1304 if (!LeftOfParens) 1305 return false; 1306 1307 // Certain token types inside the parentheses mean that this can't be a 1308 // cast. 1309 for (const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok; 1310 Token = Token->Next) 1311 if (Token->is(TT_BinaryOperator)) 1312 return false; 1313 1314 // If the following token is an identifier or 'this', this is a cast. All 1315 // cases where this can be something else are handled above. 1316 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this)) 1317 return true; 1318 1319 if (!Tok.Next->Next) 1320 return false; 1321 1322 // If the next token after the parenthesis is a unary operator, assume 1323 // that this is cast, unless there are unexpected tokens inside the 1324 // parenthesis. 1325 bool NextIsUnary = 1326 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star); 1327 if (!NextIsUnary || Tok.Next->is(tok::plus) || 1328 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant)) 1329 return false; 1330 // Search for unexpected tokens. 1331 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen; 1332 Prev = Prev->Previous) { 1333 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon)) 1334 return false; 1335 } 1336 return true; 1337 } 1338 1339 /// \brief Return the type of the given token assuming it is * or &. 1340 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression, 1341 bool InTemplateArgument) { 1342 if (Style.Language == FormatStyle::LK_JavaScript) 1343 return TT_BinaryOperator; 1344 1345 const FormatToken *PrevToken = Tok.getPreviousNonComment(); 1346 if (!PrevToken) 1347 return TT_UnaryOperator; 1348 1349 const FormatToken *NextToken = Tok.getNextNonComment(); 1350 if (!NextToken || 1351 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) || 1352 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) 1353 return TT_PointerOrReference; 1354 1355 if (PrevToken->is(tok::coloncolon)) 1356 return TT_PointerOrReference; 1357 1358 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, 1359 tok::comma, tok::semi, tok::kw_return, tok::colon, 1360 tok::equal, tok::kw_delete, tok::kw_sizeof) || 1361 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr, 1362 TT_UnaryOperator, TT_CastRParen)) 1363 return TT_UnaryOperator; 1364 1365 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare)) 1366 return TT_PointerOrReference; 1367 if (NextToken->is(tok::kw_operator) && !IsExpression) 1368 return TT_PointerOrReference; 1369 if (NextToken->isOneOf(tok::comma, tok::semi)) 1370 return TT_PointerOrReference; 1371 1372 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen && 1373 PrevToken->MatchingParen->Previous && 1374 PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof, 1375 tok::kw_decltype)) 1376 return TT_PointerOrReference; 1377 1378 if (PrevToken->Tok.isLiteral() || 1379 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true, 1380 tok::kw_false, tok::r_brace) || 1381 NextToken->Tok.isLiteral() || 1382 NextToken->isOneOf(tok::kw_true, tok::kw_false) || 1383 NextToken->isUnaryOperator() || 1384 // If we know we're in a template argument, there are no named 1385 // declarations. Thus, having an identifier on the right-hand side 1386 // indicates a binary operator. 1387 (InTemplateArgument && NextToken->Tok.isAnyIdentifier())) 1388 return TT_BinaryOperator; 1389 1390 // "&&(" is quite unlikely to be two successive unary "&". 1391 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren)) 1392 return TT_BinaryOperator; 1393 1394 // This catches some cases where evaluation order is used as control flow: 1395 // aaa && aaa->f(); 1396 const FormatToken *NextNextToken = NextToken->getNextNonComment(); 1397 if (NextNextToken && NextNextToken->is(tok::arrow)) 1398 return TT_BinaryOperator; 1399 1400 // It is very unlikely that we are going to find a pointer or reference type 1401 // definition on the RHS of an assignment. 1402 if (IsExpression && !Contexts.back().CaretFound) 1403 return TT_BinaryOperator; 1404 1405 return TT_PointerOrReference; 1406 } 1407 1408 TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) { 1409 const FormatToken *PrevToken = Tok.getPreviousNonComment(); 1410 if (!PrevToken) 1411 return TT_UnaryOperator; 1412 1413 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator) && 1414 !PrevToken->is(tok::exclaim)) 1415 // There aren't any trailing unary operators except for TypeScript's 1416 // non-null operator (!). Thus, this must be squence of leading operators. 1417 return TT_UnaryOperator; 1418 1419 // Use heuristics to recognize unary operators. 1420 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square, 1421 tok::question, tok::colon, tok::kw_return, 1422 tok::kw_case, tok::at, tok::l_brace)) 1423 return TT_UnaryOperator; 1424 1425 // There can't be two consecutive binary operators. 1426 if (PrevToken->is(TT_BinaryOperator)) 1427 return TT_UnaryOperator; 1428 1429 // Fall back to marking the token as binary operator. 1430 return TT_BinaryOperator; 1431 } 1432 1433 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 1434 TokenType determineIncrementUsage(const FormatToken &Tok) { 1435 const FormatToken *PrevToken = Tok.getPreviousNonComment(); 1436 if (!PrevToken || PrevToken->is(TT_CastRParen)) 1437 return TT_UnaryOperator; 1438 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) 1439 return TT_TrailingUnaryOperator; 1440 1441 return TT_UnaryOperator; 1442 } 1443 1444 SmallVector<Context, 8> Contexts; 1445 1446 const FormatStyle &Style; 1447 AnnotatedLine &Line; 1448 FormatToken *CurrentToken; 1449 bool AutoFound; 1450 const AdditionalKeywords &Keywords; 1451 1452 // Set of "<" tokens that do not open a template parameter list. If parseAngle 1453 // determines that a specific token can't be a template opener, it will make 1454 // same decision irrespective of the decisions for tokens leading up to it. 1455 // Store this information to prevent this from causing exponential runtime. 1456 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess; 1457 }; 1458 1459 static const int PrecedenceUnaryOperator = prec::PointerToMember + 1; 1460 static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2; 1461 1462 /// \brief Parses binary expressions by inserting fake parenthesis based on 1463 /// operator precedence. 1464 class ExpressionParser { 1465 public: 1466 ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords, 1467 AnnotatedLine &Line) 1468 : Style(Style), Keywords(Keywords), Current(Line.First) {} 1469 1470 /// \brief Parse expressions with the given operatore precedence. 1471 void parse(int Precedence = 0) { 1472 // Skip 'return' and ObjC selector colons as they are not part of a binary 1473 // expression. 1474 while (Current && (Current->is(tok::kw_return) || 1475 (Current->is(tok::colon) && 1476 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) 1477 next(); 1478 1479 if (!Current || Precedence > PrecedenceArrowAndPeriod) 1480 return; 1481 1482 // Conditional expressions need to be parsed separately for proper nesting. 1483 if (Precedence == prec::Conditional) { 1484 parseConditionalExpr(); 1485 return; 1486 } 1487 1488 // Parse unary operators, which all have a higher precedence than binary 1489 // operators. 1490 if (Precedence == PrecedenceUnaryOperator) { 1491 parseUnaryOperator(); 1492 return; 1493 } 1494 1495 FormatToken *Start = Current; 1496 FormatToken *LatestOperator = nullptr; 1497 unsigned OperatorIndex = 0; 1498 1499 while (Current) { 1500 // Consume operators with higher precedence. 1501 parse(Precedence + 1); 1502 1503 int CurrentPrecedence = getCurrentPrecedence(); 1504 1505 if (Current && Current->is(TT_SelectorName) && 1506 Precedence == CurrentPrecedence) { 1507 if (LatestOperator) 1508 addFakeParenthesis(Start, prec::Level(Precedence)); 1509 Start = Current; 1510 } 1511 1512 // At the end of the line or when an operator with higher precedence is 1513 // found, insert fake parenthesis and return. 1514 if (!Current || 1515 (Current->closesScope() && 1516 (Current->MatchingParen || Current->is(TT_TemplateString))) || 1517 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) || 1518 (CurrentPrecedence == prec::Conditional && 1519 Precedence == prec::Assignment && Current->is(tok::colon))) { 1520 break; 1521 } 1522 1523 // Consume scopes: (), [], <> and {} 1524 if (Current->opensScope()) { 1525 // In fragment of a JavaScript template string can look like '}..${' and 1526 // thus close a scope and open a new one at the same time. 1527 while (Current && (!Current->closesScope() || Current->opensScope())) { 1528 next(); 1529 parse(); 1530 } 1531 next(); 1532 } else { 1533 // Operator found. 1534 if (CurrentPrecedence == Precedence) { 1535 if (LatestOperator) 1536 LatestOperator->NextOperator = Current; 1537 LatestOperator = Current; 1538 Current->OperatorIndex = OperatorIndex; 1539 ++OperatorIndex; 1540 } 1541 next(/*SkipPastLeadingComments=*/Precedence > 0); 1542 } 1543 } 1544 1545 if (LatestOperator && (Current || Precedence > 0)) { 1546 // LatestOperator->LastOperator = true; 1547 if (Precedence == PrecedenceArrowAndPeriod) { 1548 // Call expressions don't have a binary operator precedence. 1549 addFakeParenthesis(Start, prec::Unknown); 1550 } else { 1551 addFakeParenthesis(Start, prec::Level(Precedence)); 1552 } 1553 } 1554 } 1555 1556 private: 1557 /// \brief Gets the precedence (+1) of the given token for binary operators 1558 /// and other tokens that we treat like binary operators. 1559 int getCurrentPrecedence() { 1560 if (Current) { 1561 const FormatToken *NextNonComment = Current->getNextNonComment(); 1562 if (Current->is(TT_ConditionalExpr)) 1563 return prec::Conditional; 1564 if (NextNonComment && NextNonComment->is(tok::colon) && 1565 NextNonComment->is(TT_DictLiteral)) 1566 return prec::Assignment; 1567 if (Current->is(TT_JsComputedPropertyName)) 1568 return prec::Assignment; 1569 if (Current->is(TT_LambdaArrow)) 1570 return prec::Comma; 1571 if (Current->is(TT_JsFatArrow)) 1572 return prec::Assignment; 1573 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) || 1574 (Current->is(tok::comment) && NextNonComment && 1575 NextNonComment->is(TT_SelectorName))) 1576 return 0; 1577 if (Current->is(TT_RangeBasedForLoopColon)) 1578 return prec::Comma; 1579 if ((Style.Language == FormatStyle::LK_Java || 1580 Style.Language == FormatStyle::LK_JavaScript) && 1581 Current->is(Keywords.kw_instanceof)) 1582 return prec::Relational; 1583 if (Style.Language == FormatStyle::LK_JavaScript && 1584 Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) 1585 return prec::Relational; 1586 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma)) 1587 return Current->getPrecedence(); 1588 if (Current->isOneOf(tok::period, tok::arrow)) 1589 return PrecedenceArrowAndPeriod; 1590 if ((Style.Language == FormatStyle::LK_Java || 1591 Style.Language == FormatStyle::LK_JavaScript) && 1592 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements, 1593 Keywords.kw_throws)) 1594 return 0; 1595 } 1596 return -1; 1597 } 1598 1599 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) { 1600 Start->FakeLParens.push_back(Precedence); 1601 if (Precedence > prec::Unknown) 1602 Start->StartsBinaryExpression = true; 1603 if (Current) { 1604 FormatToken *Previous = Current->Previous; 1605 while (Previous->is(tok::comment) && Previous->Previous) 1606 Previous = Previous->Previous; 1607 ++Previous->FakeRParens; 1608 if (Precedence > prec::Unknown) 1609 Previous->EndsBinaryExpression = true; 1610 } 1611 } 1612 1613 /// \brief Parse unary operator expressions and surround them with fake 1614 /// parentheses if appropriate. 1615 void parseUnaryOperator() { 1616 if (!Current || Current->isNot(TT_UnaryOperator)) { 1617 parse(PrecedenceArrowAndPeriod); 1618 return; 1619 } 1620 1621 FormatToken *Start = Current; 1622 next(); 1623 parseUnaryOperator(); 1624 1625 // The actual precedence doesn't matter. 1626 addFakeParenthesis(Start, prec::Unknown); 1627 } 1628 1629 void parseConditionalExpr() { 1630 while (Current && Current->isTrailingComment()) { 1631 next(); 1632 } 1633 FormatToken *Start = Current; 1634 parse(prec::LogicalOr); 1635 if (!Current || !Current->is(tok::question)) 1636 return; 1637 next(); 1638 parse(prec::Assignment); 1639 if (!Current || Current->isNot(TT_ConditionalExpr)) 1640 return; 1641 next(); 1642 parse(prec::Assignment); 1643 addFakeParenthesis(Start, prec::Conditional); 1644 } 1645 1646 void next(bool SkipPastLeadingComments = true) { 1647 if (Current) 1648 Current = Current->Next; 1649 while (Current && 1650 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) && 1651 Current->isTrailingComment()) 1652 Current = Current->Next; 1653 } 1654 1655 const FormatStyle &Style; 1656 const AdditionalKeywords &Keywords; 1657 FormatToken *Current; 1658 }; 1659 1660 } // end anonymous namespace 1661 1662 void TokenAnnotator::setCommentLineLevels( 1663 SmallVectorImpl<AnnotatedLine *> &Lines) { 1664 const AnnotatedLine *NextNonCommentLine = nullptr; 1665 for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(), 1666 E = Lines.rend(); 1667 I != E; ++I) { 1668 bool CommentLine = (*I)->First; 1669 for (const FormatToken *Tok = (*I)->First; Tok; Tok = Tok->Next) { 1670 if (!Tok->is(tok::comment)) { 1671 CommentLine = false; 1672 break; 1673 } 1674 } 1675 if (NextNonCommentLine && CommentLine) 1676 (*I)->Level = NextNonCommentLine->Level; 1677 else 1678 NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr; 1679 1680 setCommentLineLevels((*I)->Children); 1681 } 1682 } 1683 1684 static unsigned maxNestingDepth(const AnnotatedLine &Line) { 1685 unsigned Result = 0; 1686 for (const auto* Tok = Line.First; Tok != nullptr; Tok = Tok->Next) 1687 Result = std::max(Result, Tok->NestingLevel); 1688 return Result; 1689 } 1690 1691 void TokenAnnotator::annotate(AnnotatedLine &Line) { 1692 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), 1693 E = Line.Children.end(); 1694 I != E; ++I) { 1695 annotate(**I); 1696 } 1697 AnnotatingParser Parser(Style, Line, Keywords); 1698 Line.Type = Parser.parseLine(); 1699 1700 // With very deep nesting, ExpressionParser uses lots of stack and the 1701 // formatting algorithm is very slow. We're not going to do a good job here 1702 // anyway - it's probably generated code being formatted by mistake. 1703 // Just skip the whole line. 1704 if (maxNestingDepth(Line) > 50) 1705 Line.Type = LT_Invalid; 1706 1707 if (Line.Type == LT_Invalid) 1708 return; 1709 1710 ExpressionParser ExprParser(Style, Keywords, Line); 1711 ExprParser.parse(); 1712 1713 if (Line.startsWith(TT_ObjCMethodSpecifier)) 1714 Line.Type = LT_ObjCMethodDecl; 1715 else if (Line.startsWith(TT_ObjCDecl)) 1716 Line.Type = LT_ObjCDecl; 1717 else if (Line.startsWith(TT_ObjCProperty)) 1718 Line.Type = LT_ObjCProperty; 1719 1720 Line.First->SpacesRequiredBefore = 1; 1721 Line.First->CanBreakBefore = Line.First->MustBreakBefore; 1722 } 1723 1724 // This function heuristically determines whether 'Current' starts the name of a 1725 // function declaration. 1726 static bool isFunctionDeclarationName(const FormatToken &Current, 1727 const AnnotatedLine &Line) { 1728 auto skipOperatorName = [](const FormatToken* Next) -> const FormatToken* { 1729 for (; Next; Next = Next->Next) { 1730 if (Next->is(TT_OverloadedOperatorLParen)) 1731 return Next; 1732 if (Next->is(TT_OverloadedOperator)) 1733 continue; 1734 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) { 1735 // For 'new[]' and 'delete[]'. 1736 if (Next->Next && Next->Next->is(tok::l_square) && 1737 Next->Next->Next && Next->Next->Next->is(tok::r_square)) 1738 Next = Next->Next->Next; 1739 continue; 1740 } 1741 1742 break; 1743 } 1744 return nullptr; 1745 }; 1746 1747 // Find parentheses of parameter list. 1748 const FormatToken *Next = Current.Next; 1749 if (Current.is(tok::kw_operator)) { 1750 if (Current.Previous && Current.Previous->is(tok::coloncolon)) 1751 return false; 1752 Next = skipOperatorName(Next); 1753 } else { 1754 if (!Current.is(TT_StartOfName) || Current.NestingLevel != 0) 1755 return false; 1756 for (; Next; Next = Next->Next) { 1757 if (Next->is(TT_TemplateOpener)) { 1758 Next = Next->MatchingParen; 1759 } else if (Next->is(tok::coloncolon)) { 1760 Next = Next->Next; 1761 if (!Next) 1762 return false; 1763 if (Next->is(tok::kw_operator)) { 1764 Next = skipOperatorName(Next->Next); 1765 break; 1766 } 1767 if (!Next->is(tok::identifier)) 1768 return false; 1769 } else if (Next->is(tok::l_paren)) { 1770 break; 1771 } else { 1772 return false; 1773 } 1774 } 1775 } 1776 1777 // Check whether parameter list can belong to a function declaration. 1778 if (!Next || !Next->is(tok::l_paren) || !Next->MatchingParen) 1779 return false; 1780 // If the lines ends with "{", this is likely an function definition. 1781 if (Line.Last->is(tok::l_brace)) 1782 return true; 1783 if (Next->Next == Next->MatchingParen) 1784 return true; // Empty parentheses. 1785 // If there is an &/&& after the r_paren, this is likely a function. 1786 if (Next->MatchingParen->Next && 1787 Next->MatchingParen->Next->is(TT_PointerOrReference)) 1788 return true; 1789 for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen; 1790 Tok = Tok->Next) { 1791 if (Tok->is(tok::l_paren) && Tok->MatchingParen) { 1792 Tok = Tok->MatchingParen; 1793 continue; 1794 } 1795 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() || 1796 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) 1797 return true; 1798 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) || 1799 Tok->Tok.isLiteral()) 1800 return false; 1801 } 1802 return false; 1803 } 1804 1805 bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const { 1806 assert(Line.MightBeFunctionDecl); 1807 1808 if ((Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_TopLevel || 1809 Style.AlwaysBreakAfterReturnType == 1810 FormatStyle::RTBS_TopLevelDefinitions) && 1811 Line.Level > 0) 1812 return false; 1813 1814 switch (Style.AlwaysBreakAfterReturnType) { 1815 case FormatStyle::RTBS_None: 1816 return false; 1817 case FormatStyle::RTBS_All: 1818 case FormatStyle::RTBS_TopLevel: 1819 return true; 1820 case FormatStyle::RTBS_AllDefinitions: 1821 case FormatStyle::RTBS_TopLevelDefinitions: 1822 return Line.mightBeFunctionDefinition(); 1823 } 1824 1825 return false; 1826 } 1827 1828 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 1829 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), 1830 E = Line.Children.end(); 1831 I != E; ++I) { 1832 calculateFormattingInformation(**I); 1833 } 1834 1835 Line.First->TotalLength = 1836 Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth; 1837 FormatToken *Current = Line.First->Next; 1838 bool InFunctionDecl = Line.MightBeFunctionDecl; 1839 while (Current) { 1840 if (isFunctionDeclarationName(*Current, Line)) 1841 Current->Type = TT_FunctionDeclarationName; 1842 if (Current->is(TT_LineComment)) { 1843 if (Current->Previous->BlockKind == BK_BracedInit && 1844 Current->Previous->opensScope()) 1845 Current->SpacesRequiredBefore = Style.Cpp11BracedListStyle ? 0 : 1; 1846 else 1847 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 1848 1849 // If we find a trailing comment, iterate backwards to determine whether 1850 // it seems to relate to a specific parameter. If so, break before that 1851 // parameter to avoid changing the comment's meaning. E.g. don't move 'b' 1852 // to the previous line in: 1853 // SomeFunction(a, 1854 // b, // comment 1855 // c); 1856 if (!Current->HasUnescapedNewline) { 1857 for (FormatToken *Parameter = Current->Previous; Parameter; 1858 Parameter = Parameter->Previous) { 1859 if (Parameter->isOneOf(tok::comment, tok::r_brace)) 1860 break; 1861 if (Parameter->Previous && Parameter->Previous->is(tok::comma)) { 1862 if (!Parameter->Previous->is(TT_CtorInitializerComma) && 1863 Parameter->HasUnescapedNewline) 1864 Parameter->MustBreakBefore = true; 1865 break; 1866 } 1867 } 1868 } 1869 } else if (Current->SpacesRequiredBefore == 0 && 1870 spaceRequiredBefore(Line, *Current)) { 1871 Current->SpacesRequiredBefore = 1; 1872 } 1873 1874 Current->MustBreakBefore = 1875 Current->MustBreakBefore || mustBreakBefore(Line, *Current); 1876 1877 if (!Current->MustBreakBefore && InFunctionDecl && 1878 Current->is(TT_FunctionDeclarationName)) 1879 Current->MustBreakBefore = mustBreakForReturnType(Line); 1880 1881 Current->CanBreakBefore = 1882 Current->MustBreakBefore || canBreakBefore(Line, *Current); 1883 unsigned ChildSize = 0; 1884 if (Current->Previous->Children.size() == 1) { 1885 FormatToken &LastOfChild = *Current->Previous->Children[0]->Last; 1886 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit 1887 : LastOfChild.TotalLength + 1; 1888 } 1889 const FormatToken *Prev = Current->Previous; 1890 if (Current->MustBreakBefore || Prev->Children.size() > 1 || 1891 (Prev->Children.size() == 1 && 1892 Prev->Children[0]->First->MustBreakBefore) || 1893 Current->IsMultiline) 1894 Current->TotalLength = Prev->TotalLength + Style.ColumnLimit; 1895 else 1896 Current->TotalLength = Prev->TotalLength + Current->ColumnWidth + 1897 ChildSize + Current->SpacesRequiredBefore; 1898 1899 if (Current->is(TT_CtorInitializerColon)) 1900 InFunctionDecl = false; 1901 1902 // FIXME: Only calculate this if CanBreakBefore is true once static 1903 // initializers etc. are sorted out. 1904 // FIXME: Move magic numbers to a better place. 1905 Current->SplitPenalty = 20 * Current->BindingStrength + 1906 splitPenalty(Line, *Current, InFunctionDecl); 1907 1908 Current = Current->Next; 1909 } 1910 1911 calculateUnbreakableTailLengths(Line); 1912 unsigned IndentLevel = Line.Level; 1913 for (Current = Line.First; Current != nullptr; Current = Current->Next) { 1914 if (Current->Role) 1915 Current->Role->precomputeFormattingInfos(Current); 1916 if (Current->MatchingParen && 1917 Current->MatchingParen->opensBlockOrBlockTypeList(Style)) { 1918 assert(IndentLevel > 0); 1919 --IndentLevel; 1920 } 1921 Current->IndentLevel = IndentLevel; 1922 if (Current->opensBlockOrBlockTypeList(Style)) 1923 ++IndentLevel; 1924 } 1925 1926 DEBUG({ printDebugInfo(Line); }); 1927 } 1928 1929 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { 1930 unsigned UnbreakableTailLength = 0; 1931 FormatToken *Current = Line.Last; 1932 while (Current) { 1933 Current->UnbreakableTailLength = UnbreakableTailLength; 1934 if (Current->CanBreakBefore || 1935 Current->isOneOf(tok::comment, tok::string_literal)) { 1936 UnbreakableTailLength = 0; 1937 } else { 1938 UnbreakableTailLength += 1939 Current->ColumnWidth + Current->SpacesRequiredBefore; 1940 } 1941 Current = Current->Previous; 1942 } 1943 } 1944 1945 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 1946 const FormatToken &Tok, 1947 bool InFunctionDecl) { 1948 const FormatToken &Left = *Tok.Previous; 1949 const FormatToken &Right = Tok; 1950 1951 if (Left.is(tok::semi)) 1952 return 0; 1953 1954 if (Style.Language == FormatStyle::LK_Java) { 1955 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws)) 1956 return 1; 1957 if (Right.is(Keywords.kw_implements)) 1958 return 2; 1959 if (Left.is(tok::comma) && Left.NestingLevel == 0) 1960 return 3; 1961 } else if (Style.Language == FormatStyle::LK_JavaScript) { 1962 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma)) 1963 return 100; 1964 if (Left.is(TT_JsTypeColon)) 1965 return 35; 1966 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) || 1967 (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) 1968 return 100; 1969 } 1970 1971 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral)) 1972 return 1; 1973 if (Right.is(tok::l_square)) { 1974 if (Style.Language == FormatStyle::LK_Proto) 1975 return 1; 1976 if (Left.is(tok::r_square)) 1977 return 200; 1978 // Slightly prefer formatting local lambda definitions like functions. 1979 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal)) 1980 return 35; 1981 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare, 1982 TT_ArrayInitializerLSquare, 1983 TT_DesignatedInitializerLSquare)) 1984 return 500; 1985 } 1986 1987 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) || 1988 Right.is(tok::kw_operator)) { 1989 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) 1990 return 3; 1991 if (Left.is(TT_StartOfName)) 1992 return 110; 1993 if (InFunctionDecl && Right.NestingLevel == 0) 1994 return Style.PenaltyReturnTypeOnItsOwnLine; 1995 return 200; 1996 } 1997 if (Right.is(TT_PointerOrReference)) 1998 return 190; 1999 if (Right.is(TT_LambdaArrow)) 2000 return 110; 2001 if (Left.is(tok::equal) && Right.is(tok::l_brace)) 2002 return 160; 2003 if (Left.is(TT_CastRParen)) 2004 return 100; 2005 if (Left.is(tok::coloncolon) || 2006 (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto)) 2007 return 500; 2008 if (Left.isOneOf(tok::kw_class, tok::kw_struct)) 2009 return 5000; 2010 if (Left.is(tok::comment)) 2011 return 1000; 2012 2013 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon, TT_CtorInitializerColon)) 2014 return 2; 2015 2016 if (Right.isMemberAccess()) { 2017 // Breaking before the "./->" of a chained call/member access is reasonably 2018 // cheap, as formatting those with one call per line is generally 2019 // desirable. In particular, it should be cheaper to break before the call 2020 // than it is to break inside a call's parameters, which could lead to weird 2021 // "hanging" indents. The exception is the very last "./->" to support this 2022 // frequent pattern: 2023 // 2024 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc( 2025 // dddddddd); 2026 // 2027 // which might otherwise be blown up onto many lines. Here, clang-format 2028 // won't produce "hanging" indents anyway as there is no other trailing 2029 // call. 2030 // 2031 // Also apply higher penalty is not a call as that might lead to a wrapping 2032 // like: 2033 // 2034 // aaaaaaa 2035 // .aaaaaaaaa.bbbbbbbb(cccccccc); 2036 return !Right.NextOperator || !Right.NextOperator->Previous->closesScope() 2037 ? 150 2038 : 35; 2039 } 2040 2041 if (Right.is(TT_TrailingAnnotation) && 2042 (!Right.Next || Right.Next->isNot(tok::l_paren))) { 2043 // Moving trailing annotations to the next line is fine for ObjC method 2044 // declarations. 2045 if (Line.startsWith(TT_ObjCMethodSpecifier)) 2046 return 10; 2047 // Generally, breaking before a trailing annotation is bad unless it is 2048 // function-like. It seems to be especially preferable to keep standard 2049 // annotations (i.e. "const", "final" and "override") on the same line. 2050 // Use a slightly higher penalty after ")" so that annotations like 2051 // "const override" are kept together. 2052 bool is_short_annotation = Right.TokenText.size() < 10; 2053 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0); 2054 } 2055 2056 // In for-loops, prefer breaking at ',' and ';'. 2057 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal)) 2058 return 4; 2059 2060 // In Objective-C method expressions, prefer breaking before "param:" over 2061 // breaking after it. 2062 if (Right.is(TT_SelectorName)) 2063 return 0; 2064 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr)) 2065 return Line.MightBeFunctionDecl ? 50 : 500; 2066 2067 if (Left.is(tok::l_paren) && InFunctionDecl && 2068 Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) 2069 return 100; 2070 if (Left.is(tok::l_paren) && Left.Previous && 2071 (Left.Previous->isOneOf(tok::kw_if, tok::kw_for) 2072 || Left.Previous->endsSequence(tok::kw_constexpr, tok::kw_if))) 2073 return 1000; 2074 if (Left.is(tok::equal) && InFunctionDecl) 2075 return 110; 2076 if (Right.is(tok::r_brace)) 2077 return 1; 2078 if (Left.is(TT_TemplateOpener)) 2079 return 100; 2080 if (Left.opensScope()) { 2081 if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign) 2082 return 0; 2083 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter 2084 : 19; 2085 } 2086 if (Left.is(TT_JavaAnnotation)) 2087 return 50; 2088 2089 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous && 2090 Left.Previous->isLabelString() && 2091 (Left.NextOperator || Left.OperatorIndex != 0)) 2092 return 45; 2093 if (Right.is(tok::plus) && Left.isLabelString() && 2094 (Right.NextOperator || Right.OperatorIndex != 0)) 2095 return 25; 2096 if (Left.is(tok::comma)) 2097 return 1; 2098 if (Right.is(tok::lessless) && Left.isLabelString() && 2099 (Right.NextOperator || Right.OperatorIndex != 1)) 2100 return 25; 2101 if (Right.is(tok::lessless)) { 2102 // Breaking at a << is really cheap. 2103 if (!Left.is(tok::r_paren) || Right.OperatorIndex > 0) 2104 // Slightly prefer to break before the first one in log-like statements. 2105 return 2; 2106 return 1; 2107 } 2108 if (Left.is(TT_ConditionalExpr)) 2109 return prec::Conditional; 2110 prec::Level Level = Left.getPrecedence(); 2111 if (Level == prec::Unknown) 2112 Level = Right.getPrecedence(); 2113 if (Level == prec::Assignment) 2114 return Style.PenaltyBreakAssignment; 2115 if (Level != prec::Unknown) 2116 return Level; 2117 2118 return 3; 2119 } 2120 2121 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 2122 const FormatToken &Left, 2123 const FormatToken &Right) { 2124 if (Left.is(tok::kw_return) && Right.isNot(tok::semi)) 2125 return true; 2126 if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty && 2127 Left.Tok.getObjCKeywordID() == tok::objc_property) 2128 return true; 2129 if (Right.is(tok::hashhash)) 2130 return Left.is(tok::hash); 2131 if (Left.isOneOf(tok::hashhash, tok::hash)) 2132 return Right.is(tok::hash); 2133 if (Left.is(tok::l_paren) && Right.is(tok::r_paren)) 2134 return Style.SpaceInEmptyParentheses; 2135 if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) 2136 return (Right.is(TT_CastRParen) || 2137 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) 2138 ? Style.SpacesInCStyleCastParentheses 2139 : Style.SpacesInParentheses; 2140 if (Right.isOneOf(tok::semi, tok::comma)) 2141 return false; 2142 if (Right.is(tok::less) && 2143 Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList) 2144 return true; 2145 if (Right.is(tok::less) && Left.is(tok::kw_template)) 2146 return Style.SpaceAfterTemplateKeyword; 2147 if (Left.isOneOf(tok::exclaim, tok::tilde)) 2148 return false; 2149 if (Left.is(tok::at) && 2150 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant, 2151 tok::numeric_constant, tok::l_paren, tok::l_brace, 2152 tok::kw_true, tok::kw_false)) 2153 return false; 2154 if (Left.is(tok::colon)) 2155 return !Left.is(TT_ObjCMethodExpr); 2156 if (Left.is(tok::coloncolon)) 2157 return false; 2158 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) 2159 return false; 2160 if (Right.is(tok::ellipsis)) 2161 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous && 2162 Left.Previous->is(tok::kw_case)); 2163 if (Left.is(tok::l_square) && Right.is(tok::amp)) 2164 return false; 2165 if (Right.is(TT_PointerOrReference)) 2166 return (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) || 2167 (Left.Tok.isLiteral() || (Left.is(tok::kw_const) && Left.Previous && 2168 Left.Previous->is(tok::r_paren)) || 2169 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) && 2170 (Style.PointerAlignment != FormatStyle::PAS_Left || 2171 (Line.IsMultiVariableDeclStmt && 2172 (Left.NestingLevel == 0 || 2173 (Left.NestingLevel == 1 && Line.First->is(tok::kw_for))))))); 2174 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) && 2175 (!Left.is(TT_PointerOrReference) || 2176 (Style.PointerAlignment != FormatStyle::PAS_Right && 2177 !Line.IsMultiVariableDeclStmt))) 2178 return true; 2179 if (Left.is(TT_PointerOrReference)) 2180 return Right.Tok.isLiteral() || Right.is(TT_BlockComment) || 2181 (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) && 2182 !Right.is(TT_StartOfName)) || 2183 (Right.is(tok::l_brace) && Right.BlockKind == BK_Block) || 2184 (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare, 2185 tok::l_paren) && 2186 (Style.PointerAlignment != FormatStyle::PAS_Right && 2187 !Line.IsMultiVariableDeclStmt) && 2188 Left.Previous && 2189 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); 2190 if (Right.is(tok::star) && Left.is(tok::l_paren)) 2191 return false; 2192 if (Left.is(tok::l_square)) 2193 return (Left.is(TT_ArrayInitializerLSquare) && 2194 Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) || 2195 (Left.is(TT_ArraySubscriptLSquare) && Style.SpacesInSquareBrackets && 2196 Right.isNot(tok::r_square)); 2197 if (Right.is(tok::r_square)) 2198 return Right.MatchingParen && 2199 ((Style.SpacesInContainerLiterals && 2200 Right.MatchingParen->is(TT_ArrayInitializerLSquare)) || 2201 (Style.SpacesInSquareBrackets && 2202 Right.MatchingParen->is(TT_ArraySubscriptLSquare))); 2203 if (Right.is(tok::l_square) && 2204 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare, 2205 TT_DesignatedInitializerLSquare) && 2206 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral)) 2207 return false; 2208 if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 2209 return !Left.Children.empty(); // No spaces in "{}". 2210 if ((Left.is(tok::l_brace) && Left.BlockKind != BK_Block) || 2211 (Right.is(tok::r_brace) && Right.MatchingParen && 2212 Right.MatchingParen->BlockKind != BK_Block)) 2213 return !Style.Cpp11BracedListStyle; 2214 if (Left.is(TT_BlockComment)) 2215 return !Left.TokenText.endswith("=*/"); 2216 if (Right.is(tok::l_paren)) { 2217 if (Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) 2218 return true; 2219 return Line.Type == LT_ObjCDecl || Left.is(tok::semi) || 2220 (Style.SpaceBeforeParens != FormatStyle::SBPO_Never && 2221 (Left.isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while, 2222 tok::kw_switch, tok::kw_case, TT_ForEachMacro, 2223 TT_ObjCForIn) || 2224 Left.endsSequence(tok::kw_constexpr, tok::kw_if) || 2225 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch, 2226 tok::kw_new, tok::kw_delete) && 2227 (!Left.Previous || Left.Previous->isNot(tok::period))))) || 2228 (Style.SpaceBeforeParens == FormatStyle::SBPO_Always && 2229 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() || 2230 Left.is(tok::r_paren)) && 2231 Line.Type != LT_PreprocessorDirective); 2232 } 2233 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword) 2234 return false; 2235 if (Right.is(TT_UnaryOperator)) 2236 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) && 2237 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr)); 2238 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square, 2239 tok::r_paren) || 2240 Left.isSimpleTypeSpecifier()) && 2241 Right.is(tok::l_brace) && Right.getNextNonComment() && 2242 Right.BlockKind != BK_Block) 2243 return false; 2244 if (Left.is(tok::period) || Right.is(tok::period)) 2245 return false; 2246 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L") 2247 return false; 2248 if (Left.is(TT_TemplateCloser) && Left.MatchingParen && 2249 Left.MatchingParen->Previous && 2250 Left.MatchingParen->Previous->is(tok::period)) 2251 // A.<B>DoSomething(); 2252 return false; 2253 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square)) 2254 return false; 2255 return true; 2256 } 2257 2258 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 2259 const FormatToken &Right) { 2260 const FormatToken &Left = *Right.Previous; 2261 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo()) 2262 return true; // Never ever merge two identifiers. 2263 if (Style.isCpp()) { 2264 if (Left.is(tok::kw_operator)) 2265 return Right.is(tok::coloncolon); 2266 } else if (Style.Language == FormatStyle::LK_Proto) { 2267 if (Right.is(tok::period) && 2268 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required, 2269 Keywords.kw_repeated, Keywords.kw_extend)) 2270 return true; 2271 if (Right.is(tok::l_paren) && 2272 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) 2273 return true; 2274 } else if (Style.Language == FormatStyle::LK_JavaScript) { 2275 if (Left.is(TT_JsFatArrow)) 2276 return true; 2277 // for await ( ... 2278 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && 2279 Left.Previous && Left.Previous->is(tok::kw_for)) 2280 return true; 2281 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) && 2282 Right.MatchingParen) { 2283 const FormatToken *Next = Right.MatchingParen->getNextNonComment(); 2284 // An async arrow function, for example: `x = async () => foo();`, 2285 // as opposed to calling a function called async: `x = async();` 2286 if (Next && Next->is(TT_JsFatArrow)) 2287 return true; 2288 } 2289 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) || 2290 (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) 2291 return false; 2292 if (Left.is(tok::identifier) && Right.is(TT_TemplateString)) 2293 return false; 2294 if (Right.is(tok::star) && 2295 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) 2296 return false; 2297 if (Right.isOneOf(tok::l_brace, tok::l_square) && 2298 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) 2299 return true; 2300 // JS methods can use some keywords as names (e.g. `delete()`). 2301 if (Right.is(tok::l_paren) && Line.MustBeDeclaration && 2302 Left.Tok.getIdentifierInfo()) 2303 return false; 2304 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, 2305 tok::kw_const) || 2306 // "of" is only a keyword if it appears after another identifier 2307 // (e.g. as "const x of y" in a for loop). 2308 (Left.is(Keywords.kw_of) && Left.Previous && 2309 Left.Previous->Tok.getIdentifierInfo())) && 2310 (!Left.Previous || !Left.Previous->is(tok::period))) 2311 return true; 2312 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous && 2313 Left.Previous->is(tok::period) && Right.is(tok::l_paren)) 2314 return false; 2315 if (Left.is(Keywords.kw_as) && 2316 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) 2317 return true; 2318 if (Left.is(tok::kw_default) && Left.Previous && 2319 Left.Previous->is(tok::kw_export)) 2320 return true; 2321 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace)) 2322 return true; 2323 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion)) 2324 return false; 2325 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator)) 2326 return false; 2327 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) && 2328 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) 2329 return false; 2330 if (Left.is(tok::ellipsis)) 2331 return false; 2332 if (Left.is(TT_TemplateCloser) && 2333 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square, 2334 Keywords.kw_implements, Keywords.kw_extends)) 2335 // Type assertions ('<type>expr') are not followed by whitespace. Other 2336 // locations that should have whitespace following are identified by the 2337 // above set of follower tokens. 2338 return false; 2339 if (Right.is(TT_JsNonNullAssertion)) 2340 return false; 2341 if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as)) 2342 return true; // "x! as string" 2343 } else if (Style.Language == FormatStyle::LK_Java) { 2344 if (Left.is(tok::r_square) && Right.is(tok::l_brace)) 2345 return true; 2346 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) 2347 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never; 2348 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private, 2349 tok::kw_protected) || 2350 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract, 2351 Keywords.kw_native)) && 2352 Right.is(TT_TemplateOpener)) 2353 return true; 2354 } 2355 if (Left.is(TT_ImplicitStringLiteral)) 2356 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd(); 2357 if (Line.Type == LT_ObjCMethodDecl) { 2358 if (Left.is(TT_ObjCMethodSpecifier)) 2359 return true; 2360 if (Left.is(tok::r_paren) && Right.is(tok::identifier)) 2361 // Don't space between ')' and <id> 2362 return false; 2363 } 2364 if (Line.Type == LT_ObjCProperty && 2365 (Right.is(tok::equal) || Left.is(tok::equal))) 2366 return false; 2367 2368 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) || 2369 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) 2370 return true; 2371 if (Right.is(TT_OverloadedOperatorLParen)) 2372 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always; 2373 if (Left.is(tok::comma)) 2374 return true; 2375 if (Right.is(tok::comma)) 2376 return false; 2377 if (Right.isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen)) 2378 return true; 2379 if (Right.is(tok::colon)) { 2380 if (Line.First->isOneOf(tok::kw_case, tok::kw_default) || 2381 !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi)) 2382 return false; 2383 if (Right.is(TT_ObjCMethodExpr)) 2384 return false; 2385 if (Left.is(tok::question)) 2386 return false; 2387 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon)) 2388 return false; 2389 if (Right.is(TT_DictLiteral)) 2390 return Style.SpacesInContainerLiterals; 2391 return true; 2392 } 2393 if (Left.is(TT_UnaryOperator)) 2394 return Right.is(TT_BinaryOperator); 2395 2396 // If the next token is a binary operator or a selector name, we have 2397 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly. 2398 if (Left.is(TT_CastRParen)) 2399 return Style.SpaceAfterCStyleCast || 2400 Right.isOneOf(TT_BinaryOperator, TT_SelectorName); 2401 2402 if (Left.is(tok::greater) && Right.is(tok::greater)) 2403 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) && 2404 (Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles); 2405 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) || 2406 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) || 2407 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) 2408 return false; 2409 if (!Style.SpaceBeforeAssignmentOperators && 2410 Right.getPrecedence() == prec::Assignment) 2411 return false; 2412 if (Right.is(tok::coloncolon) && Left.is(tok::identifier)) 2413 // Generally don't remove existing spaces between an identifier and "::". 2414 // The identifier might actually be a macro name such as ALWAYS_INLINE. If 2415 // this turns out to be too lenient, add analysis of the identifier itself. 2416 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd(); 2417 if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment)) 2418 return (Left.is(TT_TemplateOpener) && 2419 Style.Standard == FormatStyle::LS_Cpp03) || 2420 !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square, 2421 tok::kw___super, TT_TemplateCloser, TT_TemplateOpener)); 2422 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser))) 2423 return Style.SpacesInAngles; 2424 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) || 2425 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && 2426 !Right.is(tok::r_paren))) 2427 return true; 2428 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) && 2429 Right.isNot(TT_FunctionTypeLParen)) 2430 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always; 2431 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) && 2432 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen)) 2433 return false; 2434 if (Right.is(tok::less) && Left.isNot(tok::l_paren) && 2435 Line.startsWith(tok::hash)) 2436 return true; 2437 if (Right.is(TT_TrailingUnaryOperator)) 2438 return false; 2439 if (Left.is(TT_RegexLiteral)) 2440 return false; 2441 return spaceRequiredBetween(Line, Left, Right); 2442 } 2443 2444 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style. 2445 static bool isAllmanBrace(const FormatToken &Tok) { 2446 return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block && 2447 !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral); 2448 } 2449 2450 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, 2451 const FormatToken &Right) { 2452 const FormatToken &Left = *Right.Previous; 2453 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0) 2454 return true; 2455 2456 if (Style.Language == FormatStyle::LK_JavaScript) { 2457 // FIXME: This might apply to other languages and token kinds. 2458 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous && 2459 Left.Previous->is(tok::string_literal)) 2460 return true; 2461 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 && 2462 Left.Previous && Left.Previous->is(tok::equal) && 2463 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export, 2464 tok::kw_const) && 2465 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match 2466 // above. 2467 !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) 2468 // Object literals on the top level of a file are treated as "enum-style". 2469 // Each key/value pair is put on a separate line, instead of bin-packing. 2470 return true; 2471 if (Left.is(tok::l_brace) && Line.Level == 0 && 2472 (Line.startsWith(tok::kw_enum) || 2473 Line.startsWith(tok::kw_export, tok::kw_enum))) 2474 // JavaScript top-level enum key/value pairs are put on separate lines 2475 // instead of bin-packing. 2476 return true; 2477 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && 2478 !Left.Children.empty()) 2479 // Support AllowShortFunctionsOnASingleLine for JavaScript. 2480 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None || 2481 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty || 2482 (Left.NestingLevel == 0 && Line.Level == 0 && 2483 Style.AllowShortFunctionsOnASingleLine & 2484 FormatStyle::SFS_InlineOnly); 2485 } else if (Style.Language == FormatStyle::LK_Java) { 2486 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next && 2487 Right.Next->is(tok::string_literal)) 2488 return true; 2489 } else if (Style.Language == FormatStyle::LK_Cpp || 2490 Style.Language == FormatStyle::LK_ObjC || 2491 Style.Language == FormatStyle::LK_Proto) { 2492 if (Left.isStringLiteral() && Right.isStringLiteral()) 2493 return true; 2494 } 2495 2496 // If the last token before a '}', ']', or ')' is a comma or a trailing 2497 // comment, the intention is to insert a line break after it in order to make 2498 // shuffling around entries easier. Import statements, especially in 2499 // JavaScript, can be an exception to this rule. 2500 if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) { 2501 const FormatToken *BeforeClosingBrace = nullptr; 2502 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) || 2503 (Style.Language == FormatStyle::LK_JavaScript && 2504 Left.is(tok::l_paren))) && 2505 Left.BlockKind != BK_Block && Left.MatchingParen) 2506 BeforeClosingBrace = Left.MatchingParen->Previous; 2507 else if (Right.MatchingParen && 2508 (Right.MatchingParen->isOneOf(tok::l_brace, 2509 TT_ArrayInitializerLSquare) || 2510 (Style.Language == FormatStyle::LK_JavaScript && 2511 Right.MatchingParen->is(tok::l_paren)))) 2512 BeforeClosingBrace = &Left; 2513 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) || 2514 BeforeClosingBrace->isTrailingComment())) 2515 return true; 2516 } 2517 2518 if (Right.is(tok::comment)) 2519 return Left.BlockKind != BK_BracedInit && 2520 Left.isNot(TT_CtorInitializerColon) && 2521 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline); 2522 if (Left.isTrailingComment()) 2523 return true; 2524 if (Right.Previous->IsUnterminatedLiteral) 2525 return true; 2526 if (Right.is(tok::lessless) && Right.Next && 2527 Right.Previous->is(tok::string_literal) && 2528 Right.Next->is(tok::string_literal)) 2529 return true; 2530 if (Right.Previous->ClosesTemplateDeclaration && 2531 Right.Previous->MatchingParen && 2532 Right.Previous->MatchingParen->NestingLevel == 0 && 2533 Style.AlwaysBreakTemplateDeclarations) 2534 return true; 2535 if (Right.is(TT_CtorInitializerComma) && 2536 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma && 2537 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) 2538 return true; 2539 if (Right.is(TT_CtorInitializerColon) && 2540 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma && 2541 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) 2542 return true; 2543 // Break only if we have multiple inheritance. 2544 if (Style.BreakBeforeInheritanceComma && 2545 Right.is(TT_InheritanceComma)) 2546 return true; 2547 if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\"")) 2548 // Raw string literals are special wrt. line breaks. The author has made a 2549 // deliberate choice and might have aligned the contents of the string 2550 // literal accordingly. Thus, we try keep existing line breaks. 2551 return Right.NewlinesBefore > 0; 2552 if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 && 2553 Style.Language == FormatStyle::LK_Proto) 2554 // Don't put enums onto single lines in protocol buffers. 2555 return true; 2556 if (Right.is(TT_InlineASMBrace)) 2557 return Right.HasUnescapedNewline; 2558 if (isAllmanBrace(Left) || isAllmanBrace(Right)) 2559 return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) || 2560 (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) || 2561 (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct); 2562 if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine) 2563 return true; 2564 2565 if ((Style.Language == FormatStyle::LK_Java || 2566 Style.Language == FormatStyle::LK_JavaScript) && 2567 Left.is(TT_LeadingJavaAnnotation) && 2568 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) && 2569 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) 2570 return true; 2571 2572 return false; 2573 } 2574 2575 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 2576 const FormatToken &Right) { 2577 const FormatToken &Left = *Right.Previous; 2578 2579 // Language-specific stuff. 2580 if (Style.Language == FormatStyle::LK_Java) { 2581 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends, 2582 Keywords.kw_implements)) 2583 return false; 2584 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends, 2585 Keywords.kw_implements)) 2586 return true; 2587 } else if (Style.Language == FormatStyle::LK_JavaScript) { 2588 const FormatToken *NonComment = Right.getPreviousNonComment(); 2589 if (NonComment && 2590 NonComment->isOneOf( 2591 tok::kw_return, tok::kw_continue, tok::kw_break, tok::kw_throw, 2592 Keywords.kw_interface, Keywords.kw_type, tok::kw_static, 2593 tok::kw_public, tok::kw_private, tok::kw_protected, 2594 Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set)) 2595 return false; // Otherwise automatic semicolon insertion would trigger. 2596 if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace)) 2597 return false; 2598 if (Left.is(TT_JsTypeColon)) 2599 return true; 2600 if (Right.NestingLevel == 0 && Right.is(Keywords.kw_is)) 2601 return false; 2602 if (Left.is(Keywords.kw_in)) 2603 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None; 2604 if (Right.is(Keywords.kw_in)) 2605 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None; 2606 if (Right.is(Keywords.kw_as)) 2607 return false; // must not break before as in 'x as type' casts 2608 if (Left.is(Keywords.kw_as)) 2609 return true; 2610 if (Left.is(TT_JsNonNullAssertion)) 2611 return true; 2612 if (Left.is(Keywords.kw_declare) && 2613 Right.isOneOf(Keywords.kw_module, tok::kw_namespace, 2614 Keywords.kw_function, tok::kw_class, tok::kw_enum, 2615 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var, 2616 Keywords.kw_let, tok::kw_const)) 2617 // See grammar for 'declare' statements at: 2618 // https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10 2619 return false; 2620 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) && 2621 Right.isOneOf(tok::identifier, tok::string_literal)) 2622 return false; // must not break in "module foo { ...}" 2623 if (Right.is(TT_TemplateString) && Right.closesScope()) 2624 return false; 2625 if (Left.is(TT_TemplateString) && Left.opensScope()) 2626 return true; 2627 } 2628 2629 if (Left.is(tok::at)) 2630 return false; 2631 if (Left.Tok.getObjCKeywordID() == tok::objc_interface) 2632 return false; 2633 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation)) 2634 return !Right.is(tok::l_paren); 2635 if (Right.is(TT_PointerOrReference)) 2636 return Line.IsMultiVariableDeclStmt || 2637 (Style.PointerAlignment == FormatStyle::PAS_Right && 2638 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName))); 2639 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) || 2640 Right.is(tok::kw_operator)) 2641 return true; 2642 if (Left.is(TT_PointerOrReference)) 2643 return false; 2644 if (Right.isTrailingComment()) 2645 // We rely on MustBreakBefore being set correctly here as we should not 2646 // change the "binding" behavior of a comment. 2647 // The first comment in a braced lists is always interpreted as belonging to 2648 // the first list element. Otherwise, it should be placed outside of the 2649 // list. 2650 return Left.BlockKind == BK_BracedInit || 2651 (Left.is(TT_CtorInitializerColon) && 2652 Style.BreakConstructorInitializers == 2653 FormatStyle::BCIS_AfterColon); 2654 if (Left.is(tok::question) && Right.is(tok::colon)) 2655 return false; 2656 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question)) 2657 return Style.BreakBeforeTernaryOperators; 2658 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question)) 2659 return !Style.BreakBeforeTernaryOperators; 2660 if (Right.is(TT_InheritanceColon)) 2661 return true; 2662 if (Right.is(TT_ObjCMethodExpr) && !Right.is(tok::r_square) && 2663 Left.isNot(TT_SelectorName)) 2664 return true; 2665 if (Right.is(tok::colon) && 2666 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) 2667 return false; 2668 if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) 2669 return true; 2670 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next && 2671 Right.Next->is(TT_ObjCMethodExpr))) 2672 return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls. 2673 if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty) 2674 return true; 2675 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen)) 2676 return true; 2677 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen, 2678 TT_OverloadedOperator)) 2679 return false; 2680 if (Left.is(TT_RangeBasedForLoopColon)) 2681 return true; 2682 if (Right.is(TT_RangeBasedForLoopColon)) 2683 return false; 2684 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener)) 2685 return true; 2686 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) || 2687 Left.is(tok::kw_operator)) 2688 return false; 2689 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) && 2690 Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0) 2691 return false; 2692 if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen)) 2693 return false; 2694 if (Left.is(tok::l_paren) && Left.Previous && 2695 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) 2696 return false; 2697 if (Right.is(TT_ImplicitStringLiteral)) 2698 return false; 2699 2700 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser)) 2701 return false; 2702 if (Right.is(tok::r_square) && Right.MatchingParen && 2703 Right.MatchingParen->is(TT_LambdaLSquare)) 2704 return false; 2705 2706 // We only break before r_brace if there was a corresponding break before 2707 // the l_brace, which is tracked by BreakBeforeClosingBrace. 2708 if (Right.is(tok::r_brace)) 2709 return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block; 2710 2711 // Allow breaking after a trailing annotation, e.g. after a method 2712 // declaration. 2713 if (Left.is(TT_TrailingAnnotation)) 2714 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren, 2715 tok::less, tok::coloncolon); 2716 2717 if (Right.is(tok::kw___attribute)) 2718 return true; 2719 2720 if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 2721 return true; 2722 2723 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral)) 2724 return true; 2725 2726 if (Left.is(TT_CtorInitializerColon)) 2727 return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon; 2728 if (Right.is(TT_CtorInitializerColon)) 2729 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon; 2730 if (Left.is(TT_CtorInitializerComma) && 2731 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) 2732 return false; 2733 if (Right.is(TT_CtorInitializerComma) && 2734 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) 2735 return true; 2736 if (Left.is(TT_InheritanceComma) && Style.BreakBeforeInheritanceComma) 2737 return false; 2738 if (Right.is(TT_InheritanceComma) && Style.BreakBeforeInheritanceComma) 2739 return true; 2740 if ((Left.is(tok::greater) && Right.is(tok::greater)) || 2741 (Left.is(tok::less) && Right.is(tok::less))) 2742 return false; 2743 if (Right.is(TT_BinaryOperator) && 2744 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None && 2745 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All || 2746 Right.getPrecedence() != prec::Assignment)) 2747 return true; 2748 if (Left.is(TT_ArrayInitializerLSquare)) 2749 return true; 2750 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const)) 2751 return true; 2752 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) && 2753 !Left.isOneOf(tok::arrowstar, tok::lessless) && 2754 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All && 2755 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None || 2756 Left.getPrecedence() == prec::Assignment)) 2757 return true; 2758 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, 2759 tok::kw_class, tok::kw_struct, tok::comment) || 2760 Right.isMemberAccess() || 2761 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless, 2762 tok::colon, tok::l_square, tok::at) || 2763 (Left.is(tok::r_paren) && 2764 Right.isOneOf(tok::identifier, tok::kw_const)) || 2765 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || 2766 (Left.is(TT_TemplateOpener) && !Right.is(TT_TemplateCloser)); 2767 } 2768 2769 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { 2770 llvm::errs() << "AnnotatedTokens:\n"; 2771 const FormatToken *Tok = Line.First; 2772 while (Tok) { 2773 llvm::errs() << " M=" << Tok->MustBreakBefore 2774 << " C=" << Tok->CanBreakBefore 2775 << " T=" << getTokenTypeName(Tok->Type) 2776 << " S=" << Tok->SpacesRequiredBefore 2777 << " B=" << Tok->BlockParameterCount 2778 << " BK=" << Tok->BlockKind 2779 << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() 2780 << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind 2781 << " FakeLParens="; 2782 for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) 2783 llvm::errs() << Tok->FakeLParens[i] << "/"; 2784 llvm::errs() << " FakeRParens=" << Tok->FakeRParens; 2785 llvm::errs() << " Text='" << Tok->TokenText << "'\n"; 2786 if (!Tok->Next) 2787 assert(Tok == Line.Last); 2788 Tok = Tok->Next; 2789 } 2790 llvm::errs() << "----\n"; 2791 } 2792 2793 } // namespace format 2794 } // namespace clang 2795