18 #include "llvm/ADT/SmallPtrSet.h" 19 #include "llvm/Support/Debug.h" 21 #define DEBUG_TYPE "format-token-annotator" 39 static bool canBeObjCSelectorComponent(
const FormatToken &
Tok) {
40 return Tok.Tok.getIdentifierInfo() !=
nullptr;
48 class AnnotatingParser {
50 AnnotatingParser(
const FormatStyle &
Style, AnnotatedLine &
Line,
51 const AdditionalKeywords &Keywords)
52 :
Style(Style),
Line(Line), CurrentToken(Line.First), AutoFound(
false),
54 Contexts.push_back(Context(tok::unknown, 1,
false));
55 resetTokenMetadata(CurrentToken);
60 if (!CurrentToken || !CurrentToken->Previous)
62 if (NonTemplateLess.count(CurrentToken->Previous))
65 const FormatToken &
Previous = *CurrentToken->Previous;
66 if (Previous.Previous) {
67 if (Previous.Previous->Tok.isLiteral())
69 if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
70 (!Previous.Previous->MatchingParen ||
71 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen)))
75 FormatToken *Left = CurrentToken->Previous;
76 Left->ParentBracket = Contexts.back().ContextKind;
77 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
81 bool InExprContext = Contexts.back().IsExpression;
83 Contexts.back().IsExpression =
false;
86 Contexts.back().InTemplateArgument =
87 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
90 CurrentToken->is(tok::question))
93 while (CurrentToken) {
94 if (CurrentToken->is(tok::greater)) {
95 Left->MatchingParen = CurrentToken;
96 CurrentToken->MatchingParen = Left;
104 Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
105 CurrentToken->Type = TT_DictLiteral;
107 CurrentToken->Type = TT_TemplateCloser;
111 if (CurrentToken->is(tok::question) &&
116 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
117 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
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))
132 updateParameterCount(Left, CurrentToken);
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;
147 bool parseParens(
bool LookForDecls =
false) {
150 FormatToken *Left = CurrentToken->Previous;
151 Left->ParentBracket = Contexts.back().ContextKind;
152 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
155 Contexts.back().ColonIsForRangeExpr =
156 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
158 bool StartsObjCMethodExpr =
false;
159 if (FormatToken *MaybeSel = Left->Previous) {
161 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
162 MaybeSel->Previous->is(tok::at)) {
163 StartsObjCMethodExpr =
true;
167 if (Left->is(TT_OverloadedOperatorLParen)) {
168 Contexts.back().IsExpression =
false;
170 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
171 Line.startsWith(tok::kw_export, Keywords.kw_type,
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,
180 Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) ||
181 Left->Previous->is(TT_BinaryOperator))) {
183 Contexts.back().IsExpression =
true;
185 (Left->Previous->is(Keywords.kw_function) ||
186 (Left->Previous->endsSequence(tok::identifier,
187 Keywords.kw_function)))) {
189 Contexts.back().IsExpression =
false;
191 Left->Previous->is(TT_JsTypeColon)) {
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)) {
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) {
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)) {
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) {
216 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
217 Contexts.back().IsExpression = !IsForOrCatch;
220 if (StartsObjCMethodExpr) {
221 Contexts.back().ColonIsObjCMethodExpr =
true;
222 Left->Type = TT_ObjCMethodExpr;
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) {
245 if (LookForDecls && CurrentToken->Next) {
246 FormatToken *Prev = CurrentToken->getPreviousNonComment();
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;
259 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
260 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
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;
276 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
277 Left->Previous && Left->Previous->is(tok::l_paren)) {
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;
288 if (StartsObjCMethodExpr) {
289 CurrentToken->Type = TT_ObjCMethodExpr;
290 if (Contexts.back().FirstObjCSelectorName) {
291 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
292 Contexts.back().LongestObjCSelectorName;
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;
303 if (!HasMultipleLines)
305 else if (HasMultipleParametersOnALine)
313 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
316 if (CurrentToken->is(tok::l_brace))
317 Left->Type = TT_Unknown;
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;
333 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
334 PossibleObjCForInToken = CurrentToken;
335 PossibleObjCForInToken->Type = TT_ObjCForIn;
339 if (CurrentToken->is(tok::comma))
340 Contexts.back().CanBeExpression =
true;
342 FormatToken *Tok = CurrentToken;
345 updateParameterCount(Left, Tok);
346 if (CurrentToken && CurrentToken->HasUnescapedNewline)
347 HasMultipleLines =
true;
352 bool isCpp11AttributeSpecifier(
const FormatToken &Tok) {
353 if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square))
355 const FormatToken *AttrTok = Tok.Next->Next;
360 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
362 if (AttrTok->isNot(tok::identifier))
364 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
368 if (AttrTok->is(tok::colon) ||
369 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
370 AttrTok->startsSequence(tok::r_paren, tok::identifier))
372 if (AttrTok->is(tok::ellipsis))
374 AttrTok = AttrTok->Next;
376 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
387 FormatToken *Left = CurrentToken->Previous;
388 Left->ParentBracket = Contexts.back().ContextKind;
389 FormatToken *
Parent = Left->getPreviousNonComment();
394 bool CppArrayTemplates =
395 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
396 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
397 Contexts.back().InTemplateArgument);
399 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
400 Contexts.back().InCpp11AttributeSpecifier;
402 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
403 bool StartsObjCMethodExpr =
404 !InsideInlineASM && !CppArrayTemplates && Style.isCpp() &&
405 !IsCpp11AttributeSpecifier && Contexts.back().CanBeExpression &&
406 Left->isNot(TT_LambdaLSquare) &&
407 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
409 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
410 tok::kw_return, tok::kw_throw) ||
411 Parent->isUnaryOperator() ||
413 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
415 bool ColonFound =
false;
417 unsigned BindingIncrease = 1;
418 if (Left->isCppStructuredBinding(Style)) {
419 Left->Type = TT_StructuredBindingLSquare;
420 }
else if (Left->is(TT_Unknown)) {
421 if (StartsObjCMethodExpr) {
422 Left->Type = TT_ObjCMethodExpr;
423 }
else if (IsCpp11AttributeSpecifier) {
424 Left->Type = TT_AttributeSquare;
426 Contexts.back().ContextKind == tok::l_brace &&
427 Parent->isOneOf(tok::l_brace, tok::comma)) {
428 Left->Type = TT_JsComputedPropertyName;
429 }
else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
430 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
431 Left->Type = TT_DesignatedInitializerLSquare;
432 }
else if (CurrentToken->is(tok::r_square) && Parent &&
433 Parent->is(TT_TemplateCloser)) {
434 Left->Type = TT_ArraySubscriptLSquare;
463 Left->Type = TT_ArrayInitializerLSquare;
464 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
466 !Left->endsSequence(tok::l_square, tok::numeric_constant,
468 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
469 Left->Type = TT_ProtoExtensionLSquare;
470 BindingIncrease = 10;
472 }
else if (!CppArrayTemplates && Parent &&
473 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
474 tok::comma, tok::l_paren, tok::l_square,
475 tok::question, tok::colon, tok::kw_return,
478 Left->Type = TT_ArrayInitializerLSquare;
480 BindingIncrease = 10;
481 Left->Type = TT_ArraySubscriptLSquare;
485 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
486 Contexts.back().IsExpression =
true;
488 Parent->is(TT_JsTypeColon))
489 Contexts.back().IsExpression =
false;
491 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
492 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
494 while (CurrentToken) {
495 if (CurrentToken->is(tok::r_square)) {
496 if (IsCpp11AttributeSpecifier)
497 CurrentToken->Type = TT_AttributeSquare;
498 else if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
499 Left->is(TT_ObjCMethodExpr)) {
502 StartsObjCMethodExpr =
false;
503 Left->Type = TT_Unknown;
505 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
506 CurrentToken->Type = TT_ObjCMethodExpr;
509 if (!ColonFound && CurrentToken->Previous &&
510 CurrentToken->Previous->is(TT_Unknown) &&
511 canBeObjCSelectorComponent(*CurrentToken->Previous))
512 CurrentToken->Previous->Type = TT_SelectorName;
516 if (Parent && Parent->is(TT_PointerOrReference))
517 Parent->Type = TT_BinaryOperator;
519 Left->MatchingParen = CurrentToken;
520 CurrentToken->MatchingParen = Left;
525 if (!Contexts.back().FirstObjCSelectorName) {
526 FormatToken*
Previous = CurrentToken->getPreviousNonComment();
527 if (Previous && Previous->is(TT_SelectorName)) {
528 Previous->ObjCSelectorNameParts = 1;
529 Contexts.back().FirstObjCSelectorName =
Previous;
532 Left->ParameterCount =
533 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
535 if (Contexts.back().FirstObjCSelectorName) {
536 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
537 Contexts.back().LongestObjCSelectorName;
538 if (Left->BlockParameterCount > 1)
539 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
544 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
546 if (CurrentToken->is(tok::colon)) {
547 if (IsCpp11AttributeSpecifier &&
548 CurrentToken->endsSequence(tok::colon, tok::identifier,
552 CurrentToken->Type = TT_AttributeColon;
553 }
else if (Left->isOneOf(TT_ArraySubscriptLSquare,
554 TT_DesignatedInitializerLSquare)) {
555 Left->Type = TT_ObjCMethodExpr;
556 StartsObjCMethodExpr =
true;
557 Contexts.back().ColonIsObjCMethodExpr =
true;
558 if (Parent && Parent->is(tok::r_paren))
560 Parent->Type = TT_CastRParen;
564 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
566 Left->Type = TT_ArrayInitializerLSquare;
567 FormatToken *Tok = CurrentToken;
570 updateParameterCount(Left, Tok);
577 FormatToken *Left = CurrentToken->Previous;
578 Left->ParentBracket = Contexts.back().ContextKind;
580 if (Contexts.back().CaretFound)
581 Left->Type = TT_ObjCBlockLBrace;
582 Contexts.back().CaretFound =
false;
584 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
585 Contexts.back().ColonIsDictLiteral =
true;
587 Contexts.back().IsExpression =
true;
589 Left->Previous->is(TT_JsTypeColon))
590 Contexts.back().IsExpression =
false;
592 while (CurrentToken) {
593 if (CurrentToken->is(tok::r_brace)) {
594 Left->MatchingParen = CurrentToken;
595 CurrentToken->MatchingParen = Left;
599 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
601 updateParameterCount(Left, CurrentToken);
602 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
603 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
604 if (Previous->is(TT_JsTypeOptionalQuestion))
605 Previous = Previous->getPreviousNonComment();
606 if ((CurrentToken->is(tok::colon) &&
607 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
610 Left->Type = TT_DictLiteral;
611 if (Previous->Tok.getIdentifierInfo() ||
612 Previous->is(tok::string_literal))
613 Previous->Type = TT_SelectorName;
615 if (CurrentToken->is(tok::colon) ||
617 Left->Type = TT_DictLiteral;
619 if (CurrentToken->is(tok::comma) &&
621 Left->Type = TT_DictLiteral;
629 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
633 if (Current->is(tok::l_brace) && Current->BlockKind ==
BK_Block)
634 ++Left->BlockParameterCount;
635 if (Current->is(tok::comma)) {
636 ++Left->ParameterCount;
638 Left->Role.reset(
new CommaSeparatedList(Style));
639 Left->Role->CommaFound(Current);
640 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
641 Left->ParameterCount = 1;
645 bool parseConditional() {
646 while (CurrentToken) {
647 if (CurrentToken->is(tok::colon)) {
648 CurrentToken->Type = TT_ConditionalExpr;
658 bool parseTemplateDeclaration() {
659 if (CurrentToken && CurrentToken->is(tok::less)) {
660 CurrentToken->Type = TT_TemplateOpener;
665 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
671 bool consumeToken() {
672 FormatToken *Tok = CurrentToken;
674 switch (Tok->Tok.getKind()) {
677 if (!Tok->Previous && Line.MustBeDeclaration)
678 Tok->Type = TT_ObjCMethodSpecifier;
685 if (Contexts.back().ColonIsForRangeExpr ||
686 (Contexts.size() == 1 &&
687 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
688 Contexts.back().ContextKind == tok::l_paren ||
689 Contexts.back().ContextKind == tok::l_square ||
690 (!Contexts.back().IsExpression &&
691 Contexts.back().ContextKind == tok::l_brace) ||
692 (Contexts.size() == 1 &&
693 Line.MustBeDeclaration)) {
694 Contexts.back().IsExpression =
false;
695 Tok->Type = TT_JsTypeColon;
699 if (Contexts.back().ColonIsDictLiteral ||
702 Tok->Type = TT_DictLiteral;
704 if (FormatToken *
Previous = Tok->getPreviousNonComment())
707 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
708 Line.startsWith(TT_ObjCMethodSpecifier)) {
709 Tok->Type = TT_ObjCMethodExpr;
710 const FormatToken *BeforePrevious = Tok->Previous->Previous;
713 bool UnknownIdentifierInMethodDeclaration =
714 Line.startsWith(TT_ObjCMethodSpecifier) &&
715 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
716 if (!BeforePrevious ||
718 !(BeforePrevious->is(TT_CastRParen) ||
719 (BeforePrevious->is(TT_ObjCMethodExpr) &&
720 BeforePrevious->is(tok::colon))) ||
721 BeforePrevious->is(tok::r_square) ||
722 Contexts.back().LongestObjCSelectorName == 0 ||
723 UnknownIdentifierInMethodDeclaration) {
724 Tok->Previous->Type = TT_SelectorName;
725 if (!Contexts.back().FirstObjCSelectorName)
726 Contexts.back().FirstObjCSelectorName = Tok->Previous;
727 else if (Tok->Previous->ColumnWidth >
728 Contexts.back().LongestObjCSelectorName)
729 Contexts.back().LongestObjCSelectorName =
730 Tok->Previous->ColumnWidth;
731 Tok->Previous->ParameterIndex =
732 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
733 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
735 }
else if (Contexts.back().ColonIsForRangeExpr) {
736 Tok->Type = TT_RangeBasedForLoopColon;
737 }
else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
738 Tok->Type = TT_BitFieldColon;
739 }
else if (Contexts.size() == 1 &&
740 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
741 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren,
743 Tok->Type = TT_CtorInitializerColon;
745 Tok->Type = TT_InheritanceColon;
746 }
else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
747 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
748 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
749 Tok->Next->Next->is(tok::colon)))) {
752 Tok->Type = TT_ObjCMethodExpr;
753 }
else if (Contexts.back().ContextKind == tok::l_paren) {
754 Tok->Type = TT_InlineASMColon;
762 !Contexts.back().IsExpression)
763 Tok->Type = TT_JsTypeOperator;
767 if (Tok->is(tok::kw_if) && CurrentToken &&
768 CurrentToken->is(tok::kw_constexpr))
770 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
772 if (!parseParens(
true))
779 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
780 (Tok->Next && Tok->Next->is(tok::colon)))
783 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
786 Contexts.back().ColonIsForRangeExpr =
true;
796 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
797 Tok->Previous->MatchingParen &&
798 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
799 Tok->Previous->Type = TT_OverloadedOperator;
800 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
801 Tok->Type = TT_OverloadedOperatorLParen;
806 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
807 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
809 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
810 TT_LeadingJavaAnnotation)))
811 Line.MightBeFunctionDecl =
true;
819 FormatToken *
Previous = Tok->getPreviousNonComment();
820 if (Previous && Previous->Type != TT_DictLiteral)
821 Previous->Type = TT_SelectorName;
828 Tok->Type = TT_TemplateOpener;
836 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
837 Tok->Type = TT_DictLiteral;
838 FormatToken *
Previous = Tok->getPreviousNonComment();
839 if (Previous && Previous->Type != TT_DictLiteral)
840 Previous->Type = TT_SelectorName;
843 Tok->Type = TT_BinaryOperator;
844 NonTemplateLess.insert(Tok);
859 Tok->Type = TT_BinaryOperator;
861 case tok::kw_operator:
865 while (CurrentToken &&
866 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
867 if (CurrentToken->isOneOf(tok::star, tok::amp))
868 CurrentToken->Type = TT_PointerOrReference;
871 CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator,
873 CurrentToken->Previous->Type = TT_OverloadedOperator;
876 CurrentToken->Type = TT_OverloadedOperatorLParen;
877 if (CurrentToken->Previous->is(TT_BinaryOperator))
878 CurrentToken->Previous->Type = TT_OverloadedOperator;
883 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
889 Tok->Type = TT_JsTypeOptionalQuestion;
894 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
899 case tok::kw_template:
900 parseTemplateDeclaration();
903 if (Contexts.back().InCtorInitializer)
904 Tok->Type = TT_CtorInitializerComma;
905 else if (Contexts.back().InInheritanceList)
906 Tok->Type = TT_InheritanceComma;
907 else if (Contexts.back().FirstStartOfName &&
908 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
909 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
910 Line.IsMultiVariableDeclStmt =
true;
912 if (Contexts.back().IsForEachMacro)
913 Contexts.back().IsExpression =
true;
915 case tok::identifier:
916 if (Tok->isOneOf(Keywords.kw___has_include,
917 Keywords.kw___has_include_next)) {
927 void parseIncludeDirective() {
928 if (CurrentToken && CurrentToken->is(tok::less)) {
930 while (CurrentToken) {
933 if (CurrentToken->isNot(tok::comment) &&
934 !CurrentToken->TokenText.startswith(
"//"))
935 CurrentToken->Type = TT_ImplicitStringLiteral;
941 void parseWarningOrError() {
946 while (CurrentToken) {
947 CurrentToken->Type = TT_ImplicitStringLiteral;
955 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
956 bool IsMark = CurrentToken->is(Keywords.kw_mark);
959 while (CurrentToken) {
960 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
961 CurrentToken->Type = TT_ImplicitStringLiteral;
967 void parseHasInclude() {
968 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
971 parseIncludeDirective();
975 LineType parsePreprocessorDirective() {
976 bool IsFirstToken = CurrentToken->IsFirst;
986 while (CurrentToken) {
988 CurrentToken->Type = TT_ImplicitStringLiteral;
994 if (CurrentToken->Tok.is(tok::numeric_constant)) {
995 CurrentToken->SpacesRequiredBefore = 1;
1000 if (!CurrentToken->Tok.getIdentifierInfo())
1002 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1003 case tok::pp_include:
1004 case tok::pp_include_next:
1005 case tok::pp_import:
1007 parseIncludeDirective();
1011 case tok::pp_warning:
1012 parseWarningOrError();
1014 case tok::pp_pragma:
1019 Contexts.back().IsExpression =
true;
1025 while (CurrentToken) {
1026 FormatToken *Tok = CurrentToken;
1028 if (Tok->is(tok::l_paren))
1030 else if (Tok->isOneOf(Keywords.kw___has_include,
1031 Keywords.kw___has_include_next))
1039 NonTemplateLess.clear();
1040 if (CurrentToken->is(tok::hash))
1041 return parsePreprocessorDirective();
1046 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1048 CurrentToken->is(Keywords.kw_package)) ||
1049 (Info && Info->getPPKeywordID() == tok::pp_import &&
1050 CurrentToken->Next &&
1051 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1054 parseIncludeDirective();
1060 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
1061 parseIncludeDirective();
1068 CurrentToken->is(Keywords.kw_option)) {
1070 if (CurrentToken && CurrentToken->is(tok::identifier))
1074 bool KeywordVirtualFound =
false;
1075 bool ImportStatement =
false;
1079 CurrentToken->is(Keywords.kw_import))
1080 ImportStatement =
true;
1082 while (CurrentToken) {
1083 if (CurrentToken->is(tok::kw_virtual))
1084 KeywordVirtualFound =
true;
1092 if (Line.First->is(tok::kw_export) &&
1093 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1094 CurrentToken->Next->isStringLiteral())
1095 ImportStatement =
true;
1096 if (isClosureImportStatement(*CurrentToken))
1097 ImportStatement =
true;
1099 if (!consumeToken())
1102 if (KeywordVirtualFound)
1104 if (ImportStatement)
1107 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
1108 if (Contexts.back().FirstObjCSelectorName)
1109 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1110 Contexts.back().LongestObjCSelectorName;
1118 bool isClosureImportStatement(
const FormatToken &Tok) {
1121 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
1123 (Tok.Next->Next->TokenText ==
"module" ||
1124 Tok.Next->Next->TokenText ==
"provide" ||
1125 Tok.Next->Next->TokenText ==
"require" ||
1126 Tok.Next->Next->TokenText ==
"requireType" ||
1127 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
1128 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1131 void resetTokenMetadata(FormatToken *Token) {
1137 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
1138 TT_FunctionLBrace, TT_ImplicitStringLiteral,
1139 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
1140 TT_OverloadedOperator, TT_RegexLiteral,
1141 TT_TemplateString, TT_ObjCStringLiteral))
1142 CurrentToken->Type = TT_Unknown;
1143 CurrentToken->Role.reset();
1144 CurrentToken->MatchingParen =
nullptr;
1145 CurrentToken->FakeLParens.clear();
1146 CurrentToken->FakeRParens = 0;
1151 CurrentToken->NestingLevel = Contexts.size() - 1;
1152 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1153 modifyContext(*CurrentToken);
1154 determineTokenType(*CurrentToken);
1155 CurrentToken = CurrentToken->Next;
1158 resetTokenMetadata(CurrentToken);
1189 struct ScopedContextCreator {
1190 AnnotatingParser &
P;
1195 P.Contexts.push_back(Context(ContextKind,
1196 P.Contexts.back().BindingStrength + Increase,
1197 P.Contexts.back().IsExpression));
1200 ~ScopedContextCreator() { P.Contexts.pop_back(); }
1203 void modifyContext(
const FormatToken &Current) {
1205 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1209 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1210 Line.startsWith(tok::kw_export, Keywords.kw_type,
1211 tok::identifier))) &&
1212 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1213 Contexts.back().IsExpression =
true;
1214 if (!Line.startsWith(TT_UnaryOperator)) {
1215 for (FormatToken *
Previous = Current.Previous;
1217 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1219 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
1226 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1227 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1229 Previous->Type = TT_PointerOrReference;
1232 }
else if (Current.is(tok::lessless) &&
1233 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1234 Contexts.back().IsExpression =
true;
1235 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1236 Contexts.back().IsExpression =
true;
1237 }
else if (Current.is(TT_TrailingReturnArrow)) {
1238 Contexts.back().IsExpression =
false;
1239 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1241 }
else if (Current.Previous &&
1242 Current.Previous->is(TT_CtorInitializerColon)) {
1243 Contexts.back().IsExpression =
true;
1244 Contexts.back().InCtorInitializer =
true;
1245 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1246 Contexts.back().InInheritanceList =
true;
1247 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1248 for (FormatToken *
Previous = Current.Previous;
1251 Previous->Type = TT_PointerOrReference;
1252 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer)
1253 Contexts.back().IsExpression =
false;
1254 }
else if (Current.is(tok::kw_new)) {
1255 Contexts.back().CanBeExpression =
false;
1256 }
else if (Current.isOneOf(tok::semi, tok::exclaim)) {
1258 Contexts.back().IsExpression =
true;
1262 void determineTokenType(FormatToken &Current) {
1263 if (!Current.is(TT_Unknown))
1268 if (Current.is(tok::exclaim)) {
1269 if (Current.Previous &&
1270 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1271 tok::r_paren, tok::r_square,
1273 Current.Previous->Tok.isLiteral())) {
1274 Current.Type = TT_JsNonNullAssertion;
1278 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1279 Current.Type = TT_JsNonNullAssertion;
1288 if (Current.is(Keywords.kw_instanceof)) {
1289 Current.Type = TT_BinaryOperator;
1290 }
else if (isStartOfName(Current) &&
1291 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1292 Contexts.back().FirstStartOfName = &Current;
1293 Current.Type = TT_StartOfName;
1294 }
else if (Current.is(tok::semi)) {
1298 Contexts.back().FirstStartOfName =
nullptr;
1299 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1301 }
else if (Current.is(tok::arrow) &&
1303 Current.Type = TT_LambdaArrow;
1304 }
else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1305 Current.NestingLevel == 0) {
1306 Current.Type = TT_TrailingReturnArrow;
1307 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1308 Current.Type = determineStarAmpUsage(Current,
1309 Contexts.back().CanBeExpression &&
1310 Contexts.back().IsExpression,
1311 Contexts.back().InTemplateArgument);
1312 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1313 Current.Type = determinePlusMinusCaretUsage(Current);
1314 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1315 Contexts.back().CaretFound =
true;
1316 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1317 Current.Type = determineIncrementUsage(Current);
1318 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1319 Current.Type = TT_UnaryOperator;
1320 }
else if (Current.is(tok::question)) {
1322 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1325 Current.Type = TT_JsTypeOptionalQuestion;
1327 Current.Type = TT_ConditionalExpr;
1329 }
else if (Current.isBinaryOperator() &&
1330 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1331 (!Current.is(tok::greater) &&
1333 Current.Type = TT_BinaryOperator;
1334 }
else if (Current.is(tok::comment)) {
1335 if (Current.TokenText.startswith(
"/*")) {
1336 if (Current.TokenText.endswith(
"*/"))
1337 Current.Type = TT_BlockComment;
1341 Current.Tok.setKind(tok::unknown);
1343 Current.Type = TT_LineComment;
1345 }
else if (Current.is(tok::r_paren)) {
1346 if (rParenEndsCast(Current))
1347 Current.Type = TT_CastRParen;
1348 if (Current.MatchingParen && Current.Next &&
1349 !Current.Next->isBinaryOperator() &&
1350 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1351 tok::comma, tok::period, tok::arrow,
1353 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1355 if (AfterParen->Tok.isNot(tok::caret)) {
1356 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1357 if (BeforeParen->is(tok::identifier) &&
1358 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1359 (!BeforeParen->Previous ||
1360 BeforeParen->Previous->ClosesTemplateDeclaration))
1361 Current.Type = TT_FunctionAnnotationRParen;
1364 }
else if (Current.is(tok::at) && Current.Next &&
1369 switch (Current.Next->Tok.getObjCKeywordID()) {
1370 case tok::objc_interface:
1371 case tok::objc_implementation:
1372 case tok::objc_protocol:
1373 Current.Type = TT_ObjCDecl;
1375 case tok::objc_property:
1376 Current.Type = TT_ObjCProperty;
1381 }
else if (Current.is(tok::period)) {
1382 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1383 if (PreviousNoComment &&
1384 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1385 Current.Type = TT_DesignatedInitializerPeriod;
1387 Current.Previous->isOneOf(TT_JavaAnnotation,
1388 TT_LeadingJavaAnnotation)) {
1389 Current.Type = Current.Previous->Type;
1391 }
else if (canBeObjCSelectorComponent(Current) &&
1393 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1394 Current.Previous->MatchingParen &&
1395 Current.Previous->MatchingParen->Previous &&
1396 Current.Previous->MatchingParen->Previous->is(
1397 TT_ObjCMethodSpecifier)) {
1401 Current.Type = TT_SelectorName;
1402 }
else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
1404 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1405 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1408 Current.Type = TT_TrailingAnnotation;
1412 if (Current.Previous->is(tok::at) &&
1413 Current.isNot(Keywords.kw_interface)) {
1414 const FormatToken &AtToken = *Current.Previous;
1415 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1416 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1417 Current.Type = TT_LeadingJavaAnnotation;
1419 Current.Type = TT_JavaAnnotation;
1420 }
else if (Current.Previous->is(tok::period) &&
1421 Current.Previous->isOneOf(TT_JavaAnnotation,
1422 TT_LeadingJavaAnnotation)) {
1423 Current.Type = Current.Previous->Type;
1433 bool isStartOfName(
const FormatToken &Tok) {
1434 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1437 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1441 Tok.Previous->is(Keywords.kw_in))
1445 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1446 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1447 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1449 if (!PreviousNotConst)
1452 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1453 PreviousNotConst->Previous &&
1454 PreviousNotConst->Previous->is(tok::hash);
1456 if (PreviousNotConst->is(TT_TemplateCloser))
1457 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1458 PreviousNotConst->MatchingParen->Previous &&
1459 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1460 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1462 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1463 PreviousNotConst->MatchingParen->Previous &&
1464 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1467 return (!IsPPKeyword &&
1468 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1469 PreviousNotConst->is(TT_PointerOrReference) ||
1470 PreviousNotConst->isSimpleTypeSpecifier();
1474 bool rParenEndsCast(
const FormatToken &Tok) {
1480 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1483 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1487 if (LeftOfParens->is(tok::r_paren)) {
1488 if (!LeftOfParens->MatchingParen ||
1489 !LeftOfParens->MatchingParen->Previous)
1491 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1496 if (LeftOfParens->Tok.getIdentifierInfo() &&
1497 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1503 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1504 TT_TemplateCloser, tok::ellipsis))
1508 if (Tok.Next->is(tok::question))
1517 if (Tok.Next->isNot(tok::string_literal) &&
1518 (Tok.Next->Tok.isLiteral() ||
1519 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1523 bool ParensAreType =
1525 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1526 Tok.Previous->isSimpleTypeSpecifier();
1527 bool ParensCouldEndDecl =
1528 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1529 if (ParensAreType && !ParensCouldEndDecl)
1540 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1541 Token = Token->Next)
1542 if (Token->is(TT_BinaryOperator))
1547 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1550 if (!Tok.Next->Next)
1557 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1558 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1559 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1562 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1563 Prev = Prev->Previous) {
1564 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1574 return TT_BinaryOperator;
1576 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1578 return TT_UnaryOperator;
1580 const FormatToken *NextToken = Tok.getNextNonComment();
1582 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) ||
1583 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1584 return TT_PointerOrReference;
1586 if (PrevToken->is(tok::coloncolon))
1587 return TT_PointerOrReference;
1589 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1590 tok::comma, tok::semi, tok::kw_return, tok::colon,
1591 tok::equal, tok::kw_delete, tok::kw_sizeof,
1593 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1594 TT_UnaryOperator, TT_CastRParen))
1595 return TT_UnaryOperator;
1597 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1598 return TT_PointerOrReference;
1600 return TT_PointerOrReference;
1601 if (NextToken->isOneOf(tok::comma, tok::semi))
1602 return TT_PointerOrReference;
1604 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
1605 FormatToken *TokenBeforeMatchingParen =
1606 PrevToken->MatchingParen->getPreviousNonComment();
1607 if (TokenBeforeMatchingParen &&
1608 TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype))
1609 return TT_PointerOrReference;
1612 if (PrevToken->Tok.isLiteral() ||
1613 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1614 tok::kw_false, tok::r_brace) ||
1615 NextToken->Tok.isLiteral() ||
1616 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1617 NextToken->isUnaryOperator() ||
1621 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1622 return TT_BinaryOperator;
1625 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1626 return TT_BinaryOperator;
1630 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1631 if (NextNextToken && NextNextToken->is(tok::arrow))
1632 return TT_BinaryOperator;
1636 if (IsExpression && !Contexts.back().CaretFound)
1637 return TT_BinaryOperator;
1639 return TT_PointerOrReference;
1642 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1643 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1645 return TT_UnaryOperator;
1647 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
1649 return TT_UnaryOperator;
1652 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1653 tok::question, tok::colon, tok::kw_return,
1654 tok::kw_case, tok::at, tok::l_brace))
1655 return TT_UnaryOperator;
1658 if (PrevToken->is(TT_BinaryOperator))
1659 return TT_UnaryOperator;
1662 return TT_BinaryOperator;
1666 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1667 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1668 if (!PrevToken || PrevToken->is(TT_CastRParen))
1669 return TT_UnaryOperator;
1670 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1671 return TT_TrailingUnaryOperator;
1673 return TT_UnaryOperator;
1676 SmallVector<Context, 8> Contexts;
1678 const FormatStyle &
Style;
1679 AnnotatedLine &
Line;
1680 FormatToken *CurrentToken;
1682 const AdditionalKeywords &Keywords;
1688 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
1696 class ExpressionParser {
1698 ExpressionParser(
const FormatStyle &
Style,
const AdditionalKeywords &Keywords,
1699 AnnotatedLine &
Line)
1700 :
Style(Style), Keywords(Keywords), Current(Line.First) {}
1703 void parse(
int Precedence = 0) {
1706 while (Current && (Current->is(tok::kw_return) ||
1707 (Current->is(tok::colon) &&
1708 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1711 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1716 parseConditionalExpr();
1722 if (Precedence == PrecedenceUnaryOperator) {
1723 parseUnaryOperator();
1727 FormatToken *Start = Current;
1728 FormatToken *LatestOperator =
nullptr;
1729 unsigned OperatorIndex = 0;
1733 parse(Precedence + 1);
1735 int CurrentPrecedence = getCurrentPrecedence();
1737 if (Current && Current->is(TT_SelectorName) &&
1738 Precedence == CurrentPrecedence) {
1740 addFakeParenthesis(Start,
prec::Level(Precedence));
1747 (Current->closesScope() &&
1748 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1749 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1756 if (Current->opensScope()) {
1759 while (Current && (!Current->closesScope() || Current->opensScope())) {
1766 if (CurrentPrecedence == Precedence) {
1768 LatestOperator->NextOperator = Current;
1769 LatestOperator = Current;
1770 Current->OperatorIndex = OperatorIndex;
1773 next(Precedence > 0);
1777 if (LatestOperator && (Current || Precedence > 0)) {
1779 if (Precedence == PrecedenceArrowAndPeriod) {
1783 addFakeParenthesis(Start,
prec::Level(Precedence));
1791 int getCurrentPrecedence() {
1793 const FormatToken *NextNonComment = Current->getNextNonComment();
1794 if (Current->is(TT_ConditionalExpr))
1796 if (NextNonComment && Current->is(TT_SelectorName) &&
1797 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
1800 NextNonComment->is(tok::less))))
1802 if (Current->is(TT_JsComputedPropertyName))
1804 if (Current->is(TT_LambdaArrow))
1806 if (Current->is(TT_JsFatArrow))
1808 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1809 (Current->is(tok::comment) && NextNonComment &&
1810 NextNonComment->is(TT_SelectorName)))
1812 if (Current->is(TT_RangeBasedForLoopColon))
1816 Current->is(Keywords.kw_instanceof))
1819 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
1821 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1822 return Current->getPrecedence();
1823 if (Current->isOneOf(tok::period, tok::arrow))
1824 return PrecedenceArrowAndPeriod;
1827 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1828 Keywords.kw_throws))
1834 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
1835 Start->FakeLParens.push_back(Precedence);
1837 Start->StartsBinaryExpression =
true;
1839 FormatToken *
Previous = Current->Previous;
1840 while (Previous->is(tok::comment) && Previous->Previous)
1841 Previous = Previous->Previous;
1842 ++Previous->FakeRParens;
1844 Previous->EndsBinaryExpression =
true;
1850 void parseUnaryOperator() {
1852 while (Current && Current->is(TT_UnaryOperator)) {
1853 Tokens.push_back(Current);
1856 parse(PrecedenceArrowAndPeriod);
1857 for (FormatToken *Token : llvm::reverse(Tokens))
1862 void parseConditionalExpr() {
1863 while (Current && Current->isTrailingComment()) {
1866 FormatToken *Start = Current;
1868 if (!Current || !Current->is(tok::question))
1872 if (!Current || Current->isNot(TT_ConditionalExpr))
1879 void next(
bool SkipPastLeadingComments =
true) {
1881 Current = Current->Next;
1883 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1884 Current->isTrailingComment())
1885 Current = Current->Next;
1888 const FormatStyle &
Style;
1889 const AdditionalKeywords &Keywords;
1890 FormatToken *Current;
1901 bool CommentLine =
true;
1903 if (!
Tok->
is(tok::comment)) {
1904 CommentLine =
false;
1911 if (NextNonCommentLine && CommentLine &&
1914 (*I)->First->OriginalColumn) {
1920 : NextNonCommentLine->
Level;
1922 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
1925 setCommentLineLevels((*I)->Children);
1930 unsigned Result = 0;
1943 Line.
Type = Parser.parseLine();
1955 ExpressionParser ExprParser(
Style, Keywords, Line);
1974 for (; Next; Next = Next->Next) {
1975 if (Next->is(TT_OverloadedOperatorLParen))
1977 if (Next->is(TT_OverloadedOperator))
1979 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
1981 if (Next->Next && Next->Next->is(tok::l_square) && Next->Next->Next &&
1982 Next->Next->Next->is(tok::r_square))
1983 Next = Next->Next->Next;
1994 if (Current.
is(tok::kw_operator)) {
1997 Next = skipOperatorName(Next);
2001 for (; Next; Next = Next->
Next) {
2002 if (Next->
is(TT_TemplateOpener)) {
2004 }
else if (Next->
is(tok::coloncolon)) {
2008 if (Next->
is(tok::kw_operator)) {
2009 Next = skipOperatorName(Next->
Next);
2012 if (!Next->
is(tok::identifier))
2014 }
else if (Next->
is(tok::l_paren)) {
2026 if (Line.
Last->
is(tok::l_brace))
2041 Tok->
isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
2043 if (
Tok->
isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2077 calculateFormattingInformation(**I);
2087 Current->
Type = TT_FunctionDeclarationName;
2088 if (Current->
is(TT_LineComment)) {
2105 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
2108 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
2116 spaceRequiredBefore(Line, *Current)) {
2124 Current->
is(TT_FunctionDeclarationName))
2129 unsigned ChildSize = 0;
2138 Prev->
Children[0]->First->MustBreakBefore) ||
2145 if (Current->
is(TT_CtorInitializerColon))
2146 InFunctionDecl =
false;
2157 Current->
SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
2166 Current = Current->
Next;
2169 calculateUnbreakableTailLengths(Line);
2170 unsigned IndentLevel = Line.
Level;
2171 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
2173 Current->
Role->precomputeFormattingInfos(Current);
2176 assert(IndentLevel > 0);
2187 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
2188 unsigned UnbreakableTailLength = 0;
2193 Current->
isOneOf(tok::comment, tok::string_literal)) {
2194 UnbreakableTailLength = 0;
2196 UnbreakableTailLength +=
2203 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
2205 bool InFunctionDecl) {
2209 if (Left.
is(tok::semi))
2213 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2215 if (Right.
is(Keywords.kw_implements))
2220 if (Right.
is(Keywords.kw_function) && Left.
isNot(tok::comma))
2222 if (Left.
is(TT_JsTypeColon))
2224 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2225 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2232 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
2234 if (Right.
is(tok::l_square)) {
2237 if (Left.
is(tok::r_square))
2240 if (Right.
is(TT_LambdaLSquare) && Left.
is(tok::equal))
2242 if (!Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2243 TT_ArrayInitializerLSquare,
2244 TT_DesignatedInitializerLSquare, TT_AttributeSquare))
2248 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2249 Right.
is(tok::kw_operator)) {
2252 if (Left.
is(TT_StartOfName))
2258 if (Right.
is(TT_PointerOrReference))
2260 if (Right.
is(TT_LambdaArrow))
2262 if (Left.
is(tok::equal) && Right.
is(tok::l_brace))
2264 if (Left.
is(TT_CastRParen))
2266 if (Left.
is(tok::coloncolon) ||
2269 if (Left.
isOneOf(tok::kw_class, tok::kw_struct))
2271 if (Left.
is(tok::comment))
2274 if (Left.
isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2275 TT_CtorInitializerColon))
2303 if (Right.
is(TT_TrailingAnnotation) &&
2314 bool is_short_annotation = Right.
TokenText.size() < 10;
2315 return (Left.
is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2319 if (Line.
startsWith(tok::kw_for) && Left.
is(tok::equal))
2324 if (Right.
is(TT_SelectorName))
2326 if (Left.
is(tok::colon) && Left.
is(TT_ObjCMethodExpr))
2336 if (Left.
is(tok::l_paren) && InFunctionDecl &&
2339 if (Left.
is(tok::l_paren) && Left.
Previous &&
2343 if (Left.
is(tok::equal) && InFunctionDecl)
2345 if (Right.
is(tok::r_brace))
2347 if (Left.
is(TT_TemplateOpener))
2357 if (Left.
is(TT_JavaAnnotation))
2367 if (Left.
is(tok::comma))
2372 if (Right.
is(tok::lessless)) {
2381 if (Left.
is(TT_ConditionalExpr))
2394 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
2397 if (Left.
is(tok::kw_return) && Right.
isNot(tok::semi))
2404 if (Right.
is(tok::hashhash))
2405 return Left.
is(tok::hash);
2406 if (Left.
isOneOf(tok::hashhash, tok::hash))
2407 return Right.
is(tok::hash);
2408 if (Left.
is(tok::l_paren) && Right.
is(tok::r_paren))
2410 if (Left.
is(tok::l_paren) || Right.
is(tok::r_paren))
2411 return (Right.
is(TT_CastRParen) ||
2415 if (Right.
isOneOf(tok::semi, tok::comma))
2418 bool IsLightweightGeneric =
2423 if (Right.
is(tok::less) && Left.
is(tok::kw_template))
2425 if (Left.
isOneOf(tok::exclaim, tok::tilde))
2427 if (Left.
is(tok::at) &&
2428 Right.
isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2429 tok::numeric_constant, tok::l_paren, tok::l_brace,
2430 tok::kw_true, tok::kw_false))
2432 if (Left.
is(tok::colon))
2433 return !Left.
is(TT_ObjCMethodExpr);
2434 if (Left.
is(tok::coloncolon))
2436 if (Left.
is(tok::less) || Right.
isOneOf(tok::greater, tok::less)) {
2439 (Left.
is(TT_DictLiteral) || Right.
is(TT_DictLiteral)))) {
2441 if (Left.
is(tok::less) && Right.
is(tok::greater))
2447 if (Right.
is(tok::ellipsis))
2450 if (Left.
is(tok::l_square) && Right.
is(tok::amp))
2452 if (Right.
is(TT_PointerOrReference)) {
2458 if (!TokenBeforeMatchingParen ||
2459 !TokenBeforeMatchingParen->
isOneOf(tok::kw_typeof, tok::kw_decltype))
2463 (!Left.
isOneOf(TT_PointerOrReference, tok::l_paren) &&
2469 if (Right.
is(TT_FunctionTypeLParen) && Left.
isNot(tok::l_paren) &&
2470 (!Left.
is(TT_PointerOrReference) ||
2474 if (Left.
is(TT_PointerOrReference))
2476 (Right.
isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2477 !Right.
is(TT_StartOfName)) ||
2479 (!Right.
isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2485 if (Right.
is(tok::star) && Left.
is(tok::l_paren))
2487 const auto SpaceRequiredForArrayInitializerLSquare =
2496 if (Left.
is(tok::l_square))
2497 return (Left.
is(TT_ArrayInitializerLSquare) && Right.
isNot(tok::r_square) &&
2498 SpaceRequiredForArrayInitializerLSquare(Left,
Style)) ||
2499 (Left.
isOneOf(TT_ArraySubscriptLSquare,
2500 TT_StructuredBindingLSquare) &&
2502 if (Right.
is(tok::r_square))
2505 SpaceRequiredForArrayInitializerLSquare(*Right.
MatchingParen,
2509 TT_StructuredBindingLSquare)) ||
2511 if (Right.
is(tok::l_square) &&
2512 !Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2513 TT_DesignatedInitializerLSquare,
2514 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
2515 !Left.
isOneOf(tok::numeric_constant, TT_DictLiteral))
2517 if (Left.
is(tok::l_brace) && Right.
is(tok::r_brace))
2523 if (Left.
is(TT_BlockComment))
2527 if (Right.
is(tok::l_paren)) {
2528 if ((Left.
is(tok::r_paren) && Left.
is(TT_AttributeParen)) ||
2529 (Left.
is(tok::r_square) && Left.
is(TT_AttributeSquare)))
2533 (Left.
isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
2534 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2537 (Left.
isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2538 tok::kw_new, tok::kw_delete) &&
2542 Left.
is(tok::r_paren)) &&
2547 if (Right.
is(TT_UnaryOperator))
2548 return !Left.
isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2549 (Left.
isNot(tok::colon) || Left.
isNot(TT_ObjCMethodExpr));
2550 if ((Left.
isOneOf(tok::identifier, tok::greater, tok::r_square,
2556 if (Left.
is(tok::period) || Right.
is(tok::period))
2558 if (Right.
is(tok::hash) && Left.
is(tok::identifier) && Left.
TokenText ==
"L")
2568 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_square))
2570 if (Left.
is(tok::l_brace) && Left.
endsSequence(TT_DictLiteral, tok::at))
2580 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2586 if (Left.
is(tok::kw_operator))
2587 return Right.
is(tok::coloncolon);
2593 if (Right.
is(tok::period) &&
2594 Left.
isOneOf(Keywords.kw_optional, Keywords.kw_required,
2595 Keywords.kw_repeated, Keywords.kw_extend))
2597 if (Right.
is(tok::l_paren) &&
2598 Left.
isOneOf(Keywords.kw_returns, Keywords.kw_option))
2600 if (Right.
isOneOf(tok::l_brace, tok::less) && Left.
is(TT_SelectorName))
2603 if (Left.
is(tok::slash) || Right.
is(tok::slash))
2606 Right.
isOneOf(tok::l_brace, tok::less))
2609 if (Left.
is(tok::percent))
2613 if (Left.
is(tok::numeric_constant) && Right.
is(tok::percent))
2616 if (Left.
is(TT_JsFatArrow))
2619 if (Right.
is(tok::l_paren) && Left.
is(Keywords.kw_await) && Left.
Previous &&
2622 if (Left.
is(Keywords.kw_async) && Right.
is(tok::l_paren) &&
2627 if (Next && Next->
is(TT_JsFatArrow))
2630 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2631 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2636 if (Left.
is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2637 Right.
is(TT_TemplateString))
2639 if (Right.
is(tok::star) &&
2640 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield))
2642 if (Right.
isOneOf(tok::l_brace, tok::l_square) &&
2643 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield,
2644 Keywords.kw_extends, Keywords.kw_implements))
2646 if (Right.
is(tok::l_paren)) {
2656 if (Left.
isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
2660 if ((Left.
isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2671 Left.
Previous->
is(tok::period) && Right.
is(tok::l_paren))
2673 if (Left.
is(Keywords.kw_as) &&
2674 Right.
isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2676 if (Left.
is(tok::kw_default) && Left.
Previous &&
2679 if (Left.
is(Keywords.kw_is) && Right.
is(tok::l_brace))
2681 if (Right.
isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2683 if (Left.
is(TT_JsTypeOperator) || Right.
is(TT_JsTypeOperator))
2685 if ((Left.
is(tok::l_brace) || Right.
is(tok::r_brace)) &&
2686 Line.
First->
isOneOf(Keywords.kw_import, tok::kw_export))
2688 if (Left.
is(tok::ellipsis))
2690 if (Left.
is(TT_TemplateCloser) &&
2691 !Right.
isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2692 Keywords.kw_implements, Keywords.kw_extends))
2697 if (Right.
is(TT_JsNonNullAssertion))
2699 if (Left.
is(TT_JsNonNullAssertion) &&
2700 Right.
isOneOf(Keywords.kw_as, Keywords.kw_in))
2703 if (Left.
is(tok::r_square) && Right.
is(tok::l_brace))
2705 if (Left.
is(Keywords.kw_synchronized) && Right.
is(tok::l_paren))
2707 if ((Left.
isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2708 tok::kw_protected) ||
2709 Left.
isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2710 Keywords.kw_native)) &&
2711 Right.
is(TT_TemplateOpener))
2714 if (Left.
is(TT_ImplicitStringLiteral))
2717 if (Left.
is(TT_ObjCMethodSpecifier))
2719 if (Left.
is(tok::r_paren) && canBeObjCSelectorComponent(Right))
2726 (Right.
is(tok::equal) || Left.
is(tok::equal)))
2729 if (Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2730 Left.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2732 if (Right.
is(TT_OverloadedOperatorLParen))
2734 if (Left.
is(tok::comma))
2736 if (Right.
is(tok::comma))
2738 if (Right.
is(TT_ObjCBlockLParen))
2740 if (Right.
is(TT_CtorInitializerColon))
2744 if (Right.
is(TT_RangeBasedForLoopColon) &&
2747 if (Right.
is(tok::colon)) {
2748 if (Line.
First->
isOneOf(tok::kw_case, tok::kw_default) ||
2751 if (Right.
is(TT_ObjCMethodExpr))
2753 if (Left.
is(tok::question))
2755 if (Right.
is(TT_InlineASMColon) && Left.
is(tok::coloncolon))
2757 if (Right.
is(TT_DictLiteral))
2759 if (Right.
is(TT_AttributeColon))
2763 if (Left.
is(TT_UnaryOperator))
2764 return Right.
is(TT_BinaryOperator);
2768 if (Left.
is(TT_CastRParen))
2770 Right.
isOneOf(TT_BinaryOperator, TT_SelectorName);
2772 if (Left.
is(tok::greater) && Right.
is(tok::greater)) {
2776 return Right.
is(TT_TemplateCloser) && Left.
is(TT_TemplateCloser) &&
2779 if (Right.
isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
2780 Left.
isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2781 (Right.
is(tok::period) && Right.
isNot(TT_DesignatedInitializerPeriod)))
2787 (Left.
is(tok::identifier) || Left.
is(tok::kw_this)))
2789 if (Right.
is(tok::coloncolon) && Left.
is(tok::identifier))
2794 if (Right.
is(tok::coloncolon) && !Left.
isOneOf(tok::l_brace, tok::comment))
2795 return (Left.
is(TT_TemplateOpener) &&
2797 !(Left.
isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
2798 tok::kw___super, TT_TemplateCloser,
2799 TT_TemplateOpener)) ||
2801 if ((Left.
is(TT_TemplateOpener)) != (Right.
is(TT_TemplateCloser)))
2804 if (Right.
is(TT_StructuredBindingLSquare))
2805 return !Left.
isOneOf(tok::amp, tok::ampamp) ||
2808 if (Right.
Next && Right.
Next->
is(TT_StructuredBindingLSquare) &&
2809 Right.
isOneOf(tok::amp, tok::ampamp))
2811 if ((Right.
is(TT_BinaryOperator) && !Left.
is(tok::l_paren)) ||
2812 (Left.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2813 !Right.
is(tok::r_paren)))
2815 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_paren) &&
2816 Right.
isNot(TT_FunctionTypeLParen))
2818 if (Right.
is(TT_TemplateOpener) && Left.
is(tok::r_paren) &&
2821 if (Right.
is(tok::less) && Left.
isNot(tok::l_paren) &&
2824 if (Right.
is(TT_TrailingUnaryOperator))
2826 if (Left.
is(TT_RegexLiteral))
2828 return spaceRequiredBetween(Line, Left, Right);
2834 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
2837 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
2845 if (Right.
is(tok::string_literal) && Left.
is(tok::plus) && Left.
Previous &&
2848 if (Left.
is(TT_DictLiteral) && Left.
is(tok::l_brace) && Line.
Level == 0 &&
2850 Line.
First->
isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
2854 !Line.
First->
isOneOf(Keywords.kw_var, Keywords.kw_let))
2858 if (Left.
is(tok::l_brace) && Line.
Level == 0 &&
2860 Line.
startsWith(tok::kw_const, tok::kw_enum) ||
2861 Line.
startsWith(tok::kw_export, tok::kw_enum) ||
2862 Line.
startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
2866 if (Right.
is(tok::r_brace) && Left.
is(tok::l_brace) &&
2875 if (Right.
is(tok::plus) && Left.
is(tok::string_literal) && Right.
Next &&
2876 Right.
Next->
is(tok::string_literal))
2893 if ((Left.
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2895 Left.
is(tok::l_paren))) &&
2900 TT_ArrayInitializerLSquare) ||
2903 BeforeClosingBrace = &Left;
2904 if (BeforeClosingBrace && (BeforeClosingBrace->
is(tok::comma) ||
2909 if (Right.
is(tok::comment))
2911 Left.
isNot(TT_CtorInitializerColon) &&
2917 if (Right.
is(tok::lessless) && Right.
Next &&
2919 Right.
Next->
is(tok::string_literal))
2926 if (Right.
is(TT_CtorInitializerComma) &&
2930 if (Right.
is(TT_CtorInitializerColon) &&
2936 Right.
is(TT_InheritanceComma))
2938 if (Right.
is(tok::string_literal) && Right.
TokenText.startswith(
"R\""))
2951 if (Right.
is(TT_InlineASMBrace))
2955 (Line.
startsWith(tok::kw_typedef, tok::kw_enum) &&
2964 Left.
is(TT_LeadingJavaAnnotation) &&
2965 Right.
isNot(TT_LeadingJavaAnnotation) && Right.
isNot(tok::l_paren) &&
2969 if (Right.
is(TT_ProtoExtensionLSquare))
3001 Right.
is(TT_SelectorName) && !Right.
is(tok::r_square) && Right.
Next) {
3011 if (LBrace && LBrace->
is(tok::colon)) {
3012 LBrace = LBrace->
Next;
3013 if (LBrace && LBrace->
is(tok::at)) {
3014 LBrace = LBrace->
Next;
3016 LBrace = LBrace->
Next;
3028 ((LBrace->
is(tok::l_brace) &&
3029 (LBrace->
is(TT_DictLiteral) ||
3030 (LBrace->
Next && LBrace->
Next->
is(tok::r_brace)))) ||
3031 LBrace->
is(TT_ArrayInitializerLSquare) || LBrace->
is(tok::less))) {
3053 if (Left.
isOneOf(tok::r_brace, tok::greater, tok::r_square))
3063 !Right.
isOneOf(tok::l_paren, TT_LambdaLSquare)) {
3074 auto Next =
Comma->getNextNonComment();
3077 if (!Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret))
3084 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
3090 if (Left.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3091 Keywords.kw_implements))
3093 if (Right.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3094 Keywords.kw_implements))
3100 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
3101 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
3102 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
3103 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
3104 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
3108 Left.
isOneOf(tok::r_square, tok::r_paren)) &&
3109 Right.
isOneOf(tok::l_square, tok::l_paren))
3111 if (Left.
is(TT_JsFatArrow) && Right.
is(tok::l_brace))
3113 if (Left.
is(TT_JsTypeColon))
3116 if (Left.
is(tok::exclaim) && Right.
is(tok::colon))
3121 if (Right.
is(Keywords.kw_is)) {
3130 if (!Next || !Next->
is(tok::colon))
3133 if (Left.
is(Keywords.kw_in))
3135 if (Right.
is(Keywords.kw_in))
3137 if (Right.
is(Keywords.kw_as))
3139 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
3145 if (Left.
is(Keywords.kw_as))
3147 if (Left.
is(TT_JsNonNullAssertion))
3149 if (Left.
is(Keywords.kw_declare) &&
3150 Right.
isOneOf(Keywords.kw_module, tok::kw_namespace,
3151 Keywords.kw_function, tok::kw_class, tok::kw_enum,
3152 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
3153 Keywords.kw_let, tok::kw_const))
3157 if (Left.
isOneOf(Keywords.kw_module, tok::kw_namespace) &&
3158 Right.
isOneOf(tok::identifier, tok::string_literal))
3166 if (Left.
is(tok::at))
3170 if (Left.
isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
3171 return !Right.
is(tok::l_paren);
3172 if (Right.
is(TT_PointerOrReference))
3175 (!Right.
Next || Right.
Next->
isNot(TT_FunctionDeclarationName)));
3176 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3177 Right.
is(tok::kw_operator))
3179 if (Left.
is(TT_PointerOrReference))
3188 (Left.
is(TT_CtorInitializerColon) &&
3190 if (Left.
is(tok::question) && Right.
is(tok::colon))
3192 if (Right.
is(TT_ConditionalExpr) || Right.
is(tok::question))
3194 if (Left.
is(TT_ConditionalExpr) || Left.
is(tok::question))
3196 if (Left.
is(TT_InheritanceColon))
3198 if (Right.
is(TT_InheritanceColon))
3200 if (Right.
is(TT_ObjCMethodExpr) && !Right.
is(tok::r_square) &&
3201 Left.
isNot(TT_SelectorName))
3204 if (Right.
is(tok::colon) &&
3205 !Right.
isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
3207 if (Left.
is(tok::colon) && Left.
isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
3236 if (((Right.
is(tok::l_brace) || Right.
is(tok::less)) &&
3237 Right.
is(TT_DictLiteral)) ||
3238 Right.
is(TT_ArrayInitializerLSquare))
3246 if (Right.
is(TT_SelectorName) || (Right.
is(tok::identifier) && Right.
Next &&
3247 Right.
Next->
is(TT_ObjCMethodExpr)))
3248 return Left.
isNot(tok::period);
3253 if (Right.
isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
3254 TT_OverloadedOperator))
3256 if (Left.
is(TT_RangeBasedForLoopColon))
3258 if (Right.
is(TT_RangeBasedForLoopColon))
3260 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_TemplateOpener))
3262 if (Left.
isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
3263 Left.
is(tok::kw_operator))
3265 if (Left.
is(tok::equal) && !Right.
isOneOf(tok::kw_default, tok::kw_delete) &&
3268 if (Left.
is(tok::equal) && Right.
is(tok::l_brace) &&
3271 if (Left.
is(tok::l_paren) && Left.
is(TT_AttributeParen))
3273 if (Left.
is(tok::l_paren) && Left.
Previous &&
3276 if (Right.
is(TT_ImplicitStringLiteral))
3279 if (Right.
is(tok::r_paren) || Right.
is(TT_TemplateCloser))
3287 if (Right.
is(tok::r_brace))
3292 if (Left.
is(TT_TrailingAnnotation))
3293 return !Right.
isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
3294 tok::less, tok::coloncolon);
3296 if (Right.
is(tok::kw___attribute) ||
3297 (Right.
is(tok::l_square) && Right.
is(TT_AttributeSquare)))
3300 if (Left.
is(tok::identifier) && Right.
is(tok::string_literal))
3303 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
3306 if (Left.
is(TT_CtorInitializerColon))
3308 if (Right.
is(TT_CtorInitializerColon))
3310 if (Left.
is(TT_CtorInitializerComma) &&
3313 if (Right.
is(TT_CtorInitializerComma) &&
3316 if (Left.
is(TT_InheritanceComma) &&
3319 if (Right.
is(TT_InheritanceComma) &&
3322 if ((Left.
is(tok::greater) && Right.
is(tok::greater)) ||
3323 (Left.
is(tok::less) && Right.
is(tok::less)))
3325 if (Right.
is(TT_BinaryOperator) &&
3330 if (Left.
is(TT_ArrayInitializerLSquare))
3332 if (Right.
is(tok::kw_typename) && Left.
isNot(tok::kw_const))
3335 !Left.
isOneOf(tok::arrowstar, tok::lessless) &&
3340 if ((Left.
is(TT_AttributeSquare) && Right.
is(tok::l_square)) ||
3341 (Left.
is(tok::r_square) && Right.
is(TT_AttributeSquare)))
3343 return Left.
isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
3344 tok::kw_class, tok::kw_struct, tok::comment) ||
3346 Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
3347 tok::colon, tok::l_square, tok::at) ||
3348 (Left.
is(tok::r_paren) &&
3349 Right.
isOneOf(tok::identifier, tok::kw_const)) ||
3350 (Left.
is(tok::l_paren) && !Right.
is(tok::r_paren)) ||
3351 (Left.
is(TT_TemplateOpener) && !Right.
is(TT_TemplateCloser));
3354 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
3355 llvm::errs() <<
"AnnotatedTokens(L=" << Line.
Level <<
"):\n";
3365 <<
" PPK=" << Tok->
PackingKind <<
" FakeLParens=";
3366 for (
unsigned i = 0, e = Tok->
FakeLParens.size(); i != e; ++i)
3368 llvm::errs() <<
" FakeRParens=" << Tok->
FakeRParens;
3370 llvm::errs() <<
" Text='" << Tok->
TokenText <<
"'\n";
3372 assert(Tok == Line.
Last);
3375 llvm::errs() <<
"----\n";
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
Defines the SourceManager interface.
Parser - This implements a parser for the C family of languages.
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
tok::TokenKind ContextKind
This file implements a token annotator, i.e.
const char * getName() const
const AnnotatedLine * Line
FormatToken * FirstStartOfName
SourceLocation getEnd() const
bool InCpp11AttributeSpecifier
IdentifierInfo * getIdentifierInfo() const
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
Optional< types::ID > Type
bool ColonIsObjCMethodExpr
Dataflow Directional Tag Classes.
FormatToken * FirstObjCSelectorName
The parameter type of a method or function.
unsigned LongestObjCSelectorName
__DEVICE__ int max(int __a, int __b)
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
SourceLocation getBegin() const