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