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;
954 CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator,
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.isOneOf(tok::semi, tok::exclaim)) {
1349 Contexts.back().IsExpression =
true;
1353 void determineTokenType(FormatToken &Current) {
1354 if (!Current.is(TT_Unknown))
1358 if (Style.Language == FormatStyle::LK_JavaScript) {
1359 if (Current.is(tok::exclaim)) {
1360 if (Current.Previous &&
1361 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1362 tok::r_paren, tok::r_square,
1364 Current.Previous->Tok.isLiteral())) {
1365 Current.Type = TT_JsNonNullAssertion;
1369 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1370 Current.Type = TT_JsNonNullAssertion;
1379 if (Current.is(Keywords.kw_instanceof)) {
1380 Current.Type = TT_BinaryOperator;
1381 }
else if (isStartOfName(Current) &&
1382 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1383 Contexts.back().FirstStartOfName = &Current;
1384 Current.Type = TT_StartOfName;
1385 }
else if (Current.is(tok::semi)) {
1389 Contexts.back().FirstStartOfName =
nullptr;
1390 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1392 }
else if (Current.is(tok::arrow) &&
1393 Style.Language == FormatStyle::LK_Java) {
1394 Current.Type = TT_LambdaArrow;
1395 }
else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1396 Current.NestingLevel == 0 &&
1397 !Current.Previous->is(tok::kw_operator)) {
1399 Current.Type = TT_TrailingReturnArrow;
1400 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1401 Current.Type = determineStarAmpUsage(Current,
1402 Contexts.back().CanBeExpression &&
1403 Contexts.back().IsExpression,
1404 Contexts.back().InTemplateArgument);
1405 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1406 Current.Type = determinePlusMinusCaretUsage(Current);
1407 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1408 Contexts.back().CaretFound =
true;
1409 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1410 Current.Type = determineIncrementUsage(Current);
1411 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1412 Current.Type = TT_UnaryOperator;
1413 }
else if (Current.is(tok::question)) {
1414 if (Style.Language == FormatStyle::LK_JavaScript &&
1415 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1418 Current.Type = TT_JsTypeOptionalQuestion;
1420 Current.Type = TT_ConditionalExpr;
1422 }
else if (Current.isBinaryOperator() &&
1423 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1424 (!Current.is(tok::greater) &&
1425 Style.Language != FormatStyle::LK_TextProto)) {
1426 Current.Type = TT_BinaryOperator;
1427 }
else if (Current.is(tok::comment)) {
1428 if (Current.TokenText.startswith(
"/*")) {
1429 if (Current.TokenText.endswith(
"*/"))
1430 Current.Type = TT_BlockComment;
1434 Current.Tok.setKind(tok::unknown);
1436 Current.Type = TT_LineComment;
1438 }
else if (Current.is(tok::r_paren)) {
1439 if (rParenEndsCast(Current))
1440 Current.Type = TT_CastRParen;
1441 if (Current.MatchingParen && Current.Next &&
1442 !Current.Next->isBinaryOperator() &&
1443 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1444 tok::comma, tok::period, tok::arrow,
1446 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1448 if (AfterParen->Tok.isNot(tok::caret)) {
1449 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1450 if (BeforeParen->is(tok::identifier) &&
1451 !BeforeParen->is(TT_TypenameMacro) &&
1452 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1453 (!BeforeParen->Previous ||
1454 BeforeParen->Previous->ClosesTemplateDeclaration))
1455 Current.Type = TT_FunctionAnnotationRParen;
1458 }
else if (Current.is(tok::at) && Current.Next &&
1459 Style.Language != FormatStyle::LK_JavaScript &&
1460 Style.Language != FormatStyle::LK_Java) {
1463 switch (Current.Next->Tok.getObjCKeywordID()) {
1464 case tok::objc_interface:
1465 case tok::objc_implementation:
1466 case tok::objc_protocol:
1467 Current.Type = TT_ObjCDecl;
1469 case tok::objc_property:
1470 Current.Type = TT_ObjCProperty;
1475 }
else if (Current.is(tok::period)) {
1476 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1477 if (PreviousNoComment &&
1478 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1479 Current.Type = TT_DesignatedInitializerPeriod;
1480 else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
1481 Current.Previous->isOneOf(TT_JavaAnnotation,
1482 TT_LeadingJavaAnnotation)) {
1483 Current.Type = Current.Previous->Type;
1485 }
else if (canBeObjCSelectorComponent(Current) &&
1488 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1489 Current.Previous->MatchingParen &&
1490 Current.Previous->MatchingParen->Previous &&
1491 Current.Previous->MatchingParen->Previous->is(
1492 TT_ObjCMethodSpecifier)) {
1496 Current.Type = TT_SelectorName;
1497 }
else if (Current.isOneOf(tok::identifier, tok::kw_const,
1498 tok::kw_noexcept) &&
1500 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1501 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1504 Current.Type = TT_TrailingAnnotation;
1505 }
else if ((Style.Language == FormatStyle::LK_Java ||
1506 Style.Language == FormatStyle::LK_JavaScript) &&
1508 if (Current.Previous->is(tok::at) &&
1509 Current.isNot(Keywords.kw_interface)) {
1510 const FormatToken &AtToken = *Current.Previous;
1511 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1512 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1513 Current.Type = TT_LeadingJavaAnnotation;
1515 Current.Type = TT_JavaAnnotation;
1516 }
else if (Current.Previous->is(tok::period) &&
1517 Current.Previous->isOneOf(TT_JavaAnnotation,
1518 TT_LeadingJavaAnnotation)) {
1519 Current.Type = Current.Previous->Type;
1529 bool isStartOfName(
const FormatToken &Tok) {
1530 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1533 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1536 if (Style.Language == FormatStyle::LK_JavaScript &&
1537 Tok.Previous->is(Keywords.kw_in))
1541 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1542 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1543 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1545 if (!PreviousNotConst)
1548 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1549 PreviousNotConst->Previous &&
1550 PreviousNotConst->Previous->is(tok::hash);
1552 if (PreviousNotConst->is(TT_TemplateCloser))
1553 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1554 PreviousNotConst->MatchingParen->Previous &&
1555 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1556 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1558 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1559 PreviousNotConst->MatchingParen->Previous &&
1560 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1563 return (!IsPPKeyword &&
1564 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1565 PreviousNotConst->is(TT_PointerOrReference) ||
1566 PreviousNotConst->isSimpleTypeSpecifier();
1570 bool rParenEndsCast(
const FormatToken &Tok) {
1572 if (!Style.isCpp() && Style.Language != FormatStyle::LK_Java)
1576 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1579 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1583 if (LeftOfParens->is(tok::r_paren)) {
1584 if (!LeftOfParens->MatchingParen ||
1585 !LeftOfParens->MatchingParen->Previous)
1587 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1592 if (LeftOfParens->Tok.getIdentifierInfo() &&
1593 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1599 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1600 TT_TemplateCloser, tok::ellipsis))
1604 if (Tok.Next->is(tok::question))
1609 if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
1610 tok::kw_throw, tok::arrow, Keywords.kw_override,
1611 Keywords.kw_final) ||
1612 isCpp11AttributeSpecifier(*Tok.Next))
1617 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren))
1621 if (Tok.Next->isNot(tok::string_literal) &&
1622 (Tok.Next->Tok.isLiteral() ||
1623 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1627 bool ParensAreType =
1629 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1630 Tok.Previous->isSimpleTypeSpecifier();
1631 bool ParensCouldEndDecl =
1632 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1633 if (ParensAreType && !ParensCouldEndDecl)
1644 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1645 Token = Token->Next)
1646 if (Token->is(TT_BinaryOperator))
1651 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1654 if (!Tok.Next->Next)
1661 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1662 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1663 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1666 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1667 Prev = Prev->Previous) {
1668 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1677 if (Style.Language == FormatStyle::LK_JavaScript)
1678 return TT_BinaryOperator;
1680 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1682 return TT_UnaryOperator;
1684 const FormatToken *NextToken = Tok.getNextNonComment();
1686 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const,
1687 tok::kw_noexcept) ||
1688 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1689 return TT_PointerOrReference;
1691 if (PrevToken->is(tok::coloncolon))
1692 return TT_PointerOrReference;
1694 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1695 tok::comma, tok::semi, tok::kw_return, tok::colon,
1696 tok::equal, tok::kw_delete, tok::kw_sizeof,
1698 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1699 TT_UnaryOperator, TT_CastRParen))
1700 return TT_UnaryOperator;
1702 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1703 return TT_PointerOrReference;
1705 return TT_PointerOrReference;
1706 if (NextToken->isOneOf(tok::comma, tok::semi))
1707 return TT_PointerOrReference;
1709 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
1710 FormatToken *TokenBeforeMatchingParen =
1711 PrevToken->MatchingParen->getPreviousNonComment();
1712 if (TokenBeforeMatchingParen &&
1713 TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype,
1715 return TT_PointerOrReference;
1718 if (PrevToken->Tok.isLiteral() ||
1719 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1720 tok::kw_false, tok::r_brace) ||
1721 NextToken->Tok.isLiteral() ||
1722 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1723 NextToken->isUnaryOperator() ||
1727 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1728 return TT_BinaryOperator;
1731 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1732 return TT_BinaryOperator;
1736 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1737 if (NextNextToken && NextNextToken->is(tok::arrow))
1738 return TT_BinaryOperator;
1742 if (IsExpression && !Contexts.back().CaretFound)
1743 return TT_BinaryOperator;
1745 return TT_PointerOrReference;
1748 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1749 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1751 return TT_UnaryOperator;
1753 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
1755 return TT_UnaryOperator;
1758 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1759 tok::question, tok::colon, tok::kw_return,
1760 tok::kw_case, tok::at, tok::l_brace, tok::kw_throw))
1761 return TT_UnaryOperator;
1764 if (PrevToken->is(TT_BinaryOperator))
1765 return TT_UnaryOperator;
1768 return TT_BinaryOperator;
1772 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1773 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1774 if (!PrevToken || PrevToken->is(TT_CastRParen))
1775 return TT_UnaryOperator;
1776 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1777 return TT_TrailingUnaryOperator;
1779 return TT_UnaryOperator;
1782 SmallVector<Context, 8> Contexts;
1784 const FormatStyle &
Style;
1785 AnnotatedLine &
Line;
1786 FormatToken *CurrentToken;
1788 const AdditionalKeywords &Keywords;
1794 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
1802 class ExpressionParser {
1804 ExpressionParser(
const FormatStyle &
Style,
const AdditionalKeywords &Keywords,
1805 AnnotatedLine &
Line)
1806 :
Style(Style), Keywords(Keywords), Current(Line.First) {}
1809 void parse(
int Precedence = 0) {
1812 while (Current && (Current->is(tok::kw_return) ||
1813 (Current->is(tok::colon) &&
1814 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1817 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1822 parseConditionalExpr();
1828 if (Precedence == PrecedenceUnaryOperator) {
1829 parseUnaryOperator();
1833 FormatToken *Start = Current;
1834 FormatToken *LatestOperator =
nullptr;
1835 unsigned OperatorIndex = 0;
1839 parse(Precedence + 1);
1841 int CurrentPrecedence = getCurrentPrecedence();
1843 if (Current && Current->is(TT_SelectorName) &&
1844 Precedence == CurrentPrecedence) {
1846 addFakeParenthesis(Start,
prec::Level(Precedence));
1853 (Current->closesScope() &&
1854 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1855 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1862 if (Current->opensScope()) {
1865 while (Current && (!Current->closesScope() || Current->opensScope())) {
1872 if (CurrentPrecedence == Precedence) {
1874 LatestOperator->NextOperator = Current;
1875 LatestOperator = Current;
1876 Current->OperatorIndex = OperatorIndex;
1879 next(Precedence > 0);
1883 if (LatestOperator && (Current || Precedence > 0)) {
1885 if (Precedence == PrecedenceArrowAndPeriod) {
1889 addFakeParenthesis(Start,
prec::Level(Precedence));
1897 int getCurrentPrecedence() {
1899 const FormatToken *NextNonComment = Current->getNextNonComment();
1900 if (Current->is(TT_ConditionalExpr))
1902 if (NextNonComment && Current->is(TT_SelectorName) &&
1903 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
1904 ((Style.Language == FormatStyle::LK_Proto ||
1905 Style.Language == FormatStyle::LK_TextProto) &&
1906 NextNonComment->is(tok::less))))
1908 if (Current->is(TT_JsComputedPropertyName))
1910 if (Current->is(TT_LambdaArrow))
1912 if (Current->is(TT_JsFatArrow))
1914 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1915 (Current->is(tok::comment) && NextNonComment &&
1916 NextNonComment->is(TT_SelectorName)))
1918 if (Current->is(TT_RangeBasedForLoopColon))
1920 if ((Style.Language == FormatStyle::LK_Java ||
1921 Style.Language == FormatStyle::LK_JavaScript) &&
1922 Current->is(Keywords.kw_instanceof))
1924 if (Style.Language == FormatStyle::LK_JavaScript &&
1925 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
1927 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1928 return Current->getPrecedence();
1929 if (Current->isOneOf(tok::period, tok::arrow))
1930 return PrecedenceArrowAndPeriod;
1931 if ((Style.Language == FormatStyle::LK_Java ||
1932 Style.Language == FormatStyle::LK_JavaScript) &&
1933 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1934 Keywords.kw_throws))
1940 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
1941 Start->FakeLParens.push_back(Precedence);
1943 Start->StartsBinaryExpression =
true;
1945 FormatToken *
Previous = Current->Previous;
1946 while (Previous->is(tok::comment) && Previous->Previous)
1947 Previous = Previous->Previous;
1948 ++Previous->FakeRParens;
1950 Previous->EndsBinaryExpression =
true;
1956 void parseUnaryOperator() {
1958 while (Current && Current->is(TT_UnaryOperator)) {
1959 Tokens.push_back(Current);
1962 parse(PrecedenceArrowAndPeriod);
1963 for (FormatToken *Token : llvm::reverse(Tokens))
1968 void parseConditionalExpr() {
1969 while (Current && Current->isTrailingComment()) {
1972 FormatToken *Start = Current;
1974 if (!Current || !Current->is(tok::question))
1978 if (!Current || Current->isNot(TT_ConditionalExpr))
1985 void next(
bool SkipPastLeadingComments =
true) {
1987 Current = Current->Next;
1989 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1990 Current->isTrailingComment())
1991 Current = Current->Next;
1994 const FormatStyle &
Style;
1995 const AdditionalKeywords &Keywords;
1996 FormatToken *Current;
2007 bool CommentLine =
true;
2009 if (!
Tok->
is(tok::comment)) {
2010 CommentLine =
false;
2017 if (NextNonCommentLine && CommentLine &&
2020 (*I)->First->OriginalColumn) {
2025 (
Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
2029 : NextNonCommentLine->
Level;
2031 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
2034 setCommentLineLevels((*I)->Children);
2039 unsigned Result = 0;
2052 Line.
Type = Parser.parseLine();
2064 ExpressionParser ExprParser(
Style, Keywords, Line);
2083 for (; Next; Next = Next->Next) {
2084 if (Next->is(TT_OverloadedOperatorLParen))
2086 if (Next->is(TT_OverloadedOperator))
2088 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
2090 if (Next->Next && Next->Next->is(tok::l_square) && Next->Next->Next &&
2091 Next->Next->Next->is(tok::r_square))
2092 Next = Next->Next->Next;
2103 if (Current.
is(tok::kw_operator)) {
2106 Next = skipOperatorName(Next);
2110 for (; Next; Next = Next->
Next) {
2111 if (Next->
is(TT_TemplateOpener)) {
2113 }
else if (Next->
is(tok::coloncolon)) {
2117 if (Next->
is(tok::kw_operator)) {
2118 Next = skipOperatorName(Next->
Next);
2121 if (!Next->
is(tok::identifier))
2123 }
else if (Next->
is(tok::l_paren)) {
2135 if (Line.
Last->
is(tok::l_brace))
2150 Tok->
isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
2152 if (
Tok->
isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2162 if ((
Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
2163 Style.AlwaysBreakAfterReturnType ==
2164 FormatStyle::RTBS_TopLevelDefinitions) &&
2168 switch (
Style.AlwaysBreakAfterReturnType) {
2169 case FormatStyle::RTBS_None:
2171 case FormatStyle::RTBS_All:
2172 case FormatStyle::RTBS_TopLevel:
2174 case FormatStyle::RTBS_AllDefinitions:
2175 case FormatStyle::RTBS_TopLevelDefinitions:
2186 calculateFormattingInformation(**I);
2196 Current->
Type = TT_FunctionDeclarationName;
2197 if (Current->
is(TT_LineComment)) {
2201 (
Style.Cpp11BracedListStyle && !
Style.SpacesInParentheses) ? 0 : 1;
2215 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
2218 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
2226 spaceRequiredBefore(Line, *Current)) {
2234 Current->
is(TT_FunctionDeclarationName))
2239 unsigned ChildSize = 0;
2248 Prev->
Children[0]->First->MustBreakBefore) ||
2255 if (Current->
is(TT_CtorInitializerColon))
2256 InFunctionDecl =
false;
2267 Current->
SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
2268 if (
Style.Language == FormatStyle::LK_ObjC &&
2276 Current = Current->
Next;
2279 calculateUnbreakableTailLengths(Line);
2280 unsigned IndentLevel = Line.
Level;
2281 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
2283 Current->
Role->precomputeFormattingInfos(Current);
2286 assert(IndentLevel > 0);
2297 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
2298 unsigned UnbreakableTailLength = 0;
2303 Current->
isOneOf(tok::comment, tok::string_literal)) {
2304 UnbreakableTailLength = 0;
2306 UnbreakableTailLength +=
2313 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
2315 bool InFunctionDecl) {
2319 if (Left.
is(tok::semi))
2322 if (
Style.Language == FormatStyle::LK_Java) {
2323 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2325 if (Right.
is(Keywords.kw_implements))
2329 }
else if (
Style.Language == FormatStyle::LK_JavaScript) {
2330 if (Right.
is(Keywords.kw_function) && Left.
isNot(tok::comma))
2332 if (Left.
is(TT_JsTypeColon))
2334 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2335 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2342 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
2344 if (Right.
is(tok::l_square)) {
2345 if (
Style.Language == FormatStyle::LK_Proto)
2347 if (Left.
is(tok::r_square))
2350 if (Right.
is(TT_LambdaLSquare) && Left.
is(tok::equal))
2352 if (!Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2353 TT_ArrayInitializerLSquare,
2354 TT_DesignatedInitializerLSquare, TT_AttributeSquare))
2358 if (Left.
is(tok::coloncolon) ||
2359 (Right.
is(tok::period) &&
Style.Language == FormatStyle::LK_Proto))
2361 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2362 Right.
is(tok::kw_operator)) {
2365 if (Left.
is(TT_StartOfName))
2368 return Style.PenaltyReturnTypeOnItsOwnLine;
2371 if (Right.
is(TT_PointerOrReference))
2373 if (Right.
is(TT_LambdaArrow))
2375 if (Left.
is(tok::equal) && Right.
is(tok::l_brace))
2377 if (Left.
is(TT_CastRParen))
2379 if (Left.
isOneOf(tok::kw_class, tok::kw_struct))
2381 if (Left.
is(tok::comment))
2384 if (Left.
isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2385 TT_CtorInitializerColon))
2413 if (Right.
is(TT_TrailingAnnotation) &&
2424 bool is_short_annotation = Right.
TokenText.size() < 10;
2425 return (Left.
is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2429 if (Line.
startsWith(tok::kw_for) && Left.
is(tok::equal))
2434 if (Right.
is(TT_SelectorName))
2436 if (Left.
is(tok::colon) && Left.
is(TT_ObjCMethodExpr))
2446 if (Left.
is(tok::l_paren) && InFunctionDecl &&
2449 if (Left.
is(tok::l_paren) && Left.
Previous &&
2452 if (Left.
is(tok::equal) && InFunctionDecl)
2454 if (Right.
is(tok::r_brace))
2456 if (Left.
is(TT_TemplateOpener))
2461 if (Left.
is(tok::l_brace) && !
Style.Cpp11BracedListStyle)
2466 if (Left.
is(TT_JavaAnnotation))
2469 if (Left.
is(TT_UnaryOperator))
2478 if (Left.
is(tok::comma))
2483 if (Right.
is(tok::lessless)) {
2491 return Style.PenaltyBreakTemplateDeclaration;
2492 if (Left.
is(TT_ConditionalExpr))
2498 return Style.PenaltyBreakAssignment;
2505 bool TokenAnnotator::spaceRequiredBeforeParens(
const FormatToken &Right)
const {
2506 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always ||
2507 (
Style.SpaceBeforeParens == FormatStyle::SBPO_NonEmptyParentheses &&
2511 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
2514 if (Left.
is(tok::kw_return) && Right.
isNot(tok::semi))
2516 if (Left.
is(Keywords.kw_assert) &&
Style.Language == FormatStyle::LK_Java)
2521 if (Right.
is(tok::hashhash))
2522 return Left.
is(tok::hash);
2523 if (Left.
isOneOf(tok::hashhash, tok::hash))
2524 return Right.
is(tok::hash);
2525 if ((Left.
is(tok::l_paren) && Right.
is(tok::r_paren)) ||
2528 return Style.SpaceInEmptyParentheses;
2529 if (Left.
is(tok::l_paren) || Right.
is(tok::r_paren))
2530 return (Right.
is(TT_CastRParen) ||
2532 ?
Style.SpacesInCStyleCastParentheses
2533 :
Style.SpacesInParentheses;
2534 if (Right.
isOneOf(tok::semi, tok::comma))
2540 return !IsLightweightGeneric &&
Style.ObjCSpaceBeforeProtocolList;
2542 if (Right.
is(tok::less) && Left.
is(tok::kw_template))
2543 return Style.SpaceAfterTemplateKeyword;
2544 if (Left.
isOneOf(tok::exclaim, tok::tilde))
2546 if (Left.
is(tok::at) &&
2547 Right.
isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2548 tok::numeric_constant, tok::l_paren, tok::l_brace,
2549 tok::kw_true, tok::kw_false))
2551 if (Left.
is(tok::colon))
2552 return !Left.
is(TT_ObjCMethodExpr);
2553 if (Left.
is(tok::coloncolon))
2555 if (Left.
is(tok::less) || Right.
isOneOf(tok::greater, tok::less)) {
2556 if (
Style.Language == FormatStyle::LK_TextProto ||
2557 (
Style.Language == FormatStyle::LK_Proto &&
2558 (Left.
is(TT_DictLiteral) || Right.
is(TT_DictLiteral)))) {
2560 if (Left.
is(tok::less) && Right.
is(tok::greater))
2562 return !
Style.Cpp11BracedListStyle;
2566 if (Right.
is(tok::ellipsis))
2569 if (Left.
is(tok::l_square) && Right.
is(tok::amp))
2571 if (Right.
is(TT_PointerOrReference)) {
2577 if (!TokenBeforeMatchingParen ||
2578 !TokenBeforeMatchingParen->
isOneOf(tok::kw_typeof, tok::kw_decltype,
2583 (!Left.
isOneOf(TT_PointerOrReference, tok::l_paren) &&
2584 (
Style.PointerAlignment != FormatStyle::PAS_Left ||
2589 if (Right.
is(TT_FunctionTypeLParen) && Left.
isNot(tok::l_paren) &&
2590 (!Left.
is(TT_PointerOrReference) ||
2591 (
Style.PointerAlignment != FormatStyle::PAS_Right &&
2594 if (Left.
is(TT_PointerOrReference))
2596 (Right.
isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2597 !Right.
is(TT_StartOfName)) ||
2599 (!Right.
isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2601 (
Style.PointerAlignment != FormatStyle::PAS_Right &&
2606 if (Right.
is(tok::star) && Left.
is(tok::l_paren))
2608 const auto SpaceRequiredForArrayInitializerLSquare =
2610 return Style.SpacesInContainerLiterals ||
2611 ((
Style.Language == FormatStyle::LK_Proto ||
2612 Style.Language == FormatStyle::LK_TextProto) &&
2613 !
Style.Cpp11BracedListStyle &&
2617 if (Left.
is(tok::l_square))
2618 return (Left.
is(TT_ArrayInitializerLSquare) && Right.
isNot(tok::r_square) &&
2619 SpaceRequiredForArrayInitializerLSquare(Left,
Style)) ||
2620 (Left.
isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
2621 TT_LambdaLSquare) &&
2622 Style.SpacesInSquareBrackets && Right.
isNot(tok::r_square));
2623 if (Right.
is(tok::r_square))
2626 SpaceRequiredForArrayInitializerLSquare(*Right.
MatchingParen,
2628 (
Style.SpacesInSquareBrackets &&
2630 TT_StructuredBindingLSquare,
2631 TT_LambdaLSquare)) ||
2633 if (Right.
is(tok::l_square) &&
2634 !Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2635 TT_DesignatedInitializerLSquare,
2636 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
2637 !Left.
isOneOf(tok::numeric_constant, TT_DictLiteral))
2639 if (Left.
is(tok::l_brace) && Right.
is(tok::r_brace))
2644 return Style.Cpp11BracedListStyle ?
Style.SpacesInParentheses :
true;
2645 if (Left.
is(TT_BlockComment))
2647 return Style.Language == FormatStyle::LK_JavaScript ||
2649 if (Right.
is(tok::l_paren)) {
2650 if ((Left.
is(tok::r_paren) && Left.
is(TT_AttributeParen)) ||
2651 (Left.
is(tok::r_square) && Left.
is(TT_AttributeSquare)))
2654 (
Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
2656 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2659 (Left.
isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2660 tok::kw_new, tok::kw_delete) &&
2662 (spaceRequiredBeforeParens(Right) &&
2671 if (Right.
is(TT_UnaryOperator))
2672 return !Left.
isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2673 (Left.
isNot(tok::colon) || Left.
isNot(TT_ObjCMethodExpr));
2674 if ((Left.
isOneOf(tok::identifier, tok::greater, tok::r_square,
2680 if (Left.
is(tok::period) || Right.
is(tok::period))
2682 if (Right.
is(tok::hash) && Left.
is(tok::identifier) && Left.
TokenText ==
"L")
2692 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_square))
2694 if (Left.
is(tok::l_brace) && Left.
endsSequence(TT_DictLiteral, tok::at))
2701 if (Right.
Type == TT_TrailingAnnotation &&
2702 Right.
isOneOf(tok::amp, tok::ampamp) &&
2703 Left.
isOneOf(tok::kw_const, tok::kw_volatile) &&
2708 return Style.PointerAlignment != FormatStyle::PAS_Left;
2712 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2717 if (
Style.isCpp()) {
2718 if (Left.
is(tok::kw_operator))
2719 return Right.
is(tok::coloncolon);
2723 }
else if (
Style.Language == FormatStyle::LK_Proto ||
2724 Style.Language == FormatStyle::LK_TextProto) {
2725 if (Right.
is(tok::period) &&
2726 Left.
isOneOf(Keywords.kw_optional, Keywords.kw_required,
2727 Keywords.kw_repeated, Keywords.kw_extend))
2729 if (Right.
is(tok::l_paren) &&
2730 Left.
isOneOf(Keywords.kw_returns, Keywords.kw_option))
2732 if (Right.
isOneOf(tok::l_brace, tok::less) && Left.
is(TT_SelectorName))
2735 if (Left.
is(tok::slash) || Right.
is(tok::slash))
2739 Right.
isOneOf(tok::l_brace, tok::less))
2740 return !
Style.Cpp11BracedListStyle;
2742 if (Left.
is(tok::percent))
2746 if (Left.
is(tok::numeric_constant) && Right.
is(tok::percent))
2748 }
else if (
Style.isCSharp()) {
2750 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_StartOfName))
2753 if (Right.
is(tok::l_paren))
2754 if (Left.
is(tok::kw_using))
2755 return spaceRequiredBeforeParens(Left);
2756 }
else if (
Style.Language == FormatStyle::LK_JavaScript) {
2757 if (Left.
is(TT_JsFatArrow))
2760 if (Right.
is(tok::l_paren) && Left.
is(Keywords.kw_await) && Left.
Previous &&
2763 if (Left.
is(Keywords.kw_async) && Right.
is(tok::l_paren) &&
2768 if (Next && Next->
is(TT_JsFatArrow))
2771 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2772 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2777 if (Left.
is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2778 Right.
is(TT_TemplateString))
2780 if (Right.
is(tok::star) &&
2781 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield))
2783 if (Right.
isOneOf(tok::l_brace, tok::l_square) &&
2784 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield,
2785 Keywords.kw_extends, Keywords.kw_implements))
2787 if (Right.
is(tok::l_paren)) {
2797 if (Left.
isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
2802 if (Left.
endsSequence(tok::kw_const, Keywords.kw_as)) {
2805 if ((Left.
isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2816 Left.
Previous->
is(tok::period) && Right.
is(tok::l_paren))
2818 if (Left.
is(Keywords.kw_as) &&
2819 Right.
isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2821 if (Left.
is(tok::kw_default) && Left.
Previous &&
2824 if (Left.
is(Keywords.kw_is) && Right.
is(tok::l_brace))
2826 if (Right.
isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2828 if (Left.
is(TT_JsTypeOperator) || Right.
is(TT_JsTypeOperator))
2830 if ((Left.
is(tok::l_brace) || Right.
is(tok::r_brace)) &&
2831 Line.
First->
isOneOf(Keywords.kw_import, tok::kw_export))
2833 if (Left.
is(tok::ellipsis))
2835 if (Left.
is(TT_TemplateCloser) &&
2836 !Right.
isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2837 Keywords.kw_implements, Keywords.kw_extends))
2842 if (Right.
is(TT_JsNonNullAssertion))
2844 if (Left.
is(TT_JsNonNullAssertion) &&
2845 Right.
isOneOf(Keywords.kw_as, Keywords.kw_in))
2847 }
else if (
Style.Language == FormatStyle::LK_Java) {
2848 if (Left.
is(tok::r_square) && Right.
is(tok::l_brace))
2850 if (Left.
is(Keywords.kw_synchronized) && Right.
is(tok::l_paren))
2851 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never;
2852 if ((Left.
isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2853 tok::kw_protected) ||
2854 Left.
isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2855 Keywords.kw_native)) &&
2856 Right.
is(TT_TemplateOpener))
2859 if (Left.
is(TT_ImplicitStringLiteral))
2862 if (Left.
is(TT_ObjCMethodSpecifier))
2864 if (Left.
is(tok::r_paren) && canBeObjCSelectorComponent(Right))
2871 (Right.
is(tok::equal) || Left.
is(tok::equal)))
2874 if (Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2875 Left.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2877 if (Right.
is(TT_OverloadedOperatorLParen))
2878 return spaceRequiredBeforeParens(Right);
2879 if (Left.
is(tok::comma))
2881 if (Right.
is(tok::comma))
2883 if (Right.
is(TT_ObjCBlockLParen))
2885 if (Right.
is(TT_CtorInitializerColon))
2886 return Style.SpaceBeforeCtorInitializerColon;
2887 if (Right.
is(TT_InheritanceColon) && !
Style.SpaceBeforeInheritanceColon)
2889 if (Right.
is(TT_RangeBasedForLoopColon) &&
2890 !
Style.SpaceBeforeRangeBasedForLoopColon)
2892 if (Right.
is(tok::colon)) {
2893 if (Line.
First->
isOneOf(tok::kw_case, tok::kw_default) ||
2896 if (Right.
is(TT_ObjCMethodExpr))
2898 if (Left.
is(tok::question))
2900 if (Right.
is(TT_InlineASMColon) && Left.
is(tok::coloncolon))
2902 if (Right.
is(TT_DictLiteral))
2903 return Style.SpacesInContainerLiterals;
2904 if (Right.
is(TT_AttributeColon))
2908 if (Left.
is(TT_UnaryOperator)) {
2912 if (!Right.
is(tok::l_paren)) {
2913 if (Left.
is(tok::exclaim) && Left.
TokenText ==
"not")
2915 if (Left.
is(tok::tilde) && Left.
TokenText ==
"compl")
2918 return (
Style.SpaceAfterLogicalNot && Left.
is(tok::exclaim)) ||
2919 Right.
is(TT_BinaryOperator);
2924 if (Left.
is(TT_CastRParen))
2925 return Style.SpaceAfterCStyleCast ||
2926 Right.
isOneOf(TT_BinaryOperator, TT_SelectorName);
2928 if (Left.
is(tok::greater) && Right.
is(tok::greater)) {
2929 if (
Style.Language == FormatStyle::LK_TextProto ||
2930 (
Style.Language == FormatStyle::LK_Proto && Left.
is(TT_DictLiteral)))
2931 return !
Style.Cpp11BracedListStyle;
2932 return Right.
is(TT_TemplateCloser) && Left.
is(TT_TemplateCloser) &&
2933 (
Style.Standard < FormatStyle::LS_Cpp11 ||
Style.SpacesInAngles);
2935 if (Right.
isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
2936 Left.
isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2937 (Right.
is(tok::period) && Right.
isNot(TT_DesignatedInitializerPeriod)))
2939 if (!
Style.SpaceBeforeAssignmentOperators && Left.
isNot(TT_TemplateCloser) &&
2942 if (
Style.Language == FormatStyle::LK_Java && Right.
is(tok::coloncolon) &&
2943 (Left.
is(tok::identifier) || Left.
is(tok::kw_this)))
2945 if (Right.
is(tok::coloncolon) && Left.
is(tok::identifier))
2950 if (Right.
is(tok::coloncolon) && !Left.
isOneOf(tok::l_brace, tok::comment))
2951 return (Left.
is(TT_TemplateOpener) &&
2952 Style.Standard < FormatStyle::LS_Cpp11) ||
2953 !(Left.
isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
2954 tok::kw___super, TT_TemplateCloser,
2955 TT_TemplateOpener)) ||
2956 (Left.
is(tok ::l_paren) &&
Style.SpacesInParentheses);
2957 if ((Left.
is(TT_TemplateOpener)) != (Right.
is(TT_TemplateCloser)))
2958 return Style.SpacesInAngles;
2960 if (Right.
is(TT_StructuredBindingLSquare))
2961 return !Left.
isOneOf(tok::amp, tok::ampamp) ||
2962 Style.PointerAlignment != FormatStyle::PAS_Right;
2964 if (Right.
Next && Right.
Next->
is(TT_StructuredBindingLSquare) &&
2965 Right.
isOneOf(tok::amp, tok::ampamp))
2966 return Style.PointerAlignment != FormatStyle::PAS_Left;
2967 if ((Right.
is(TT_BinaryOperator) && !Left.
is(tok::l_paren)) ||
2968 (Left.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2969 !Right.
is(tok::r_paren)))
2971 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_paren) &&
2972 Right.
isNot(TT_FunctionTypeLParen))
2973 return spaceRequiredBeforeParens(Right);
2974 if (Right.
is(TT_TemplateOpener) && Left.
is(tok::r_paren) &&
2977 if (Right.
is(tok::less) && Left.
isNot(tok::l_paren) &&
2980 if (Right.
is(TT_TrailingUnaryOperator))
2982 if (Left.
is(TT_RegexLiteral))
2984 return spaceRequiredBetween(Line, Left, Right);
2990 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
2993 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
2999 if (
Style.Language == FormatStyle::LK_JavaScript) {
3001 if (Right.
is(tok::string_literal) && Left.
is(tok::plus) && Left.
Previous &&
3004 if (Left.
is(TT_DictLiteral) && Left.
is(tok::l_brace) && Line.
Level == 0 &&
3006 Line.
First->
isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
3010 !Line.
First->
isOneOf(Keywords.kw_var, Keywords.kw_let))
3014 if (Left.
is(tok::l_brace) && Line.
Level == 0 &&
3016 Line.
startsWith(tok::kw_const, tok::kw_enum) ||
3017 Line.
startsWith(tok::kw_export, tok::kw_enum) ||
3018 Line.
startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
3022 if (Right.
is(tok::r_brace) && Left.
is(tok::l_brace) &&
3025 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
3026 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
3028 Style.AllowShortFunctionsOnASingleLine &
3029 FormatStyle::SFS_InlineOnly);
3030 }
else if (
Style.Language == FormatStyle::LK_Java) {
3031 if (Right.
is(tok::plus) && Left.
is(tok::string_literal) && Right.
Next &&
3032 Right.
Next->
is(tok::string_literal))
3034 }
else if (
Style.Language == FormatStyle::LK_Cpp ||
3035 Style.Language == FormatStyle::LK_ObjC ||
3036 Style.Language == FormatStyle::LK_Proto ||
3037 Style.Language == FormatStyle::LK_TableGen ||
3038 Style.Language == FormatStyle::LK_TextProto) {
3049 if ((Left.
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
3050 (
Style.Language == FormatStyle::LK_JavaScript &&
3051 Left.
is(tok::l_paren))) &&
3056 TT_ArrayInitializerLSquare) ||
3057 (
Style.Language == FormatStyle::LK_JavaScript &&
3059 BeforeClosingBrace = &Left;
3060 if (BeforeClosingBrace && (BeforeClosingBrace->
is(tok::comma) ||
3065 if (Right.
is(tok::comment))
3067 Left.
isNot(TT_CtorInitializerColon) &&
3073 if (Right.
is(tok::lessless) && Right.
Next &&
3075 Right.
Next->
is(tok::string_literal))
3080 Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes)
3082 if (Right.
is(TT_CtorInitializerComma) &&
3083 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
3084 !
Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
3086 if (Right.
is(TT_CtorInitializerColon) &&
3087 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
3088 !
Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
3091 if (
Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
3092 Right.
is(TT_InheritanceComma))
3094 if (Right.
is(tok::string_literal) && Right.
TokenText.startswith(
"R\""))
3107 if (Right.
is(TT_InlineASMBrace))
3110 return (Line.
startsWith(tok::kw_enum) &&
Style.BraceWrapping.AfterEnum) ||
3111 (Line.
startsWith(tok::kw_typedef, tok::kw_enum) &&
3112 Style.BraceWrapping.AfterEnum) ||
3115 if (Left.
is(TT_ObjCBlockLBrace) &&
3116 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
3119 if (Left.
is(TT_LambdaLBrace)) {
3122 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline)
3125 if (
Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
3126 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
3128 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty))
3133 if (
Style.isCSharp() &&
3134 ((Left.
is(TT_AttributeSquare) && Left.
is(tok::r_square)) ||
3135 (Left.
is(tok::r_square) && Right.
is(TT_AttributeSquare) &&
3136 Right.
is(tok::l_square))))
3140 if ((
Style.Language == FormatStyle::LK_Java ||
3141 Style.Language == FormatStyle::LK_JavaScript) &&
3142 Left.
is(TT_LeadingJavaAnnotation) &&
3143 Right.
isNot(TT_LeadingJavaAnnotation) && Right.
isNot(tok::l_paren) &&
3144 (Line.
Last->
is(tok::l_brace) ||
Style.BreakAfterJavaFieldAnnotations))
3147 if (Right.
is(TT_ProtoExtensionLSquare))
3177 if ((
Style.Language == FormatStyle::LK_Proto ||
3178 Style.Language == FormatStyle::LK_TextProto) &&
3179 Right.
is(TT_SelectorName) && !Right.
is(tok::r_square) && Right.
Next) {
3189 if (LBrace && LBrace->
is(tok::colon)) {
3190 LBrace = LBrace->
Next;
3191 if (LBrace && LBrace->
is(tok::at)) {
3192 LBrace = LBrace->
Next;
3194 LBrace = LBrace->
Next;
3206 ((LBrace->
is(tok::l_brace) &&
3207 (LBrace->
is(TT_DictLiteral) ||
3208 (LBrace->
Next && LBrace->
Next->
is(tok::r_brace)))) ||
3209 LBrace->
is(TT_ArrayInitializerLSquare) || LBrace->
is(tok::less))) {
3231 if (Left.
isOneOf(tok::r_brace, tok::greater, tok::r_square))
3238 if ((
Style.Language == FormatStyle::LK_Cpp ||
3239 Style.Language == FormatStyle::LK_ObjC) &&
3241 !Right.
isOneOf(tok::l_paren, TT_LambdaLSquare)) {
3252 auto Next =
Comma->getNextNonComment();
3255 if (!Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret))
3262 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
3267 if (
Style.Language == FormatStyle::LK_Java) {
3268 if (Left.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3269 Keywords.kw_implements))
3271 if (Right.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3272 Keywords.kw_implements))
3274 }
else if (
Style.Language == FormatStyle::LK_JavaScript) {
3278 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
3279 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
3280 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
3281 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
3282 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
3286 Left.
isOneOf(tok::r_square, tok::r_paren)) &&
3287 Right.
isOneOf(tok::l_square, tok::l_paren))
3289 if (Left.
is(TT_JsFatArrow) && Right.
is(tok::l_brace))
3291 if (Left.
is(TT_JsTypeColon))
3294 if (Left.
is(tok::exclaim) && Right.
is(tok::colon))
3299 if (Right.
is(Keywords.kw_is)) {
3308 if (!Next || !Next->
is(tok::colon))
3311 if (Left.
is(Keywords.kw_in))
3312 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
3313 if (Right.
is(Keywords.kw_in))
3314 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
3315 if (Right.
is(Keywords.kw_as))
3317 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
3323 if (Left.
is(Keywords.kw_as))
3325 if (Left.
is(TT_JsNonNullAssertion))
3327 if (Left.
is(Keywords.kw_declare) &&
3328 Right.
isOneOf(Keywords.kw_module, tok::kw_namespace,
3329 Keywords.kw_function, tok::kw_class, tok::kw_enum,
3330 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
3331 Keywords.kw_let, tok::kw_const))
3335 if (Left.
isOneOf(Keywords.kw_module, tok::kw_namespace) &&
3336 Right.
isOneOf(tok::identifier, tok::string_literal))
3342 if (Left.
is(tok::identifier) && Right.
is(TT_TemplateString)) {
3349 if (Left.
is(tok::at))
3353 if (Left.
isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
3354 return !Right.
is(tok::l_paren);
3355 if (Right.
is(TT_PointerOrReference))
3357 (
Style.PointerAlignment == FormatStyle::PAS_Right &&
3358 (!Right.
Next || Right.
Next->
isNot(TT_FunctionDeclarationName)));
3359 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3360 Right.
is(tok::kw_operator))
3362 if (Left.
is(TT_PointerOrReference))
3371 (Left.
is(TT_CtorInitializerColon) &&
3372 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
3373 if (Left.
is(tok::question) && Right.
is(tok::colon))
3375 if (Right.
is(TT_ConditionalExpr) || Right.
is(tok::question))
3376 return Style.BreakBeforeTernaryOperators;
3377 if (Left.
is(TT_ConditionalExpr) || Left.
is(tok::question))
3378 return !
Style.BreakBeforeTernaryOperators;
3379 if (Left.
is(TT_InheritanceColon))
3380 return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
3381 if (Right.
is(TT_InheritanceColon))
3382 return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
3383 if (Right.
is(TT_ObjCMethodExpr) && !Right.
is(tok::r_square) &&
3384 Left.
isNot(TT_SelectorName))
3387 if (Right.
is(tok::colon) &&
3388 !Right.
isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
3390 if (Left.
is(tok::colon) && Left.
isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
3391 if (
Style.Language == FormatStyle::LK_Proto ||
3392 Style.Language == FormatStyle::LK_TextProto) {
3419 if (((Right.
is(tok::l_brace) || Right.
is(tok::less)) &&
3420 Right.
is(TT_DictLiteral)) ||
3421 Right.
is(TT_ArrayInitializerLSquare))
3429 if (Right.
is(TT_SelectorName) || (Right.
is(tok::identifier) && Right.
Next &&
3430 Right.
Next->
is(TT_ObjCMethodExpr)))
3431 return Left.
isNot(tok::period);
3436 if (Right.
isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
3437 TT_OverloadedOperator))
3439 if (Left.
is(TT_RangeBasedForLoopColon))
3441 if (Right.
is(TT_RangeBasedForLoopColon))
3443 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_TemplateOpener))
3445 if (Left.
isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
3446 Left.
is(tok::kw_operator))
3448 if (Left.
is(tok::equal) && !Right.
isOneOf(tok::kw_default, tok::kw_delete) &&
3451 if (Left.
is(tok::equal) && Right.
is(tok::l_brace) &&
3452 !
Style.Cpp11BracedListStyle)
3454 if (Left.
is(tok::l_paren) && Left.
is(TT_AttributeParen))
3456 if (Left.
is(tok::l_paren) && Left.
Previous &&
3459 if (Right.
is(TT_ImplicitStringLiteral))
3462 if (Right.
is(tok::r_paren) || Right.
is(TT_TemplateCloser))
3470 if (Right.
is(tok::r_brace))
3475 if (Left.
is(TT_TrailingAnnotation))
3476 return !Right.
isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
3477 tok::less, tok::coloncolon);
3479 if (Right.
is(tok::kw___attribute) ||
3480 (Right.
is(tok::l_square) && Right.
is(TT_AttributeSquare)))
3483 if (Left.
is(tok::identifier) && Right.
is(tok::string_literal))
3486 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
3489 if (Left.
is(TT_CtorInitializerColon))
3490 return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
3491 if (Right.
is(TT_CtorInitializerColon))
3492 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
3493 if (Left.
is(TT_CtorInitializerComma) &&
3494 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
3496 if (Right.
is(TT_CtorInitializerComma) &&
3497 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
3499 if (Left.
is(TT_InheritanceComma) &&
3500 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
3502 if (Right.
is(TT_InheritanceComma) &&
3503 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
3505 if ((Left.
is(tok::greater) && Right.
is(tok::greater)) ||
3506 (Left.
is(tok::less) && Right.
is(tok::less)))
3508 if (Right.
is(TT_BinaryOperator) &&
3509 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
3510 (
Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
3513 if (Left.
is(TT_ArrayInitializerLSquare))
3515 if (Right.
is(tok::kw_typename) && Left.
isNot(tok::kw_const))
3518 !Left.
isOneOf(tok::arrowstar, tok::lessless) &&
3519 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
3520 (
Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
3523 if ((Left.
is(TT_AttributeSquare) && Right.
is(tok::l_square)) ||
3524 (Left.
is(tok::r_square) && Right.
is(TT_AttributeSquare)))
3526 return Left.
isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
3527 tok::kw_class, tok::kw_struct, tok::comment) ||
3529 Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
3530 tok::colon, tok::l_square, tok::at) ||
3531 (Left.
is(tok::r_paren) &&
3532 Right.
isOneOf(tok::identifier, tok::kw_const)) ||
3533 (Left.
is(tok::l_paren) && !Right.
is(tok::r_paren)) ||
3534 (Left.
is(TT_TemplateOpener) && !Right.
is(TT_TemplateCloser));
3537 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
3538 llvm::errs() <<
"AnnotatedTokens(L=" << Line.
Level <<
"):\n";
3548 <<
" PPK=" << Tok->
PackingKind <<
" FakeLParens=";
3549 for (
unsigned i = 0, e = Tok->
FakeLParens.size(); i != e; ++i)
3551 llvm::errs() <<
" FakeRParens=" << Tok->
FakeRParens;
3553 llvm::errs() <<
" Text='" << Tok->
TokenText <<
"'\n";
3555 assert(Tok == Line.
Last);
3558 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
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