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