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) 46 return false; 47 FormatToken *Left = CurrentToken->Previous; 48 Left->ParentBracket = Contexts.back().ContextKind; 49 ScopedContextCreator ContextCreator(*this, tok::less, 10); 50 51 // If this angle is in the context of an expression, we need to be more 52 // hesitant to detect it as opening template parameters. 53 bool InExprContext = Contexts.back().IsExpression; 54 55 Contexts.back().IsExpression = false; 56 // If there's a template keyword before the opening angle bracket, this is a 57 // template parameter, not an argument. 58 Contexts.back().InTemplateArgument = 59 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template); 60 61 if (Style.Language == FormatStyle::LK_Java && 62 CurrentToken->is(tok::question)) 63 next(); 64 65 while (CurrentToken) { 66 if (CurrentToken->is(tok::greater)) { 67 Left->MatchingParen = CurrentToken; 68 CurrentToken->MatchingParen = Left; 69 CurrentToken->Type = TT_TemplateCloser; 70 next(); 71 return true; 72 } 73 if (CurrentToken->is(tok::question) && 74 Style.Language == FormatStyle::LK_Java) { 75 next(); 76 continue; 77 } 78 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) || 79 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext)) 80 return false; 81 // If a && or || is found and interpreted as a binary operator, this set 82 // of angles is likely part of something like "a < b && c > d". If the 83 // angles are inside an expression, the ||/&& might also be a binary 84 // operator that was misinterpreted because we are parsing template 85 // parameters. 86 // FIXME: This is getting out of hand, write a decent parser. 87 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) && 88 CurrentToken->Previous->is(TT_BinaryOperator) && 89 Contexts[Contexts.size() - 2].IsExpression && 90 Line.First->isNot(tok::kw_template)) 91 return false; 92 updateParameterCount(Left, CurrentToken); 93 if (!consumeToken()) 94 return false; 95 } 96 return false; 97 } 98 99 bool parseParens(bool LookForDecls = false) { 100 if (!CurrentToken) 101 return false; 102 FormatToken *Left = CurrentToken->Previous; 103 Left->ParentBracket = Contexts.back().ContextKind; 104 ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); 105 106 // FIXME: This is a bit of a hack. Do better. 107 Contexts.back().ColonIsForRangeExpr = 108 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 109 110 bool StartsObjCMethodExpr = false; 111 if (CurrentToken->is(tok::caret)) { 112 // (^ can start a block type. 113 Left->Type = TT_ObjCBlockLParen; 114 } else if (FormatToken *MaybeSel = Left->Previous) { 115 // @selector( starts a selector. 116 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous && 117 MaybeSel->Previous->is(tok::at)) { 118 StartsObjCMethodExpr = true; 119 } 120 } 121 122 if (Left->Previous && 123 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_if, 124 tok::kw_while, tok::l_paren, tok::comma) || 125 Left->Previous->is(TT_BinaryOperator))) { 126 // static_assert, if and while usually contain expressions. 127 Contexts.back().IsExpression = true; 128 } else if (Left->Previous && Left->Previous->is(tok::r_square) && 129 Left->Previous->MatchingParen && 130 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) { 131 // This is a parameter list of a lambda expression. 132 Contexts.back().IsExpression = false; 133 } else if (Line.InPPDirective && 134 (!Left->Previous || 135 !Left->Previous->isOneOf(tok::identifier, 136 TT_OverloadedOperator))) { 137 Contexts.back().IsExpression = true; 138 } else if (Contexts[Contexts.size() - 2].CaretFound) { 139 // This is the parameter list of an ObjC block. 140 Contexts.back().IsExpression = false; 141 } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) { 142 Left->Type = TT_AttributeParen; 143 } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) { 144 // The first argument to a foreach macro is a declaration. 145 Contexts.back().IsForEachMacro = true; 146 Contexts.back().IsExpression = false; 147 } else if (Left->Previous && Left->Previous->MatchingParen && 148 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) { 149 Contexts.back().IsExpression = false; 150 } 151 152 if (StartsObjCMethodExpr) { 153 Contexts.back().ColonIsObjCMethodExpr = true; 154 Left->Type = TT_ObjCMethodExpr; 155 } 156 157 bool MightBeFunctionType = CurrentToken->is(tok::star); 158 bool HasMultipleLines = false; 159 bool HasMultipleParametersOnALine = false; 160 bool MightBeObjCForRangeLoop = 161 Left->Previous && Left->Previous->is(tok::kw_for); 162 while (CurrentToken) { 163 // LookForDecls is set when "if (" has been seen. Check for 164 // 'identifier' '*' 'identifier' followed by not '=' -- this 165 // '*' has to be a binary operator but determineStarAmpUsage() will 166 // categorize it as an unary operator, so set the right type here. 167 if (LookForDecls && CurrentToken->Next) { 168 FormatToken *Prev = CurrentToken->getPreviousNonComment(); 169 if (Prev) { 170 FormatToken *PrevPrev = Prev->getPreviousNonComment(); 171 FormatToken *Next = CurrentToken->Next; 172 if (PrevPrev && PrevPrev->is(tok::identifier) && 173 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) && 174 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) { 175 Prev->Type = TT_BinaryOperator; 176 LookForDecls = false; 177 } 178 } 179 } 180 181 if (CurrentToken->Previous->is(TT_PointerOrReference) && 182 CurrentToken->Previous->Previous->isOneOf(tok::l_paren, 183 tok::coloncolon)) 184 MightBeFunctionType = true; 185 if (CurrentToken->Previous->is(TT_BinaryOperator)) 186 Contexts.back().IsExpression = true; 187 if (CurrentToken->is(tok::r_paren)) { 188 if (MightBeFunctionType && CurrentToken->Next && 189 (CurrentToken->Next->is(tok::l_paren) || 190 (CurrentToken->Next->is(tok::l_square) && 191 !Contexts.back().IsExpression))) 192 Left->Type = TT_FunctionTypeLParen; 193 Left->MatchingParen = CurrentToken; 194 CurrentToken->MatchingParen = Left; 195 196 if (StartsObjCMethodExpr) { 197 CurrentToken->Type = TT_ObjCMethodExpr; 198 if (Contexts.back().FirstObjCSelectorName) { 199 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 200 Contexts.back().LongestObjCSelectorName; 201 } 202 } 203 204 if (Left->is(TT_AttributeParen)) 205 CurrentToken->Type = TT_AttributeParen; 206 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation)) 207 CurrentToken->Type = TT_JavaAnnotation; 208 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation)) 209 CurrentToken->Type = TT_LeadingJavaAnnotation; 210 211 if (!HasMultipleLines) 212 Left->PackingKind = PPK_Inconclusive; 213 else if (HasMultipleParametersOnALine) 214 Left->PackingKind = PPK_BinPacked; 215 else 216 Left->PackingKind = PPK_OnePerLine; 217 218 next(); 219 return true; 220 } 221 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) 222 return false; 223 224 if (CurrentToken->is(tok::l_brace)) 225 Left->Type = TT_Unknown; // Not TT_ObjCBlockLParen 226 if (CurrentToken->is(tok::comma) && CurrentToken->Next && 227 !CurrentToken->Next->HasUnescapedNewline && 228 !CurrentToken->Next->isTrailingComment()) 229 HasMultipleParametersOnALine = true; 230 if (CurrentToken->isOneOf(tok::kw_const, tok::kw_auto) || 231 CurrentToken->isSimpleTypeSpecifier()) 232 Contexts.back().IsExpression = false; 233 if (CurrentToken->isOneOf(tok::semi, tok::colon)) 234 MightBeObjCForRangeLoop = false; 235 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) 236 CurrentToken->Type = TT_ObjCForIn; 237 // When we discover a 'new', we set CanBeExpression to 'false' in order to 238 // parse the type correctly. Reset that after a comma. 239 if (CurrentToken->is(tok::comma)) 240 Contexts.back().CanBeExpression = true; 241 242 FormatToken *Tok = CurrentToken; 243 if (!consumeToken()) 244 return false; 245 updateParameterCount(Left, Tok); 246 if (CurrentToken && CurrentToken->HasUnescapedNewline) 247 HasMultipleLines = true; 248 } 249 return false; 250 } 251 252 bool parseSquare() { 253 if (!CurrentToken) 254 return false; 255 256 // A '[' could be an index subscript (after an identifier or after 257 // ')' or ']'), it could be the start of an Objective-C method 258 // expression, or it could the the start of an Objective-C array literal. 259 FormatToken *Left = CurrentToken->Previous; 260 Left->ParentBracket = Contexts.back().ContextKind; 261 FormatToken *Parent = Left->getPreviousNonComment(); 262 bool StartsObjCMethodExpr = 263 Style.Language == FormatStyle::LK_Cpp && 264 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) && 265 CurrentToken->isNot(tok::l_brace) && 266 (!Parent || 267 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, 268 tok::kw_return, tok::kw_throw) || 269 Parent->isUnaryOperator() || 270 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) || 271 getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown); 272 bool ColonFound = false; 273 274 unsigned BindingIncrease = 1; 275 if (Left->is(TT_Unknown)) { 276 if (StartsObjCMethodExpr) { 277 Left->Type = TT_ObjCMethodExpr; 278 } else if (Parent && Parent->isOneOf(tok::at, tok::equal, tok::comma)) { 279 Left->Type = TT_ArrayInitializerLSquare; 280 } else { 281 BindingIncrease = 10; 282 Left->Type = TT_ArraySubscriptLSquare; 283 } 284 } 285 286 ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease); 287 Contexts.back().IsExpression = true; 288 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr; 289 290 while (CurrentToken) { 291 if (CurrentToken->is(tok::r_square)) { 292 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) && 293 Left->is(TT_ObjCMethodExpr)) { 294 // An ObjC method call is rarely followed by an open parenthesis. 295 // FIXME: Do we incorrectly label ":" with this? 296 StartsObjCMethodExpr = false; 297 Left->Type = TT_Unknown; 298 } 299 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) { 300 CurrentToken->Type = TT_ObjCMethodExpr; 301 // determineStarAmpUsage() thinks that '*' '[' is allocating an 302 // array of pointers, but if '[' starts a selector then '*' is a 303 // binary operator. 304 if (Parent && Parent->is(TT_PointerOrReference)) 305 Parent->Type = TT_BinaryOperator; 306 } 307 Left->MatchingParen = CurrentToken; 308 CurrentToken->MatchingParen = Left; 309 if (Contexts.back().FirstObjCSelectorName) { 310 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 311 Contexts.back().LongestObjCSelectorName; 312 if (Left->BlockParameterCount > 1) 313 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0; 314 } 315 next(); 316 return true; 317 } 318 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace)) 319 return false; 320 if (CurrentToken->is(tok::colon)) { 321 if (Left->is(TT_ArraySubscriptLSquare)) { 322 Left->Type = TT_ObjCMethodExpr; 323 StartsObjCMethodExpr = true; 324 Contexts.back().ColonIsObjCMethodExpr = true; 325 if (Parent && Parent->is(tok::r_paren)) 326 Parent->Type = TT_CastRParen; 327 } 328 ColonFound = true; 329 } 330 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) && 331 !ColonFound) 332 Left->Type = TT_ArrayInitializerLSquare; 333 FormatToken *Tok = CurrentToken; 334 if (!consumeToken()) 335 return false; 336 updateParameterCount(Left, Tok); 337 } 338 return false; 339 } 340 341 bool parseBrace() { 342 if (CurrentToken) { 343 FormatToken *Left = CurrentToken->Previous; 344 Left->ParentBracket = Contexts.back().ContextKind; 345 346 if (Contexts.back().CaretFound) 347 Left->Type = TT_ObjCBlockLBrace; 348 Contexts.back().CaretFound = false; 349 350 ScopedContextCreator ContextCreator(*this, tok::l_brace, 1); 351 Contexts.back().ColonIsDictLiteral = true; 352 if (Left->BlockKind == BK_BracedInit) 353 Contexts.back().IsExpression = true; 354 355 while (CurrentToken) { 356 if (CurrentToken->is(tok::r_brace)) { 357 Left->MatchingParen = CurrentToken; 358 CurrentToken->MatchingParen = Left; 359 next(); 360 return true; 361 } 362 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square)) 363 return false; 364 updateParameterCount(Left, CurrentToken); 365 if (CurrentToken->isOneOf(tok::colon, tok::l_brace)) { 366 FormatToken *Previous = CurrentToken->getPreviousNonComment(); 367 if ((CurrentToken->is(tok::colon) || 368 Style.Language == FormatStyle::LK_Proto) && 369 Previous->is(tok::identifier)) 370 Previous->Type = TT_SelectorName; 371 if (CurrentToken->is(tok::colon) || 372 Style.Language == FormatStyle::LK_JavaScript) 373 Left->Type = TT_DictLiteral; 374 } 375 if (!consumeToken()) 376 return false; 377 } 378 } 379 return true; 380 } 381 382 void updateParameterCount(FormatToken *Left, FormatToken *Current) { 383 if (Current->is(TT_LambdaLSquare) || 384 (Current->is(tok::caret) && Current->is(TT_UnaryOperator)) || 385 (Style.Language == FormatStyle::LK_JavaScript && 386 Current->is(Keywords.kw_function))) { 387 ++Left->BlockParameterCount; 388 } 389 if (Current->is(tok::comma)) { 390 ++Left->ParameterCount; 391 if (!Left->Role) 392 Left->Role.reset(new CommaSeparatedList(Style)); 393 Left->Role->CommaFound(Current); 394 } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) { 395 Left->ParameterCount = 1; 396 } 397 } 398 399 bool parseConditional() { 400 while (CurrentToken) { 401 if (CurrentToken->is(tok::colon)) { 402 CurrentToken->Type = TT_ConditionalExpr; 403 next(); 404 return true; 405 } 406 if (!consumeToken()) 407 return false; 408 } 409 return false; 410 } 411 412 bool parseTemplateDeclaration() { 413 if (CurrentToken && CurrentToken->is(tok::less)) { 414 CurrentToken->Type = TT_TemplateOpener; 415 next(); 416 if (!parseAngle()) 417 return false; 418 if (CurrentToken) 419 CurrentToken->Previous->ClosesTemplateDeclaration = true; 420 return true; 421 } 422 return false; 423 } 424 425 bool consumeToken() { 426 FormatToken *Tok = CurrentToken; 427 next(); 428 switch (Tok->Tok.getKind()) { 429 case tok::plus: 430 case tok::minus: 431 if (!Tok->Previous && Line.MustBeDeclaration) 432 Tok->Type = TT_ObjCMethodSpecifier; 433 break; 434 case tok::colon: 435 if (!Tok->Previous) 436 return false; 437 // Colons from ?: are handled in parseConditional(). 438 if (Style.Language == FormatStyle::LK_JavaScript) { 439 if (Contexts.back().ColonIsForRangeExpr || // colon in for loop 440 (Contexts.size() == 1 && // switch/case labels 441 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) || 442 Contexts.back().ContextKind == tok::l_paren || // function params 443 Contexts.back().ContextKind == tok::l_square || // array type 444 Line.MustBeDeclaration) { // method/property declaration 445 Tok->Type = TT_JsTypeColon; 446 break; 447 } 448 } 449 if (Contexts.back().ColonIsDictLiteral) { 450 Tok->Type = TT_DictLiteral; 451 } else if (Contexts.back().ColonIsObjCMethodExpr || 452 Line.First->is(TT_ObjCMethodSpecifier)) { 453 Tok->Type = TT_ObjCMethodExpr; 454 Tok->Previous->Type = TT_SelectorName; 455 if (Tok->Previous->ColumnWidth > 456 Contexts.back().LongestObjCSelectorName) { 457 Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth; 458 } 459 if (!Contexts.back().FirstObjCSelectorName) 460 Contexts.back().FirstObjCSelectorName = Tok->Previous; 461 } else if (Contexts.back().ColonIsForRangeExpr) { 462 Tok->Type = TT_RangeBasedForLoopColon; 463 } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) { 464 Tok->Type = TT_BitFieldColon; 465 } else if (Contexts.size() == 1 && 466 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) { 467 if (Tok->Previous->is(tok::r_paren)) 468 Tok->Type = TT_CtorInitializerColon; 469 else 470 Tok->Type = TT_InheritanceColon; 471 } else if (Tok->Previous->is(tok::identifier) && Tok->Next && 472 Tok->Next->isOneOf(tok::r_paren, tok::comma)) { 473 // This handles a special macro in ObjC code where selectors including 474 // the colon are passed as macro arguments. 475 Tok->Type = TT_ObjCMethodExpr; 476 } else if (Contexts.back().ContextKind == tok::l_paren) { 477 Tok->Type = TT_InlineASMColon; 478 } 479 break; 480 case tok::kw_if: 481 case tok::kw_while: 482 if (CurrentToken && CurrentToken->is(tok::l_paren)) { 483 next(); 484 if (!parseParens(/*LookForDecls=*/true)) 485 return false; 486 } 487 break; 488 case tok::kw_for: 489 Contexts.back().ColonIsForRangeExpr = true; 490 next(); 491 if (!parseParens()) 492 return false; 493 break; 494 case tok::l_paren: 495 if (!parseParens()) 496 return false; 497 if (Line.MustBeDeclaration && Contexts.size() == 1 && 498 !Contexts.back().IsExpression && Line.First->isNot(TT_ObjCProperty) && 499 (!Tok->Previous || 500 !Tok->Previous->isOneOf(tok::kw_decltype, TT_LeadingJavaAnnotation))) 501 Line.MightBeFunctionDecl = true; 502 break; 503 case tok::l_square: 504 if (!parseSquare()) 505 return false; 506 break; 507 case tok::l_brace: 508 if (!parseBrace()) 509 return false; 510 break; 511 case tok::less: 512 if (!NonTemplateLess.count(Tok) && 513 (!Tok->Previous || 514 (!Tok->Previous->Tok.isLiteral() && 515 !(Tok->Previous->is(tok::r_paren) && Contexts.size() > 1))) && 516 parseAngle()) { 517 Tok->Type = TT_TemplateOpener; 518 } else { 519 Tok->Type = TT_BinaryOperator; 520 NonTemplateLess.insert(Tok); 521 CurrentToken = Tok; 522 next(); 523 } 524 break; 525 case tok::r_paren: 526 case tok::r_square: 527 return false; 528 case tok::r_brace: 529 // Lines can start with '}'. 530 if (Tok->Previous) 531 return false; 532 break; 533 case tok::greater: 534 Tok->Type = TT_BinaryOperator; 535 break; 536 case tok::kw_operator: 537 while (CurrentToken && 538 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) { 539 if (CurrentToken->isOneOf(tok::star, tok::amp)) 540 CurrentToken->Type = TT_PointerOrReference; 541 consumeToken(); 542 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator)) 543 CurrentToken->Previous->Type = TT_OverloadedOperator; 544 } 545 if (CurrentToken) { 546 CurrentToken->Type = TT_OverloadedOperatorLParen; 547 if (CurrentToken->Previous->is(TT_BinaryOperator)) 548 CurrentToken->Previous->Type = TT_OverloadedOperator; 549 } 550 break; 551 case tok::question: 552 if (Style.Language == FormatStyle::LK_JavaScript && Tok->Next && 553 Tok->Next->isOneOf(tok::semi, tok::colon, tok::r_paren, 554 tok::r_brace)) { 555 // Question marks before semicolons, colons, etc. indicate optional 556 // types (fields, parameters), e.g. 557 // function(x?: string, y?) {...} 558 // class X { y?; } 559 Tok->Type = TT_JsTypeOptionalQuestion; 560 break; 561 } 562 // Declarations cannot be conditional expressions, this can only be part 563 // of a type declaration. 564 if (Line.MustBeDeclaration && 565 Style.Language == FormatStyle::LK_JavaScript) 566 break; 567 parseConditional(); 568 break; 569 case tok::kw_template: 570 parseTemplateDeclaration(); 571 break; 572 case tok::comma: 573 if (Contexts.back().InCtorInitializer) 574 Tok->Type = TT_CtorInitializerComma; 575 else if (Contexts.back().FirstStartOfName && 576 (Contexts.size() == 1 || Line.First->is(tok::kw_for))) { 577 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true; 578 Line.IsMultiVariableDeclStmt = true; 579 } 580 if (Contexts.back().IsForEachMacro) 581 Contexts.back().IsExpression = true; 582 break; 583 default: 584 break; 585 } 586 return true; 587 } 588 589 void parseIncludeDirective() { 590 if (CurrentToken && CurrentToken->is(tok::less)) { 591 next(); 592 while (CurrentToken) { 593 if (CurrentToken->isNot(tok::comment) || CurrentToken->Next) 594 CurrentToken->Type = TT_ImplicitStringLiteral; 595 next(); 596 } 597 } 598 } 599 600 void parseWarningOrError() { 601 next(); 602 // We still want to format the whitespace left of the first token of the 603 // warning or error. 604 next(); 605 while (CurrentToken) { 606 CurrentToken->Type = TT_ImplicitStringLiteral; 607 next(); 608 } 609 } 610 611 void parsePragma() { 612 next(); // Consume "pragma". 613 if (CurrentToken && 614 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) { 615 bool IsMark = CurrentToken->is(Keywords.kw_mark); 616 next(); // Consume "mark". 617 next(); // Consume first token (so we fix leading whitespace). 618 while (CurrentToken) { 619 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator)) 620 CurrentToken->Type = TT_ImplicitStringLiteral; 621 next(); 622 } 623 } 624 } 625 626 LineType parsePreprocessorDirective() { 627 LineType Type = LT_PreprocessorDirective; 628 next(); 629 if (!CurrentToken) 630 return Type; 631 if (CurrentToken->Tok.is(tok::numeric_constant)) { 632 CurrentToken->SpacesRequiredBefore = 1; 633 return Type; 634 } 635 // Hashes in the middle of a line can lead to any strange token 636 // sequence. 637 if (!CurrentToken->Tok.getIdentifierInfo()) 638 return Type; 639 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) { 640 case tok::pp_include: 641 case tok::pp_include_next: 642 case tok::pp_import: 643 next(); 644 parseIncludeDirective(); 645 Type = LT_ImportStatement; 646 break; 647 case tok::pp_error: 648 case tok::pp_warning: 649 parseWarningOrError(); 650 break; 651 case tok::pp_pragma: 652 parsePragma(); 653 break; 654 case tok::pp_if: 655 case tok::pp_elif: 656 Contexts.back().IsExpression = true; 657 parseLine(); 658 break; 659 default: 660 break; 661 } 662 while (CurrentToken) 663 next(); 664 return Type; 665 } 666 667 public: 668 LineType parseLine() { 669 NonTemplateLess.clear(); 670 if (CurrentToken->is(tok::hash)) 671 return parsePreprocessorDirective(); 672 673 // Directly allow to 'import <string-literal>' to support protocol buffer 674 // definitions (code.google.com/p/protobuf) or missing "#" (either way we 675 // should not break the line). 676 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo(); 677 if ((Style.Language == FormatStyle::LK_Java && 678 CurrentToken->is(Keywords.kw_package)) || 679 (Info && Info->getPPKeywordID() == tok::pp_import && 680 CurrentToken->Next && 681 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier, 682 tok::kw_static))) { 683 next(); 684 parseIncludeDirective(); 685 return LT_ImportStatement; 686 } 687 688 // If this line starts and ends in '<' and '>', respectively, it is likely 689 // part of "#define <a/b.h>". 690 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) { 691 parseIncludeDirective(); 692 return LT_ImportStatement; 693 } 694 695 // In .proto files, top-level options are very similar to import statements 696 // and should not be line-wrapped. 697 if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 && 698 CurrentToken->is(Keywords.kw_option)) { 699 next(); 700 if (CurrentToken && CurrentToken->is(tok::identifier)) 701 return LT_ImportStatement; 702 } 703 704 bool KeywordVirtualFound = false; 705 bool ImportStatement = false; 706 while (CurrentToken) { 707 if (CurrentToken->is(tok::kw_virtual)) 708 KeywordVirtualFound = true; 709 if (IsImportStatement(*CurrentToken)) 710 ImportStatement = true; 711 if (!consumeToken()) 712 return LT_Invalid; 713 } 714 if (KeywordVirtualFound) 715 return LT_VirtualFunctionDecl; 716 if (ImportStatement) 717 return LT_ImportStatement; 718 719 if (Line.First->is(TT_ObjCMethodSpecifier)) { 720 if (Contexts.back().FirstObjCSelectorName) 721 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 722 Contexts.back().LongestObjCSelectorName; 723 return LT_ObjCMethodDecl; 724 } 725 726 return LT_Other; 727 } 728 729 private: 730 bool IsImportStatement(const FormatToken &Tok) { 731 // FIXME: Closure-library specific stuff should not be hard-coded but be 732 // configurable. 733 return Style.Language == FormatStyle::LK_JavaScript && 734 Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) && 735 Tok.Next->Next && (Tok.Next->Next->TokenText == "module" || 736 Tok.Next->Next->TokenText == "require" || 737 Tok.Next->Next->TokenText == "provide") && 738 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren); 739 } 740 741 void resetTokenMetadata(FormatToken *Token) { 742 if (!Token) 743 return; 744 745 // Reset token type in case we have already looked at it and then 746 // recovered from an error (e.g. failure to find the matching >). 747 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro, 748 TT_FunctionLBrace, TT_ImplicitStringLiteral, 749 TT_InlineASMBrace, TT_RegexLiteral, 750 TT_TrailingReturnArrow)) 751 CurrentToken->Type = TT_Unknown; 752 CurrentToken->Role.reset(); 753 CurrentToken->MatchingParen = nullptr; 754 CurrentToken->FakeLParens.clear(); 755 CurrentToken->FakeRParens = 0; 756 } 757 758 void next() { 759 if (CurrentToken) { 760 CurrentToken->NestingLevel = Contexts.size() - 1; 761 CurrentToken->BindingStrength = Contexts.back().BindingStrength; 762 modifyContext(*CurrentToken); 763 determineTokenType(*CurrentToken); 764 CurrentToken = CurrentToken->Next; 765 } 766 767 resetTokenMetadata(CurrentToken); 768 } 769 770 /// \brief A struct to hold information valid in a specific context, e.g. 771 /// a pair of parenthesis. 772 struct Context { 773 Context(tok::TokenKind ContextKind, unsigned BindingStrength, 774 bool IsExpression) 775 : ContextKind(ContextKind), BindingStrength(BindingStrength), 776 IsExpression(IsExpression) {} 777 778 tok::TokenKind ContextKind; 779 unsigned BindingStrength; 780 bool IsExpression; 781 unsigned LongestObjCSelectorName = 0; 782 bool ColonIsForRangeExpr = false; 783 bool ColonIsDictLiteral = false; 784 bool ColonIsObjCMethodExpr = false; 785 FormatToken *FirstObjCSelectorName = nullptr; 786 FormatToken *FirstStartOfName = nullptr; 787 bool CanBeExpression = true; 788 bool InTemplateArgument = false; 789 bool InCtorInitializer = false; 790 bool CaretFound = false; 791 bool IsForEachMacro = false; 792 }; 793 794 /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 795 /// of each instance. 796 struct ScopedContextCreator { 797 AnnotatingParser &P; 798 799 ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind, 800 unsigned Increase) 801 : P(P) { 802 P.Contexts.push_back(Context(ContextKind, 803 P.Contexts.back().BindingStrength + Increase, 804 P.Contexts.back().IsExpression)); 805 } 806 807 ~ScopedContextCreator() { P.Contexts.pop_back(); } 808 }; 809 810 void modifyContext(const FormatToken &Current) { 811 if (Current.getPrecedence() == prec::Assignment && 812 !Line.First->isOneOf(tok::kw_template, tok::kw_using) && 813 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) { 814 Contexts.back().IsExpression = true; 815 if (!Line.First->is(TT_UnaryOperator)) { 816 for (FormatToken *Previous = Current.Previous; 817 Previous && !Previous->isOneOf(tok::comma, tok::semi); 818 Previous = Previous->Previous) { 819 if (Previous->isOneOf(tok::r_square, tok::r_paren)) { 820 Previous = Previous->MatchingParen; 821 if (!Previous) 822 break; 823 } 824 if (Previous->opensScope()) 825 break; 826 if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) && 827 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) && 828 Previous->Previous && Previous->Previous->isNot(tok::equal)) 829 Previous->Type = TT_PointerOrReference; 830 } 831 } 832 } else if (Current.is(tok::lessless) && 833 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) { 834 Contexts.back().IsExpression = true; 835 } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) { 836 Contexts.back().IsExpression = true; 837 } else if (Current.is(TT_TrailingReturnArrow)) { 838 Contexts.back().IsExpression = false; 839 } else if (Current.is(tok::l_paren) && !Line.MustBeDeclaration && 840 !Line.InPPDirective && 841 (!Current.Previous || 842 Current.Previous->isNot(tok::kw_decltype))) { 843 bool ParametersOfFunctionType = 844 Current.Previous && Current.Previous->is(tok::r_paren) && 845 Current.Previous->MatchingParen && 846 Current.Previous->MatchingParen->is(TT_FunctionTypeLParen); 847 bool IsForOrCatch = Current.Previous && 848 Current.Previous->isOneOf(tok::kw_for, tok::kw_catch); 849 Contexts.back().IsExpression = !ParametersOfFunctionType && !IsForOrCatch; 850 } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { 851 for (FormatToken *Previous = Current.Previous; 852 Previous && Previous->isOneOf(tok::star, tok::amp); 853 Previous = Previous->Previous) 854 Previous->Type = TT_PointerOrReference; 855 if (Line.MustBeDeclaration) 856 Contexts.back().IsExpression = Contexts.front().InCtorInitializer; 857 } else if (Current.Previous && 858 Current.Previous->is(TT_CtorInitializerColon)) { 859 Contexts.back().IsExpression = true; 860 Contexts.back().InCtorInitializer = true; 861 } else if (Current.is(tok::kw_new)) { 862 Contexts.back().CanBeExpression = false; 863 } else if (Current.is(tok::semi) || Current.is(tok::exclaim)) { 864 // This should be the condition or increment in a for-loop. 865 Contexts.back().IsExpression = true; 866 } 867 } 868 869 void determineTokenType(FormatToken &Current) { 870 if (!Current.is(TT_Unknown)) 871 // The token type is already known. 872 return; 873 874 // Line.MightBeFunctionDecl can only be true after the parentheses of a 875 // function declaration have been found. In this case, 'Current' is a 876 // trailing token of this declaration and thus cannot be a name. 877 if (Current.is(Keywords.kw_instanceof)) { 878 Current.Type = TT_BinaryOperator; 879 } else if (isStartOfName(Current) && 880 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) { 881 Contexts.back().FirstStartOfName = &Current; 882 Current.Type = TT_StartOfName; 883 } else if (Current.is(tok::kw_auto)) { 884 AutoFound = true; 885 } else if (Current.is(tok::arrow) && 886 Style.Language == FormatStyle::LK_Java) { 887 Current.Type = TT_LambdaArrow; 888 } else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration && 889 Current.NestingLevel == 0) { 890 Current.Type = TT_TrailingReturnArrow; 891 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) { 892 Current.Type = 893 determineStarAmpUsage(Current, Contexts.back().CanBeExpression && 894 Contexts.back().IsExpression, 895 Contexts.back().InTemplateArgument); 896 } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { 897 Current.Type = determinePlusMinusCaretUsage(Current); 898 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret)) 899 Contexts.back().CaretFound = true; 900 } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { 901 Current.Type = determineIncrementUsage(Current); 902 } else if (Current.isOneOf(tok::exclaim, tok::tilde)) { 903 Current.Type = TT_UnaryOperator; 904 } else if (Current.is(tok::question)) { 905 if (Style.Language == FormatStyle::LK_JavaScript && 906 Line.MustBeDeclaration) { 907 // In JavaScript, `interface X { foo?(): bar; }` is an optional method 908 // on the interface, not a ternary expression. 909 Current.Type = TT_JsTypeOptionalQuestion; 910 } else { 911 Current.Type = TT_ConditionalExpr; 912 } 913 } else if (Current.isBinaryOperator() && 914 (!Current.Previous || Current.Previous->isNot(tok::l_square))) { 915 Current.Type = TT_BinaryOperator; 916 } else if (Current.is(tok::comment)) { 917 if (Current.TokenText.startswith("/*")) { 918 if (Current.TokenText.endswith("*/")) 919 Current.Type = TT_BlockComment; 920 else 921 // The lexer has for some reason determined a comment here. But we 922 // cannot really handle it, if it isn't properly terminated. 923 Current.Tok.setKind(tok::unknown); 924 } else { 925 Current.Type = TT_LineComment; 926 } 927 } else if (Current.is(tok::r_paren)) { 928 if (rParenEndsCast(Current)) 929 Current.Type = TT_CastRParen; 930 if (Current.MatchingParen && Current.Next && 931 !Current.Next->isBinaryOperator() && 932 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace)) 933 if (FormatToken *BeforeParen = Current.MatchingParen->Previous) 934 if (BeforeParen->is(tok::identifier) && 935 BeforeParen->TokenText == BeforeParen->TokenText.upper() && 936 (!BeforeParen->Previous || 937 BeforeParen->Previous->ClosesTemplateDeclaration)) 938 Current.Type = TT_FunctionAnnotationRParen; 939 } else if (Current.is(tok::at) && Current.Next) { 940 if (Current.Next->isStringLiteral()) { 941 Current.Type = TT_ObjCStringLiteral; 942 } else { 943 switch (Current.Next->Tok.getObjCKeywordID()) { 944 case tok::objc_interface: 945 case tok::objc_implementation: 946 case tok::objc_protocol: 947 Current.Type = TT_ObjCDecl; 948 break; 949 case tok::objc_property: 950 Current.Type = TT_ObjCProperty; 951 break; 952 default: 953 break; 954 } 955 } 956 } else if (Current.is(tok::period)) { 957 FormatToken *PreviousNoComment = Current.getPreviousNonComment(); 958 if (PreviousNoComment && 959 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) 960 Current.Type = TT_DesignatedInitializerPeriod; 961 else if (Style.Language == FormatStyle::LK_Java && Current.Previous && 962 Current.Previous->isOneOf(TT_JavaAnnotation, 963 TT_LeadingJavaAnnotation)) { 964 Current.Type = Current.Previous->Type; 965 } 966 } else if (Current.isOneOf(tok::identifier, tok::kw_const) && 967 Current.Previous && 968 !Current.Previous->isOneOf(tok::equal, tok::at) && 969 Line.MightBeFunctionDecl && Contexts.size() == 1) { 970 // Line.MightBeFunctionDecl can only be true after the parentheses of a 971 // function declaration have been found. 972 Current.Type = TT_TrailingAnnotation; 973 } else if ((Style.Language == FormatStyle::LK_Java || 974 Style.Language == FormatStyle::LK_JavaScript) && 975 Current.Previous) { 976 if (Current.Previous->is(tok::at) && 977 Current.isNot(Keywords.kw_interface)) { 978 const FormatToken &AtToken = *Current.Previous; 979 const FormatToken *Previous = AtToken.getPreviousNonComment(); 980 if (!Previous || Previous->is(TT_LeadingJavaAnnotation)) 981 Current.Type = TT_LeadingJavaAnnotation; 982 else 983 Current.Type = TT_JavaAnnotation; 984 } else if (Current.Previous->is(tok::period) && 985 Current.Previous->isOneOf(TT_JavaAnnotation, 986 TT_LeadingJavaAnnotation)) { 987 Current.Type = Current.Previous->Type; 988 } 989 } 990 } 991 992 /// \brief Take a guess at whether \p Tok starts a name of a function or 993 /// variable declaration. 994 /// 995 /// This is a heuristic based on whether \p Tok is an identifier following 996 /// something that is likely a type. 997 bool isStartOfName(const FormatToken &Tok) { 998 if (Tok.isNot(tok::identifier) || !Tok.Previous) 999 return false; 1000 1001 if (Tok.Previous->is(TT_LeadingJavaAnnotation)) 1002 return false; 1003 1004 // Skip "const" as it does not have an influence on whether this is a name. 1005 FormatToken *PreviousNotConst = Tok.Previous; 1006 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const)) 1007 PreviousNotConst = PreviousNotConst->Previous; 1008 1009 if (!PreviousNotConst) 1010 return false; 1011 1012 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) && 1013 PreviousNotConst->Previous && 1014 PreviousNotConst->Previous->is(tok::hash); 1015 1016 if (PreviousNotConst->is(TT_TemplateCloser)) 1017 return PreviousNotConst && PreviousNotConst->MatchingParen && 1018 PreviousNotConst->MatchingParen->Previous && 1019 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) && 1020 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template); 1021 1022 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen && 1023 PreviousNotConst->MatchingParen->Previous && 1024 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype)) 1025 return true; 1026 1027 return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) || 1028 PreviousNotConst->is(TT_PointerOrReference) || 1029 PreviousNotConst->isSimpleTypeSpecifier(); 1030 } 1031 1032 /// \brief Determine whether ')' is ending a cast. 1033 bool rParenEndsCast(const FormatToken &Tok) { 1034 FormatToken *LeftOfParens = nullptr; 1035 if (Tok.MatchingParen) 1036 LeftOfParens = Tok.MatchingParen->getPreviousNonComment(); 1037 if (LeftOfParens && LeftOfParens->is(tok::r_paren) && 1038 LeftOfParens->MatchingParen) 1039 LeftOfParens = LeftOfParens->MatchingParen->Previous; 1040 if (LeftOfParens && LeftOfParens->is(tok::r_square) && 1041 LeftOfParens->MatchingParen && 1042 LeftOfParens->MatchingParen->is(TT_LambdaLSquare)) 1043 return false; 1044 if (Tok.Next) { 1045 if (Tok.Next->is(tok::question)) 1046 return false; 1047 if (Style.Language == FormatStyle::LK_JavaScript && 1048 Tok.Next->is(Keywords.kw_in)) 1049 return false; 1050 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren)) 1051 return true; 1052 } 1053 bool IsCast = false; 1054 bool ParensAreEmpty = Tok.Previous == Tok.MatchingParen; 1055 bool ParensAreType = 1056 !Tok.Previous || 1057 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) || 1058 Tok.Previous->isSimpleTypeSpecifier(); 1059 bool ParensCouldEndDecl = 1060 Tok.Next && Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace); 1061 bool IsSizeOfOrAlignOf = 1062 LeftOfParens && LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof); 1063 if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf && 1064 (Contexts.size() > 1 && Contexts[Contexts.size() - 2].IsExpression)) 1065 IsCast = true; 1066 else if (Tok.Next && Tok.Next->isNot(tok::string_literal) && 1067 (Tok.Next->Tok.isLiteral() || 1068 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof))) 1069 IsCast = true; 1070 // If there is an identifier after the (), it is likely a cast, unless 1071 // there is also an identifier before the (). 1072 else if (LeftOfParens && Tok.Next && 1073 (LeftOfParens->Tok.getIdentifierInfo() == nullptr || 1074 LeftOfParens->is(tok::kw_return)) && 1075 !LeftOfParens->isOneOf(TT_OverloadedOperator, tok::at, 1076 TT_TemplateCloser)) { 1077 if (Tok.Next->isOneOf(tok::identifier, tok::numeric_constant)) { 1078 IsCast = true; 1079 } else { 1080 // Use heuristics to recognize c style casting. 1081 FormatToken *Prev = Tok.Previous; 1082 if (Prev && Prev->isOneOf(tok::amp, tok::star)) 1083 Prev = Prev->Previous; 1084 1085 if (Prev && Tok.Next && Tok.Next->Next) { 1086 bool NextIsUnary = Tok.Next->isUnaryOperator() || 1087 Tok.Next->isOneOf(tok::amp, tok::star); 1088 IsCast = 1089 NextIsUnary && !Tok.Next->is(tok::plus) && 1090 Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant); 1091 } 1092 1093 for (; Prev != Tok.MatchingParen; Prev = Prev->Previous) { 1094 if (!Prev || 1095 !Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon)) { 1096 IsCast = false; 1097 break; 1098 } 1099 } 1100 } 1101 } 1102 return IsCast && !ParensAreEmpty; 1103 } 1104 1105 /// \brief Return the type of the given token assuming it is * or &. 1106 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression, 1107 bool InTemplateArgument) { 1108 if (Style.Language == FormatStyle::LK_JavaScript) 1109 return TT_BinaryOperator; 1110 1111 const FormatToken *PrevToken = Tok.getPreviousNonComment(); 1112 if (!PrevToken) 1113 return TT_UnaryOperator; 1114 1115 const FormatToken *NextToken = Tok.getNextNonComment(); 1116 if (!NextToken || 1117 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) 1118 return TT_Unknown; 1119 1120 if (PrevToken->is(tok::coloncolon)) 1121 return TT_PointerOrReference; 1122 1123 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, 1124 tok::comma, tok::semi, tok::kw_return, tok::colon, 1125 tok::equal, tok::kw_delete, tok::kw_sizeof) || 1126 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr, 1127 TT_UnaryOperator, TT_CastRParen)) 1128 return TT_UnaryOperator; 1129 1130 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare)) 1131 return TT_PointerOrReference; 1132 if (NextToken->isOneOf(tok::kw_operator, tok::comma, tok::semi)) 1133 return TT_PointerOrReference; 1134 1135 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen && 1136 PrevToken->MatchingParen->Previous && 1137 PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof, 1138 tok::kw_decltype)) 1139 return TT_PointerOrReference; 1140 1141 if (PrevToken->Tok.isLiteral() || 1142 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true, 1143 tok::kw_false, tok::r_brace) || 1144 NextToken->Tok.isLiteral() || 1145 NextToken->isOneOf(tok::kw_true, tok::kw_false) || 1146 NextToken->isUnaryOperator() || 1147 // If we know we're in a template argument, there are no named 1148 // declarations. Thus, having an identifier on the right-hand side 1149 // indicates a binary operator. 1150 (InTemplateArgument && NextToken->Tok.isAnyIdentifier())) 1151 return TT_BinaryOperator; 1152 1153 // "&&(" is quite unlikely to be two successive unary "&". 1154 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren)) 1155 return TT_BinaryOperator; 1156 1157 // This catches some cases where evaluation order is used as control flow: 1158 // aaa && aaa->f(); 1159 const FormatToken *NextNextToken = NextToken->getNextNonComment(); 1160 if (NextNextToken && NextNextToken->is(tok::arrow)) 1161 return TT_BinaryOperator; 1162 1163 // It is very unlikely that we are going to find a pointer or reference type 1164 // definition on the RHS of an assignment. 1165 if (IsExpression && !Contexts.back().CaretFound) 1166 return TT_BinaryOperator; 1167 1168 return TT_PointerOrReference; 1169 } 1170 1171 TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) { 1172 const FormatToken *PrevToken = Tok.getPreviousNonComment(); 1173 if (!PrevToken || PrevToken->is(TT_CastRParen)) 1174 return TT_UnaryOperator; 1175 1176 // Use heuristics to recognize unary operators. 1177 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square, 1178 tok::question, tok::colon, tok::kw_return, 1179 tok::kw_case, tok::at, tok::l_brace)) 1180 return TT_UnaryOperator; 1181 1182 // There can't be two consecutive binary operators. 1183 if (PrevToken->is(TT_BinaryOperator)) 1184 return TT_UnaryOperator; 1185 1186 // Fall back to marking the token as binary operator. 1187 return TT_BinaryOperator; 1188 } 1189 1190 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 1191 TokenType determineIncrementUsage(const FormatToken &Tok) { 1192 const FormatToken *PrevToken = Tok.getPreviousNonComment(); 1193 if (!PrevToken || PrevToken->is(TT_CastRParen)) 1194 return TT_UnaryOperator; 1195 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) 1196 return TT_TrailingUnaryOperator; 1197 1198 return TT_UnaryOperator; 1199 } 1200 1201 SmallVector<Context, 8> Contexts; 1202 1203 const FormatStyle &Style; 1204 AnnotatedLine &Line; 1205 FormatToken *CurrentToken; 1206 bool AutoFound; 1207 const AdditionalKeywords &Keywords; 1208 1209 // Set of "<" tokens that do not open a template parameter list. If parseAngle 1210 // determines that a specific token can't be a template opener, it will make 1211 // same decision irrespective of the decisions for tokens leading up to it. 1212 // Store this information to prevent this from causing exponential runtime. 1213 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess; 1214 }; 1215 1216 static const int PrecedenceUnaryOperator = prec::PointerToMember + 1; 1217 static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2; 1218 1219 /// \brief Parses binary expressions by inserting fake parenthesis based on 1220 /// operator precedence. 1221 class ExpressionParser { 1222 public: 1223 ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords, 1224 AnnotatedLine &Line) 1225 : Style(Style), Keywords(Keywords), Current(Line.First) {} 1226 1227 /// \brief Parse expressions with the given operatore precedence. 1228 void parse(int Precedence = 0) { 1229 // Skip 'return' and ObjC selector colons as they are not part of a binary 1230 // expression. 1231 while (Current && (Current->is(tok::kw_return) || 1232 (Current->is(tok::colon) && 1233 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) 1234 next(); 1235 1236 if (!Current || Precedence > PrecedenceArrowAndPeriod) 1237 return; 1238 1239 // Conditional expressions need to be parsed separately for proper nesting. 1240 if (Precedence == prec::Conditional) { 1241 parseConditionalExpr(); 1242 return; 1243 } 1244 1245 // Parse unary operators, which all have a higher precedence than binary 1246 // operators. 1247 if (Precedence == PrecedenceUnaryOperator) { 1248 parseUnaryOperator(); 1249 return; 1250 } 1251 1252 FormatToken *Start = Current; 1253 FormatToken *LatestOperator = nullptr; 1254 unsigned OperatorIndex = 0; 1255 1256 while (Current) { 1257 // Consume operators with higher precedence. 1258 parse(Precedence + 1); 1259 1260 int CurrentPrecedence = getCurrentPrecedence(); 1261 1262 if (Current && Current->is(TT_SelectorName) && 1263 Precedence == CurrentPrecedence) { 1264 if (LatestOperator) 1265 addFakeParenthesis(Start, prec::Level(Precedence)); 1266 Start = Current; 1267 } 1268 1269 // At the end of the line or when an operator with higher precedence is 1270 // found, insert fake parenthesis and return. 1271 if (!Current || (Current->closesScope() && Current->MatchingParen) || 1272 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) || 1273 (CurrentPrecedence == prec::Conditional && 1274 Precedence == prec::Assignment && Current->is(tok::colon))) { 1275 break; 1276 } 1277 1278 // Consume scopes: (), [], <> and {} 1279 if (Current->opensScope()) { 1280 while (Current && !Current->closesScope()) { 1281 next(); 1282 parse(); 1283 } 1284 next(); 1285 } else { 1286 // Operator found. 1287 if (CurrentPrecedence == Precedence) { 1288 LatestOperator = Current; 1289 Current->OperatorIndex = OperatorIndex; 1290 ++OperatorIndex; 1291 } 1292 next(/*SkipPastLeadingComments=*/Precedence > 0); 1293 } 1294 } 1295 1296 if (LatestOperator && (Current || Precedence > 0)) { 1297 LatestOperator->LastOperator = true; 1298 if (Precedence == PrecedenceArrowAndPeriod) { 1299 // Call expressions don't have a binary operator precedence. 1300 addFakeParenthesis(Start, prec::Unknown); 1301 } else { 1302 addFakeParenthesis(Start, prec::Level(Precedence)); 1303 } 1304 } 1305 } 1306 1307 private: 1308 /// \brief Gets the precedence (+1) of the given token for binary operators 1309 /// and other tokens that we treat like binary operators. 1310 int getCurrentPrecedence() { 1311 if (Current) { 1312 const FormatToken *NextNonComment = Current->getNextNonComment(); 1313 if (Current->is(TT_ConditionalExpr)) 1314 return prec::Conditional; 1315 else if (NextNonComment && NextNonComment->is(tok::colon) && 1316 NextNonComment->is(TT_DictLiteral)) 1317 return prec::Comma; 1318 else if (Current->is(TT_LambdaArrow)) 1319 return prec::Comma; 1320 else if (Current->isOneOf(tok::semi, TT_InlineASMColon, 1321 TT_SelectorName) || 1322 (Current->is(tok::comment) && NextNonComment && 1323 NextNonComment->is(TT_SelectorName))) 1324 return 0; 1325 else if (Current->is(TT_RangeBasedForLoopColon)) 1326 return prec::Comma; 1327 else if (Current->is(TT_BinaryOperator) || Current->is(tok::comma)) 1328 return Current->getPrecedence(); 1329 else if (Current->isOneOf(tok::period, tok::arrow)) 1330 return PrecedenceArrowAndPeriod; 1331 else if (Style.Language == FormatStyle::LK_Java && 1332 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements, 1333 Keywords.kw_throws)) 1334 return 0; 1335 } 1336 return -1; 1337 } 1338 1339 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) { 1340 Start->FakeLParens.push_back(Precedence); 1341 if (Precedence > prec::Unknown) 1342 Start->StartsBinaryExpression = true; 1343 if (Current) { 1344 FormatToken *Previous = Current->Previous; 1345 while (Previous->is(tok::comment) && Previous->Previous) 1346 Previous = Previous->Previous; 1347 ++Previous->FakeRParens; 1348 if (Precedence > prec::Unknown) 1349 Previous->EndsBinaryExpression = true; 1350 } 1351 } 1352 1353 /// \brief Parse unary operator expressions and surround them with fake 1354 /// parentheses if appropriate. 1355 void parseUnaryOperator() { 1356 if (!Current || Current->isNot(TT_UnaryOperator)) { 1357 parse(PrecedenceArrowAndPeriod); 1358 return; 1359 } 1360 1361 FormatToken *Start = Current; 1362 next(); 1363 parseUnaryOperator(); 1364 1365 // The actual precedence doesn't matter. 1366 addFakeParenthesis(Start, prec::Unknown); 1367 } 1368 1369 void parseConditionalExpr() { 1370 while (Current && Current->isTrailingComment()) { 1371 next(); 1372 } 1373 FormatToken *Start = Current; 1374 parse(prec::LogicalOr); 1375 if (!Current || !Current->is(tok::question)) 1376 return; 1377 next(); 1378 parse(prec::Assignment); 1379 if (!Current || Current->isNot(TT_ConditionalExpr)) 1380 return; 1381 next(); 1382 parse(prec::Assignment); 1383 addFakeParenthesis(Start, prec::Conditional); 1384 } 1385 1386 void next(bool SkipPastLeadingComments = true) { 1387 if (Current) 1388 Current = Current->Next; 1389 while (Current && 1390 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) && 1391 Current->isTrailingComment()) 1392 Current = Current->Next; 1393 } 1394 1395 const FormatStyle &Style; 1396 const AdditionalKeywords &Keywords; 1397 FormatToken *Current; 1398 }; 1399 1400 } // end anonymous namespace 1401 1402 void TokenAnnotator::setCommentLineLevels( 1403 SmallVectorImpl<AnnotatedLine *> &Lines) { 1404 const AnnotatedLine *NextNonCommentLine = nullptr; 1405 for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(), 1406 E = Lines.rend(); 1407 I != E; ++I) { 1408 if (NextNonCommentLine && (*I)->First->is(tok::comment) && 1409 (*I)->First->Next == nullptr) 1410 (*I)->Level = NextNonCommentLine->Level; 1411 else 1412 NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr; 1413 1414 setCommentLineLevels((*I)->Children); 1415 } 1416 } 1417 1418 void TokenAnnotator::annotate(AnnotatedLine &Line) { 1419 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), 1420 E = Line.Children.end(); 1421 I != E; ++I) { 1422 annotate(**I); 1423 } 1424 AnnotatingParser Parser(Style, Line, Keywords); 1425 Line.Type = Parser.parseLine(); 1426 if (Line.Type == LT_Invalid) 1427 return; 1428 1429 ExpressionParser ExprParser(Style, Keywords, Line); 1430 ExprParser.parse(); 1431 1432 if (Line.First->is(TT_ObjCMethodSpecifier)) 1433 Line.Type = LT_ObjCMethodDecl; 1434 else if (Line.First->is(TT_ObjCDecl)) 1435 Line.Type = LT_ObjCDecl; 1436 else if (Line.First->is(TT_ObjCProperty)) 1437 Line.Type = LT_ObjCProperty; 1438 1439 Line.First->SpacesRequiredBefore = 1; 1440 Line.First->CanBreakBefore = Line.First->MustBreakBefore; 1441 } 1442 1443 // This function heuristically determines whether 'Current' starts the name of a 1444 // function declaration. 1445 static bool isFunctionDeclarationName(const FormatToken &Current) { 1446 if (!Current.is(TT_StartOfName) || Current.NestingLevel != 0) 1447 return false; 1448 const FormatToken *Next = Current.Next; 1449 for (; Next; Next = Next->Next) { 1450 if (Next->is(TT_TemplateOpener)) { 1451 Next = Next->MatchingParen; 1452 } else if (Next->is(tok::coloncolon)) { 1453 Next = Next->Next; 1454 if (!Next || !Next->is(tok::identifier)) 1455 return false; 1456 } else if (Next->is(tok::l_paren)) { 1457 break; 1458 } else { 1459 return false; 1460 } 1461 } 1462 if (!Next) 1463 return false; 1464 assert(Next->is(tok::l_paren)); 1465 if (Next->Next == Next->MatchingParen) 1466 return true; 1467 for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen; 1468 Tok = Tok->Next) { 1469 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() || 1470 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName)) 1471 return true; 1472 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) || 1473 Tok->Tok.isLiteral()) 1474 return false; 1475 } 1476 return false; 1477 } 1478 1479 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 1480 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), 1481 E = Line.Children.end(); 1482 I != E; ++I) { 1483 calculateFormattingInformation(**I); 1484 } 1485 1486 Line.First->TotalLength = 1487 Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth; 1488 if (!Line.First->Next) 1489 return; 1490 FormatToken *Current = Line.First->Next; 1491 bool InFunctionDecl = Line.MightBeFunctionDecl; 1492 while (Current) { 1493 if (isFunctionDeclarationName(*Current)) 1494 Current->Type = TT_FunctionDeclarationName; 1495 if (Current->is(TT_LineComment)) { 1496 if (Current->Previous->BlockKind == BK_BracedInit && 1497 Current->Previous->opensScope()) 1498 Current->SpacesRequiredBefore = Style.Cpp11BracedListStyle ? 0 : 1; 1499 else 1500 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 1501 1502 // If we find a trailing comment, iterate backwards to determine whether 1503 // it seems to relate to a specific parameter. If so, break before that 1504 // parameter to avoid changing the comment's meaning. E.g. don't move 'b' 1505 // to the previous line in: 1506 // SomeFunction(a, 1507 // b, // comment 1508 // c); 1509 if (!Current->HasUnescapedNewline) { 1510 for (FormatToken *Parameter = Current->Previous; Parameter; 1511 Parameter = Parameter->Previous) { 1512 if (Parameter->isOneOf(tok::comment, tok::r_brace)) 1513 break; 1514 if (Parameter->Previous && Parameter->Previous->is(tok::comma)) { 1515 if (!Parameter->Previous->is(TT_CtorInitializerComma) && 1516 Parameter->HasUnescapedNewline) 1517 Parameter->MustBreakBefore = true; 1518 break; 1519 } 1520 } 1521 } 1522 } else if (Current->SpacesRequiredBefore == 0 && 1523 spaceRequiredBefore(Line, *Current)) { 1524 Current->SpacesRequiredBefore = 1; 1525 } 1526 1527 Current->MustBreakBefore = 1528 Current->MustBreakBefore || mustBreakBefore(Line, *Current); 1529 1530 if (Style.AlwaysBreakAfterDefinitionReturnType && InFunctionDecl && 1531 Current->is(TT_FunctionDeclarationName) && 1532 !Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions. 1533 // FIXME: Line.Last points to other characters than tok::semi 1534 // and tok::lbrace. 1535 Current->MustBreakBefore = true; 1536 1537 Current->CanBreakBefore = 1538 Current->MustBreakBefore || canBreakBefore(Line, *Current); 1539 unsigned ChildSize = 0; 1540 if (Current->Previous->Children.size() == 1) { 1541 FormatToken &LastOfChild = *Current->Previous->Children[0]->Last; 1542 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit 1543 : LastOfChild.TotalLength + 1; 1544 } 1545 const FormatToken *Prev = Current->Previous; 1546 if (Current->MustBreakBefore || Prev->Children.size() > 1 || 1547 (Prev->Children.size() == 1 && 1548 Prev->Children[0]->First->MustBreakBefore) || 1549 Current->IsMultiline) 1550 Current->TotalLength = Prev->TotalLength + Style.ColumnLimit; 1551 else 1552 Current->TotalLength = Prev->TotalLength + Current->ColumnWidth + 1553 ChildSize + Current->SpacesRequiredBefore; 1554 1555 if (Current->is(TT_CtorInitializerColon)) 1556 InFunctionDecl = false; 1557 1558 // FIXME: Only calculate this if CanBreakBefore is true once static 1559 // initializers etc. are sorted out. 1560 // FIXME: Move magic numbers to a better place. 1561 Current->SplitPenalty = 20 * Current->BindingStrength + 1562 splitPenalty(Line, *Current, InFunctionDecl); 1563 1564 Current = Current->Next; 1565 } 1566 1567 calculateUnbreakableTailLengths(Line); 1568 for (Current = Line.First; Current != nullptr; Current = Current->Next) { 1569 if (Current->Role) 1570 Current->Role->precomputeFormattingInfos(Current); 1571 } 1572 1573 DEBUG({ printDebugInfo(Line); }); 1574 } 1575 1576 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { 1577 unsigned UnbreakableTailLength = 0; 1578 FormatToken *Current = Line.Last; 1579 while (Current) { 1580 Current->UnbreakableTailLength = UnbreakableTailLength; 1581 if (Current->CanBreakBefore || 1582 Current->isOneOf(tok::comment, tok::string_literal)) { 1583 UnbreakableTailLength = 0; 1584 } else { 1585 UnbreakableTailLength += 1586 Current->ColumnWidth + Current->SpacesRequiredBefore; 1587 } 1588 Current = Current->Previous; 1589 } 1590 } 1591 1592 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 1593 const FormatToken &Tok, 1594 bool InFunctionDecl) { 1595 const FormatToken &Left = *Tok.Previous; 1596 const FormatToken &Right = Tok; 1597 1598 if (Left.is(tok::semi)) 1599 return 0; 1600 1601 if (Style.Language == FormatStyle::LK_Java) { 1602 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws)) 1603 return 1; 1604 if (Right.is(Keywords.kw_implements)) 1605 return 2; 1606 if (Left.is(tok::comma) && Left.NestingLevel == 0) 1607 return 3; 1608 } else if (Style.Language == FormatStyle::LK_JavaScript) { 1609 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma)) 1610 return 100; 1611 } 1612 1613 if (Left.is(tok::comma) || (Right.is(tok::identifier) && Right.Next && 1614 Right.Next->is(TT_DictLiteral))) 1615 return 1; 1616 if (Right.is(tok::l_square)) { 1617 if (Style.Language == FormatStyle::LK_Proto) 1618 return 1; 1619 // Slightly prefer formatting local lambda definitions like functions. 1620 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal)) 1621 return 50; 1622 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare)) 1623 return 500; 1624 } 1625 1626 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) || 1627 Right.is(tok::kw_operator)) { 1628 if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) 1629 return 3; 1630 if (Left.is(TT_StartOfName)) 1631 return 110; 1632 if (InFunctionDecl && Right.NestingLevel == 0) 1633 return Style.PenaltyReturnTypeOnItsOwnLine; 1634 return 200; 1635 } 1636 if (Right.is(TT_PointerOrReference)) 1637 return 190; 1638 if (Right.is(TT_TrailingReturnArrow)) 1639 return 110; 1640 if (Left.is(tok::equal) && Right.is(tok::l_brace)) 1641 return 150; 1642 if (Left.is(TT_CastRParen)) 1643 return 100; 1644 if (Left.is(tok::coloncolon) || 1645 (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto)) 1646 return 500; 1647 if (Left.isOneOf(tok::kw_class, tok::kw_struct)) 1648 return 5000; 1649 1650 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon)) 1651 return 2; 1652 1653 if (Right.isMemberAccess()) { 1654 if (Left.is(tok::r_paren) && Left.MatchingParen && 1655 Left.MatchingParen->ParameterCount > 0) 1656 return 20; // Should be smaller than breaking at a nested comma. 1657 return 150; 1658 } 1659 1660 if (Right.is(TT_TrailingAnnotation) && 1661 (!Right.Next || Right.Next->isNot(tok::l_paren))) { 1662 // Moving trailing annotations to the next line is fine for ObjC method 1663 // declarations. 1664 if (Line.First->is(TT_ObjCMethodSpecifier)) 1665 1666 return 10; 1667 // Generally, breaking before a trailing annotation is bad unless it is 1668 // function-like. It seems to be especially preferable to keep standard 1669 // annotations (i.e. "const", "final" and "override") on the same line. 1670 // Use a slightly higher penalty after ")" so that annotations like 1671 // "const override" are kept together. 1672 bool is_short_annotation = Right.TokenText.size() < 10; 1673 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0); 1674 } 1675 1676 // In for-loops, prefer breaking at ',' and ';'. 1677 if (Line.First->is(tok::kw_for) && Left.is(tok::equal)) 1678 return 4; 1679 1680 // In Objective-C method expressions, prefer breaking before "param:" over 1681 // breaking after it. 1682 if (Right.is(TT_SelectorName)) 1683 return 0; 1684 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr)) 1685 return Line.MightBeFunctionDecl ? 50 : 500; 1686 1687 if (Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket) 1688 return 100; 1689 if (Left.is(tok::l_paren) && Left.Previous && Left.Previous->is(tok::kw_if)) 1690 return 1000; 1691 if (Left.is(tok::equal) && InFunctionDecl) 1692 return 110; 1693 if (Right.is(tok::r_brace)) 1694 return 1; 1695 if (Left.is(TT_TemplateOpener)) 1696 return 100; 1697 if (Left.opensScope()) { 1698 if (!Style.AlignAfterOpenBracket) 1699 return 0; 1700 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter 1701 : 19; 1702 } 1703 if (Left.is(TT_JavaAnnotation)) 1704 return 50; 1705 1706 if (Right.is(tok::lessless)) { 1707 if (Left.is(tok::string_literal) && 1708 (!Right.LastOperator || Right.OperatorIndex != 1)) { 1709 StringRef Content = Left.TokenText; 1710 if (Content.startswith("\"")) 1711 Content = Content.drop_front(1); 1712 if (Content.endswith("\"")) 1713 Content = Content.drop_back(1); 1714 Content = Content.trim(); 1715 if (Content.size() > 1 && 1716 (Content.back() == ':' || Content.back() == '=')) 1717 return 25; 1718 } 1719 return 1; // Breaking at a << is really cheap. 1720 } 1721 if (Left.is(TT_ConditionalExpr)) 1722 return prec::Conditional; 1723 prec::Level Level = Left.getPrecedence(); 1724 if (Level != prec::Unknown) 1725 return Level; 1726 Level = Right.getPrecedence(); 1727 if (Level != prec::Unknown) 1728 return Level; 1729 1730 return 3; 1731 } 1732 1733 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 1734 const FormatToken &Left, 1735 const FormatToken &Right) { 1736 if (Left.is(tok::kw_return) && Right.isNot(tok::semi)) 1737 return true; 1738 if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty && 1739 Left.Tok.getObjCKeywordID() == tok::objc_property) 1740 return true; 1741 if (Right.is(tok::hashhash)) 1742 return Left.is(tok::hash); 1743 if (Left.isOneOf(tok::hashhash, tok::hash)) 1744 return Right.is(tok::hash); 1745 if (Left.is(tok::l_paren) && Right.is(tok::r_paren)) 1746 return Style.SpaceInEmptyParentheses; 1747 if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) 1748 return (Right.is(TT_CastRParen) || 1749 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) 1750 ? Style.SpacesInCStyleCastParentheses 1751 : Style.SpacesInParentheses; 1752 if (Right.isOneOf(tok::semi, tok::comma)) 1753 return false; 1754 if (Right.is(tok::less) && 1755 (Left.is(tok::kw_template) || 1756 (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 1757 return true; 1758 if (Left.isOneOf(tok::exclaim, tok::tilde)) 1759 return false; 1760 if (Left.is(tok::at) && 1761 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant, 1762 tok::numeric_constant, tok::l_paren, tok::l_brace, 1763 tok::kw_true, tok::kw_false)) 1764 return false; 1765 if (Left.is(tok::coloncolon)) 1766 return false; 1767 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) 1768 return false; 1769 if (Right.is(tok::ellipsis)) 1770 return Left.Tok.isLiteral(); 1771 if (Left.is(tok::l_square) && Right.is(tok::amp)) 1772 return false; 1773 if (Right.is(TT_PointerOrReference)) 1774 return !(Left.is(tok::r_paren) && Left.MatchingParen && 1775 (Left.MatchingParen->is(TT_OverloadedOperatorLParen) || 1776 (Left.MatchingParen->Previous && 1777 Left.MatchingParen->Previous->is( 1778 TT_FunctionDeclarationName)))) && 1779 (Left.Tok.isLiteral() || 1780 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) && 1781 (Style.PointerAlignment != FormatStyle::PAS_Left || 1782 Line.IsMultiVariableDeclStmt))); 1783 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) && 1784 (!Left.is(TT_PointerOrReference) || 1785 (Style.PointerAlignment != FormatStyle::PAS_Right && 1786 !Line.IsMultiVariableDeclStmt))) 1787 return true; 1788 if (Left.is(TT_PointerOrReference)) 1789 return Right.Tok.isLiteral() || Right.is(TT_BlockComment) || 1790 (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare, 1791 tok::l_paren) && 1792 (Style.PointerAlignment != FormatStyle::PAS_Right && 1793 !Line.IsMultiVariableDeclStmt) && 1794 Left.Previous && 1795 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); 1796 if (Right.is(tok::star) && Left.is(tok::l_paren)) 1797 return false; 1798 if (Left.is(tok::l_square)) 1799 return (Left.is(TT_ArrayInitializerLSquare) && 1800 Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) || 1801 (Left.is(TT_ArraySubscriptLSquare) && Style.SpacesInSquareBrackets && 1802 Right.isNot(tok::r_square)); 1803 if (Right.is(tok::r_square)) 1804 return Right.MatchingParen && 1805 ((Style.SpacesInContainerLiterals && 1806 Right.MatchingParen->is(TT_ArrayInitializerLSquare)) || 1807 (Style.SpacesInSquareBrackets && 1808 Right.MatchingParen->is(TT_ArraySubscriptLSquare))); 1809 if (Right.is(tok::l_square) && 1810 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare) && 1811 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral)) 1812 return false; 1813 if (Left.is(tok::colon)) 1814 return !Left.is(TT_ObjCMethodExpr); 1815 if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 1816 return !Left.Children.empty(); // No spaces in "{}". 1817 if ((Left.is(tok::l_brace) && Left.BlockKind != BK_Block) || 1818 (Right.is(tok::r_brace) && Right.MatchingParen && 1819 Right.MatchingParen->BlockKind != BK_Block)) 1820 return !Style.Cpp11BracedListStyle; 1821 if (Left.is(TT_BlockComment)) 1822 return !Left.TokenText.endswith("=*/"); 1823 if (Right.is(tok::l_paren)) { 1824 if (Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) 1825 return true; 1826 return Line.Type == LT_ObjCDecl || Left.is(tok::semi) || 1827 (Style.SpaceBeforeParens != FormatStyle::SBPO_Never && 1828 (Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, 1829 tok::kw_switch, tok::kw_case, TT_ForEachMacro) || 1830 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch, 1831 tok::kw_new, tok::kw_delete) && 1832 (!Left.Previous || Left.Previous->isNot(tok::period))))) || 1833 (Style.SpaceBeforeParens == FormatStyle::SBPO_Always && 1834 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() || Left.is(tok::r_paren)) && 1835 Line.Type != LT_PreprocessorDirective); 1836 } 1837 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword) 1838 return false; 1839 if (Right.is(TT_UnaryOperator)) 1840 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) && 1841 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr)); 1842 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square, 1843 tok::r_paren) || 1844 Left.isSimpleTypeSpecifier()) && 1845 Right.is(tok::l_brace) && Right.getNextNonComment() && 1846 Right.BlockKind != BK_Block) 1847 return false; 1848 if (Left.is(tok::period) || Right.is(tok::period)) 1849 return false; 1850 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L") 1851 return false; 1852 if (Left.is(TT_TemplateCloser) && Left.MatchingParen && 1853 Left.MatchingParen->Previous && 1854 Left.MatchingParen->Previous->is(tok::period)) 1855 // A.<B>DoSomething(); 1856 return false; 1857 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square)) 1858 return false; 1859 return true; 1860 } 1861 1862 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 1863 const FormatToken &Right) { 1864 const FormatToken &Left = *Right.Previous; 1865 if (Style.Language == FormatStyle::LK_Proto) { 1866 if (Right.is(tok::period) && 1867 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required, 1868 Keywords.kw_repeated)) 1869 return true; 1870 if (Right.is(tok::l_paren) && 1871 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) 1872 return true; 1873 } else if (Style.Language == FormatStyle::LK_JavaScript) { 1874 if (Left.is(Keywords.kw_var)) 1875 return true; 1876 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion)) 1877 return false; 1878 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) && 1879 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) 1880 return false; 1881 if (Left.is(tok::ellipsis)) 1882 return false; 1883 if (Left.is(TT_TemplateCloser) && 1884 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square, 1885 Keywords.kw_implements, Keywords.kw_extends)) 1886 // Type assertions ('<type>expr') are not followed by whitespace. Other 1887 // locations that should have whitespace following are identified by the 1888 // above set of follower tokens. 1889 return false; 1890 } else if (Style.Language == FormatStyle::LK_Java) { 1891 if (Left.is(tok::r_square) && Right.is(tok::l_brace)) 1892 return true; 1893 if (Left.is(TT_LambdaArrow) || Right.is(TT_LambdaArrow)) 1894 return true; 1895 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) 1896 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never; 1897 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private, 1898 tok::kw_protected) || 1899 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract, 1900 Keywords.kw_native)) && 1901 Right.is(TT_TemplateOpener)) 1902 return true; 1903 } 1904 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo()) 1905 return true; // Never ever merge two identifiers. 1906 if (Left.is(TT_ImplicitStringLiteral)) 1907 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd(); 1908 if (Line.Type == LT_ObjCMethodDecl) { 1909 if (Left.is(TT_ObjCMethodSpecifier)) 1910 return true; 1911 if (Left.is(tok::r_paren) && Right.is(tok::identifier)) 1912 // Don't space between ')' and <id> 1913 return false; 1914 } 1915 if (Line.Type == LT_ObjCProperty && 1916 (Right.is(tok::equal) || Left.is(tok::equal))) 1917 return false; 1918 1919 if (Right.is(TT_TrailingReturnArrow) || Left.is(TT_TrailingReturnArrow)) 1920 return true; 1921 if (Left.is(tok::comma)) 1922 return true; 1923 if (Right.is(tok::comma)) 1924 return false; 1925 if (Right.isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen)) 1926 return true; 1927 if (Left.is(tok::kw_operator)) 1928 return Right.is(tok::coloncolon); 1929 if (Right.is(TT_OverloadedOperatorLParen)) 1930 return false; 1931 if (Right.is(tok::colon)) { 1932 if (Line.First->isOneOf(tok::kw_case, tok::kw_default) || 1933 !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi)) 1934 return false; 1935 if (Right.is(TT_ObjCMethodExpr)) 1936 return false; 1937 if (Left.is(tok::question)) 1938 return false; 1939 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon)) 1940 return false; 1941 if (Right.is(TT_DictLiteral)) 1942 return Style.SpacesInContainerLiterals; 1943 return true; 1944 } 1945 if (Left.is(TT_UnaryOperator)) 1946 return Right.is(TT_BinaryOperator); 1947 1948 // If the next token is a binary operator or a selector name, we have 1949 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly. 1950 if (Left.is(TT_CastRParen)) 1951 return Style.SpaceAfterCStyleCast || 1952 Right.isOneOf(TT_BinaryOperator, TT_SelectorName); 1953 1954 if (Left.is(tok::greater) && Right.is(tok::greater)) { 1955 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) && 1956 (Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles); 1957 } 1958 if (Right.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) || 1959 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar)) 1960 return false; 1961 if (!Style.SpaceBeforeAssignmentOperators && 1962 Right.getPrecedence() == prec::Assignment) 1963 return false; 1964 if (Right.is(tok::coloncolon) && Left.isNot(tok::l_brace)) 1965 return (Left.is(TT_TemplateOpener) && 1966 Style.Standard == FormatStyle::LS_Cpp03) || 1967 !(Left.isOneOf(tok::identifier, tok::l_paren, tok::r_paren) || 1968 Left.isOneOf(TT_TemplateCloser, TT_TemplateOpener)); 1969 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser))) 1970 return Style.SpacesInAngles; 1971 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) || 1972 Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) 1973 return true; 1974 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) && 1975 Right.isNot(TT_FunctionTypeLParen)) 1976 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always; 1977 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) && 1978 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen)) 1979 return false; 1980 if (Right.is(tok::less) && Left.isNot(tok::l_paren) && 1981 Line.First->is(tok::hash)) 1982 return true; 1983 if (Right.is(TT_TrailingUnaryOperator)) 1984 return false; 1985 if (Left.is(TT_RegexLiteral)) 1986 return false; 1987 return spaceRequiredBetween(Line, Left, Right); 1988 } 1989 1990 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style. 1991 static bool isAllmanBrace(const FormatToken &Tok) { 1992 return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block && 1993 !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral); 1994 } 1995 1996 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, 1997 const FormatToken &Right) { 1998 const FormatToken &Left = *Right.Previous; 1999 if (Right.NewlinesBefore > 1) 2000 return true; 2001 2002 // If the last token before a '}' is a comma or a trailing comment, the 2003 // intention is to insert a line break after it in order to make shuffling 2004 // around entries easier. 2005 const FormatToken *BeforeClosingBrace = nullptr; 2006 if (Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) && 2007 Left.BlockKind != BK_Block && Left.MatchingParen) 2008 BeforeClosingBrace = Left.MatchingParen->Previous; 2009 else if (Right.MatchingParen && 2010 Right.MatchingParen->isOneOf(tok::l_brace, 2011 TT_ArrayInitializerLSquare)) 2012 BeforeClosingBrace = &Left; 2013 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) || 2014 BeforeClosingBrace->isTrailingComment())) 2015 return true; 2016 2017 if (Right.is(tok::comment)) 2018 return Left.BlockKind != BK_BracedInit && 2019 Left.isNot(TT_CtorInitializerColon) && 2020 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline); 2021 if (Left.isTrailingComment()) 2022 return true; 2023 if (Left.isStringLiteral() && 2024 (Right.isStringLiteral() || Right.is(TT_ObjCStringLiteral))) 2025 return true; 2026 if (Right.Previous->IsUnterminatedLiteral) 2027 return true; 2028 if (Right.is(tok::lessless) && Right.Next && 2029 Right.Previous->is(tok::string_literal) && 2030 Right.Next->is(tok::string_literal)) 2031 return true; 2032 if (Right.Previous->ClosesTemplateDeclaration && 2033 Right.Previous->MatchingParen && 2034 Right.Previous->MatchingParen->NestingLevel == 0 && 2035 Style.AlwaysBreakTemplateDeclarations) 2036 return true; 2037 if ((Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) && 2038 Style.BreakConstructorInitializersBeforeComma && 2039 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) 2040 return true; 2041 if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\"")) 2042 // Raw string literals are special wrt. line breaks. The author has made a 2043 // deliberate choice and might have aligned the contents of the string 2044 // literal accordingly. Thus, we try keep existing line breaks. 2045 return Right.NewlinesBefore > 0; 2046 if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 && 2047 Style.Language == FormatStyle::LK_Proto) 2048 // Don't put enums onto single lines in protocol buffers. 2049 return true; 2050 if (Right.is(TT_InlineASMBrace)) 2051 return Right.HasUnescapedNewline; 2052 if (Style.Language == FormatStyle::LK_JavaScript && Right.is(tok::r_brace) && 2053 Left.is(tok::l_brace) && !Left.Children.empty()) 2054 // Support AllowShortFunctionsOnASingleLine for JavaScript. 2055 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None || 2056 (Left.NestingLevel == 0 && Line.Level == 0 && 2057 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline); 2058 if (isAllmanBrace(Left) || isAllmanBrace(Right)) 2059 return Style.BreakBeforeBraces == FormatStyle::BS_Allman || 2060 Style.BreakBeforeBraces == FormatStyle::BS_GNU; 2061 if (Style.Language == FormatStyle::LK_Proto && Left.isNot(tok::l_brace) && 2062 Right.is(TT_SelectorName)) 2063 return true; 2064 if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine) 2065 return true; 2066 2067 if ((Style.Language == FormatStyle::LK_Java || 2068 Style.Language == FormatStyle::LK_JavaScript) && 2069 Left.is(TT_LeadingJavaAnnotation) && 2070 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) && 2071 Line.Last->is(tok::l_brace)) 2072 return true; 2073 2074 if (Style.Language == FormatStyle::LK_JavaScript) { 2075 // FIXME: This might apply to other languages and token kinds. 2076 if (Right.is(tok::char_constant) && Left.is(tok::plus) && Left.Previous && 2077 Left.Previous->is(tok::char_constant)) 2078 return true; 2079 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && 2080 Left.NestingLevel == 0 && Left.Previous && 2081 Left.Previous->is(tok::equal) && 2082 Line.First->isOneOf(tok::identifier, Keywords.kw_import, 2083 tok::kw_export) && 2084 // kw_var is a pseudo-token that's a tok::identifier, so matches above. 2085 !Line.First->is(Keywords.kw_var)) 2086 // Enum style object literal. 2087 return true; 2088 } else if (Style.Language == FormatStyle::LK_Java) { 2089 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next && 2090 Right.Next->is(tok::string_literal)) 2091 return true; 2092 } 2093 2094 return false; 2095 } 2096 2097 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 2098 const FormatToken &Right) { 2099 const FormatToken &Left = *Right.Previous; 2100 2101 if (Style.Language == FormatStyle::LK_Java) { 2102 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends, 2103 Keywords.kw_implements)) 2104 return false; 2105 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends, 2106 Keywords.kw_implements)) 2107 return true; 2108 } 2109 2110 if (Left.is(tok::at)) 2111 return false; 2112 if (Left.Tok.getObjCKeywordID() == tok::objc_interface) 2113 return false; 2114 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation)) 2115 return !Right.is(tok::l_paren); 2116 if (Right.is(TT_PointerOrReference)) 2117 return Line.IsMultiVariableDeclStmt || 2118 (Style.PointerAlignment == FormatStyle::PAS_Right && 2119 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName))); 2120 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) || 2121 Right.is(tok::kw_operator)) 2122 return true; 2123 if (Left.is(TT_PointerOrReference)) 2124 return false; 2125 if (Right.isTrailingComment()) 2126 // We rely on MustBreakBefore being set correctly here as we should not 2127 // change the "binding" behavior of a comment. 2128 // The first comment in a braced lists is always interpreted as belonging to 2129 // the first list element. Otherwise, it should be placed outside of the 2130 // list. 2131 return Left.BlockKind == BK_BracedInit; 2132 if (Left.is(tok::question) && Right.is(tok::colon)) 2133 return false; 2134 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question)) 2135 return Style.BreakBeforeTernaryOperators; 2136 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question)) 2137 return !Style.BreakBeforeTernaryOperators; 2138 if (Right.is(TT_InheritanceColon)) 2139 return true; 2140 if (Right.is(tok::colon) && 2141 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) 2142 return false; 2143 if (Left.is(tok::colon) && (Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr))) 2144 return true; 2145 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next && 2146 Right.Next->is(TT_ObjCMethodExpr))) 2147 return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls. 2148 if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty) 2149 return true; 2150 if (Left.ClosesTemplateDeclaration) 2151 return true; 2152 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen, 2153 TT_OverloadedOperator)) 2154 return false; 2155 if (Left.is(TT_RangeBasedForLoopColon)) 2156 return true; 2157 if (Right.is(TT_RangeBasedForLoopColon)) 2158 return false; 2159 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) || 2160 Left.is(tok::kw_operator)) 2161 return false; 2162 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) && 2163 Line.Type == LT_VirtualFunctionDecl) 2164 return false; 2165 if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen)) 2166 return false; 2167 if (Left.is(tok::l_paren) && Left.Previous && 2168 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) 2169 return false; 2170 if (Right.is(TT_ImplicitStringLiteral)) 2171 return false; 2172 2173 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser)) 2174 return false; 2175 2176 // We only break before r_brace if there was a corresponding break before 2177 // the l_brace, which is tracked by BreakBeforeClosingBrace. 2178 if (Right.is(tok::r_brace)) 2179 return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block; 2180 2181 // Allow breaking after a trailing annotation, e.g. after a method 2182 // declaration. 2183 if (Left.is(TT_TrailingAnnotation)) 2184 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren, 2185 tok::less, tok::coloncolon); 2186 2187 if (Right.is(tok::kw___attribute)) 2188 return true; 2189 2190 if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 2191 return true; 2192 2193 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral)) 2194 return true; 2195 2196 if (Left.is(TT_CtorInitializerComma) && 2197 Style.BreakConstructorInitializersBeforeComma) 2198 return false; 2199 if (Right.is(TT_CtorInitializerComma) && 2200 Style.BreakConstructorInitializersBeforeComma) 2201 return true; 2202 if ((Left.is(tok::greater) && Right.is(tok::greater)) || 2203 (Left.is(tok::less) && Right.is(tok::less))) 2204 return false; 2205 if (Right.is(TT_BinaryOperator) && 2206 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None && 2207 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All || 2208 Right.getPrecedence() != prec::Assignment)) 2209 return true; 2210 if (Left.is(TT_ArrayInitializerLSquare)) 2211 return true; 2212 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const)) 2213 return true; 2214 if (Left.isBinaryOperator() && !Left.isOneOf(tok::arrowstar, tok::lessless) && 2215 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All && 2216 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None || 2217 Left.getPrecedence() == prec::Assignment)) 2218 return true; 2219 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, 2220 tok::kw_class, tok::kw_struct) || 2221 Right.isMemberAccess() || 2222 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless, 2223 tok::colon, tok::l_square, tok::at) || 2224 (Left.is(tok::r_paren) && 2225 Right.isOneOf(tok::identifier, tok::kw_const)) || 2226 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)); 2227 } 2228 2229 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { 2230 llvm::errs() << "AnnotatedTokens:\n"; 2231 const FormatToken *Tok = Line.First; 2232 while (Tok) { 2233 llvm::errs() << " M=" << Tok->MustBreakBefore 2234 << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type 2235 << " S=" << Tok->SpacesRequiredBefore 2236 << " B=" << Tok->BlockParameterCount 2237 << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() 2238 << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind 2239 << " FakeLParens="; 2240 for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) 2241 llvm::errs() << Tok->FakeLParens[i] << "/"; 2242 llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n"; 2243 if (!Tok->Next) 2244 assert(Tok == Line.Last); 2245 Tok = Tok->Next; 2246 } 2247 llvm::errs() << "----\n"; 2248 } 2249 2250 } // namespace format 2251 } // namespace clang 2252