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))
371 if (AttrTok->is(tok::ellipsis))
373 AttrTok = AttrTok->Next;
375 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
386 FormatToken *Left = CurrentToken->Previous;
387 Left->ParentBracket = Contexts.back().ContextKind;
388 FormatToken *
Parent = Left->getPreviousNonComment();
393 bool CppArrayTemplates =
394 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
395 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
396 Contexts.back().InTemplateArgument);
398 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
399 Contexts.back().InCpp11AttributeSpecifier;
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) &&
406 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
407 tok::kw_return, tok::kw_throw) ||
408 Parent->isUnaryOperator() ||
410 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
412 bool ColonFound =
false;
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;
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;
460 Left->Type = TT_ArrayInitializerLSquare;
461 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
463 !Left->endsSequence(tok::l_square, tok::numeric_constant,
465 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
466 Left->Type = TT_ProtoExtensionLSquare;
467 BindingIncrease = 10;
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,
475 Left->Type = TT_ArrayInitializerLSquare;
477 BindingIncrease = 10;
478 Left->Type = TT_ArraySubscriptLSquare;
482 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
483 Contexts.back().IsExpression =
true;
485 Parent->is(TT_JsTypeColon))
486 Contexts.back().IsExpression =
false;
488 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
489 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
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)) {
499 StartsObjCMethodExpr =
false;
500 Left->Type = TT_Unknown;
502 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
503 CurrentToken->Type = TT_ObjCMethodExpr;
506 if (!ColonFound && CurrentToken->Previous &&
507 CurrentToken->Previous->is(TT_Unknown) &&
508 canBeObjCSelectorComponent(*CurrentToken->Previous))
509 CurrentToken->Previous->Type = TT_SelectorName;
513 if (Parent && Parent->is(TT_PointerOrReference))
514 Parent->Type = TT_BinaryOperator;
516 Left->MatchingParen = CurrentToken;
517 CurrentToken->MatchingParen = Left;
522 if (!Contexts.back().FirstObjCSelectorName) {
523 FormatToken*
Previous = CurrentToken->getPreviousNonComment();
524 if (Previous && Previous->is(TT_SelectorName)) {
525 Previous->ObjCSelectorNameParts = 1;
526 Contexts.back().FirstObjCSelectorName =
Previous;
529 Left->ParameterCount =
530 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
532 if (Contexts.back().FirstObjCSelectorName) {
533 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
534 Contexts.back().LongestObjCSelectorName;
535 if (Left->BlockParameterCount > 1)
536 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
541 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
543 if (CurrentToken->is(tok::colon)) {
544 if (IsCpp11AttributeSpecifier &&
545 CurrentToken->endsSequence(tok::colon, tok::identifier,
549 CurrentToken->Type = TT_AttributeColon;
550 }
else if (Left->isOneOf(TT_ArraySubscriptLSquare,
551 TT_DesignatedInitializerLSquare)) {
552 Left->Type = TT_ObjCMethodExpr;
553 StartsObjCMethodExpr =
true;
554 Contexts.back().ColonIsObjCMethodExpr =
true;
555 if (Parent && Parent->is(tok::r_paren))
557 Parent->Type = TT_CastRParen;
561 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
563 Left->Type = TT_ArrayInitializerLSquare;
564 FormatToken *Tok = CurrentToken;
567 updateParameterCount(Left, Tok);
574 FormatToken *Left = CurrentToken->Previous;
575 Left->ParentBracket = Contexts.back().ContextKind;
577 if (Contexts.back().CaretFound)
578 Left->Type = TT_ObjCBlockLBrace;
579 Contexts.back().CaretFound =
false;
581 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
582 Contexts.back().ColonIsDictLiteral =
true;
584 Contexts.back().IsExpression =
true;
586 Left->Previous->is(TT_JsTypeColon))
587 Contexts.back().IsExpression =
false;
589 while (CurrentToken) {
590 if (CurrentToken->is(tok::r_brace)) {
591 Left->MatchingParen = CurrentToken;
592 CurrentToken->MatchingParen = Left;
596 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
598 updateParameterCount(Left, CurrentToken);
599 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
600 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
601 if (Previous->is(TT_JsTypeOptionalQuestion))
602 Previous = Previous->getPreviousNonComment();
603 if ((CurrentToken->is(tok::colon) &&
604 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
607 Left->Type = TT_DictLiteral;
608 if (Previous->Tok.getIdentifierInfo() ||
609 Previous->is(tok::string_literal))
610 Previous->Type = TT_SelectorName;
612 if (CurrentToken->is(tok::colon) ||
614 Left->Type = TT_DictLiteral;
616 if (CurrentToken->is(tok::comma) &&
618 Left->Type = TT_DictLiteral;
626 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
630 if (Current->is(tok::l_brace) && Current->BlockKind ==
BK_Block)
631 ++Left->BlockParameterCount;
632 if (Current->is(tok::comma)) {
633 ++Left->ParameterCount;
635 Left->Role.reset(
new CommaSeparatedList(Style));
636 Left->Role->CommaFound(Current);
637 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
638 Left->ParameterCount = 1;
642 bool parseConditional() {
643 while (CurrentToken) {
644 if (CurrentToken->is(tok::colon)) {
645 CurrentToken->Type = TT_ConditionalExpr;
655 bool parseTemplateDeclaration() {
656 if (CurrentToken && CurrentToken->is(tok::less)) {
657 CurrentToken->Type = TT_TemplateOpener;
662 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
668 bool consumeToken() {
669 FormatToken *Tok = CurrentToken;
671 switch (Tok->Tok.getKind()) {
674 if (!Tok->Previous && Line.MustBeDeclaration)
675 Tok->Type = TT_ObjCMethodSpecifier;
682 if (Contexts.back().ColonIsForRangeExpr ||
683 (Contexts.size() == 1 &&
684 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
685 Contexts.back().ContextKind == tok::l_paren ||
686 Contexts.back().ContextKind == tok::l_square ||
687 (!Contexts.back().IsExpression &&
688 Contexts.back().ContextKind == tok::l_brace) ||
689 (Contexts.size() == 1 &&
690 Line.MustBeDeclaration)) {
691 Contexts.back().IsExpression =
false;
692 Tok->Type = TT_JsTypeColon;
696 if (Contexts.back().ColonIsDictLiteral ||
699 Tok->Type = TT_DictLiteral;
701 if (FormatToken *
Previous = Tok->getPreviousNonComment())
704 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
705 Line.startsWith(TT_ObjCMethodSpecifier)) {
706 Tok->Type = TT_ObjCMethodExpr;
707 const FormatToken *BeforePrevious = Tok->Previous->Previous;
710 bool UnknownIdentifierInMethodDeclaration =
711 Line.startsWith(TT_ObjCMethodSpecifier) &&
712 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
713 if (!BeforePrevious ||
715 !(BeforePrevious->is(TT_CastRParen) ||
716 (BeforePrevious->is(TT_ObjCMethodExpr) &&
717 BeforePrevious->is(tok::colon))) ||
718 BeforePrevious->is(tok::r_square) ||
719 Contexts.back().LongestObjCSelectorName == 0 ||
720 UnknownIdentifierInMethodDeclaration) {
721 Tok->Previous->Type = TT_SelectorName;
722 if (!Contexts.back().FirstObjCSelectorName)
723 Contexts.back().FirstObjCSelectorName = Tok->Previous;
724 else if (Tok->Previous->ColumnWidth >
725 Contexts.back().LongestObjCSelectorName)
726 Contexts.back().LongestObjCSelectorName =
727 Tok->Previous->ColumnWidth;
728 Tok->Previous->ParameterIndex =
729 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
730 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
732 }
else if (Contexts.back().ColonIsForRangeExpr) {
733 Tok->Type = TT_RangeBasedForLoopColon;
734 }
else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
735 Tok->Type = TT_BitFieldColon;
736 }
else if (Contexts.size() == 1 &&
737 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
738 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren,
740 Tok->Type = TT_CtorInitializerColon;
742 Tok->Type = TT_InheritanceColon;
743 }
else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
744 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
745 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
746 Tok->Next->Next->is(tok::colon)))) {
749 Tok->Type = TT_ObjCMethodExpr;
750 }
else if (Contexts.back().ContextKind == tok::l_paren) {
751 Tok->Type = TT_InlineASMColon;
759 !Contexts.back().IsExpression)
760 Tok->Type = TT_JsTypeOperator;
764 if (Tok->is(tok::kw_if) && CurrentToken &&
765 CurrentToken->is(tok::kw_constexpr))
767 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
769 if (!parseParens(
true))
776 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
777 (Tok->Next && Tok->Next->is(tok::colon)))
780 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
783 Contexts.back().ColonIsForRangeExpr =
true;
793 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
794 Tok->Previous->MatchingParen &&
795 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
796 Tok->Previous->Type = TT_OverloadedOperator;
797 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
798 Tok->Type = TT_OverloadedOperatorLParen;
803 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
804 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
806 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
807 TT_LeadingJavaAnnotation)))
808 Line.MightBeFunctionDecl =
true;
816 FormatToken *
Previous = Tok->getPreviousNonComment();
817 if (Previous && Previous->Type != TT_DictLiteral)
818 Previous->Type = TT_SelectorName;
825 Tok->Type = TT_TemplateOpener;
833 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
834 Tok->Type = TT_DictLiteral;
835 FormatToken *
Previous = Tok->getPreviousNonComment();
836 if (Previous && Previous->Type != TT_DictLiteral)
837 Previous->Type = TT_SelectorName;
840 Tok->Type = TT_BinaryOperator;
841 NonTemplateLess.insert(Tok);
856 Tok->Type = TT_BinaryOperator;
858 case tok::kw_operator:
862 while (CurrentToken &&
863 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
864 if (CurrentToken->isOneOf(tok::star, tok::amp))
865 CurrentToken->Type = TT_PointerOrReference;
868 CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator,
870 CurrentToken->Previous->Type = TT_OverloadedOperator;
873 CurrentToken->Type = TT_OverloadedOperatorLParen;
874 if (CurrentToken->Previous->is(TT_BinaryOperator))
875 CurrentToken->Previous->Type = TT_OverloadedOperator;
880 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
886 Tok->Type = TT_JsTypeOptionalQuestion;
891 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
896 case tok::kw_template:
897 parseTemplateDeclaration();
900 if (Contexts.back().InCtorInitializer)
901 Tok->Type = TT_CtorInitializerComma;
902 else if (Contexts.back().InInheritanceList)
903 Tok->Type = TT_InheritanceComma;
904 else if (Contexts.back().FirstStartOfName &&
905 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
906 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
907 Line.IsMultiVariableDeclStmt =
true;
909 if (Contexts.back().IsForEachMacro)
910 Contexts.back().IsExpression =
true;
912 case tok::identifier:
913 if (Tok->isOneOf(Keywords.kw___has_include,
914 Keywords.kw___has_include_next)) {
924 void parseIncludeDirective() {
925 if (CurrentToken && CurrentToken->is(tok::less)) {
927 while (CurrentToken) {
930 if (CurrentToken->isNot(tok::comment) &&
931 !CurrentToken->TokenText.startswith(
"//"))
932 CurrentToken->Type = TT_ImplicitStringLiteral;
938 void parseWarningOrError() {
943 while (CurrentToken) {
944 CurrentToken->Type = TT_ImplicitStringLiteral;
952 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
953 bool IsMark = CurrentToken->is(Keywords.kw_mark);
956 while (CurrentToken) {
957 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
958 CurrentToken->Type = TT_ImplicitStringLiteral;
964 void parseHasInclude() {
965 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
968 parseIncludeDirective();
972 LineType parsePreprocessorDirective() {
973 bool IsFirstToken = CurrentToken->IsFirst;
983 while (CurrentToken) {
985 CurrentToken->Type = TT_ImplicitStringLiteral;
991 if (CurrentToken->Tok.is(tok::numeric_constant)) {
992 CurrentToken->SpacesRequiredBefore = 1;
997 if (!CurrentToken->Tok.getIdentifierInfo())
999 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1000 case tok::pp_include:
1001 case tok::pp_include_next:
1002 case tok::pp_import:
1004 parseIncludeDirective();
1008 case tok::pp_warning:
1009 parseWarningOrError();
1011 case tok::pp_pragma:
1016 Contexts.back().IsExpression =
true;
1022 while (CurrentToken) {
1023 FormatToken *Tok = CurrentToken;
1025 if (Tok->is(tok::l_paren))
1027 else if (Tok->isOneOf(Keywords.kw___has_include,
1028 Keywords.kw___has_include_next))
1036 NonTemplateLess.clear();
1037 if (CurrentToken->is(tok::hash))
1038 return parsePreprocessorDirective();
1043 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1045 CurrentToken->is(Keywords.kw_package)) ||
1046 (Info && Info->getPPKeywordID() == tok::pp_import &&
1047 CurrentToken->Next &&
1048 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1051 parseIncludeDirective();
1057 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
1058 parseIncludeDirective();
1065 CurrentToken->is(Keywords.kw_option)) {
1067 if (CurrentToken && CurrentToken->is(tok::identifier))
1071 bool KeywordVirtualFound =
false;
1072 bool ImportStatement =
false;
1076 CurrentToken->is(Keywords.kw_import))
1077 ImportStatement =
true;
1079 while (CurrentToken) {
1080 if (CurrentToken->is(tok::kw_virtual))
1081 KeywordVirtualFound =
true;
1089 if (Line.First->is(tok::kw_export) &&
1090 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1091 CurrentToken->Next->isStringLiteral())
1092 ImportStatement =
true;
1093 if (isClosureImportStatement(*CurrentToken))
1094 ImportStatement =
true;
1096 if (!consumeToken())
1099 if (KeywordVirtualFound)
1101 if (ImportStatement)
1104 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
1105 if (Contexts.back().FirstObjCSelectorName)
1106 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1107 Contexts.back().LongestObjCSelectorName;
1115 bool isClosureImportStatement(
const FormatToken &Tok) {
1118 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
1120 (Tok.Next->Next->TokenText ==
"module" ||
1121 Tok.Next->Next->TokenText ==
"provide" ||
1122 Tok.Next->Next->TokenText ==
"require" ||
1123 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
1124 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1127 void resetTokenMetadata(FormatToken *Token) {
1133 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
1134 TT_FunctionLBrace, TT_ImplicitStringLiteral,
1135 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
1136 TT_OverloadedOperator, TT_RegexLiteral,
1137 TT_TemplateString, TT_ObjCStringLiteral))
1138 CurrentToken->Type = TT_Unknown;
1139 CurrentToken->Role.reset();
1140 CurrentToken->MatchingParen =
nullptr;
1141 CurrentToken->FakeLParens.clear();
1142 CurrentToken->FakeRParens = 0;
1147 CurrentToken->NestingLevel = Contexts.size() - 1;
1148 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1149 modifyContext(*CurrentToken);
1150 determineTokenType(*CurrentToken);
1151 CurrentToken = CurrentToken->Next;
1154 resetTokenMetadata(CurrentToken);
1185 struct ScopedContextCreator {
1186 AnnotatingParser &
P;
1191 P.Contexts.push_back(Context(ContextKind,
1192 P.Contexts.back().BindingStrength + Increase,
1193 P.Contexts.back().IsExpression));
1196 ~ScopedContextCreator() { P.Contexts.pop_back(); }
1199 void modifyContext(
const FormatToken &Current) {
1201 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1205 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1206 Line.startsWith(tok::kw_export, Keywords.kw_type,
1207 tok::identifier))) &&
1208 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1209 Contexts.back().IsExpression =
true;
1210 if (!Line.startsWith(TT_UnaryOperator)) {
1211 for (FormatToken *
Previous = Current.Previous;
1213 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1215 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
1222 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1223 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1225 Previous->Type = TT_PointerOrReference;
1228 }
else if (Current.is(tok::lessless) &&
1229 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1230 Contexts.back().IsExpression =
true;
1231 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1232 Contexts.back().IsExpression =
true;
1233 }
else if (Current.is(TT_TrailingReturnArrow)) {
1234 Contexts.back().IsExpression =
false;
1235 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1237 }
else if (Current.Previous &&
1238 Current.Previous->is(TT_CtorInitializerColon)) {
1239 Contexts.back().IsExpression =
true;
1240 Contexts.back().InCtorInitializer =
true;
1241 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1242 Contexts.back().InInheritanceList =
true;
1243 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1244 for (FormatToken *
Previous = Current.Previous;
1247 Previous->Type = TT_PointerOrReference;
1248 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer)
1249 Contexts.back().IsExpression =
false;
1250 }
else if (Current.is(tok::kw_new)) {
1251 Contexts.back().CanBeExpression =
false;
1252 }
else if (Current.isOneOf(tok::semi, tok::exclaim)) {
1254 Contexts.back().IsExpression =
true;
1258 void determineTokenType(FormatToken &Current) {
1259 if (!Current.is(TT_Unknown))
1264 if (Current.is(tok::exclaim)) {
1265 if (Current.Previous &&
1266 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1267 tok::r_paren, tok::r_square,
1269 Current.Previous->Tok.isLiteral())) {
1270 Current.Type = TT_JsNonNullAssertion;
1274 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1275 Current.Type = TT_JsNonNullAssertion;
1284 if (Current.is(Keywords.kw_instanceof)) {
1285 Current.Type = TT_BinaryOperator;
1286 }
else if (isStartOfName(Current) &&
1287 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1288 Contexts.back().FirstStartOfName = &Current;
1289 Current.Type = TT_StartOfName;
1290 }
else if (Current.is(tok::semi)) {
1294 Contexts.back().FirstStartOfName =
nullptr;
1295 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1297 }
else if (Current.is(tok::arrow) &&
1299 Current.Type = TT_LambdaArrow;
1300 }
else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1301 Current.NestingLevel == 0) {
1302 Current.Type = TT_TrailingReturnArrow;
1303 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1304 Current.Type = determineStarAmpUsage(Current,
1305 Contexts.back().CanBeExpression &&
1306 Contexts.back().IsExpression,
1307 Contexts.back().InTemplateArgument);
1308 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1309 Current.Type = determinePlusMinusCaretUsage(Current);
1310 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1311 Contexts.back().CaretFound =
true;
1312 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1313 Current.Type = determineIncrementUsage(Current);
1314 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1315 Current.Type = TT_UnaryOperator;
1316 }
else if (Current.is(tok::question)) {
1318 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1321 Current.Type = TT_JsTypeOptionalQuestion;
1323 Current.Type = TT_ConditionalExpr;
1325 }
else if (Current.isBinaryOperator() &&
1326 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1327 (!Current.is(tok::greater) &&
1329 Current.Type = TT_BinaryOperator;
1330 }
else if (Current.is(tok::comment)) {
1331 if (Current.TokenText.startswith(
"/*")) {
1332 if (Current.TokenText.endswith(
"*/"))
1333 Current.Type = TT_BlockComment;
1337 Current.Tok.setKind(tok::unknown);
1339 Current.Type = TT_LineComment;
1341 }
else if (Current.is(tok::r_paren)) {
1342 if (rParenEndsCast(Current))
1343 Current.Type = TT_CastRParen;
1344 if (Current.MatchingParen && Current.Next &&
1345 !Current.Next->isBinaryOperator() &&
1346 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1347 tok::comma, tok::period, tok::arrow,
1349 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1351 if (AfterParen->Tok.isNot(tok::caret)) {
1352 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1353 if (BeforeParen->is(tok::identifier) &&
1354 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1355 (!BeforeParen->Previous ||
1356 BeforeParen->Previous->ClosesTemplateDeclaration))
1357 Current.Type = TT_FunctionAnnotationRParen;
1360 }
else if (Current.is(tok::at) && Current.Next &&
1365 switch (Current.Next->Tok.getObjCKeywordID()) {
1366 case tok::objc_interface:
1367 case tok::objc_implementation:
1368 case tok::objc_protocol:
1369 Current.Type = TT_ObjCDecl;
1371 case tok::objc_property:
1372 Current.Type = TT_ObjCProperty;
1377 }
else if (Current.is(tok::period)) {
1378 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1379 if (PreviousNoComment &&
1380 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1381 Current.Type = TT_DesignatedInitializerPeriod;
1383 Current.Previous->isOneOf(TT_JavaAnnotation,
1384 TT_LeadingJavaAnnotation)) {
1385 Current.Type = Current.Previous->Type;
1387 }
else if (canBeObjCSelectorComponent(Current) &&
1389 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1390 Current.Previous->MatchingParen &&
1391 Current.Previous->MatchingParen->Previous &&
1392 Current.Previous->MatchingParen->Previous->is(
1393 TT_ObjCMethodSpecifier)) {
1397 Current.Type = TT_SelectorName;
1398 }
else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
1400 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1401 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1404 Current.Type = TT_TrailingAnnotation;
1408 if (Current.Previous->is(tok::at) &&
1409 Current.isNot(Keywords.kw_interface)) {
1410 const FormatToken &AtToken = *Current.Previous;
1411 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1412 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1413 Current.Type = TT_LeadingJavaAnnotation;
1415 Current.Type = TT_JavaAnnotation;
1416 }
else if (Current.Previous->is(tok::period) &&
1417 Current.Previous->isOneOf(TT_JavaAnnotation,
1418 TT_LeadingJavaAnnotation)) {
1419 Current.Type = Current.Previous->Type;
1429 bool isStartOfName(
const FormatToken &Tok) {
1430 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1433 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1437 Tok.Previous->is(Keywords.kw_in))
1441 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1442 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1443 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1445 if (!PreviousNotConst)
1448 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1449 PreviousNotConst->Previous &&
1450 PreviousNotConst->Previous->is(tok::hash);
1452 if (PreviousNotConst->is(TT_TemplateCloser))
1453 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1454 PreviousNotConst->MatchingParen->Previous &&
1455 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1456 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1458 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1459 PreviousNotConst->MatchingParen->Previous &&
1460 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1463 return (!IsPPKeyword &&
1464 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1465 PreviousNotConst->is(TT_PointerOrReference) ||
1466 PreviousNotConst->isSimpleTypeSpecifier();
1470 bool rParenEndsCast(
const FormatToken &Tok) {
1476 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1479 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1483 if (LeftOfParens->is(tok::r_paren)) {
1484 if (!LeftOfParens->MatchingParen ||
1485 !LeftOfParens->MatchingParen->Previous)
1487 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1492 if (LeftOfParens->Tok.getIdentifierInfo() &&
1493 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1499 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1500 TT_TemplateCloser, tok::ellipsis))
1504 if (Tok.Next->is(tok::question))
1513 if (Tok.Next->isNot(tok::string_literal) &&
1514 (Tok.Next->Tok.isLiteral() ||
1515 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1519 bool ParensAreType =
1521 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1522 Tok.Previous->isSimpleTypeSpecifier();
1523 bool ParensCouldEndDecl =
1524 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1525 if (ParensAreType && !ParensCouldEndDecl)
1536 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1537 Token = Token->Next)
1538 if (Token->is(TT_BinaryOperator))
1543 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1546 if (!Tok.Next->Next)
1553 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1554 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1555 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1558 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1559 Prev = Prev->Previous) {
1560 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1570 return TT_BinaryOperator;
1572 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1574 return TT_UnaryOperator;
1576 const FormatToken *NextToken = Tok.getNextNonComment();
1578 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) ||
1579 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1580 return TT_PointerOrReference;
1582 if (PrevToken->is(tok::coloncolon))
1583 return TT_PointerOrReference;
1585 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1586 tok::comma, tok::semi, tok::kw_return, tok::colon,
1587 tok::equal, tok::kw_delete, tok::kw_sizeof,
1589 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1590 TT_UnaryOperator, TT_CastRParen))
1591 return TT_UnaryOperator;
1593 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1594 return TT_PointerOrReference;
1596 return TT_PointerOrReference;
1597 if (NextToken->isOneOf(tok::comma, tok::semi))
1598 return TT_PointerOrReference;
1600 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
1601 FormatToken *TokenBeforeMatchingParen =
1602 PrevToken->MatchingParen->getPreviousNonComment();
1603 if (TokenBeforeMatchingParen &&
1604 TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype))
1605 return TT_PointerOrReference;
1608 if (PrevToken->Tok.isLiteral() ||
1609 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1610 tok::kw_false, tok::r_brace) ||
1611 NextToken->Tok.isLiteral() ||
1612 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1613 NextToken->isUnaryOperator() ||
1617 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1618 return TT_BinaryOperator;
1621 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1622 return TT_BinaryOperator;
1626 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1627 if (NextNextToken && NextNextToken->is(tok::arrow))
1628 return TT_BinaryOperator;
1632 if (IsExpression && !Contexts.back().CaretFound)
1633 return TT_BinaryOperator;
1635 return TT_PointerOrReference;
1638 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1639 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1641 return TT_UnaryOperator;
1643 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
1645 return TT_UnaryOperator;
1648 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1649 tok::question, tok::colon, tok::kw_return,
1650 tok::kw_case, tok::at, tok::l_brace))
1651 return TT_UnaryOperator;
1654 if (PrevToken->is(TT_BinaryOperator))
1655 return TT_UnaryOperator;
1658 return TT_BinaryOperator;
1662 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1663 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1664 if (!PrevToken || PrevToken->is(TT_CastRParen))
1665 return TT_UnaryOperator;
1666 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1667 return TT_TrailingUnaryOperator;
1669 return TT_UnaryOperator;
1672 SmallVector<Context, 8> Contexts;
1674 const FormatStyle &
Style;
1675 AnnotatedLine &
Line;
1676 FormatToken *CurrentToken;
1678 const AdditionalKeywords &Keywords;
1684 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
1692 class ExpressionParser {
1694 ExpressionParser(
const FormatStyle &
Style,
const AdditionalKeywords &Keywords,
1695 AnnotatedLine &
Line)
1696 :
Style(Style), Keywords(Keywords), Current(Line.First) {}
1699 void parse(
int Precedence = 0) {
1702 while (Current && (Current->is(tok::kw_return) ||
1703 (Current->is(tok::colon) &&
1704 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1707 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1712 parseConditionalExpr();
1718 if (Precedence == PrecedenceUnaryOperator) {
1719 parseUnaryOperator();
1723 FormatToken *Start = Current;
1724 FormatToken *LatestOperator =
nullptr;
1725 unsigned OperatorIndex = 0;
1729 parse(Precedence + 1);
1731 int CurrentPrecedence = getCurrentPrecedence();
1733 if (Current && Current->is(TT_SelectorName) &&
1734 Precedence == CurrentPrecedence) {
1736 addFakeParenthesis(Start,
prec::Level(Precedence));
1743 (Current->closesScope() &&
1744 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1745 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1752 if (Current->opensScope()) {
1755 while (Current && (!Current->closesScope() || Current->opensScope())) {
1762 if (CurrentPrecedence == Precedence) {
1764 LatestOperator->NextOperator = Current;
1765 LatestOperator = Current;
1766 Current->OperatorIndex = OperatorIndex;
1769 next(Precedence > 0);
1773 if (LatestOperator && (Current || Precedence > 0)) {
1775 if (Precedence == PrecedenceArrowAndPeriod) {
1779 addFakeParenthesis(Start,
prec::Level(Precedence));
1787 int getCurrentPrecedence() {
1789 const FormatToken *NextNonComment = Current->getNextNonComment();
1790 if (Current->is(TT_ConditionalExpr))
1792 if (NextNonComment && Current->is(TT_SelectorName) &&
1793 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
1796 NextNonComment->is(tok::less))))
1798 if (Current->is(TT_JsComputedPropertyName))
1800 if (Current->is(TT_LambdaArrow))
1802 if (Current->is(TT_JsFatArrow))
1804 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1805 (Current->is(tok::comment) && NextNonComment &&
1806 NextNonComment->is(TT_SelectorName)))
1808 if (Current->is(TT_RangeBasedForLoopColon))
1812 Current->is(Keywords.kw_instanceof))
1815 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
1817 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1818 return Current->getPrecedence();
1819 if (Current->isOneOf(tok::period, tok::arrow))
1820 return PrecedenceArrowAndPeriod;
1823 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1824 Keywords.kw_throws))
1830 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
1831 Start->FakeLParens.push_back(Precedence);
1833 Start->StartsBinaryExpression =
true;
1835 FormatToken *
Previous = Current->Previous;
1836 while (Previous->is(tok::comment) && Previous->Previous)
1837 Previous = Previous->Previous;
1838 ++Previous->FakeRParens;
1840 Previous->EndsBinaryExpression =
true;
1846 void parseUnaryOperator() {
1848 while (Current && Current->is(TT_UnaryOperator)) {
1849 Tokens.push_back(Current);
1852 parse(PrecedenceArrowAndPeriod);
1853 for (FormatToken *Token : llvm::reverse(Tokens))
1858 void parseConditionalExpr() {
1859 while (Current && Current->isTrailingComment()) {
1862 FormatToken *Start = Current;
1864 if (!Current || !Current->is(tok::question))
1868 if (!Current || Current->isNot(TT_ConditionalExpr))
1875 void next(
bool SkipPastLeadingComments =
true) {
1877 Current = Current->Next;
1879 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1880 Current->isTrailingComment())
1881 Current = Current->Next;
1884 const FormatStyle &
Style;
1885 const AdditionalKeywords &Keywords;
1886 FormatToken *Current;
1897 bool CommentLine =
true;
1899 if (!
Tok->
is(tok::comment)) {
1900 CommentLine =
false;
1907 if (NextNonCommentLine && CommentLine &&
1910 (*I)->First->OriginalColumn) {
1916 : NextNonCommentLine->
Level;
1918 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
1921 setCommentLineLevels((*I)->Children);
1926 unsigned Result = 0;
1939 Line.
Type = Parser.parseLine();
1951 ExpressionParser ExprParser(
Style, Keywords, Line);
1970 for (; Next; Next = Next->Next) {
1971 if (Next->is(TT_OverloadedOperatorLParen))
1973 if (Next->is(TT_OverloadedOperator))
1975 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
1977 if (Next->Next && Next->Next->is(tok::l_square) && Next->Next->Next &&
1978 Next->Next->Next->is(tok::r_square))
1979 Next = Next->Next->Next;
1990 if (Current.
is(tok::kw_operator)) {
1993 Next = skipOperatorName(Next);
1997 for (; Next; Next = Next->
Next) {
1998 if (Next->
is(TT_TemplateOpener)) {
2000 }
else if (Next->
is(tok::coloncolon)) {
2004 if (Next->
is(tok::kw_operator)) {
2005 Next = skipOperatorName(Next->
Next);
2008 if (!Next->
is(tok::identifier))
2010 }
else if (Next->
is(tok::l_paren)) {
2022 if (Line.
Last->
is(tok::l_brace))
2037 Tok->
isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
2039 if (
Tok->
isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2073 calculateFormattingInformation(**I);
2083 Current->
Type = TT_FunctionDeclarationName;
2084 if (Current->
is(TT_LineComment)) {
2101 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
2104 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
2112 spaceRequiredBefore(Line, *Current)) {
2120 Current->
is(TT_FunctionDeclarationName))
2125 unsigned ChildSize = 0;
2134 Prev->
Children[0]->First->MustBreakBefore) ||
2141 if (Current->
is(TT_CtorInitializerColon))
2142 InFunctionDecl =
false;
2153 Current->
SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
2162 Current = Current->
Next;
2165 calculateUnbreakableTailLengths(Line);
2166 unsigned IndentLevel = Line.
Level;
2167 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
2169 Current->
Role->precomputeFormattingInfos(Current);
2172 assert(IndentLevel > 0);
2183 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
2184 unsigned UnbreakableTailLength = 0;
2189 Current->
isOneOf(tok::comment, tok::string_literal)) {
2190 UnbreakableTailLength = 0;
2192 UnbreakableTailLength +=
2199 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
2201 bool InFunctionDecl) {
2205 if (Left.
is(tok::semi))
2209 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2211 if (Right.
is(Keywords.kw_implements))
2216 if (Right.
is(Keywords.kw_function) && Left.
isNot(tok::comma))
2218 if (Left.
is(TT_JsTypeColon))
2220 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2221 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2228 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
2230 if (Right.
is(tok::l_square)) {
2233 if (Left.
is(tok::r_square))
2236 if (Right.
is(TT_LambdaLSquare) && Left.
is(tok::equal))
2238 if (!Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2239 TT_ArrayInitializerLSquare,
2240 TT_DesignatedInitializerLSquare, TT_AttributeSquare))
2244 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2245 Right.
is(tok::kw_operator)) {
2248 if (Left.
is(TT_StartOfName))
2254 if (Right.
is(TT_PointerOrReference))
2256 if (Right.
is(TT_LambdaArrow))
2258 if (Left.
is(tok::equal) && Right.
is(tok::l_brace))
2260 if (Left.
is(TT_CastRParen))
2262 if (Left.
is(tok::coloncolon) ||
2265 if (Left.
isOneOf(tok::kw_class, tok::kw_struct))
2267 if (Left.
is(tok::comment))
2270 if (Left.
isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2271 TT_CtorInitializerColon))
2299 if (Right.
is(TT_TrailingAnnotation) &&
2310 bool is_short_annotation = Right.
TokenText.size() < 10;
2311 return (Left.
is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2315 if (Line.
startsWith(tok::kw_for) && Left.
is(tok::equal))
2320 if (Right.
is(TT_SelectorName))
2322 if (Left.
is(tok::colon) && Left.
is(TT_ObjCMethodExpr))
2332 if (Left.
is(tok::l_paren) && InFunctionDecl &&
2335 if (Left.
is(tok::l_paren) && Left.
Previous &&
2339 if (Left.
is(tok::equal) && InFunctionDecl)
2341 if (Right.
is(tok::r_brace))
2343 if (Left.
is(TT_TemplateOpener))
2353 if (Left.
is(TT_JavaAnnotation))
2363 if (Left.
is(tok::comma))
2368 if (Right.
is(tok::lessless)) {
2377 if (Left.
is(TT_ConditionalExpr))
2390 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
2393 if (Left.
is(tok::kw_return) && Right.
isNot(tok::semi))
2400 if (Right.
is(tok::hashhash))
2401 return Left.
is(tok::hash);
2402 if (Left.
isOneOf(tok::hashhash, tok::hash))
2403 return Right.
is(tok::hash);
2404 if (Left.
is(tok::l_paren) && Right.
is(tok::r_paren))
2406 if (Left.
is(tok::l_paren) || Right.
is(tok::r_paren))
2407 return (Right.
is(TT_CastRParen) ||
2411 if (Right.
isOneOf(tok::semi, tok::comma))
2414 bool IsLightweightGeneric =
2419 if (Right.
is(tok::less) && Left.
is(tok::kw_template))
2421 if (Left.
isOneOf(tok::exclaim, tok::tilde))
2423 if (Left.
is(tok::at) &&
2424 Right.
isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2425 tok::numeric_constant, tok::l_paren, tok::l_brace,
2426 tok::kw_true, tok::kw_false))
2428 if (Left.
is(tok::colon))
2429 return !Left.
is(TT_ObjCMethodExpr);
2430 if (Left.
is(tok::coloncolon))
2432 if (Left.
is(tok::less) || Right.
isOneOf(tok::greater, tok::less)) {
2435 (Left.
is(TT_DictLiteral) || Right.
is(TT_DictLiteral)))) {
2437 if (Left.
is(tok::less) && Right.
is(tok::greater))
2443 if (Right.
is(tok::ellipsis))
2446 if (Left.
is(tok::l_square) && Right.
is(tok::amp))
2448 if (Right.
is(TT_PointerOrReference)) {
2454 if (!TokenBeforeMatchingParen ||
2455 !TokenBeforeMatchingParen->
isOneOf(tok::kw_typeof, tok::kw_decltype))
2459 (!Left.
isOneOf(TT_PointerOrReference, tok::l_paren) &&
2465 if (Right.
is(TT_FunctionTypeLParen) && Left.
isNot(tok::l_paren) &&
2466 (!Left.
is(TT_PointerOrReference) ||
2470 if (Left.
is(TT_PointerOrReference))
2472 (Right.
isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2473 !Right.
is(TT_StartOfName)) ||
2475 (!Right.
isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2481 if (Right.
is(tok::star) && Left.
is(tok::l_paren))
2483 const auto SpaceRequiredForArrayInitializerLSquare =
2492 if (Left.
is(tok::l_square))
2493 return (Left.
is(TT_ArrayInitializerLSquare) && Right.
isNot(tok::r_square) &&
2494 SpaceRequiredForArrayInitializerLSquare(Left,
Style)) ||
2495 (Left.
isOneOf(TT_ArraySubscriptLSquare,
2496 TT_StructuredBindingLSquare) &&
2498 if (Right.
is(tok::r_square))
2501 SpaceRequiredForArrayInitializerLSquare(*Right.
MatchingParen,
2505 TT_StructuredBindingLSquare)) ||
2507 if (Right.
is(tok::l_square) &&
2508 !Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2509 TT_DesignatedInitializerLSquare,
2510 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
2511 !Left.
isOneOf(tok::numeric_constant, TT_DictLiteral))
2513 if (Left.
is(tok::l_brace) && Right.
is(tok::r_brace))
2519 if (Left.
is(TT_BlockComment))
2521 if (Right.
is(tok::l_paren)) {
2522 if ((Left.
is(tok::r_paren) && Left.
is(TT_AttributeParen)) ||
2523 (Left.
is(tok::r_square) && Left.
is(TT_AttributeSquare)))
2527 (Left.
isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
2528 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2531 (Left.
isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2532 tok::kw_new, tok::kw_delete) &&
2536 Left.
is(tok::r_paren)) &&
2541 if (Right.
is(TT_UnaryOperator))
2542 return !Left.
isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2543 (Left.
isNot(tok::colon) || Left.
isNot(TT_ObjCMethodExpr));
2544 if ((Left.
isOneOf(tok::identifier, tok::greater, tok::r_square,
2550 if (Left.
is(tok::period) || Right.
is(tok::period))
2552 if (Right.
is(tok::hash) && Left.
is(tok::identifier) && Left.
TokenText ==
"L")
2559 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_square))
2561 if (Left.
is(tok::l_brace) && Left.
endsSequence(TT_DictLiteral, tok::at))
2571 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2577 if (Left.
is(tok::kw_operator))
2578 return Right.
is(tok::coloncolon);
2584 if (Right.
is(tok::period) &&
2585 Left.
isOneOf(Keywords.kw_optional, Keywords.kw_required,
2586 Keywords.kw_repeated, Keywords.kw_extend))
2588 if (Right.
is(tok::l_paren) &&
2589 Left.
isOneOf(Keywords.kw_returns, Keywords.kw_option))
2591 if (Right.
isOneOf(tok::l_brace, tok::less) && Left.
is(TT_SelectorName))
2594 if (Left.
is(tok::slash) || Right.
is(tok::slash))
2597 Right.
isOneOf(tok::l_brace, tok::less))
2600 if (Left.
is(tok::percent))
2604 if (Left.
is(tok::numeric_constant) && Right.
is(tok::percent))
2607 if (Left.
is(TT_JsFatArrow))
2610 if (Right.
is(tok::l_paren) && Left.
is(Keywords.kw_await) && Left.
Previous &&
2613 if (Left.
is(Keywords.kw_async) && Right.
is(tok::l_paren) &&
2618 if (Next && Next->
is(TT_JsFatArrow))
2621 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2622 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2627 if (Left.
is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2628 Right.
is(TT_TemplateString))
2630 if (Right.
is(tok::star) &&
2631 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield))
2633 if (Right.
isOneOf(tok::l_brace, tok::l_square) &&
2634 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield,
2635 Keywords.kw_extends, Keywords.kw_implements))
2637 if (Right.
is(tok::l_paren)) {
2647 if (Left.
isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
2651 if ((Left.
isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2662 Left.
Previous->
is(tok::period) && Right.
is(tok::l_paren))
2664 if (Left.
is(Keywords.kw_as) &&
2665 Right.
isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2667 if (Left.
is(tok::kw_default) && Left.
Previous &&
2670 if (Left.
is(Keywords.kw_is) && Right.
is(tok::l_brace))
2672 if (Right.
isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2674 if (Left.
is(TT_JsTypeOperator) || Right.
is(TT_JsTypeOperator))
2676 if ((Left.
is(tok::l_brace) || Right.
is(tok::r_brace)) &&
2677 Line.
First->
isOneOf(Keywords.kw_import, tok::kw_export))
2679 if (Left.
is(tok::ellipsis))
2681 if (Left.
is(TT_TemplateCloser) &&
2682 !Right.
isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2683 Keywords.kw_implements, Keywords.kw_extends))
2688 if (Right.
is(TT_JsNonNullAssertion))
2690 if (Left.
is(TT_JsNonNullAssertion) &&
2691 Right.
isOneOf(Keywords.kw_as, Keywords.kw_in))
2694 if (Left.
is(tok::r_square) && Right.
is(tok::l_brace))
2696 if (Left.
is(Keywords.kw_synchronized) && Right.
is(tok::l_paren))
2698 if ((Left.
isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2699 tok::kw_protected) ||
2700 Left.
isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2701 Keywords.kw_native)) &&
2702 Right.
is(TT_TemplateOpener))
2705 if (Left.
is(TT_ImplicitStringLiteral))
2708 if (Left.
is(TT_ObjCMethodSpecifier))
2710 if (Left.
is(tok::r_paren) && canBeObjCSelectorComponent(Right))
2717 (Right.
is(tok::equal) || Left.
is(tok::equal)))
2720 if (Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2721 Left.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2723 if (Right.
is(TT_OverloadedOperatorLParen))
2725 if (Left.
is(tok::comma))
2727 if (Right.
is(tok::comma))
2729 if (Right.
is(TT_ObjCBlockLParen))
2731 if (Right.
is(TT_CtorInitializerColon))
2735 if (Right.
is(TT_RangeBasedForLoopColon) &&
2738 if (Right.
is(tok::colon)) {
2739 if (Line.
First->
isOneOf(tok::kw_case, tok::kw_default) ||
2742 if (Right.
is(TT_ObjCMethodExpr))
2744 if (Left.
is(tok::question))
2746 if (Right.
is(TT_InlineASMColon) && Left.
is(tok::coloncolon))
2748 if (Right.
is(TT_DictLiteral))
2750 if (Right.
is(TT_AttributeColon))
2754 if (Left.
is(TT_UnaryOperator))
2755 return Right.
is(TT_BinaryOperator);
2759 if (Left.
is(TT_CastRParen))
2761 Right.
isOneOf(TT_BinaryOperator, TT_SelectorName);
2763 if (Left.
is(tok::greater) && Right.
is(tok::greater)) {
2767 return Right.
is(TT_TemplateCloser) && Left.
is(TT_TemplateCloser) &&
2770 if (Right.
isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
2771 Left.
isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2772 (Right.
is(tok::period) && Right.
isNot(TT_DesignatedInitializerPeriod)))
2777 if (Right.
is(tok::coloncolon) && Left.
is(tok::identifier))
2782 if (Right.
is(tok::coloncolon) && !Left.
isOneOf(tok::l_brace, tok::comment))
2783 return (Left.
is(TT_TemplateOpener) &&
2785 !(Left.
isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
2786 tok::kw___super, TT_TemplateCloser,
2787 TT_TemplateOpener)) ||
2789 if ((Left.
is(TT_TemplateOpener)) != (Right.
is(TT_TemplateCloser)))
2792 if (Right.
is(TT_StructuredBindingLSquare))
2793 return !Left.
isOneOf(tok::amp, tok::ampamp) ||
2796 if (Right.
Next && Right.
Next->
is(TT_StructuredBindingLSquare) &&
2797 Right.
isOneOf(tok::amp, tok::ampamp))
2799 if ((Right.
is(TT_BinaryOperator) && !Left.
is(tok::l_paren)) ||
2800 (Left.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2801 !Right.
is(tok::r_paren)))
2803 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_paren) &&
2804 Right.
isNot(TT_FunctionTypeLParen))
2806 if (Right.
is(TT_TemplateOpener) && Left.
is(tok::r_paren) &&
2809 if (Right.
is(tok::less) && Left.
isNot(tok::l_paren) &&
2812 if (Right.
is(TT_TrailingUnaryOperator))
2814 if (Left.
is(TT_RegexLiteral))
2816 return spaceRequiredBetween(Line, Left, Right);
2822 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
2825 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
2833 if (Right.
is(tok::string_literal) && Left.
is(tok::plus) && Left.
Previous &&
2836 if (Left.
is(TT_DictLiteral) && Left.
is(tok::l_brace) && Line.
Level == 0 &&
2838 Line.
First->
isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
2842 !Line.
First->
isOneOf(Keywords.kw_var, Keywords.kw_let))
2846 if (Left.
is(tok::l_brace) && Line.
Level == 0 &&
2848 Line.
startsWith(tok::kw_const, tok::kw_enum) ||
2849 Line.
startsWith(tok::kw_export, tok::kw_enum) ||
2850 Line.
startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
2854 if (Right.
is(tok::r_brace) && Left.
is(tok::l_brace) &&
2863 if (Right.
is(tok::plus) && Left.
is(tok::string_literal) && Right.
Next &&
2864 Right.
Next->
is(tok::string_literal))
2880 if ((Left.
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2882 Left.
is(tok::l_paren))) &&
2887 TT_ArrayInitializerLSquare) ||
2890 BeforeClosingBrace = &Left;
2891 if (BeforeClosingBrace && (BeforeClosingBrace->
is(tok::comma) ||
2896 if (Right.
is(tok::comment))
2898 Left.
isNot(TT_CtorInitializerColon) &&
2904 if (Right.
is(tok::lessless) && Right.
Next &&
2906 Right.
Next->
is(tok::string_literal))
2913 if (Right.
is(TT_CtorInitializerComma) &&
2917 if (Right.
is(TT_CtorInitializerColon) &&
2923 Right.
is(TT_InheritanceComma))
2925 if (Right.
is(tok::string_literal) && Right.
TokenText.startswith(
"R\""))
2938 if (Right.
is(TT_InlineASMBrace))
2942 (Line.
startsWith(tok::kw_typedef, tok::kw_enum) &&
2951 Left.
is(TT_LeadingJavaAnnotation) &&
2952 Right.
isNot(TT_LeadingJavaAnnotation) && Right.
isNot(tok::l_paren) &&
2956 if (Right.
is(TT_ProtoExtensionLSquare))
2988 Right.
is(TT_SelectorName) && !Right.
is(tok::r_square) && Right.
Next) {
2998 if (LBrace && LBrace->
is(tok::colon)) {
2999 LBrace = LBrace->
Next;
3000 if (LBrace && LBrace->
is(tok::at)) {
3001 LBrace = LBrace->
Next;
3003 LBrace = LBrace->
Next;
3015 ((LBrace->
is(tok::l_brace) &&
3016 (LBrace->
is(TT_DictLiteral) ||
3017 (LBrace->
Next && LBrace->
Next->
is(tok::r_brace)))) ||
3018 LBrace->
is(TT_ArrayInitializerLSquare) || LBrace->
is(tok::less))) {
3040 if (Left.
isOneOf(tok::r_brace, tok::greater, tok::r_square))
3047 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
3053 if (Left.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3054 Keywords.kw_implements))
3056 if (Right.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3057 Keywords.kw_implements))
3063 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
3064 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
3065 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
3066 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
3067 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
3071 Left.
isOneOf(tok::r_square, tok::r_paren)) &&
3072 Right.
isOneOf(tok::l_square, tok::l_paren))
3074 if (Left.
is(TT_JsFatArrow) && Right.
is(tok::l_brace))
3076 if (Left.
is(TT_JsTypeColon))
3079 if (Left.
is(tok::exclaim) && Right.
is(tok::colon))
3081 if (Right.
is(Keywords.kw_is))
3083 if (Left.
is(Keywords.kw_in))
3085 if (Right.
is(Keywords.kw_in))
3087 if (Right.
is(Keywords.kw_as))
3089 if (Left.
is(Keywords.kw_as))
3091 if (Left.
is(TT_JsNonNullAssertion))
3093 if (Left.
is(Keywords.kw_declare) &&
3094 Right.
isOneOf(Keywords.kw_module, tok::kw_namespace,
3095 Keywords.kw_function, tok::kw_class, tok::kw_enum,
3096 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
3097 Keywords.kw_let, tok::kw_const))
3101 if (Left.
isOneOf(Keywords.kw_module, tok::kw_namespace) &&
3102 Right.
isOneOf(tok::identifier, tok::string_literal))
3110 if (Left.
is(tok::at))
3114 if (Left.
isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
3115 return !Right.
is(tok::l_paren);
3116 if (Right.
is(TT_PointerOrReference))
3119 (!Right.
Next || Right.
Next->
isNot(TT_FunctionDeclarationName)));
3120 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3121 Right.
is(tok::kw_operator))
3123 if (Left.
is(TT_PointerOrReference))
3132 (Left.
is(TT_CtorInitializerColon) &&
3134 if (Left.
is(tok::question) && Right.
is(tok::colon))
3136 if (Right.
is(TT_ConditionalExpr) || Right.
is(tok::question))
3138 if (Left.
is(TT_ConditionalExpr) || Left.
is(tok::question))
3140 if (Left.
is(TT_InheritanceColon))
3142 if (Right.
is(TT_InheritanceColon))
3144 if (Right.
is(TT_ObjCMethodExpr) && !Right.
is(tok::r_square) &&
3145 Left.
isNot(TT_SelectorName))
3148 if (Right.
is(tok::colon) &&
3149 !Right.
isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
3151 if (Left.
is(tok::colon) && Left.
isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
3180 if (((Right.
is(tok::l_brace) || Right.
is(tok::less)) &&
3181 Right.
is(TT_DictLiteral)) ||
3182 Right.
is(TT_ArrayInitializerLSquare))
3190 if (Right.
is(TT_SelectorName) || (Right.
is(tok::identifier) && Right.
Next &&
3191 Right.
Next->
is(TT_ObjCMethodExpr)))
3192 return Left.
isNot(tok::period);
3197 if (Right.
isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
3198 TT_OverloadedOperator))
3200 if (Left.
is(TT_RangeBasedForLoopColon))
3202 if (Right.
is(TT_RangeBasedForLoopColon))
3204 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_TemplateOpener))
3206 if (Left.
isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
3207 Left.
is(tok::kw_operator))
3209 if (Left.
is(tok::equal) && !Right.
isOneOf(tok::kw_default, tok::kw_delete) &&
3212 if (Left.
is(tok::equal) && Right.
is(tok::l_brace) &&
3215 if (Left.
is(tok::l_paren) && Left.
is(TT_AttributeParen))
3217 if (Left.
is(tok::l_paren) && Left.
Previous &&
3220 if (Right.
is(TT_ImplicitStringLiteral))
3223 if (Right.
is(tok::r_paren) || Right.
is(TT_TemplateCloser))
3231 if (Right.
is(tok::r_brace))
3236 if (Left.
is(TT_TrailingAnnotation))
3237 return !Right.
isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
3238 tok::less, tok::coloncolon);
3240 if (Right.
is(tok::kw___attribute) ||
3241 (Right.
is(tok::l_square) && Right.
is(TT_AttributeSquare)))
3244 if (Left.
is(tok::identifier) && Right.
is(tok::string_literal))
3247 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
3250 if (Left.
is(TT_CtorInitializerColon))
3252 if (Right.
is(TT_CtorInitializerColon))
3254 if (Left.
is(TT_CtorInitializerComma) &&
3257 if (Right.
is(TT_CtorInitializerComma) &&
3260 if (Left.
is(TT_InheritanceComma) &&
3263 if (Right.
is(TT_InheritanceComma) &&
3266 if ((Left.
is(tok::greater) && Right.
is(tok::greater)) ||
3267 (Left.
is(tok::less) && Right.
is(tok::less)))
3269 if (Right.
is(TT_BinaryOperator) &&
3274 if (Left.
is(TT_ArrayInitializerLSquare))
3276 if (Right.
is(tok::kw_typename) && Left.
isNot(tok::kw_const))
3279 !Left.
isOneOf(tok::arrowstar, tok::lessless) &&
3284 if ((Left.
is(TT_AttributeSquare) && Right.
is(tok::l_square)) ||
3285 (Left.
is(tok::r_square) && Right.
is(TT_AttributeSquare)))
3287 return Left.
isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
3288 tok::kw_class, tok::kw_struct, tok::comment) ||
3290 Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
3291 tok::colon, tok::l_square, tok::at) ||
3292 (Left.
is(tok::r_paren) &&
3293 Right.
isOneOf(tok::identifier, tok::kw_const)) ||
3294 (Left.
is(tok::l_paren) && !Right.
is(tok::r_paren)) ||
3295 (Left.
is(TT_TemplateOpener) && !Right.
is(TT_TemplateCloser));
3298 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
3299 llvm::errs() <<
"AnnotatedTokens(L=" << Line.
Level <<
"):\n";
3309 <<
" PPK=" << Tok->
PackingKind <<
" FakeLParens=";
3310 for (
unsigned i = 0, e = Tok->
FakeLParens.size(); i != e; ++i)
3312 llvm::errs() <<
" FakeRParens=" << Tok->
FakeRParens;
3314 llvm::errs() <<
" Text='" << Tok->
TokenText <<
"'\n";
3316 assert(Tok == Line.
Last);
3319 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.
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