19 #include "llvm/ADT/SmallPtrSet.h" 20 #include "llvm/Support/Debug.h" 22 #define DEBUG_TYPE "format-token-annotator" 40 static bool canBeObjCSelectorComponent(
const FormatToken &
Tok) {
41 return Tok.Tok.getIdentifierInfo() !=
nullptr;
46 static bool isLambdaParameterList(
const FormatToken *Left) {
48 if (Left->Previous && Left->Previous->is(tok::greater) &&
49 Left->Previous->MatchingParen &&
50 Left->Previous->MatchingParen->is(TT_TemplateOpener))
51 Left = Left->Previous->MatchingParen;
54 return Left->Previous && Left->Previous->is(tok::r_square) &&
55 Left->Previous->MatchingParen &&
56 Left->Previous->MatchingParen->is(TT_LambdaLSquare);
64 class AnnotatingParser {
66 AnnotatingParser(
const FormatStyle &
Style, AnnotatedLine &
Line,
67 const AdditionalKeywords &Keywords)
68 :
Style(Style),
Line(Line), CurrentToken(Line.First), AutoFound(
false),
70 Contexts.push_back(Context(tok::unknown, 1,
false));
71 resetTokenMetadata(CurrentToken);
76 if (!CurrentToken || !CurrentToken->Previous)
78 if (NonTemplateLess.count(CurrentToken->Previous))
81 const FormatToken &
Previous = *CurrentToken->Previous;
82 if (Previous.Previous) {
83 if (Previous.Previous->Tok.isLiteral())
85 if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
86 (!Previous.Previous->MatchingParen ||
87 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen)))
91 FormatToken *Left = CurrentToken->Previous;
92 Left->ParentBracket = Contexts.back().ContextKind;
93 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
97 bool InExprContext = Contexts.back().IsExpression;
99 Contexts.back().IsExpression =
false;
102 Contexts.back().InTemplateArgument =
103 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
105 if (Style.Language == FormatStyle::LK_Java &&
106 CurrentToken->is(tok::question))
109 while (CurrentToken) {
110 if (CurrentToken->is(tok::greater)) {
111 Left->MatchingParen = CurrentToken;
112 CurrentToken->MatchingParen = Left;
118 if (Style.Language == FormatStyle::LK_TextProto ||
119 (Style.Language == FormatStyle::LK_Proto && Left->Previous &&
120 Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
121 CurrentToken->Type = TT_DictLiteral;
123 CurrentToken->Type = TT_TemplateCloser;
127 if (CurrentToken->is(tok::question) &&
128 Style.Language == FormatStyle::LK_Java) {
132 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
133 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
134 Style.Language != FormatStyle::LK_Proto &&
135 Style.Language != FormatStyle::LK_TextProto))
143 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
144 CurrentToken->Previous->is(TT_BinaryOperator) &&
145 Contexts[Contexts.size() - 2].IsExpression &&
146 !Line.startsWith(tok::kw_template))
148 updateParameterCount(Left, CurrentToken);
149 if (Style.Language == FormatStyle::LK_Proto) {
150 if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
151 if (CurrentToken->is(tok::colon) ||
152 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
153 Previous->isNot(tok::colon)))
154 Previous->Type = TT_SelectorName;
163 bool parseParens(
bool LookForDecls =
false) {
166 FormatToken *Left = CurrentToken->Previous;
167 Left->ParentBracket = Contexts.back().ContextKind;
168 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
171 Contexts.back().ColonIsForRangeExpr =
172 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
174 bool StartsObjCMethodExpr =
false;
175 if (FormatToken *MaybeSel = Left->Previous) {
177 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
178 MaybeSel->Previous->is(tok::at)) {
179 StartsObjCMethodExpr =
true;
183 if (Left->is(TT_OverloadedOperatorLParen)) {
184 Contexts.back().IsExpression =
false;
185 }
else if (Style.Language == FormatStyle::LK_JavaScript &&
186 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
187 Line.startsWith(tok::kw_export, Keywords.kw_type,
191 Contexts.back().IsExpression =
false;
192 }
else if (Left->Previous &&
193 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
194 tok::kw_while, tok::l_paren,
196 Left->Previous->isIf() ||
197 Left->Previous->is(TT_BinaryOperator))) {
199 Contexts.back().IsExpression =
true;
200 }
else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
201 (Left->Previous->is(Keywords.kw_function) ||
202 (Left->Previous->endsSequence(tok::identifier,
203 Keywords.kw_function)))) {
205 Contexts.back().IsExpression =
false;
206 }
else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
207 Left->Previous->is(TT_JsTypeColon)) {
209 Contexts.back().IsExpression =
false;
210 }
else if (isLambdaParameterList(Left)) {
212 Contexts.back().IsExpression =
false;
213 }
else if (Line.InPPDirective &&
214 (!Left->Previous || !Left->Previous->is(tok::identifier))) {
215 Contexts.back().IsExpression =
true;
216 }
else if (Contexts[Contexts.size() - 2].CaretFound) {
218 Contexts.back().IsExpression =
false;
219 }
else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
220 Left->Type = TT_AttributeParen;
221 }
else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
223 Contexts.back().IsForEachMacro =
true;
224 Contexts.back().IsExpression =
false;
225 }
else if (Left->Previous && Left->Previous->MatchingParen &&
226 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
227 Contexts.back().IsExpression =
false;
228 }
else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
230 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
231 Contexts.back().IsExpression = !IsForOrCatch;
234 if (StartsObjCMethodExpr) {
235 Contexts.back().ColonIsObjCMethodExpr =
true;
236 Left->Type = TT_ObjCMethodExpr;
246 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
247 bool ProbablyFunctionType =
248 CurrentToken->isOneOf(tok::star, tok::amp, tok::caret);
249 bool HasMultipleLines =
false;
250 bool HasMultipleParametersOnALine =
false;
251 bool MightBeObjCForRangeLoop =
252 Left->Previous && Left->Previous->is(tok::kw_for);
253 FormatToken *PossibleObjCForInToken =
nullptr;
254 while (CurrentToken) {
259 if (LookForDecls && CurrentToken->Next) {
260 FormatToken *Prev = CurrentToken->getPreviousNonComment();
262 FormatToken *PrevPrev = Prev->getPreviousNonComment();
263 FormatToken *Next = CurrentToken->Next;
264 if (PrevPrev && PrevPrev->is(tok::identifier) &&
265 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
266 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
267 Prev->Type = TT_BinaryOperator;
268 LookForDecls =
false;
273 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
274 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
276 ProbablyFunctionType =
true;
277 if (CurrentToken->is(tok::comma))
278 MightBeFunctionType =
false;
279 if (CurrentToken->Previous->is(TT_BinaryOperator))
280 Contexts.back().IsExpression =
true;
281 if (CurrentToken->is(tok::r_paren)) {
282 if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next &&
283 (CurrentToken->Next->is(tok::l_paren) ||
284 (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
285 Left->Type = Left->Next->is(tok::caret) ? TT_ObjCBlockLParen
286 : TT_FunctionTypeLParen;
287 Left->MatchingParen = CurrentToken;
288 CurrentToken->MatchingParen = Left;
290 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
291 Left->Previous && Left->Previous->is(tok::l_paren)) {
295 for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) {
296 if (Tok->is(TT_BinaryOperator) &&
297 Tok->isOneOf(tok::star, tok::amp, tok::ampamp))
298 Tok->Type = TT_PointerOrReference;
302 if (StartsObjCMethodExpr) {
303 CurrentToken->Type = TT_ObjCMethodExpr;
304 if (Contexts.back().FirstObjCSelectorName) {
305 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
306 Contexts.back().LongestObjCSelectorName;
310 if (Left->is(TT_AttributeParen))
311 CurrentToken->Type = TT_AttributeParen;
312 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
313 CurrentToken->Type = TT_JavaAnnotation;
314 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
315 CurrentToken->Type = TT_LeadingJavaAnnotation;
316 if (Left->Previous && Left->Previous->is(TT_AttributeSquare))
317 CurrentToken->Type = TT_AttributeSquare;
319 if (!HasMultipleLines)
321 else if (HasMultipleParametersOnALine)
329 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
332 if (CurrentToken->is(tok::l_brace))
333 Left->Type = TT_Unknown;
334 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
335 !CurrentToken->Next->HasUnescapedNewline &&
336 !CurrentToken->Next->isTrailingComment())
337 HasMultipleParametersOnALine =
true;
338 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
339 CurrentToken->Previous->isSimpleTypeSpecifier()) &&
340 !CurrentToken->is(tok::l_brace))
341 Contexts.back().IsExpression =
false;
342 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
343 MightBeObjCForRangeLoop =
false;
344 if (PossibleObjCForInToken) {
345 PossibleObjCForInToken->Type = TT_Unknown;
346 PossibleObjCForInToken =
nullptr;
349 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
350 PossibleObjCForInToken = CurrentToken;
351 PossibleObjCForInToken->Type = TT_ObjCForIn;
355 if (CurrentToken->is(tok::comma))
356 Contexts.back().CanBeExpression =
true;
358 FormatToken *Tok = CurrentToken;
361 updateParameterCount(Left, Tok);
362 if (CurrentToken && CurrentToken->HasUnescapedNewline)
363 HasMultipleLines =
true;
368 bool isCSharpAttributeSpecifier(
const FormatToken &Tok) {
369 if (!Style.isCSharp())
372 const FormatToken *AttrTok = Tok.Next;
377 if (AttrTok->is(tok::r_square))
381 while (AttrTok && AttrTok->isNot(tok::r_square)) {
382 AttrTok = AttrTok->Next;
389 AttrTok = AttrTok->Next;
394 if (AttrTok->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
395 tok::kw_class, tok::kw_static, tok::l_square,
396 Keywords.kw_internal)) {
402 AttrTok->Next->startsSequence(tok::identifier, tok::l_paren))
408 bool isCpp11AttributeSpecifier(
const FormatToken &Tok) {
409 if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square))
412 if (Tok.Previous && Tok.Previous->is(tok::at)) {
415 const FormatToken *AttrTok = Tok.Next->Next;
420 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
422 if (AttrTok->isNot(tok::identifier))
424 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
428 if (AttrTok->is(tok::colon) ||
429 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
430 AttrTok->startsSequence(tok::r_paren, tok::identifier))
432 if (AttrTok->is(tok::ellipsis))
434 AttrTok = AttrTok->Next;
436 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
447 FormatToken *Left = CurrentToken->Previous;
448 Left->ParentBracket = Contexts.back().ContextKind;
449 FormatToken *
Parent = Left->getPreviousNonComment();
454 bool CppArrayTemplates =
455 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
456 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
457 Contexts.back().InTemplateArgument);
459 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
460 Contexts.back().InCpp11AttributeSpecifier;
463 bool IsCSharp11AttributeSpecifier =
464 isCSharpAttributeSpecifier(*Left) ||
465 Contexts.back().InCSharpAttributeSpecifier;
467 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
468 bool IsCppStructuredBinding = Left->isCppStructuredBinding(Style);
469 bool StartsObjCMethodExpr =
470 !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
471 Style.isCpp() && !IsCpp11AttributeSpecifier &&
472 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
473 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
475 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
476 tok::kw_return, tok::kw_throw) ||
477 Parent->isUnaryOperator() ||
479 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
482 bool ColonFound =
false;
484 unsigned BindingIncrease = 1;
485 if (IsCppStructuredBinding) {
486 Left->Type = TT_StructuredBindingLSquare;
487 }
else if (Left->is(TT_Unknown)) {
488 if (StartsObjCMethodExpr) {
489 Left->Type = TT_ObjCMethodExpr;
490 }
else if (IsCpp11AttributeSpecifier) {
491 Left->Type = TT_AttributeSquare;
492 }
else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
493 Contexts.back().ContextKind == tok::l_brace &&
494 Parent->isOneOf(tok::l_brace, tok::comma)) {
495 Left->Type = TT_JsComputedPropertyName;
496 }
else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
497 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
498 Left->Type = TT_DesignatedInitializerLSquare;
499 }
else if (IsCSharp11AttributeSpecifier) {
500 Left->Type = TT_AttributeSquare;
501 }
else if (CurrentToken->is(tok::r_square) && Parent &&
502 Parent->is(TT_TemplateCloser)) {
503 Left->Type = TT_ArraySubscriptLSquare;
504 }
else if (Style.Language == FormatStyle::LK_Proto ||
505 Style.Language == FormatStyle::LK_TextProto) {
532 Left->Type = TT_ArrayInitializerLSquare;
533 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
535 !Left->endsSequence(tok::l_square, tok::numeric_constant,
537 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
538 Left->Type = TT_ProtoExtensionLSquare;
539 BindingIncrease = 10;
541 }
else if (!CppArrayTemplates && Parent &&
542 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
543 tok::comma, tok::l_paren, tok::l_square,
544 tok::question, tok::colon, tok::kw_return,
547 Left->Type = TT_ArrayInitializerLSquare;
549 BindingIncrease = 10;
550 Left->Type = TT_ArraySubscriptLSquare;
554 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
555 Contexts.back().IsExpression =
true;
556 if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
557 Parent->is(TT_JsTypeColon))
558 Contexts.back().IsExpression =
false;
560 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
561 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
562 Contexts.back().InCSharpAttributeSpecifier = IsCSharp11AttributeSpecifier;
564 while (CurrentToken) {
565 if (CurrentToken->is(tok::r_square)) {
566 if (IsCpp11AttributeSpecifier)
567 CurrentToken->Type = TT_AttributeSquare;
568 if (IsCSharp11AttributeSpecifier)
569 CurrentToken->Type = TT_AttributeSquare;
570 else if (((CurrentToken->Next &&
571 CurrentToken->Next->is(tok::l_paren)) ||
572 (CurrentToken->Previous &&
573 CurrentToken->Previous->Previous == Left)) &&
574 Left->is(TT_ObjCMethodExpr)) {
579 StartsObjCMethodExpr =
false;
580 Left->Type = TT_Unknown;
582 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
583 CurrentToken->Type = TT_ObjCMethodExpr;
586 if (!ColonFound && CurrentToken->Previous &&
587 CurrentToken->Previous->is(TT_Unknown) &&
588 canBeObjCSelectorComponent(*CurrentToken->Previous))
589 CurrentToken->Previous->Type = TT_SelectorName;
593 if (Parent && Parent->is(TT_PointerOrReference))
594 Parent->Type = TT_BinaryOperator;
597 if (CurrentToken->Type == TT_ObjCMethodExpr && CurrentToken->Next &&
598 CurrentToken->Next->is(TT_LambdaArrow))
599 CurrentToken->Next->Type = TT_Unknown;
600 Left->MatchingParen = CurrentToken;
601 CurrentToken->MatchingParen = Left;
606 if (!Contexts.back().FirstObjCSelectorName) {
607 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
608 if (Previous && Previous->is(TT_SelectorName)) {
609 Previous->ObjCSelectorNameParts = 1;
610 Contexts.back().FirstObjCSelectorName =
Previous;
613 Left->ParameterCount =
614 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
616 if (Contexts.back().FirstObjCSelectorName) {
617 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
618 Contexts.back().LongestObjCSelectorName;
619 if (Left->BlockParameterCount > 1)
620 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
625 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
627 if (CurrentToken->is(tok::colon)) {
628 if (IsCpp11AttributeSpecifier &&
629 CurrentToken->endsSequence(tok::colon, tok::identifier,
633 CurrentToken->Type = TT_AttributeColon;
634 }
else if (Left->isOneOf(TT_ArraySubscriptLSquare,
635 TT_DesignatedInitializerLSquare)) {
636 Left->Type = TT_ObjCMethodExpr;
637 StartsObjCMethodExpr =
true;
638 Contexts.back().ColonIsObjCMethodExpr =
true;
639 if (Parent && Parent->is(tok::r_paren))
641 Parent->Type = TT_CastRParen;
645 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
647 Left->Type = TT_ArrayInitializerLSquare;
648 FormatToken *Tok = CurrentToken;
651 updateParameterCount(Left, Tok);
658 FormatToken *Left = CurrentToken->Previous;
659 Left->ParentBracket = Contexts.back().ContextKind;
661 if (Contexts.back().CaretFound)
662 Left->Type = TT_ObjCBlockLBrace;
663 Contexts.back().CaretFound =
false;
665 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
666 Contexts.back().ColonIsDictLiteral =
true;
668 Contexts.back().IsExpression =
true;
669 if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
670 Left->Previous->is(TT_JsTypeColon))
671 Contexts.back().IsExpression =
false;
673 while (CurrentToken) {
674 if (CurrentToken->is(tok::r_brace)) {
675 Left->MatchingParen = CurrentToken;
676 CurrentToken->MatchingParen = Left;
680 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
682 updateParameterCount(Left, CurrentToken);
683 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
684 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
685 if (Previous->is(TT_JsTypeOptionalQuestion))
686 Previous = Previous->getPreviousNonComment();
687 if ((CurrentToken->is(tok::colon) &&
688 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
689 Style.Language == FormatStyle::LK_Proto ||
690 Style.Language == FormatStyle::LK_TextProto) {
691 Left->Type = TT_DictLiteral;
692 if (Previous->Tok.getIdentifierInfo() ||
693 Previous->is(tok::string_literal))
694 Previous->Type = TT_SelectorName;
696 if (CurrentToken->is(tok::colon) ||
697 Style.Language == FormatStyle::LK_JavaScript)
698 Left->Type = TT_DictLiteral;
700 if (CurrentToken->is(tok::comma) &&
701 Style.Language == FormatStyle::LK_JavaScript)
702 Left->Type = TT_DictLiteral;
710 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
714 if (Current->is(tok::l_brace) && Current->BlockKind ==
BK_Block)
715 ++Left->BlockParameterCount;
716 if (Current->is(tok::comma)) {
717 ++Left->ParameterCount;
719 Left->Role.reset(
new CommaSeparatedList(Style));
720 Left->Role->CommaFound(Current);
721 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
722 Left->ParameterCount = 1;
726 bool parseConditional() {
727 while (CurrentToken) {
728 if (CurrentToken->is(tok::colon)) {
729 CurrentToken->Type = TT_ConditionalExpr;
739 bool parseTemplateDeclaration() {
740 if (CurrentToken && CurrentToken->is(tok::less)) {
741 CurrentToken->Type = TT_TemplateOpener;
746 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
752 bool consumeToken() {
753 FormatToken *Tok = CurrentToken;
755 switch (Tok->Tok.getKind()) {
758 if (!Tok->Previous && Line.MustBeDeclaration)
759 Tok->Type = TT_ObjCMethodSpecifier;
765 if (Style.Language == FormatStyle::LK_JavaScript) {
766 if (Contexts.back().ColonIsForRangeExpr ||
767 (Contexts.size() == 1 &&
768 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
769 Contexts.back().ContextKind == tok::l_paren ||
770 Contexts.back().ContextKind == tok::l_square ||
771 (!Contexts.back().IsExpression &&
772 Contexts.back().ContextKind == tok::l_brace) ||
773 (Contexts.size() == 1 &&
774 Line.MustBeDeclaration)) {
775 Contexts.back().IsExpression =
false;
776 Tok->Type = TT_JsTypeColon;
780 if (Contexts.back().ColonIsDictLiteral ||
781 Style.Language == FormatStyle::LK_Proto ||
782 Style.Language == FormatStyle::LK_TextProto) {
783 Tok->Type = TT_DictLiteral;
784 if (Style.Language == FormatStyle::LK_TextProto) {
785 if (FormatToken *
Previous = Tok->getPreviousNonComment())
788 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
789 Line.startsWith(TT_ObjCMethodSpecifier)) {
790 Tok->Type = TT_ObjCMethodExpr;
791 const FormatToken *BeforePrevious = Tok->Previous->Previous;
794 bool UnknownIdentifierInMethodDeclaration =
795 Line.startsWith(TT_ObjCMethodSpecifier) &&
796 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
797 if (!BeforePrevious ||
799 !(BeforePrevious->is(TT_CastRParen) ||
800 (BeforePrevious->is(TT_ObjCMethodExpr) &&
801 BeforePrevious->is(tok::colon))) ||
802 BeforePrevious->is(tok::r_square) ||
803 Contexts.back().LongestObjCSelectorName == 0 ||
804 UnknownIdentifierInMethodDeclaration) {
805 Tok->Previous->Type = TT_SelectorName;
806 if (!Contexts.back().FirstObjCSelectorName)
807 Contexts.back().FirstObjCSelectorName = Tok->Previous;
808 else if (Tok->Previous->ColumnWidth >
809 Contexts.back().LongestObjCSelectorName)
810 Contexts.back().LongestObjCSelectorName =
811 Tok->Previous->ColumnWidth;
812 Tok->Previous->ParameterIndex =
813 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
814 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
816 }
else if (Contexts.back().ColonIsForRangeExpr) {
817 Tok->Type = TT_RangeBasedForLoopColon;
818 }
else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
819 Tok->Type = TT_BitFieldColon;
820 }
else if (Contexts.size() == 1 &&
821 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
822 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren,
824 Tok->Type = TT_CtorInitializerColon;
826 Tok->Type = TT_InheritanceColon;
827 }
else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
828 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
829 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
830 Tok->Next->Next->is(tok::colon)))) {
833 Tok->Type = TT_ObjCMethodExpr;
834 }
else if (Contexts.back().ContextKind == tok::l_paren) {
835 Tok->Type = TT_InlineASMColon;
842 if (Style.Language == FormatStyle::LK_JavaScript &&
843 !Contexts.back().IsExpression)
844 Tok->Type = TT_JsTypeOperator;
848 if (Tok->is(tok::kw_if) && CurrentToken &&
849 CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier))
851 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
853 if (!parseParens(
true))
858 if (Style.Language == FormatStyle::LK_JavaScript) {
860 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
861 (Tok->Next && Tok->Next->is(tok::colon)))
864 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
867 Contexts.back().ColonIsForRangeExpr =
true;
877 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
878 Tok->Previous->MatchingParen &&
879 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
880 Tok->Previous->Type = TT_OverloadedOperator;
881 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
882 Tok->Type = TT_OverloadedOperatorLParen;
887 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
888 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
890 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
891 TT_LeadingJavaAnnotation)))
892 Line.MightBeFunctionDecl =
true;
899 if (Style.Language == FormatStyle::LK_TextProto) {
900 FormatToken *
Previous = Tok->getPreviousNonComment();
901 if (Previous && Previous->Type != TT_DictLiteral)
902 Previous->Type = TT_SelectorName;
909 Tok->Type = TT_TemplateOpener;
915 if (Style.Language == FormatStyle::LK_TextProto ||
916 (Style.Language == FormatStyle::LK_Proto && Tok->Previous &&
917 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
918 Tok->Type = TT_DictLiteral;
919 FormatToken *
Previous = Tok->getPreviousNonComment();
920 if (Previous && Previous->Type != TT_DictLiteral)
921 Previous->Type = TT_SelectorName;
924 Tok->Type = TT_BinaryOperator;
925 NonTemplateLess.insert(Tok);
939 if (Style.Language != FormatStyle::LK_TextProto)
940 Tok->Type = TT_BinaryOperator;
941 if (Tok->Previous && Tok->Previous->is(TT_TemplateCloser))
942 Tok->SpacesRequiredBefore = 1;
944 case tok::kw_operator:
945 if (Style.Language == FormatStyle::LK_TextProto ||
946 Style.Language == FormatStyle::LK_Proto)
948 while (CurrentToken &&
949 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
950 if (CurrentToken->isOneOf(tok::star, tok::amp))
951 CurrentToken->Type = TT_PointerOrReference;
953 if (CurrentToken && CurrentToken->Previous->isOneOf(
954 TT_BinaryOperator, TT_UnaryOperator, tok::comma,
955 tok::star, tok::arrow, tok::amp, tok::ampamp))
956 CurrentToken->Previous->Type = TT_OverloadedOperator;
959 CurrentToken->Type = TT_OverloadedOperatorLParen;
960 if (CurrentToken->Previous->is(TT_BinaryOperator))
961 CurrentToken->Previous->Type = TT_OverloadedOperator;
965 if (Style.Language == FormatStyle::LK_JavaScript && Tok->Next &&
966 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
972 Tok->Type = TT_JsTypeOptionalQuestion;
977 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
978 Style.Language == FormatStyle::LK_JavaScript)
982 case tok::kw_template:
983 parseTemplateDeclaration();
986 if (Contexts.back().InCtorInitializer)
987 Tok->Type = TT_CtorInitializerComma;
988 else if (Contexts.back().InInheritanceList)
989 Tok->Type = TT_InheritanceComma;
990 else if (Contexts.back().FirstStartOfName &&
991 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
992 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
993 Line.IsMultiVariableDeclStmt =
true;
995 if (Contexts.back().IsForEachMacro)
996 Contexts.back().IsExpression =
true;
998 case tok::identifier:
999 if (Tok->isOneOf(Keywords.kw___has_include,
1000 Keywords.kw___has_include_next)) {
1010 void parseIncludeDirective() {
1011 if (CurrentToken && CurrentToken->is(tok::less)) {
1013 while (CurrentToken) {
1016 if (CurrentToken->isNot(tok::comment) &&
1017 !CurrentToken->TokenText.startswith(
"//"))
1018 CurrentToken->Type = TT_ImplicitStringLiteral;
1024 void parseWarningOrError() {
1029 while (CurrentToken) {
1030 CurrentToken->Type = TT_ImplicitStringLiteral;
1035 void parsePragma() {
1038 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
1039 bool IsMark = CurrentToken->is(Keywords.kw_mark);
1042 while (CurrentToken) {
1043 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
1044 CurrentToken->Type = TT_ImplicitStringLiteral;
1050 void parseHasInclude() {
1051 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
1054 parseIncludeDirective();
1058 LineType parsePreprocessorDirective() {
1059 bool IsFirstToken = CurrentToken->IsFirst;
1065 if (Style.Language == FormatStyle::LK_JavaScript && IsFirstToken) {
1069 while (CurrentToken) {
1071 CurrentToken->Type = TT_ImplicitStringLiteral;
1077 if (CurrentToken->Tok.is(tok::numeric_constant)) {
1078 CurrentToken->SpacesRequiredBefore = 1;
1083 if (!CurrentToken->Tok.getIdentifierInfo())
1085 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1090 parseIncludeDirective();
1094 case tok::pp_warning:
1095 parseWarningOrError();
1097 case tok::pp_pragma:
1102 Contexts.back().IsExpression =
true;
1109 while (CurrentToken) {
1110 FormatToken *Tok = CurrentToken;
1112 if (Tok->is(tok::l_paren))
1114 else if (Tok->isOneOf(Keywords.kw___has_include,
1115 Keywords.kw___has_include_next))
1125 NonTemplateLess.clear();
1126 if (CurrentToken->is(tok::hash))
1127 return parsePreprocessorDirective();
1132 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1133 if ((Style.Language == FormatStyle::LK_Java &&
1134 CurrentToken->is(Keywords.kw_package)) ||
1136 CurrentToken->Next &&
1137 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1140 parseIncludeDirective();
1146 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
1147 parseIncludeDirective();
1153 if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&
1154 CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
1156 if (CurrentToken && CurrentToken->is(tok::identifier)) {
1157 while (CurrentToken)
1163 bool KeywordVirtualFound =
false;
1164 bool ImportStatement =
false;
1167 if (Style.Language == FormatStyle::LK_JavaScript &&
1168 CurrentToken->is(Keywords.kw_import))
1169 ImportStatement =
true;
1171 while (CurrentToken) {
1172 if (CurrentToken->is(tok::kw_virtual))
1173 KeywordVirtualFound =
true;
1174 if (Style.Language == FormatStyle::LK_JavaScript) {
1181 if (Line.First->is(tok::kw_export) &&
1182 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1183 CurrentToken->Next->isStringLiteral())
1184 ImportStatement =
true;
1185 if (isClosureImportStatement(*CurrentToken))
1186 ImportStatement =
true;
1188 if (!consumeToken())
1191 if (KeywordVirtualFound)
1193 if (ImportStatement)
1196 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
1197 if (Contexts.back().FirstObjCSelectorName)
1198 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1199 Contexts.back().LongestObjCSelectorName;
1207 bool isClosureImportStatement(
const FormatToken &Tok) {
1210 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
1212 (Tok.Next->Next->TokenText ==
"module" ||
1213 Tok.Next->Next->TokenText ==
"provide" ||
1214 Tok.Next->Next->TokenText ==
"require" ||
1215 Tok.Next->Next->TokenText ==
"requireType" ||
1216 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
1217 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1220 void resetTokenMetadata(FormatToken *Token) {
1226 if (!CurrentToken->isOneOf(
1227 TT_LambdaLSquare, TT_LambdaLBrace, TT_ForEachMacro,
1228 TT_TypenameMacro, TT_FunctionLBrace, TT_ImplicitStringLiteral,
1229 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow, TT_NamespaceMacro,
1230 TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString,
1231 TT_ObjCStringLiteral))
1232 CurrentToken->Type = TT_Unknown;
1233 CurrentToken->Role.reset();
1234 CurrentToken->MatchingParen =
nullptr;
1235 CurrentToken->FakeLParens.clear();
1236 CurrentToken->FakeRParens = 0;
1241 CurrentToken->NestingLevel = Contexts.size() - 1;
1242 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1243 modifyContext(*CurrentToken);
1244 determineTokenType(*CurrentToken);
1245 CurrentToken = CurrentToken->Next;
1248 resetTokenMetadata(CurrentToken);
1280 struct ScopedContextCreator {
1281 AnnotatingParser &
P;
1286 P.Contexts.push_back(Context(ContextKind,
1287 P.Contexts.back().BindingStrength + Increase,
1288 P.Contexts.back().IsExpression));
1291 ~ScopedContextCreator() { P.Contexts.pop_back(); }
1294 void modifyContext(
const FormatToken &Current) {
1296 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1299 !(Style.Language == FormatStyle::LK_JavaScript &&
1300 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1301 Line.startsWith(tok::kw_export, Keywords.kw_type,
1302 tok::identifier))) &&
1303 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1304 Contexts.back().IsExpression =
true;
1305 if (!Line.startsWith(TT_UnaryOperator)) {
1306 for (FormatToken *
Previous = Current.Previous;
1308 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1310 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
1317 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1318 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1320 Previous->Type = TT_PointerOrReference;
1323 }
else if (Current.is(tok::lessless) &&
1324 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1325 Contexts.back().IsExpression =
true;
1326 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1327 Contexts.back().IsExpression =
true;
1328 }
else if (Current.is(TT_TrailingReturnArrow)) {
1329 Contexts.back().IsExpression =
false;
1330 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1331 Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java;
1332 }
else if (Current.Previous &&
1333 Current.Previous->is(TT_CtorInitializerColon)) {
1334 Contexts.back().IsExpression =
true;
1335 Contexts.back().InCtorInitializer =
true;
1336 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1337 Contexts.back().InInheritanceList =
true;
1338 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1339 for (FormatToken *
Previous = Current.Previous;
1342 Previous->Type = TT_PointerOrReference;
1343 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer)
1344 Contexts.back().IsExpression =
false;
1345 }
else if (Current.is(tok::kw_new)) {
1346 Contexts.back().CanBeExpression =
false;
1347 }
else if (Current.is(tok::semi) ||
1348 (Current.is(tok::exclaim) && Current.Previous &&
1349 !Current.Previous->is(tok::kw_operator))) {
1353 Contexts.back().IsExpression =
true;
1357 static FormatToken *untilMatchingParen(FormatToken *Current) {
1361 if (Current->is(tok::l_paren))
1363 if (Current->is(tok::r_paren))
1367 Current = Current->Next;
1372 static bool isDeductionGuide(FormatToken &Current) {
1374 if (Current.Previous && Current.Previous->is(tok::r_paren) &&
1375 Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
1377 FormatToken *TemplateCloser = Current.Next->Next;
1378 int NestingLevel = 0;
1379 while (TemplateCloser) {
1381 if (TemplateCloser->is(tok::l_paren)) {
1383 TemplateCloser = untilMatchingParen(TemplateCloser);
1385 if (TemplateCloser->is(tok::less))
1387 if (TemplateCloser->is(tok::greater))
1389 if (NestingLevel < 1)
1391 TemplateCloser = TemplateCloser->Next;
1395 if (TemplateCloser && TemplateCloser->Next &&
1396 TemplateCloser->Next->is(tok::semi) &&
1397 Current.Previous->MatchingParen) {
1400 FormatToken *LeadingIdentifier =
1401 Current.Previous->MatchingParen->Previous;
1405 if (LeadingIdentifier) {
1406 FormatToken *PriorLeadingIdentifier = LeadingIdentifier->Previous;
1408 if (PriorLeadingIdentifier &&
1409 PriorLeadingIdentifier->is(tok::kw_explicit))
1410 PriorLeadingIdentifier = PriorLeadingIdentifier->Previous;
1412 return (PriorLeadingIdentifier &&
1413 PriorLeadingIdentifier->is(TT_TemplateCloser) &&
1414 LeadingIdentifier->TokenText == Current.Next->TokenText);
1421 void determineTokenType(FormatToken &Current) {
1422 if (!Current.is(TT_Unknown))
1426 if (Style.Language == FormatStyle::LK_JavaScript) {
1427 if (Current.is(tok::exclaim)) {
1428 if (Current.Previous &&
1429 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1430 tok::r_paren, tok::r_square,
1432 Current.Previous->Tok.isLiteral())) {
1433 Current.Type = TT_JsNonNullAssertion;
1437 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1438 Current.Type = TT_JsNonNullAssertion;
1447 if (Current.is(Keywords.kw_instanceof)) {
1448 Current.Type = TT_BinaryOperator;
1449 }
else if (isStartOfName(Current) &&
1450 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1451 Contexts.back().FirstStartOfName = &Current;
1452 Current.Type = TT_StartOfName;
1453 }
else if (Current.is(tok::semi)) {
1457 Contexts.back().FirstStartOfName =
nullptr;
1458 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1460 }
else if (Current.is(tok::arrow) &&
1461 Style.Language == FormatStyle::LK_Java) {
1462 Current.Type = TT_LambdaArrow;
1463 }
else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1464 Current.NestingLevel == 0 &&
1465 !Current.Previous->is(tok::kw_operator)) {
1467 Current.Type = TT_TrailingReturnArrow;
1469 }
else if (isDeductionGuide(Current)) {
1471 Current.Type = TT_TrailingReturnArrow;
1472 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1473 Current.Type = determineStarAmpUsage(Current,
1474 Contexts.back().CanBeExpression &&
1475 Contexts.back().IsExpression,
1476 Contexts.back().InTemplateArgument);
1477 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1478 Current.Type = determinePlusMinusCaretUsage(Current);
1479 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1480 Contexts.back().CaretFound =
true;
1481 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1482 Current.Type = determineIncrementUsage(Current);
1483 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1484 Current.Type = TT_UnaryOperator;
1485 }
else if (Current.is(tok::question)) {
1486 if (Style.Language == FormatStyle::LK_JavaScript &&
1487 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1490 Current.Type = TT_JsTypeOptionalQuestion;
1492 Current.Type = TT_ConditionalExpr;
1494 }
else if (Current.isBinaryOperator() &&
1495 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1496 (!Current.is(tok::greater) &&
1497 Style.Language != FormatStyle::LK_TextProto)) {
1498 Current.Type = TT_BinaryOperator;
1499 }
else if (Current.is(tok::comment)) {
1500 if (Current.TokenText.startswith(
"/*")) {
1501 if (Current.TokenText.endswith(
"*/"))
1502 Current.Type = TT_BlockComment;
1506 Current.Tok.setKind(tok::unknown);
1508 Current.Type = TT_LineComment;
1510 }
else if (Current.is(tok::r_paren)) {
1511 if (rParenEndsCast(Current))
1512 Current.Type = TT_CastRParen;
1513 if (Current.MatchingParen && Current.Next &&
1514 !Current.Next->isBinaryOperator() &&
1515 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1516 tok::comma, tok::period, tok::arrow,
1518 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1520 if (AfterParen->Tok.isNot(tok::caret)) {
1521 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1522 if (BeforeParen->is(tok::identifier) &&
1523 !BeforeParen->is(TT_TypenameMacro) &&
1524 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1525 (!BeforeParen->Previous ||
1526 BeforeParen->Previous->ClosesTemplateDeclaration))
1527 Current.Type = TT_FunctionAnnotationRParen;
1530 }
else if (Current.is(tok::at) && Current.Next &&
1531 Style.Language != FormatStyle::LK_JavaScript &&
1532 Style.Language != FormatStyle::LK_Java) {
1535 switch (Current.Next->Tok.getObjCKeywordID()) {
1536 case tok::objc_interface:
1537 case tok::objc_implementation:
1538 case tok::objc_protocol:
1539 Current.Type = TT_ObjCDecl;
1541 case tok::objc_property:
1542 Current.Type = TT_ObjCProperty;
1547 }
else if (Current.is(tok::period)) {
1548 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1549 if (PreviousNoComment &&
1550 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1551 Current.Type = TT_DesignatedInitializerPeriod;
1552 else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
1553 Current.Previous->isOneOf(TT_JavaAnnotation,
1554 TT_LeadingJavaAnnotation)) {
1555 Current.Type = Current.Previous->Type;
1557 }
else if (canBeObjCSelectorComponent(Current) &&
1560 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1561 Current.Previous->MatchingParen &&
1562 Current.Previous->MatchingParen->Previous &&
1563 Current.Previous->MatchingParen->Previous->is(
1564 TT_ObjCMethodSpecifier)) {
1568 Current.Type = TT_SelectorName;
1569 }
else if (Current.isOneOf(tok::identifier, tok::kw_const,
1570 tok::kw_noexcept) &&
1572 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1573 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1576 Current.Type = TT_TrailingAnnotation;
1577 }
else if ((Style.Language == FormatStyle::LK_Java ||
1578 Style.Language == FormatStyle::LK_JavaScript) &&
1580 if (Current.Previous->is(tok::at) &&
1581 Current.isNot(Keywords.kw_interface)) {
1582 const FormatToken &AtToken = *Current.Previous;
1583 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1584 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1585 Current.Type = TT_LeadingJavaAnnotation;
1587 Current.Type = TT_JavaAnnotation;
1588 }
else if (Current.Previous->is(tok::period) &&
1589 Current.Previous->isOneOf(TT_JavaAnnotation,
1590 TT_LeadingJavaAnnotation)) {
1591 Current.Type = Current.Previous->Type;
1601 bool isStartOfName(
const FormatToken &Tok) {
1602 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1605 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1608 if (Style.Language == FormatStyle::LK_JavaScript &&
1609 Tok.Previous->is(Keywords.kw_in))
1613 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1614 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1615 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1617 if (!PreviousNotConst)
1620 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1621 PreviousNotConst->Previous &&
1622 PreviousNotConst->Previous->is(tok::hash);
1624 if (PreviousNotConst->is(TT_TemplateCloser))
1625 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1626 PreviousNotConst->MatchingParen->Previous &&
1627 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1628 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1630 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1631 PreviousNotConst->MatchingParen->Previous &&
1632 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1635 return (!IsPPKeyword &&
1636 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1637 PreviousNotConst->is(TT_PointerOrReference) ||
1638 PreviousNotConst->isSimpleTypeSpecifier();
1642 bool rParenEndsCast(
const FormatToken &Tok) {
1644 if (!Style.isCpp() && Style.Language != FormatStyle::LK_Java)
1648 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1651 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1655 if (LeftOfParens->is(tok::r_paren)) {
1656 if (!LeftOfParens->MatchingParen ||
1657 !LeftOfParens->MatchingParen->Previous)
1659 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1664 if (LeftOfParens->Tok.getIdentifierInfo() &&
1665 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1671 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1672 TT_TemplateCloser, tok::ellipsis))
1676 if (Tok.Next->is(tok::question))
1681 if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
1682 tok::kw_throw, tok::arrow, Keywords.kw_override,
1683 Keywords.kw_final) ||
1684 isCpp11AttributeSpecifier(*Tok.Next))
1689 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren))
1693 if (Tok.Next->isNot(tok::string_literal) &&
1694 (Tok.Next->Tok.isLiteral() ||
1695 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1699 bool ParensAreType =
1701 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1702 Tok.Previous->isSimpleTypeSpecifier();
1703 bool ParensCouldEndDecl =
1704 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1705 if (ParensAreType && !ParensCouldEndDecl)
1716 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1717 Token = Token->Next)
1718 if (Token->is(TT_BinaryOperator))
1723 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1726 if (!Tok.Next->Next)
1733 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1734 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1735 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1738 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1739 Prev = Prev->Previous) {
1740 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1749 if (Style.Language == FormatStyle::LK_JavaScript)
1750 return TT_BinaryOperator;
1752 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1754 return TT_UnaryOperator;
1756 const FormatToken *NextToken = Tok.getNextNonComment();
1758 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const,
1759 tok::kw_noexcept) ||
1760 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1761 return TT_PointerOrReference;
1763 if (PrevToken->is(tok::coloncolon))
1764 return TT_PointerOrReference;
1766 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1767 tok::comma, tok::semi, tok::kw_return, tok::colon,
1768 tok::equal, tok::kw_delete, tok::kw_sizeof,
1770 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1771 TT_UnaryOperator, TT_CastRParen))
1772 return TT_UnaryOperator;
1774 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1775 return TT_PointerOrReference;
1777 return TT_PointerOrReference;
1778 if (NextToken->isOneOf(tok::comma, tok::semi))
1779 return TT_PointerOrReference;
1781 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
1782 FormatToken *TokenBeforeMatchingParen =
1783 PrevToken->MatchingParen->getPreviousNonComment();
1784 if (TokenBeforeMatchingParen &&
1785 TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype,
1787 return TT_PointerOrReference;
1790 if (PrevToken->Tok.isLiteral() ||
1791 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1792 tok::kw_false, tok::r_brace) ||
1793 NextToken->Tok.isLiteral() ||
1794 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1795 NextToken->isUnaryOperator() ||
1799 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1800 return TT_BinaryOperator;
1803 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1804 return TT_BinaryOperator;
1808 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1809 if (NextNextToken && NextNextToken->is(tok::arrow))
1810 return TT_BinaryOperator;
1814 if (IsExpression && !Contexts.back().CaretFound)
1815 return TT_BinaryOperator;
1817 return TT_PointerOrReference;
1820 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1821 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1823 return TT_UnaryOperator;
1825 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
1827 return TT_UnaryOperator;
1830 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1831 tok::question, tok::colon, tok::kw_return,
1832 tok::kw_case, tok::at, tok::l_brace, tok::kw_throw,
1833 tok::kw_co_return, tok::kw_co_yield))
1834 return TT_UnaryOperator;
1837 if (PrevToken->is(TT_BinaryOperator))
1838 return TT_UnaryOperator;
1841 return TT_BinaryOperator;
1845 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1846 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1847 if (!PrevToken || PrevToken->is(TT_CastRParen))
1848 return TT_UnaryOperator;
1849 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1850 return TT_TrailingUnaryOperator;
1852 return TT_UnaryOperator;
1855 SmallVector<Context, 8> Contexts;
1857 const FormatStyle &
Style;
1858 AnnotatedLine &
Line;
1859 FormatToken *CurrentToken;
1861 const AdditionalKeywords &Keywords;
1867 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
1875 class ExpressionParser {
1877 ExpressionParser(
const FormatStyle &
Style,
const AdditionalKeywords &Keywords,
1878 AnnotatedLine &
Line)
1879 :
Style(Style), Keywords(Keywords), Current(Line.First) {}
1882 void parse(
int Precedence = 0) {
1885 while (Current && (Current->is(tok::kw_return) ||
1886 (Current->is(tok::colon) &&
1887 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1890 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1895 parseConditionalExpr();
1901 if (Precedence == PrecedenceUnaryOperator) {
1902 parseUnaryOperator();
1906 FormatToken *Start = Current;
1907 FormatToken *LatestOperator =
nullptr;
1908 unsigned OperatorIndex = 0;
1912 parse(Precedence + 1);
1914 int CurrentPrecedence = getCurrentPrecedence();
1916 if (Current && Current->is(TT_SelectorName) &&
1917 Precedence == CurrentPrecedence) {
1919 addFakeParenthesis(Start,
prec::Level(Precedence));
1926 (Current->closesScope() &&
1927 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1928 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1935 if (Current->opensScope()) {
1938 while (Current && (!Current->closesScope() || Current->opensScope())) {
1945 if (CurrentPrecedence == Precedence) {
1947 LatestOperator->NextOperator = Current;
1948 LatestOperator = Current;
1949 Current->OperatorIndex = OperatorIndex;
1952 next(Precedence > 0);
1956 if (LatestOperator && (Current || Precedence > 0)) {
1958 if (Precedence == PrecedenceArrowAndPeriod) {
1962 addFakeParenthesis(Start,
prec::Level(Precedence));
1970 int getCurrentPrecedence() {
1972 const FormatToken *NextNonComment = Current->getNextNonComment();
1973 if (Current->is(TT_ConditionalExpr))
1975 if (NextNonComment && Current->is(TT_SelectorName) &&
1976 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
1977 ((Style.Language == FormatStyle::LK_Proto ||
1978 Style.Language == FormatStyle::LK_TextProto) &&
1979 NextNonComment->is(tok::less))))
1981 if (Current->is(TT_JsComputedPropertyName))
1983 if (Current->is(TT_LambdaArrow))
1985 if (Current->is(TT_JsFatArrow))
1987 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1988 (Current->is(tok::comment) && NextNonComment &&
1989 NextNonComment->is(TT_SelectorName)))
1991 if (Current->is(TT_RangeBasedForLoopColon))
1993 if ((Style.Language == FormatStyle::LK_Java ||
1994 Style.Language == FormatStyle::LK_JavaScript) &&
1995 Current->is(Keywords.kw_instanceof))
1997 if (Style.Language == FormatStyle::LK_JavaScript &&
1998 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
2000 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
2001 return Current->getPrecedence();
2002 if (Current->isOneOf(tok::period, tok::arrow))
2003 return PrecedenceArrowAndPeriod;
2004 if ((Style.Language == FormatStyle::LK_Java ||
2005 Style.Language == FormatStyle::LK_JavaScript) &&
2006 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
2007 Keywords.kw_throws))
2013 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
2014 Start->FakeLParens.push_back(Precedence);
2016 Start->StartsBinaryExpression =
true;
2018 FormatToken *
Previous = Current->Previous;
2019 while (Previous->is(tok::comment) && Previous->Previous)
2020 Previous = Previous->Previous;
2021 ++Previous->FakeRParens;
2023 Previous->EndsBinaryExpression =
true;
2029 void parseUnaryOperator() {
2031 while (Current && Current->is(TT_UnaryOperator)) {
2032 Tokens.push_back(Current);
2035 parse(PrecedenceArrowAndPeriod);
2036 for (FormatToken *Token : llvm::reverse(Tokens))
2041 void parseConditionalExpr() {
2042 while (Current && Current->isTrailingComment()) {
2045 FormatToken *Start = Current;
2047 if (!Current || !Current->is(tok::question))
2051 if (!Current || Current->isNot(TT_ConditionalExpr))
2058 void next(
bool SkipPastLeadingComments =
true) {
2060 Current = Current->Next;
2062 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
2063 Current->isTrailingComment())
2064 Current = Current->Next;
2067 const FormatStyle &
Style;
2068 const AdditionalKeywords &Keywords;
2069 FormatToken *Current;
2080 bool CommentLine =
true;
2082 if (!
Tok->
is(tok::comment)) {
2083 CommentLine =
false;
2090 if (NextNonCommentLine && CommentLine &&
2093 (*I)->First->OriginalColumn) {
2098 (
Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
2102 : NextNonCommentLine->
Level;
2104 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
2107 setCommentLineLevels((*I)->Children);
2112 unsigned Result = 0;
2125 Line.
Type = Parser.parseLine();
2137 ExpressionParser ExprParser(
Style, Keywords, Line);
2156 for (; Next; Next = Next->Next) {
2157 if (Next->is(TT_OverloadedOperatorLParen))
2159 if (Next->is(TT_OverloadedOperator))
2161 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
2164 Next->Next->startsSequence(tok::l_square, tok::r_square))
2165 Next = Next->Next->Next;
2168 if (Next->startsSequence(tok::l_square, tok::r_square)) {
2173 if ((Next->isSimpleTypeSpecifier() || Next->is(tok::identifier)) &&
2174 Next->Next && Next->Next->isOneOf(tok::star, tok::amp, tok::ampamp)) {
2187 if (Current.
is(tok::kw_operator)) {
2190 Next = skipOperatorName(Next);
2194 for (; Next; Next = Next->
Next) {
2195 if (Next->
is(TT_TemplateOpener)) {
2197 }
else if (Next->
is(tok::coloncolon)) {
2201 if (Next->
is(tok::kw_operator)) {
2202 Next = skipOperatorName(Next->
Next);
2205 if (!Next->
is(tok::identifier))
2207 }
else if (Next->
is(tok::l_paren)) {
2219 if (Line.
Last->
is(tok::l_brace))
2234 Tok->
isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
2236 if (
Tok->
isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2246 if ((
Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
2247 Style.AlwaysBreakAfterReturnType ==
2248 FormatStyle::RTBS_TopLevelDefinitions) &&
2252 switch (
Style.AlwaysBreakAfterReturnType) {
2253 case FormatStyle::RTBS_None:
2255 case FormatStyle::RTBS_All:
2256 case FormatStyle::RTBS_TopLevel:
2258 case FormatStyle::RTBS_AllDefinitions:
2259 case FormatStyle::RTBS_TopLevelDefinitions:
2270 calculateFormattingInformation(**I);
2280 Current->
Type = TT_FunctionDeclarationName;
2281 if (Current->
is(TT_LineComment)) {
2285 (
Style.Cpp11BracedListStyle && !
Style.SpacesInParentheses) ? 0 : 1;
2299 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
2302 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
2310 spaceRequiredBefore(Line, *Current)) {
2318 Current->
is(TT_FunctionDeclarationName))
2323 unsigned ChildSize = 0;
2332 Prev->
Children[0]->First->MustBreakBefore) ||
2339 if (Current->
is(TT_CtorInitializerColon))
2340 InFunctionDecl =
false;
2351 Current->
SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
2352 if (
Style.Language == FormatStyle::LK_ObjC &&
2360 Current = Current->
Next;
2363 calculateUnbreakableTailLengths(Line);
2364 unsigned IndentLevel = Line.
Level;
2365 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
2367 Current->
Role->precomputeFormattingInfos(Current);
2370 assert(IndentLevel > 0);
2381 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
2382 unsigned UnbreakableTailLength = 0;
2387 Current->
isOneOf(tok::comment, tok::string_literal)) {
2388 UnbreakableTailLength = 0;
2390 UnbreakableTailLength +=
2397 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
2399 bool InFunctionDecl) {
2403 if (Left.
is(tok::semi))
2406 if (
Style.Language == FormatStyle::LK_Java) {
2407 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2409 if (Right.
is(Keywords.kw_implements))
2413 }
else if (
Style.Language == FormatStyle::LK_JavaScript) {
2414 if (Right.
is(Keywords.kw_function) && Left.
isNot(tok::comma))
2416 if (Left.
is(TT_JsTypeColon))
2418 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2419 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2426 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
2428 if (Right.
is(tok::l_square)) {
2429 if (
Style.Language == FormatStyle::LK_Proto)
2431 if (Left.
is(tok::r_square))
2434 if (Right.
is(TT_LambdaLSquare) && Left.
is(tok::equal))
2436 if (!Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2437 TT_ArrayInitializerLSquare,
2438 TT_DesignatedInitializerLSquare, TT_AttributeSquare))
2442 if (Left.
is(tok::coloncolon) ||
2443 (Right.
is(tok::period) &&
Style.Language == FormatStyle::LK_Proto))
2445 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2446 Right.
is(tok::kw_operator)) {
2449 if (Left.
is(TT_StartOfName))
2452 return Style.PenaltyReturnTypeOnItsOwnLine;
2455 if (Right.
is(TT_PointerOrReference))
2457 if (Right.
is(TT_LambdaArrow))
2459 if (Left.
is(tok::equal) && Right.
is(tok::l_brace))
2461 if (Left.
is(TT_CastRParen))
2463 if (Left.
isOneOf(tok::kw_class, tok::kw_struct))
2465 if (Left.
is(tok::comment))
2468 if (Left.
isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2469 TT_CtorInitializerColon))
2497 if (Right.
is(TT_TrailingAnnotation) &&
2508 bool is_short_annotation = Right.
TokenText.size() < 10;
2509 return (Left.
is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2513 if (Line.
startsWith(tok::kw_for) && Left.
is(tok::equal))
2518 if (Right.
is(TT_SelectorName))
2520 if (Left.
is(tok::colon) && Left.
is(TT_ObjCMethodExpr))
2530 if (Left.
is(tok::l_paren) && InFunctionDecl &&
2533 if (Left.
is(tok::l_paren) && Left.
Previous &&
2536 if (Left.
is(tok::equal) && InFunctionDecl)
2538 if (Right.
is(tok::r_brace))
2540 if (Left.
is(TT_TemplateOpener))
2545 if (Left.
is(tok::l_brace) && !
Style.Cpp11BracedListStyle)
2550 if (Left.
is(TT_JavaAnnotation))
2553 if (Left.
is(TT_UnaryOperator))
2562 if (Left.
is(tok::comma))
2567 if (Right.
is(tok::lessless)) {
2575 return Style.PenaltyBreakTemplateDeclaration;
2576 if (Left.
is(TT_ConditionalExpr))
2582 return Style.PenaltyBreakAssignment;
2589 bool TokenAnnotator::spaceRequiredBeforeParens(
const FormatToken &Right)
const {
2590 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always ||
2591 (
Style.SpaceBeforeParens == FormatStyle::SBPO_NonEmptyParentheses &&
2598 return Tok.
isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
2599 tok::kw_constexpr, tok::kw_catch);
2602 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
2605 if (Left.
is(tok::kw_return) && Right.
isNot(tok::semi))
2607 if (Left.
is(Keywords.kw_assert) &&
Style.Language == FormatStyle::LK_Java)
2612 if (Right.
is(tok::hashhash))
2613 return Left.
is(tok::hash);
2614 if (Left.
isOneOf(tok::hashhash, tok::hash))
2615 return Right.
is(tok::hash);
2616 if ((Left.
is(tok::l_paren) && Right.
is(tok::r_paren)) ||
2619 return Style.SpaceInEmptyParentheses;
2620 if (
Style.SpacesInConditionalStatement) {
2621 if (Left.
is(tok::l_paren) && Left.
Previous &&
2629 if (Left.
is(tok::l_paren) || Right.
is(tok::r_paren))
2630 return (Right.
is(TT_CastRParen) ||
2632 ?
Style.SpacesInCStyleCastParentheses
2633 :
Style.SpacesInParentheses;
2634 if (Right.
isOneOf(tok::semi, tok::comma))
2640 return !IsLightweightGeneric &&
Style.ObjCSpaceBeforeProtocolList;
2642 if (Right.
is(tok::less) && Left.
is(tok::kw_template))
2643 return Style.SpaceAfterTemplateKeyword;
2644 if (Left.
isOneOf(tok::exclaim, tok::tilde))
2646 if (Left.
is(tok::at) &&
2647 Right.
isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2648 tok::numeric_constant, tok::l_paren, tok::l_brace,
2649 tok::kw_true, tok::kw_false))
2651 if (Left.
is(tok::colon))
2652 return !Left.
is(TT_ObjCMethodExpr);
2653 if (Left.
is(tok::coloncolon))
2655 if (Left.
is(tok::less) || Right.
isOneOf(tok::greater, tok::less)) {
2656 if (
Style.Language == FormatStyle::LK_TextProto ||
2657 (
Style.Language == FormatStyle::LK_Proto &&
2658 (Left.
is(TT_DictLiteral) || Right.
is(TT_DictLiteral)))) {
2660 if (Left.
is(tok::less) && Right.
is(tok::greater))
2662 return !
Style.Cpp11BracedListStyle;
2666 if (Right.
is(tok::ellipsis))
2669 if (Left.
is(tok::l_square) && Right.
is(tok::amp))
2670 return Style.SpacesInSquareBrackets;
2671 if (Right.
is(TT_PointerOrReference)) {
2677 if (!TokenBeforeMatchingParen ||
2678 !TokenBeforeMatchingParen->
isOneOf(tok::kw_typeof, tok::kw_decltype,
2683 (!Left.
isOneOf(TT_PointerOrReference, tok::l_paren) &&
2684 (
Style.PointerAlignment != FormatStyle::PAS_Left ||
2689 if (Right.
is(TT_FunctionTypeLParen) && Left.
isNot(tok::l_paren) &&
2690 (!Left.
is(TT_PointerOrReference) ||
2691 (
Style.PointerAlignment != FormatStyle::PAS_Right &&
2694 if (Left.
is(TT_PointerOrReference))
2696 (Right.
isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2697 !Right.
is(TT_StartOfName)) ||
2699 (!Right.
isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2701 (
Style.PointerAlignment != FormatStyle::PAS_Right &&
2706 if (Right.
is(tok::star) && Left.
is(tok::l_paren))
2708 if (Right.
isOneOf(tok::star, tok::amp, tok::ampamp) &&
2714 return (
Style.PointerAlignment != FormatStyle::PAS_Left);
2715 const auto SpaceRequiredForArrayInitializerLSquare =
2717 return Style.SpacesInContainerLiterals ||
2718 ((
Style.Language == FormatStyle::LK_Proto ||
2719 Style.Language == FormatStyle::LK_TextProto) &&
2720 !
Style.Cpp11BracedListStyle &&
2724 if (Left.
is(tok::l_square))
2725 return (Left.
is(TT_ArrayInitializerLSquare) && Right.
isNot(tok::r_square) &&
2726 SpaceRequiredForArrayInitializerLSquare(Left,
Style)) ||
2727 (Left.
isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
2728 TT_LambdaLSquare) &&
2729 Style.SpacesInSquareBrackets && Right.
isNot(tok::r_square));
2730 if (Right.
is(tok::r_square))
2733 SpaceRequiredForArrayInitializerLSquare(*Right.
MatchingParen,
2735 (
Style.SpacesInSquareBrackets &&
2737 TT_StructuredBindingLSquare,
2738 TT_LambdaLSquare)) ||
2740 if (Right.
is(tok::l_square) &&
2741 !Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2742 TT_DesignatedInitializerLSquare,
2743 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
2744 !Left.
isOneOf(tok::numeric_constant, TT_DictLiteral) &&
2745 !(!Left.
is(tok::r_square) &&
Style.SpaceBeforeSquareBrackets &&
2746 Right.
is(TT_ArraySubscriptLSquare)))
2748 if (Left.
is(tok::l_brace) && Right.
is(tok::r_brace))
2753 return Style.Cpp11BracedListStyle ?
Style.SpacesInParentheses :
true;
2754 if (Left.
is(TT_BlockComment))
2756 return Style.Language == FormatStyle::LK_JavaScript ||
2758 if (Right.
is(tok::l_paren)) {
2759 if ((Left.
is(tok::r_paren) && Left.
is(TT_AttributeParen)) ||
2760 (Left.
is(tok::r_square) && Left.
is(TT_AttributeSquare)))
2763 (
Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
2765 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2768 (Left.
isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2769 tok::kw_new, tok::kw_delete) &&
2771 (spaceRequiredBeforeParens(Right) &&
2780 if (Right.
is(TT_UnaryOperator))
2781 return !Left.
isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2782 (Left.
isNot(tok::colon) || Left.
isNot(TT_ObjCMethodExpr));
2783 if ((Left.
isOneOf(tok::identifier, tok::greater, tok::r_square,
2789 if (Left.
is(tok::period) || Right.
is(tok::period))
2791 if (Right.
is(tok::hash) && Left.
is(tok::identifier) && Left.
TokenText ==
"L")
2801 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_square))
2803 if (Left.
is(tok::l_brace) && Left.
endsSequence(TT_DictLiteral, tok::at))
2810 if (Right.
Type == TT_TrailingAnnotation &&
2811 Right.
isOneOf(tok::amp, tok::ampamp) &&
2812 Left.
isOneOf(tok::kw_const, tok::kw_volatile) &&
2817 return Style.PointerAlignment != FormatStyle::PAS_Left;
2821 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2826 if (
Style.isCpp()) {
2827 if (Left.
is(tok::kw_operator))
2828 return Right.
is(tok::coloncolon);
2832 }
else if (
Style.Language == FormatStyle::LK_Proto ||
2833 Style.Language == FormatStyle::LK_TextProto) {
2834 if (Right.
is(tok::period) &&
2835 Left.
isOneOf(Keywords.kw_optional, Keywords.kw_required,
2836 Keywords.kw_repeated, Keywords.kw_extend))
2838 if (Right.
is(tok::l_paren) &&
2839 Left.
isOneOf(Keywords.kw_returns, Keywords.kw_option))
2841 if (Right.
isOneOf(tok::l_brace, tok::less) && Left.
is(TT_SelectorName))
2844 if (Left.
is(tok::slash) || Right.
is(tok::slash))
2848 Right.
isOneOf(tok::l_brace, tok::less))
2849 return !
Style.Cpp11BracedListStyle;
2851 if (Left.
is(tok::percent))
2855 if (Left.
is(tok::numeric_constant) && Right.
is(tok::percent))
2857 }
else if (
Style.isCSharp()) {
2859 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_StartOfName))
2862 if (Right.
is(tok::l_paren))
2863 if (Left.
is(tok::kw_using))
2864 return spaceRequiredBeforeParens(Left);
2865 }
else if (
Style.Language == FormatStyle::LK_JavaScript) {
2866 if (Left.
is(TT_JsFatArrow))
2869 if (Right.
is(tok::l_paren) && Left.
is(Keywords.kw_await) && Left.
Previous &&
2872 if (Left.
is(Keywords.kw_async) && Right.
is(tok::l_paren) &&
2877 if (Next && Next->
is(TT_JsFatArrow))
2880 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2881 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2886 if (Left.
is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2887 Right.
is(TT_TemplateString))
2889 if (Right.
is(tok::star) &&
2890 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield))
2892 if (Right.
isOneOf(tok::l_brace, tok::l_square) &&
2893 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield,
2894 Keywords.kw_extends, Keywords.kw_implements))
2896 if (Right.
is(tok::l_paren)) {
2906 if (Left.
isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
2911 if (Left.
endsSequence(tok::kw_const, Keywords.kw_as)) {
2914 if ((Left.
isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2925 Left.
Previous->
is(tok::period) && Right.
is(tok::l_paren))
2927 if (Left.
is(Keywords.kw_as) &&
2928 Right.
isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2930 if (Left.
is(tok::kw_default) && Left.
Previous &&
2933 if (Left.
is(Keywords.kw_is) && Right.
is(tok::l_brace))
2935 if (Right.
isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2937 if (Left.
is(TT_JsTypeOperator) || Right.
is(TT_JsTypeOperator))
2939 if ((Left.
is(tok::l_brace) || Right.
is(tok::r_brace)) &&
2940 Line.
First->
isOneOf(Keywords.kw_import, tok::kw_export))
2942 if (Left.
is(tok::ellipsis))
2944 if (Left.
is(TT_TemplateCloser) &&
2945 !Right.
isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2946 Keywords.kw_implements, Keywords.kw_extends))
2951 if (Right.
is(TT_JsNonNullAssertion))
2953 if (Left.
is(TT_JsNonNullAssertion) &&
2954 Right.
isOneOf(Keywords.kw_as, Keywords.kw_in))
2956 }
else if (
Style.Language == FormatStyle::LK_Java) {
2957 if (Left.
is(tok::r_square) && Right.
is(tok::l_brace))
2959 if (Left.
is(Keywords.kw_synchronized) && Right.
is(tok::l_paren))
2960 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never;
2961 if ((Left.
isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2962 tok::kw_protected) ||
2963 Left.
isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2964 Keywords.kw_native)) &&
2965 Right.
is(TT_TemplateOpener))
2968 if (Left.
is(TT_ImplicitStringLiteral))
2971 if (Left.
is(TT_ObjCMethodSpecifier))
2973 if (Left.
is(tok::r_paren) && canBeObjCSelectorComponent(Right))
2980 (Right.
is(tok::equal) || Left.
is(tok::equal)))
2983 if (Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2984 Left.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2986 if (Right.
is(TT_OverloadedOperatorLParen))
2987 return spaceRequiredBeforeParens(Right);
2988 if (Left.
is(tok::comma))
2990 if (Right.
is(tok::comma))
2992 if (Right.
is(TT_ObjCBlockLParen))
2994 if (Right.
is(TT_CtorInitializerColon))
2995 return Style.SpaceBeforeCtorInitializerColon;
2996 if (Right.
is(TT_InheritanceColon) && !
Style.SpaceBeforeInheritanceColon)
2998 if (Right.
is(TT_RangeBasedForLoopColon) &&
2999 !
Style.SpaceBeforeRangeBasedForLoopColon)
3001 if (Right.
is(tok::colon)) {
3002 if (Line.
First->
isOneOf(tok::kw_case, tok::kw_default) ||
3005 if (Right.
is(TT_ObjCMethodExpr))
3007 if (Left.
is(tok::question))
3009 if (Right.
is(TT_InlineASMColon) && Left.
is(tok::coloncolon))
3011 if (Right.
is(TT_DictLiteral))
3012 return Style.SpacesInContainerLiterals;
3013 if (Right.
is(TT_AttributeColon))
3017 if (Left.
is(TT_UnaryOperator)) {
3018 if (!Right.
is(tok::l_paren)) {
3022 if (Left.
is(tok::exclaim) && Left.
TokenText ==
"not")
3024 if (Left.
is(tok::tilde) && Left.
TokenText ==
"compl")
3028 if (Left.
is(tok::amp) && Right.
is(tok::r_square))
3029 return Style.SpacesInSquareBrackets;
3031 return (
Style.SpaceAfterLogicalNot && Left.
is(tok::exclaim)) ||
3032 Right.
is(TT_BinaryOperator);
3037 if (Left.
is(TT_CastRParen))
3038 return Style.SpaceAfterCStyleCast ||
3039 Right.
isOneOf(TT_BinaryOperator, TT_SelectorName);
3041 if (Left.
is(tok::greater) && Right.
is(tok::greater)) {
3042 if (
Style.Language == FormatStyle::LK_TextProto ||
3043 (
Style.Language == FormatStyle::LK_Proto && Left.
is(TT_DictLiteral)))
3044 return !
Style.Cpp11BracedListStyle;
3045 return Right.
is(TT_TemplateCloser) && Left.
is(TT_TemplateCloser) &&
3046 (
Style.Standard < FormatStyle::LS_Cpp11 ||
Style.SpacesInAngles);
3048 if (Right.
isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
3049 Left.
isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
3050 (Right.
is(tok::period) && Right.
isNot(TT_DesignatedInitializerPeriod)))
3052 if (!
Style.SpaceBeforeAssignmentOperators && Left.
isNot(TT_TemplateCloser) &&
3055 if (
Style.Language == FormatStyle::LK_Java && Right.
is(tok::coloncolon) &&
3056 (Left.
is(tok::identifier) || Left.
is(tok::kw_this)))
3058 if (Right.
is(tok::coloncolon) && Left.
is(tok::identifier))
3063 if (Right.
is(tok::coloncolon) &&
3064 !Left.
isOneOf(tok::l_brace, tok::comment, tok::l_paren))
3065 return (Left.
is(TT_TemplateOpener) &&
3066 Style.Standard < FormatStyle::LS_Cpp11) ||
3067 !(Left.
isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
3068 tok::kw___super, TT_TemplateCloser,
3069 TT_TemplateOpener)) ||
3070 (Left.
is(tok ::l_paren) &&
Style.SpacesInParentheses);
3071 if ((Left.
is(TT_TemplateOpener)) != (Right.
is(TT_TemplateCloser)))
3072 return Style.SpacesInAngles;
3074 if (Right.
is(TT_StructuredBindingLSquare))
3075 return !Left.
isOneOf(tok::amp, tok::ampamp) ||
3076 Style.PointerAlignment != FormatStyle::PAS_Right;
3078 if (Right.
Next && Right.
Next->
is(TT_StructuredBindingLSquare) &&
3079 Right.
isOneOf(tok::amp, tok::ampamp))
3080 return Style.PointerAlignment != FormatStyle::PAS_Left;
3081 if ((Right.
is(TT_BinaryOperator) && !Left.
is(tok::l_paren)) ||
3082 (Left.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
3083 !Right.
is(tok::r_paren)))
3085 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_paren) &&
3086 Right.
isNot(TT_FunctionTypeLParen))
3087 return spaceRequiredBeforeParens(Right);
3088 if (Right.
is(TT_TemplateOpener) && Left.
is(tok::r_paren) &&
3091 if (Right.
is(tok::less) && Left.
isNot(tok::l_paren) &&
3094 if (Right.
is(TT_TrailingUnaryOperator))
3096 if (Left.
is(TT_RegexLiteral))
3098 return spaceRequiredBetween(Line, Left, Right);
3104 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
3107 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
3113 if (
Style.Language == FormatStyle::LK_JavaScript) {
3115 if (Right.
is(tok::string_literal) && Left.
is(tok::plus) && Left.
Previous &&
3118 if (Left.
is(TT_DictLiteral) && Left.
is(tok::l_brace) && Line.
Level == 0 &&
3120 Line.
First->
isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
3124 !Line.
First->
isOneOf(Keywords.kw_var, Keywords.kw_let))
3128 if (Left.
is(tok::l_brace) && Line.
Level == 0 &&
3130 Line.
startsWith(tok::kw_const, tok::kw_enum) ||
3131 Line.
startsWith(tok::kw_export, tok::kw_enum) ||
3132 Line.
startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
3136 if (Right.
is(tok::r_brace) && Left.
is(tok::l_brace) &&
3139 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
3140 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
3142 Style.AllowShortFunctionsOnASingleLine &
3143 FormatStyle::SFS_InlineOnly);
3144 }
else if (
Style.Language == FormatStyle::LK_Java) {
3145 if (Right.
is(tok::plus) && Left.
is(tok::string_literal) && Right.
Next &&
3146 Right.
Next->
is(tok::string_literal))
3148 }
else if (
Style.Language == FormatStyle::LK_Cpp ||
3149 Style.Language == FormatStyle::LK_ObjC ||
3150 Style.Language == FormatStyle::LK_Proto ||
3151 Style.Language == FormatStyle::LK_TableGen ||
3152 Style.Language == FormatStyle::LK_TextProto) {
3163 if ((Left.
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
3164 (
Style.Language == FormatStyle::LK_JavaScript &&
3165 Left.
is(tok::l_paren))) &&
3170 TT_ArrayInitializerLSquare) ||
3171 (
Style.Language == FormatStyle::LK_JavaScript &&
3173 BeforeClosingBrace = &Left;
3174 if (BeforeClosingBrace && (BeforeClosingBrace->
is(tok::comma) ||
3179 if (Right.
is(tok::comment))
3181 Left.
isNot(TT_CtorInitializerColon) &&
3187 if (Right.
is(tok::lessless) && Right.
Next &&
3189 Right.
Next->
is(tok::string_literal))
3194 Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes)
3196 if (Right.
is(TT_CtorInitializerComma) &&
3197 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
3198 !
Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
3200 if (Right.
is(TT_CtorInitializerColon) &&
3201 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
3202 !
Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
3205 if (
Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
3206 Right.
is(TT_InheritanceComma))
3208 if (Right.
is(tok::string_literal) && Right.
TokenText.startswith(
"R\""))
3221 if (Right.
is(TT_InlineASMBrace))
3224 return (Line.
startsWith(tok::kw_enum) &&
Style.BraceWrapping.AfterEnum) ||
3225 (Line.
startsWith(tok::kw_typedef, tok::kw_enum) &&
3226 Style.BraceWrapping.AfterEnum) ||
3229 if (Left.
is(TT_ObjCBlockLBrace) &&
3230 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
3233 if (Left.
is(TT_LambdaLBrace)) {
3236 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline)
3239 if (
Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
3240 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
3242 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty))
3247 if (
Style.isCSharp() &&
3248 ((Left.
is(TT_AttributeSquare) && Left.
is(tok::r_square)) ||
3249 (Left.
is(tok::r_square) && Right.
is(TT_AttributeSquare) &&
3250 Right.
is(tok::l_square))))
3254 if ((
Style.Language == FormatStyle::LK_Java ||
3255 Style.Language == FormatStyle::LK_JavaScript) &&
3256 Left.
is(TT_LeadingJavaAnnotation) &&
3257 Right.
isNot(TT_LeadingJavaAnnotation) && Right.
isNot(tok::l_paren) &&
3258 (Line.
Last->
is(tok::l_brace) ||
Style.BreakAfterJavaFieldAnnotations))
3261 if (Right.
is(TT_ProtoExtensionLSquare))
3291 if ((
Style.Language == FormatStyle::LK_Proto ||
3292 Style.Language == FormatStyle::LK_TextProto) &&
3293 Right.
is(TT_SelectorName) && !Right.
is(tok::r_square) && Right.
Next) {
3303 if (LBrace && LBrace->
is(tok::colon)) {
3304 LBrace = LBrace->
Next;
3305 if (LBrace && LBrace->
is(tok::at)) {
3306 LBrace = LBrace->
Next;
3308 LBrace = LBrace->
Next;
3320 ((LBrace->
is(tok::l_brace) &&
3321 (LBrace->
is(TT_DictLiteral) ||
3322 (LBrace->
Next && LBrace->
Next->
is(tok::r_brace)))) ||
3323 LBrace->
is(TT_ArrayInitializerLSquare) || LBrace->
is(tok::less))) {
3345 if (Left.
isOneOf(tok::r_brace, tok::greater, tok::r_square))
3352 if ((
Style.Language == FormatStyle::LK_Cpp ||
3353 Style.Language == FormatStyle::LK_ObjC) &&
3355 !Right.
isOneOf(tok::l_paren, TT_LambdaLSquare)) {
3366 auto Next =
Comma->getNextNonComment();
3369 if (!Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret))
3376 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
3381 if (
Style.Language == FormatStyle::LK_Java) {
3382 if (Left.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3383 Keywords.kw_implements))
3385 if (Right.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3386 Keywords.kw_implements))
3388 }
else if (
Style.Language == FormatStyle::LK_JavaScript) {
3392 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
3393 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
3394 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
3395 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
3396 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
3400 Left.
isOneOf(tok::r_square, tok::r_paren)) &&
3401 Right.
isOneOf(tok::l_square, tok::l_paren))
3403 if (Left.
is(TT_JsFatArrow) && Right.
is(tok::l_brace))
3405 if (Left.
is(TT_JsTypeColon))
3408 if (Left.
is(tok::exclaim) && Right.
is(tok::colon))
3413 if (Right.
is(Keywords.kw_is)) {
3422 if (!Next || !Next->
is(tok::colon))
3425 if (Left.
is(Keywords.kw_in))
3426 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
3427 if (Right.
is(Keywords.kw_in))
3428 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
3429 if (Right.
is(Keywords.kw_as))
3431 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
3437 if (Left.
is(Keywords.kw_as))
3439 if (Left.
is(TT_JsNonNullAssertion))
3441 if (Left.
is(Keywords.kw_declare) &&
3442 Right.
isOneOf(Keywords.kw_module, tok::kw_namespace,
3443 Keywords.kw_function, tok::kw_class, tok::kw_enum,
3444 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
3445 Keywords.kw_let, tok::kw_const))
3449 if (Left.
isOneOf(Keywords.kw_module, tok::kw_namespace) &&
3450 Right.
isOneOf(tok::identifier, tok::string_literal))
3456 if (Left.
is(tok::identifier) && Right.
is(TT_TemplateString)) {
3463 if (Left.
is(tok::at))
3467 if (Left.
isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
3468 return !Right.
is(tok::l_paren);
3469 if (Right.
is(TT_PointerOrReference))
3471 (
Style.PointerAlignment == FormatStyle::PAS_Right &&
3472 (!Right.
Next || Right.
Next->
isNot(TT_FunctionDeclarationName)));
3473 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3474 Right.
is(tok::kw_operator))
3476 if (Left.
is(TT_PointerOrReference))
3485 (Left.
is(TT_CtorInitializerColon) &&
3486 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
3487 if (Left.
is(tok::question) && Right.
is(tok::colon))
3489 if (Right.
is(TT_ConditionalExpr) || Right.
is(tok::question))
3490 return Style.BreakBeforeTernaryOperators;
3491 if (Left.
is(TT_ConditionalExpr) || Left.
is(tok::question))
3492 return !
Style.BreakBeforeTernaryOperators;
3493 if (Left.
is(TT_InheritanceColon))
3494 return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
3495 if (Right.
is(TT_InheritanceColon))
3496 return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
3497 if (Right.
is(TT_ObjCMethodExpr) && !Right.
is(tok::r_square) &&
3498 Left.
isNot(TT_SelectorName))
3501 if (Right.
is(tok::colon) &&
3502 !Right.
isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
3504 if (Left.
is(tok::colon) && Left.
isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
3505 if (
Style.Language == FormatStyle::LK_Proto ||
3506 Style.Language == FormatStyle::LK_TextProto) {
3533 if (((Right.
is(tok::l_brace) || Right.
is(tok::less)) &&
3534 Right.
is(TT_DictLiteral)) ||
3535 Right.
is(TT_ArrayInitializerLSquare))
3543 if (Right.
is(TT_SelectorName) || (Right.
is(tok::identifier) && Right.
Next &&
3544 Right.
Next->
is(TT_ObjCMethodExpr)))
3545 return Left.
isNot(tok::period);
3550 if (Right.
isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
3551 TT_OverloadedOperator))
3553 if (Left.
is(TT_RangeBasedForLoopColon))
3555 if (Right.
is(TT_RangeBasedForLoopColon))
3557 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_TemplateOpener))
3559 if (Left.
isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
3560 Left.
is(tok::kw_operator))
3562 if (Left.
is(tok::equal) && !Right.
isOneOf(tok::kw_default, tok::kw_delete) &&
3565 if (Left.
is(tok::equal) && Right.
is(tok::l_brace) &&
3566 !
Style.Cpp11BracedListStyle)
3568 if (Left.
is(tok::l_paren) && Left.
is(TT_AttributeParen))
3570 if (Left.
is(tok::l_paren) && Left.
Previous &&
3573 if (Right.
is(TT_ImplicitStringLiteral))
3576 if (Right.
is(tok::r_paren) || Right.
is(TT_TemplateCloser))
3584 if (Right.
is(tok::r_brace))
3589 if (Left.
is(TT_TrailingAnnotation))
3590 return !Right.
isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
3591 tok::less, tok::coloncolon);
3593 if (Right.
is(tok::kw___attribute) ||
3594 (Right.
is(tok::l_square) && Right.
is(TT_AttributeSquare)))
3597 if (Left.
is(tok::identifier) && Right.
is(tok::string_literal))
3600 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
3603 if (Left.
is(TT_CtorInitializerColon))
3604 return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
3605 if (Right.
is(TT_CtorInitializerColon))
3606 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
3607 if (Left.
is(TT_CtorInitializerComma) &&
3608 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
3610 if (Right.
is(TT_CtorInitializerComma) &&
3611 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
3613 if (Left.
is(TT_InheritanceComma) &&
3614 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
3616 if (Right.
is(TT_InheritanceComma) &&
3617 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
3619 if ((Left.
is(tok::greater) && Right.
is(tok::greater)) ||
3620 (Left.
is(tok::less) && Right.
is(tok::less)))
3622 if (Right.
is(TT_BinaryOperator) &&
3623 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
3624 (
Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
3627 if (Left.
is(TT_ArrayInitializerLSquare))
3629 if (Right.
is(tok::kw_typename) && Left.
isNot(tok::kw_const))
3632 !Left.
isOneOf(tok::arrowstar, tok::lessless) &&
3633 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
3634 (
Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
3637 if ((Left.
is(TT_AttributeSquare) && Right.
is(tok::l_square)) ||
3638 (Left.
is(tok::r_square) && Right.
is(TT_AttributeSquare)))
3640 return Left.
isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
3641 tok::kw_class, tok::kw_struct, tok::comment) ||
3643 Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
3644 tok::colon, tok::l_square, tok::at) ||
3645 (Left.
is(tok::r_paren) &&
3646 Right.
isOneOf(tok::identifier, tok::kw_const)) ||
3647 (Left.
is(tok::l_paren) && !Right.
is(tok::r_paren)) ||
3648 (Left.
is(TT_TemplateOpener) && !Right.
is(TT_TemplateCloser));
3651 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
3652 llvm::errs() <<
"AnnotatedTokens(L=" << Line.
Level <<
"):\n";
3662 <<
" PPK=" << Tok->
PackingKind <<
" FakeLParens=";
3663 for (
unsigned i = 0, e = Tok->
FakeLParens.size(); i != e; ++i)
3665 llvm::errs() <<
" FakeRParens=" << Tok->
FakeRParens;
3667 llvm::errs() <<
" Text='" << Tok->
TokenText <<
"'\n";
3669 assert(Tok == Line.
Last);
3672 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.
__DEVICE__ int max(int __a, int __b)
bool InCSharpAttributeSpecifier
const char * getName() const
return(__x >> __y)|(__x<<(32 - __y))
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.
Defines the clang::TokenKind enum and support functions.
FormatToken * FirstObjCSelectorName
The parameter type of a method or function.
unsigned LongestObjCSelectorName
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
SourceLocation getBegin() const