19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/Support/Debug.h"
22 #define DEBUG_TYPE "format-token-annotator"
31 static bool startsWithInitStatement(
const AnnotatedLine &
Line) {
47 static bool canBeObjCSelectorComponent(
const FormatToken &Tok) {
48 return Tok.Tok.getIdentifierInfo() !=
nullptr;
53 static bool isLambdaParameterList(
const FormatToken *Left) {
55 if (Left->Previous && Left->Previous->is(tok::greater) &&
56 Left->Previous->MatchingParen &&
57 Left->Previous->MatchingParen->is(TT_TemplateOpener)) {
58 Left = Left->Previous->MatchingParen;
62 return Left->Previous && Left->Previous->is(tok::r_square) &&
63 Left->Previous->MatchingParen &&
64 Left->Previous->MatchingParen->is(TT_LambdaLSquare);
69 static bool isKeywordWithCondition(
const FormatToken &Tok) {
70 return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
71 tok::kw_constexpr, tok::kw_catch);
79 class AnnotatingParser {
81 AnnotatingParser(
const FormatStyle &Style, AnnotatedLine &
Line,
82 const AdditionalKeywords &Keywords)
83 : Style(Style),
Line(
Line), CurrentToken(
Line.First), AutoFound(
false),
85 Contexts.push_back(Context(tok::unknown, 1,
false));
91 if (!CurrentToken || !CurrentToken->Previous)
93 if (NonTemplateLess.count(CurrentToken->Previous))
96 const FormatToken &
Previous = *CurrentToken->Previous;
98 if (
Previous.Previous->Tok.isLiteral())
100 if (
Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
101 (!
Previous.Previous->MatchingParen ||
102 !
Previous.Previous->MatchingParen->is(
103 TT_OverloadedOperatorLParen))) {
108 FormatToken *Left = CurrentToken->Previous;
109 Left->ParentBracket = Contexts.back().ContextKind;
110 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
114 bool InExprContext = Contexts.back().IsExpression;
116 Contexts.back().IsExpression =
false;
119 if (Left->Previous && Left->Previous->isNot(tok::kw_template))
120 Contexts.back().ContextType = Context::TemplateArgument;
123 CurrentToken->is(tok::question)) {
127 while (CurrentToken) {
128 if (CurrentToken->is(tok::greater)) {
135 if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
136 Left->ParentBracket != tok::less &&
137 (isKeywordWithCondition(*
Line.First) ||
138 CurrentToken->getStartOfNonWhitespace() ==
139 CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
143 Left->MatchingParen = CurrentToken;
144 CurrentToken->MatchingParen = Left;
152 Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
153 CurrentToken->setType(TT_DictLiteral);
155 CurrentToken->setType(TT_TemplateCloser);
160 if (CurrentToken->is(tok::question) &&
165 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
166 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
177 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
178 CurrentToken->Previous->is(TT_BinaryOperator) &&
179 Contexts[Contexts.size() - 2].IsExpression &&
180 !
Line.startsWith(tok::kw_template)) {
183 updateParameterCount(Left, CurrentToken);
185 if (FormatToken *
Previous = CurrentToken->getPreviousNonComment()) {
186 if (CurrentToken->is(tok::colon) ||
187 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
199 bool parseUntouchableParens() {
200 while (CurrentToken) {
201 CurrentToken->Finalized =
true;
202 switch (CurrentToken->Tok.getKind()) {
205 if (!parseUntouchableParens())
220 bool parseParens(
bool LookForDecls =
false) {
223 assert(CurrentToken->Previous &&
"Unknown previous token");
224 FormatToken &OpeningParen = *CurrentToken->Previous;
225 assert(OpeningParen.is(tok::l_paren));
226 FormatToken *PrevNonComment = OpeningParen.getPreviousNonComment();
227 OpeningParen.ParentBracket = Contexts.back().ContextKind;
228 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
231 Contexts.back().ColonIsForRangeExpr =
232 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
234 if (OpeningParen.Previous &&
235 OpeningParen.Previous->is(TT_UntouchableMacroFunc)) {
236 OpeningParen.Finalized =
true;
237 return parseUntouchableParens();
240 bool StartsObjCMethodExpr =
false;
241 if (FormatToken *MaybeSel = OpeningParen.Previous) {
243 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
244 MaybeSel->Previous->is(tok::at)) {
245 StartsObjCMethodExpr =
true;
249 if (OpeningParen.is(TT_OverloadedOperatorLParen)) {
251 FormatToken *Prev = &OpeningParen;
252 while (!Prev->is(tok::kw_operator)) {
253 Prev = Prev->Previous;
254 assert(Prev &&
"Expect a kw_operator prior to the OperatorLParen!");
260 bool OperatorCalledAsMemberFunction =
261 Prev->Previous && Prev->Previous->isOneOf(tok::period, tok::arrow);
262 Contexts.back().IsExpression = OperatorCalledAsMemberFunction;
263 }
else if (Style.isJavaScript() &&
264 (
Line.startsWith(Keywords.kw_type, tok::identifier) ||
265 Line.startsWith(tok::kw_export, Keywords.kw_type,
269 Contexts.back().IsExpression =
false;
270 }
else if (OpeningParen.Previous &&
271 (OpeningParen.Previous->isOneOf(tok::kw_static_assert,
272 tok::kw_while, tok::l_paren,
273 tok::comma, TT_BinaryOperator) ||
274 OpeningParen.Previous->isIf())) {
276 Contexts.back().IsExpression =
true;
277 }
else if (Style.isJavaScript() && OpeningParen.Previous &&
278 (OpeningParen.Previous->is(Keywords.kw_function) ||
279 (OpeningParen.Previous->endsSequence(tok::identifier,
280 Keywords.kw_function)))) {
282 Contexts.back().IsExpression =
false;
283 }
else if (Style.isJavaScript() && OpeningParen.Previous &&
284 OpeningParen.Previous->is(TT_JsTypeColon)) {
286 Contexts.back().IsExpression =
false;
287 }
else if (isLambdaParameterList(&OpeningParen)) {
289 Contexts.back().IsExpression =
false;
290 }
else if (
Line.InPPDirective &&
291 (!OpeningParen.Previous ||
292 !OpeningParen.Previous->is(tok::identifier))) {
293 Contexts.back().IsExpression =
true;
294 }
else if (Contexts[Contexts.size() - 2].CaretFound) {
296 Contexts.back().IsExpression =
false;
297 }
else if (OpeningParen.Previous &&
298 OpeningParen.Previous->is(TT_ForEachMacro)) {
300 Contexts.back().ContextType = Context::ForEachMacro;
301 Contexts.back().IsExpression =
false;
302 }
else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
303 OpeningParen.Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
304 Contexts.back().IsExpression =
false;
305 }
else if (!
Line.MustBeDeclaration && !
Line.InPPDirective) {
307 OpeningParen.Previous &&
308 OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch);
309 Contexts.back().IsExpression = !IsForOrCatch;
314 if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
315 if (PrevNonComment->is(tok::kw___attribute)) {
316 OpeningParen.setType(TT_AttributeParen);
317 }
else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
318 tok::kw_typeof, tok::kw__Atomic,
319 tok::kw___underlying_type)) {
320 OpeningParen.setType(TT_TypeDeclarationParen);
322 if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
323 Contexts.back().IsExpression =
true;
327 if (StartsObjCMethodExpr) {
328 Contexts.back().ColonIsObjCMethodExpr =
true;
329 OpeningParen.setType(TT_ObjCMethodExpr);
340 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
341 bool ProbablyFunctionType =
342 CurrentToken->isOneOf(tok::star, tok::amp, tok::ampamp, tok::caret);
343 bool HasMultipleLines =
false;
344 bool HasMultipleParametersOnALine =
false;
345 bool MightBeObjCForRangeLoop =
346 OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);
347 FormatToken *PossibleObjCForInToken =
nullptr;
348 while (CurrentToken) {
353 if (LookForDecls && CurrentToken->Next) {
354 FormatToken *Prev = CurrentToken->getPreviousNonComment();
356 FormatToken *PrevPrev = Prev->getPreviousNonComment();
357 FormatToken *Next = CurrentToken->Next;
358 if (PrevPrev && PrevPrev->is(tok::identifier) &&
359 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
360 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
361 Prev->setType(TT_BinaryOperator);
362 LookForDecls =
false;
367 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
368 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
370 ProbablyFunctionType =
true;
372 if (CurrentToken->is(tok::comma))
373 MightBeFunctionType =
false;
374 if (CurrentToken->Previous->is(TT_BinaryOperator))
375 Contexts.back().IsExpression =
true;
376 if (CurrentToken->is(tok::r_paren)) {
377 if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType &&
378 ProbablyFunctionType && CurrentToken->Next &&
379 (CurrentToken->Next->is(tok::l_paren) ||
380 (CurrentToken->Next->is(tok::l_square) &&
381 Line.MustBeDeclaration))) {
382 OpeningParen.setType(OpeningParen.Next->is(tok::caret)
384 : TT_FunctionTypeLParen);
386 OpeningParen.MatchingParen = CurrentToken;
387 CurrentToken->MatchingParen = &OpeningParen;
389 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
390 OpeningParen.Previous && OpeningParen.Previous->is(tok::l_paren)) {
394 for (FormatToken *Tok = &OpeningParen; Tok != CurrentToken;
396 if (Tok->is(TT_BinaryOperator) &&
397 Tok->isOneOf(tok::star, tok::amp, tok::ampamp)) {
398 Tok->setType(TT_PointerOrReference);
403 if (StartsObjCMethodExpr) {
404 CurrentToken->setType(TT_ObjCMethodExpr);
405 if (Contexts.back().FirstObjCSelectorName) {
406 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
407 Contexts.back().LongestObjCSelectorName;
411 if (OpeningParen.is(TT_AttributeParen))
412 CurrentToken->setType(TT_AttributeParen);
413 if (OpeningParen.is(TT_TypeDeclarationParen))
414 CurrentToken->setType(TT_TypeDeclarationParen);
415 if (OpeningParen.Previous &&
416 OpeningParen.Previous->is(TT_JavaAnnotation)) {
417 CurrentToken->setType(TT_JavaAnnotation);
419 if (OpeningParen.Previous &&
420 OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {
421 CurrentToken->setType(TT_LeadingJavaAnnotation);
423 if (OpeningParen.Previous &&
424 OpeningParen.Previous->is(TT_AttributeSquare)) {
425 CurrentToken->setType(TT_AttributeSquare);
428 if (!HasMultipleLines)
430 else if (HasMultipleParametersOnALine)
438 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
441 if (CurrentToken->is(tok::l_brace) && OpeningParen.is(TT_ObjCBlockLParen))
442 OpeningParen.setType(TT_Unknown);
443 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
444 !CurrentToken->Next->HasUnescapedNewline &&
445 !CurrentToken->Next->isTrailingComment()) {
446 HasMultipleParametersOnALine =
true;
448 bool ProbablyFunctionTypeLParen =
449 (CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
450 CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
451 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
452 CurrentToken->Previous->isSimpleTypeSpecifier()) &&
453 !(CurrentToken->is(tok::l_brace) ||
454 (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
455 Contexts.back().IsExpression =
false;
457 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
458 MightBeObjCForRangeLoop =
false;
459 if (PossibleObjCForInToken) {
460 PossibleObjCForInToken->setType(TT_Unknown);
461 PossibleObjCForInToken =
nullptr;
464 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
465 PossibleObjCForInToken = CurrentToken;
466 PossibleObjCForInToken->setType(TT_ObjCForIn);
470 if (CurrentToken->is(tok::comma))
471 Contexts.back().CanBeExpression =
true;
473 FormatToken *Tok = CurrentToken;
476 updateParameterCount(&OpeningParen, Tok);
477 if (CurrentToken && CurrentToken->HasUnescapedNewline)
478 HasMultipleLines =
true;
483 bool isCSharpAttributeSpecifier(
const FormatToken &Tok) {
484 if (!Style.isCSharp())
488 if (Tok.Previous && Tok.Previous->is(tok::identifier))
492 if (Tok.Previous && Tok.Previous->is(tok::r_square)) {
493 auto *MatchingParen = Tok.Previous->MatchingParen;
494 if (!MatchingParen || MatchingParen->is(TT_ArraySubscriptLSquare))
498 const FormatToken *AttrTok = Tok.Next;
503 if (AttrTok->is(tok::r_square))
507 while (AttrTok && AttrTok->isNot(tok::r_square))
508 AttrTok = AttrTok->Next;
514 AttrTok = AttrTok->Next;
519 if (AttrTok->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
520 tok::comment, tok::kw_class, tok::kw_static,
521 tok::l_square, Keywords.kw_internal)) {
527 AttrTok->Next->startsSequence(tok::identifier, tok::l_paren)) {
534 bool isCpp11AttributeSpecifier(
const FormatToken &Tok) {
535 if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square))
538 if (Tok.Previous && Tok.Previous->is(tok::at))
540 const FormatToken *AttrTok = Tok.Next->Next;
545 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
547 if (AttrTok->isNot(tok::identifier))
549 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
553 if (AttrTok->is(tok::colon) ||
554 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
555 AttrTok->startsSequence(tok::r_paren, tok::identifier)) {
558 if (AttrTok->is(tok::ellipsis))
560 AttrTok = AttrTok->Next;
562 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
573 FormatToken *Left = CurrentToken->Previous;
574 Left->ParentBracket = Contexts.back().ContextKind;
575 FormatToken *
Parent = Left->getPreviousNonComment();
580 bool CppArrayTemplates =
581 Style.isCpp() &&
Parent &&
Parent->is(TT_TemplateCloser) &&
582 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
583 Contexts.back().ContextType == Context::TemplateArgument);
585 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
586 Contexts.back().InCpp11AttributeSpecifier;
589 bool IsCSharpAttributeSpecifier =
590 isCSharpAttributeSpecifier(*Left) ||
591 Contexts.back().InCSharpAttributeSpecifier;
593 bool InsideInlineASM =
Line.startsWith(tok::kw_asm);
594 bool IsCppStructuredBinding = Left->isCppStructuredBinding(Style);
595 bool StartsObjCMethodExpr =
596 !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
597 Style.isCpp() && !IsCpp11AttributeSpecifier &&
598 !IsCSharpAttributeSpecifier && Contexts.back().CanBeExpression &&
599 Left->isNot(TT_LambdaLSquare) &&
600 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
602 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
603 tok::kw_return, tok::kw_throw) ||
604 Parent->isUnaryOperator() ||
606 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
609 bool ColonFound =
false;
611 unsigned BindingIncrease = 1;
612 if (IsCppStructuredBinding) {
613 Left->setType(TT_StructuredBindingLSquare);
614 }
else if (Left->is(TT_Unknown)) {
615 if (StartsObjCMethodExpr) {
616 Left->setType(TT_ObjCMethodExpr);
617 }
else if (InsideInlineASM) {
618 Left->setType(TT_InlineASMSymbolicNameLSquare);
619 }
else if (IsCpp11AttributeSpecifier) {
620 Left->setType(TT_AttributeSquare);
621 }
else if (Style.isJavaScript() &&
Parent &&
622 Contexts.back().ContextKind == tok::l_brace &&
623 Parent->isOneOf(tok::l_brace, tok::comma)) {
624 Left->setType(TT_JsComputedPropertyName);
625 }
else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
627 Left->setType(TT_DesignatedInitializerLSquare);
628 }
else if (IsCSharpAttributeSpecifier) {
629 Left->setType(TT_AttributeSquare);
630 }
else if (CurrentToken->is(tok::r_square) &&
Parent &&
631 Parent->is(TT_TemplateCloser)) {
632 Left->setType(TT_ArraySubscriptLSquare);
661 Left->setType(TT_ArrayInitializerLSquare);
662 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
664 !Left->endsSequence(tok::l_square, tok::numeric_constant,
666 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
667 Left->setType(TT_ProtoExtensionLSquare);
668 BindingIncrease = 10;
670 }
else if (!CppArrayTemplates &&
Parent &&
671 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
672 tok::comma, tok::l_paren, tok::l_square,
673 tok::question, tok::colon, tok::kw_return,
676 Left->setType(TT_ArrayInitializerLSquare);
678 BindingIncrease = 10;
679 Left->setType(TT_ArraySubscriptLSquare);
683 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
684 Contexts.back().IsExpression =
true;
685 if (Style.isJavaScript() &&
Parent &&
Parent->is(TT_JsTypeColon))
686 Contexts.back().IsExpression =
false;
688 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
689 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
690 Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;
692 while (CurrentToken) {
693 if (CurrentToken->is(tok::r_square)) {
694 if (IsCpp11AttributeSpecifier)
695 CurrentToken->setType(TT_AttributeSquare);
696 if (IsCSharpAttributeSpecifier) {
697 CurrentToken->setType(TT_AttributeSquare);
698 }
else if (((CurrentToken->Next &&
699 CurrentToken->Next->is(tok::l_paren)) ||
700 (CurrentToken->Previous &&
701 CurrentToken->Previous->Previous == Left)) &&
702 Left->is(TT_ObjCMethodExpr)) {
707 StartsObjCMethodExpr =
false;
708 Left->setType(TT_Unknown);
710 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
711 CurrentToken->setType(TT_ObjCMethodExpr);
714 if (!ColonFound && CurrentToken->Previous &&
715 CurrentToken->Previous->is(TT_Unknown) &&
716 canBeObjCSelectorComponent(*CurrentToken->Previous)) {
717 CurrentToken->Previous->setType(TT_SelectorName);
723 Parent->overwriteFixedType(TT_BinaryOperator);
726 if (CurrentToken->getType() == TT_ObjCMethodExpr &&
727 CurrentToken->Next && CurrentToken->Next->is(TT_LambdaArrow)) {
728 CurrentToken->Next->overwriteFixedType(TT_Unknown);
730 Left->MatchingParen = CurrentToken;
731 CurrentToken->MatchingParen = Left;
736 if (!Contexts.back().FirstObjCSelectorName) {
737 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
739 Previous->ObjCSelectorNameParts = 1;
740 Contexts.back().FirstObjCSelectorName =
Previous;
743 Left->ParameterCount =
744 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
746 if (Contexts.back().FirstObjCSelectorName) {
747 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
748 Contexts.back().LongestObjCSelectorName;
749 if (Left->BlockParameterCount > 1)
750 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
755 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
757 if (CurrentToken->is(tok::colon)) {
758 if (IsCpp11AttributeSpecifier &&
759 CurrentToken->endsSequence(tok::colon, tok::identifier,
763 CurrentToken->setType(TT_AttributeColon);
764 }
else if (Left->isOneOf(TT_ArraySubscriptLSquare,
765 TT_DesignatedInitializerLSquare)) {
766 Left->setType(TT_ObjCMethodExpr);
767 StartsObjCMethodExpr =
true;
768 Contexts.back().ColonIsObjCMethodExpr =
true;
771 Parent->setType(TT_CastRParen);
776 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
778 Left->setType(TT_ArrayInitializerLSquare);
780 FormatToken *Tok = CurrentToken;
783 updateParameterCount(Left, Tok);
788 bool couldBeInStructArrayInitializer()
const {
789 if (Contexts.size() < 2)
793 const auto End = std::next(Contexts.rbegin(), 2);
794 auto Last = Contexts.rbegin();
796 for (; Last !=
End; ++Last)
797 if (Last->ContextKind == tok::l_brace)
799 return Depth == 2 && Last->ContextKind != tok::l_brace;
806 assert(CurrentToken->Previous);
807 FormatToken &OpeningBrace = *CurrentToken->Previous;
808 assert(OpeningBrace.is(tok::l_brace));
809 OpeningBrace.ParentBracket = Contexts.back().ContextKind;
811 if (Contexts.back().CaretFound)
812 OpeningBrace.overwriteFixedType(TT_ObjCBlockLBrace);
813 Contexts.back().CaretFound =
false;
815 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
816 Contexts.back().ColonIsDictLiteral =
true;
818 Contexts.back().IsExpression =
true;
819 if (Style.isJavaScript() && OpeningBrace.Previous &&
820 OpeningBrace.Previous->is(TT_JsTypeColon)) {
821 Contexts.back().IsExpression =
false;
824 unsigned CommaCount = 0;
825 while (CurrentToken) {
826 if (CurrentToken->is(tok::r_brace)) {
827 assert(OpeningBrace.Optional == CurrentToken->Optional);
828 OpeningBrace.MatchingParen = CurrentToken;
829 CurrentToken->MatchingParen = &OpeningBrace;
831 if (OpeningBrace.ParentBracket == tok::l_brace &&
832 couldBeInStructArrayInitializer() && CommaCount > 0) {
833 Contexts.back().ContextType = Context::StructArrayInitializer;
839 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
841 updateParameterCount(&OpeningBrace, CurrentToken);
842 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
843 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
844 if (
Previous->is(TT_JsTypeOptionalQuestion))
846 if ((CurrentToken->is(tok::colon) &&
847 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
850 OpeningBrace.setType(TT_DictLiteral);
851 if (
Previous->Tok.getIdentifierInfo() ||
852 Previous->is(tok::string_literal)) {
856 if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown))
857 OpeningBrace.setType(TT_DictLiteral);
858 else if (Style.isJavaScript())
859 OpeningBrace.overwriteFixedType(TT_DictLiteral);
861 if (CurrentToken->is(tok::comma)) {
862 if (Style.isJavaScript())
863 OpeningBrace.overwriteFixedType(TT_DictLiteral);
872 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
876 if (Current->is(tok::l_brace) && Current->is(
BK_Block))
877 ++Left->BlockParameterCount;
878 if (Current->is(tok::comma)) {
879 ++Left->ParameterCount;
881 Left->Role.reset(
new CommaSeparatedList(Style));
882 Left->Role->CommaFound(Current);
883 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
884 Left->ParameterCount = 1;
888 bool parseConditional() {
889 while (CurrentToken) {
890 if (CurrentToken->is(tok::colon)) {
891 CurrentToken->setType(TT_ConditionalExpr);
901 bool parseTemplateDeclaration() {
902 if (CurrentToken && CurrentToken->is(tok::less)) {
903 CurrentToken->setType(TT_TemplateOpener);
908 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
914 bool consumeToken() {
915 FormatToken *Tok = CurrentToken;
917 switch (Tok->Tok.getKind()) {
920 if (!Tok->Previous &&
Line.MustBeDeclaration)
921 Tok->setType(TT_ObjCMethodSpecifier);
927 if (Style.isJavaScript()) {
928 if (Contexts.back().ColonIsForRangeExpr ||
929 (Contexts.size() == 1 &&
930 !
Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
931 Contexts.back().ContextKind == tok::l_paren ||
932 Contexts.back().ContextKind == tok::l_square ||
933 (!Contexts.back().IsExpression &&
934 Contexts.back().ContextKind == tok::l_brace) ||
935 (Contexts.size() == 1 &&
936 Line.MustBeDeclaration)) {
937 Contexts.back().IsExpression =
false;
938 Tok->setType(TT_JsTypeColon);
941 }
else if (Style.isCSharp()) {
942 if (Contexts.back().InCSharpAttributeSpecifier) {
943 Tok->setType(TT_AttributeColon);
946 if (Contexts.back().ContextKind == tok::l_paren) {
947 Tok->setType(TT_CSharpNamedArgumentColon);
951 if (
Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
952 Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
953 Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) {
954 Tok->setType(TT_ModulePartitionColon);
955 }
else if (Contexts.back().ColonIsDictLiteral ||
958 Tok->setType(TT_DictLiteral);
960 if (FormatToken *
Previous = Tok->getPreviousNonComment())
963 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
964 Line.startsWith(TT_ObjCMethodSpecifier)) {
965 Tok->setType(TT_ObjCMethodExpr);
966 const FormatToken *BeforePrevious = Tok->Previous->Previous;
969 bool UnknownIdentifierInMethodDeclaration =
970 Line.startsWith(TT_ObjCMethodSpecifier) &&
971 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
972 if (!BeforePrevious ||
974 !(BeforePrevious->is(TT_CastRParen) ||
975 (BeforePrevious->is(TT_ObjCMethodExpr) &&
976 BeforePrevious->is(tok::colon))) ||
977 BeforePrevious->is(tok::r_square) ||
978 Contexts.back().LongestObjCSelectorName == 0 ||
979 UnknownIdentifierInMethodDeclaration) {
980 Tok->Previous->setType(TT_SelectorName);
981 if (!Contexts.back().FirstObjCSelectorName) {
982 Contexts.back().FirstObjCSelectorName = Tok->Previous;
983 }
else if (Tok->Previous->ColumnWidth >
984 Contexts.back().LongestObjCSelectorName) {
985 Contexts.back().LongestObjCSelectorName =
986 Tok->Previous->ColumnWidth;
988 Tok->Previous->ParameterIndex =
989 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
990 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
992 }
else if (Contexts.back().ColonIsForRangeExpr) {
993 Tok->setType(TT_RangeBasedForLoopColon);
994 }
else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
995 Tok->setType(TT_BitFieldColon);
996 }
else if (Contexts.size() == 1 &&
997 !
Line.First->isOneOf(tok::kw_enum, tok::kw_case,
999 FormatToken *Prev = Tok->getPreviousNonComment();
1002 if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept)) {
1003 Tok->setType(TT_CtorInitializerColon);
1004 }
else if (Prev->is(tok::kw_try)) {
1006 FormatToken *PrevPrev = Prev->getPreviousNonComment();
1009 if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))
1010 Tok->setType(TT_CtorInitializerColon);
1012 Tok->setType(TT_InheritanceColon);
1014 }
else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
1015 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
1016 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
1017 Tok->Next->Next->is(tok::colon)))) {
1020 Tok->setType(TT_ObjCMethodExpr);
1021 }
else if (Contexts.back().ContextKind == tok::l_paren) {
1022 Tok->setType(TT_InlineASMColon);
1029 if (Style.isJavaScript() && !Contexts.back().IsExpression)
1030 Tok->setType(TT_JsTypeOperator);
1034 CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {
1039 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
1041 if (!parseParens(
true))
1046 if (Style.isJavaScript()) {
1048 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
1049 (Tok->Next && Tok->Next->is(tok::colon))) {
1053 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
1056 if (Style.isCpp() && CurrentToken && CurrentToken->is(tok::kw_co_await))
1058 Contexts.back().ColonIsForRangeExpr =
true;
1059 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1070 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
1071 Tok->Previous->MatchingParen &&
1072 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
1073 Tok->Previous->setType(TT_OverloadedOperator);
1074 Tok->Previous->MatchingParen->setType(TT_OverloadedOperator);
1075 Tok->setType(TT_OverloadedOperatorLParen);
1080 if (
Line.MustBeDeclaration && Contexts.size() == 1 &&
1081 !Contexts.back().IsExpression && !
Line.startsWith(TT_ObjCProperty) &&
1082 !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen) &&
1084 !Tok->Previous->isOneOf(tok::kw___attribute,
1085 TT_LeadingJavaAnnotation))) {
1086 Line.MightBeFunctionDecl =
true;
1095 FormatToken *
Previous = Tok->getPreviousNonComment();
1097 Previous->setType(TT_SelectorName);
1104 Tok->setType(TT_TemplateOpener);
1112 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
1113 Tok->setType(TT_DictLiteral);
1114 FormatToken *
Previous = Tok->getPreviousNonComment();
1116 Previous->setType(TT_SelectorName);
1119 Tok->setType(TT_BinaryOperator);
1120 NonTemplateLess.insert(Tok);
1135 Tok->setType(TT_BinaryOperator);
1136 if (Tok->Previous && Tok->Previous->is(TT_TemplateCloser))
1137 Tok->SpacesRequiredBefore = 1;
1139 case tok::kw_operator:
1144 while (CurrentToken &&
1145 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
1146 if (CurrentToken->isOneOf(tok::star, tok::amp))
1147 CurrentToken->setType(TT_PointerOrReference);
1149 if (CurrentToken && CurrentToken->is(tok::comma) &&
1150 CurrentToken->Previous->isNot(tok::kw_operator)) {
1153 if (CurrentToken && CurrentToken->Previous->isOneOf(
1154 TT_BinaryOperator, TT_UnaryOperator, tok::comma,
1155 tok::star, tok::arrow, tok::amp, tok::ampamp)) {
1156 CurrentToken->Previous->setType(TT_OverloadedOperator);
1159 if (CurrentToken && CurrentToken->is(tok::l_paren))
1160 CurrentToken->setType(TT_OverloadedOperatorLParen);
1161 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
1162 CurrentToken->Previous->setType(TT_OverloadedOperator);
1165 if (Style.isJavaScript() && Tok->Next &&
1166 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
1172 Tok->setType(TT_JsTypeOptionalQuestion);
1177 if (
Line.MustBeDeclaration && !Contexts.back().IsExpression &&
1178 Style.isJavaScript()) {
1181 if (Style.isCSharp()) {
1185 if ((!Contexts.back().IsExpression &&
Line.MustBeDeclaration) ||
1186 (Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::greater)) ||
1187 (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
1188 Tok->Next->Next->is(tok::equal))) {
1189 Tok->setType(TT_CSharpNullable);
1195 case tok::kw_template:
1196 parseTemplateDeclaration();
1199 switch (Contexts.back().ContextType) {
1200 case Context::CtorInitializer:
1201 Tok->setType(TT_CtorInitializerComma);
1203 case Context::InheritanceList:
1204 Tok->setType(TT_InheritanceComma);
1207 if (Contexts.back().FirstStartOfName &&
1208 (Contexts.size() == 1 || startsWithInitStatement(
Line))) {
1209 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
1210 Line.IsMultiVariableDeclStmt =
true;
1214 if (Contexts.back().ContextType == Context::ForEachMacro)
1215 Contexts.back().IsExpression =
true;
1217 case tok::identifier:
1218 if (Tok->isOneOf(Keywords.kw___has_include,
1219 Keywords.kw___has_include_next)) {
1222 if (Style.isCSharp() && Tok->is(Keywords.kw_where) && Tok->Next &&
1223 Tok->Next->isNot(tok::l_paren)) {
1224 Tok->setType(TT_CSharpGenericTypeConstraint);
1225 parseCSharpGenericTypeConstraint();
1229 if (Tok->isNot(TT_LambdaArrow) && Tok->Previous &&
1230 Tok->Previous->is(tok::kw_noexcept)) {
1231 Tok->setType(TT_TrailingReturnArrow);
1240 void parseCSharpGenericTypeConstraint() {
1241 int OpenAngleBracketsCount = 0;
1242 while (CurrentToken) {
1243 if (CurrentToken->is(tok::less)) {
1245 CurrentToken->setType(TT_TemplateOpener);
1246 ++OpenAngleBracketsCount;
1248 }
else if (CurrentToken->is(tok::greater)) {
1249 CurrentToken->setType(TT_TemplateCloser);
1250 --OpenAngleBracketsCount;
1252 }
else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {
1255 CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);
1257 }
else if (CurrentToken->is(Keywords.kw_where)) {
1258 CurrentToken->setType(TT_CSharpGenericTypeConstraint);
1260 }
else if (CurrentToken->is(tok::colon)) {
1261 CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);
1269 void parseIncludeDirective() {
1270 if (CurrentToken && CurrentToken->is(tok::less)) {
1272 while (CurrentToken) {
1275 if (CurrentToken->isNot(tok::comment) &&
1276 !CurrentToken->TokenText.startswith(
"//")) {
1277 CurrentToken->setType(TT_ImplicitStringLiteral);
1284 void parseWarningOrError() {
1289 while (CurrentToken) {
1290 CurrentToken->setType(TT_ImplicitStringLiteral);
1295 void parsePragma() {
1298 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option,
1299 Keywords.kw_region)) {
1300 bool IsMark = CurrentToken->is(Keywords.kw_mark);
1303 while (CurrentToken) {
1304 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
1305 CurrentToken->setType(TT_ImplicitStringLiteral);
1311 void parseHasInclude() {
1312 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
1315 parseIncludeDirective();
1319 LineType parsePreprocessorDirective() {
1320 bool IsFirstToken = CurrentToken->IsFirst;
1326 if (Style.isJavaScript() && IsFirstToken) {
1330 while (CurrentToken) {
1332 CurrentToken->setType(TT_ImplicitStringLiteral);
1338 if (CurrentToken->is(tok::numeric_constant)) {
1339 CurrentToken->SpacesRequiredBefore = 1;
1344 if (!CurrentToken->Tok.getIdentifierInfo())
1346 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1351 parseIncludeDirective();
1355 case tok::pp_warning:
1356 parseWarningOrError();
1358 case tok::pp_pragma:
1363 Contexts.back().IsExpression =
true;
1370 while (CurrentToken) {
1371 FormatToken *Tok = CurrentToken;
1373 if (Tok->is(tok::l_paren)) {
1375 }
else if (Tok->isOneOf(Keywords.kw___has_include,
1376 Keywords.kw___has_include_next)) {
1387 NonTemplateLess.clear();
1388 if (CurrentToken->is(tok::hash))
1389 return parsePreprocessorDirective();
1394 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1396 CurrentToken->is(Keywords.kw_package)) ||
1398 CurrentToken->Next &&
1399 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1402 parseIncludeDirective();
1408 if (CurrentToken->is(tok::less) &&
Line.Last->is(tok::greater)) {
1409 parseIncludeDirective();
1416 CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
1418 if (CurrentToken && CurrentToken->is(tok::identifier)) {
1419 while (CurrentToken)
1425 bool KeywordVirtualFound =
false;
1426 bool ImportStatement =
false;
1429 if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))
1430 ImportStatement =
true;
1432 while (CurrentToken) {
1433 if (CurrentToken->is(tok::kw_virtual))
1434 KeywordVirtualFound =
true;
1435 if (Style.isJavaScript()) {
1442 if (
Line.First->is(tok::kw_export) &&
1443 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1444 CurrentToken->Next->isStringLiteral()) {
1445 ImportStatement =
true;
1447 if (isClosureImportStatement(*CurrentToken))
1448 ImportStatement =
true;
1450 if (!consumeToken())
1453 if (KeywordVirtualFound)
1455 if (ImportStatement)
1458 if (
Line.startsWith(TT_ObjCMethodSpecifier)) {
1459 if (Contexts.back().FirstObjCSelectorName) {
1460 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1461 Contexts.back().LongestObjCSelectorName;
1466 for (
const auto &ctx : Contexts)
1467 if (ctx.ContextType == Context::StructArrayInitializer)
1474 bool isClosureImportStatement(
const FormatToken &Tok) {
1477 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
1479 (Tok.Next->Next->TokenText ==
"module" ||
1480 Tok.Next->Next->TokenText ==
"provide" ||
1481 Tok.Next->Next->TokenText ==
"require" ||
1482 Tok.Next->Next->TokenText ==
"requireType" ||
1483 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
1484 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1487 void resetTokenMetadata() {
1493 if (!CurrentToken->isTypeFinalized() &&
1494 !CurrentToken->isOneOf(
1495 TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
1496 TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
1497 TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
1498 TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
1499 TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
1500 TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
1501 TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
1502 TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
1503 TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
1504 TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
1505 TT_CompoundRequirementLBrace, TT_BracedListLBrace)) {
1506 CurrentToken->setType(TT_Unknown);
1508 CurrentToken->Role.reset();
1509 CurrentToken->MatchingParen =
nullptr;
1510 CurrentToken->FakeLParens.clear();
1511 CurrentToken->FakeRParens = 0;
1518 CurrentToken->NestingLevel = Contexts.size() - 1;
1519 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1520 modifyContext(*CurrentToken);
1521 determineTokenType(*CurrentToken);
1522 CurrentToken = CurrentToken->Next;
1524 resetTokenMetadata();
1560 StructArrayInitializer,
1568 struct ScopedContextCreator {
1569 AnnotatingParser &
P;
1575 P.Contexts.back().BindingStrength + Increase,
1576 P.Contexts.back().IsExpression));
1579 ~ScopedContextCreator() {
1581 if (
P.Contexts.back().ContextType == Context::StructArrayInitializer) {
1582 P.Contexts.pop_back();
1583 P.Contexts.back().ContextType = Context::StructArrayInitializer;
1587 P.Contexts.pop_back();
1591 void modifyContext(
const FormatToken &Current) {
1592 auto AssignmentStartsExpression = [&]() {
1596 if (
Line.First->isOneOf(tok::kw_using, tok::kw_return))
1598 if (
Line.First->is(tok::kw_template)) {
1599 assert(Current.Previous);
1600 if (Current.Previous->is(tok::kw_operator)) {
1606 const FormatToken *Tok =
Line.First->getNextNonComment();
1608 if (Tok->isNot(TT_TemplateOpener)) {
1613 Tok = Tok->MatchingParen;
1616 Tok = Tok->getNextNonComment();
1620 if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_concept,
1621 tok::kw_struct, tok::kw_using)) {
1630 if (Style.isJavaScript() &&
1631 (
Line.startsWith(Keywords.kw_type, tok::identifier) ||
1632 Line.startsWith(tok::kw_export, Keywords.kw_type,
1633 tok::identifier))) {
1637 return !Current.Previous || Current.Previous->isNot(tok::kw_operator);
1640 if (AssignmentStartsExpression()) {
1641 Contexts.back().IsExpression =
true;
1642 if (!
Line.startsWith(TT_UnaryOperator)) {
1643 for (FormatToken *
Previous = Current.Previous;
1645 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1647 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
1654 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1655 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1657 Previous->setType(TT_PointerOrReference);
1661 }
else if (Current.is(tok::lessless) &&
1662 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1663 Contexts.back().IsExpression =
true;
1664 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1665 Contexts.back().IsExpression =
true;
1666 }
else if (Current.is(TT_TrailingReturnArrow)) {
1667 Contexts.back().IsExpression =
false;
1668 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1670 }
else if (Current.Previous &&
1671 Current.Previous->is(TT_CtorInitializerColon)) {
1672 Contexts.back().IsExpression =
true;
1673 Contexts.back().ContextType = Context::CtorInitializer;
1674 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1675 Contexts.back().ContextType = Context::InheritanceList;
1676 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1677 for (FormatToken *
Previous = Current.Previous;
1680 Previous->setType(TT_PointerOrReference);
1682 if (
Line.MustBeDeclaration &&
1683 Contexts.front().ContextType != Context::CtorInitializer) {
1684 Contexts.back().IsExpression =
false;
1686 }
else if (Current.is(tok::kw_new)) {
1687 Contexts.back().CanBeExpression =
false;
1688 }
else if (Current.is(tok::semi) ||
1689 (Current.is(tok::exclaim) && Current.Previous &&
1690 !Current.Previous->is(tok::kw_operator))) {
1694 Contexts.back().IsExpression =
true;
1698 static FormatToken *untilMatchingParen(FormatToken *Current) {
1702 if (Current->is(tok::l_paren))
1704 if (Current->is(tok::r_paren))
1708 Current = Current->Next;
1713 static bool isDeductionGuide(FormatToken &Current) {
1715 if (Current.Previous && Current.Previous->is(tok::r_paren) &&
1716 Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
1718 FormatToken *TemplateCloser = Current.Next->Next;
1719 int NestingLevel = 0;
1720 while (TemplateCloser) {
1722 if (TemplateCloser->is(tok::l_paren)) {
1724 TemplateCloser = untilMatchingParen(TemplateCloser);
1725 if (!TemplateCloser)
1728 if (TemplateCloser->is(tok::less))
1730 if (TemplateCloser->is(tok::greater))
1732 if (NestingLevel < 1)
1734 TemplateCloser = TemplateCloser->Next;
1738 if (TemplateCloser && TemplateCloser->Next &&
1739 TemplateCloser->Next->is(tok::semi) &&
1740 Current.Previous->MatchingParen) {
1743 FormatToken *LeadingIdentifier =
1744 Current.Previous->MatchingParen->Previous;
1748 if (LeadingIdentifier) {
1749 FormatToken *PriorLeadingIdentifier = LeadingIdentifier->Previous;
1751 if (PriorLeadingIdentifier &&
1752 PriorLeadingIdentifier->is(tok::kw_explicit)) {
1753 PriorLeadingIdentifier = PriorLeadingIdentifier->Previous;
1756 return PriorLeadingIdentifier &&
1757 (PriorLeadingIdentifier->is(TT_TemplateCloser) ||
1758 PriorLeadingIdentifier->ClosesRequiresClause) &&
1759 LeadingIdentifier->TokenText == Current.Next->TokenText;
1766 void determineTokenType(FormatToken &Current) {
1767 if (!Current.is(TT_Unknown)) {
1772 if ((Style.isJavaScript() || Style.isCSharp()) &&
1773 Current.is(tok::exclaim)) {
1774 if (Current.Previous) {
1776 Style.isJavaScript()
1777 ? Keywords.IsJavaScriptIdentifier(
1778 *Current.Previous,
true)
1779 : Current.Previous->is(tok::identifier);
1781 Current.Previous->isOneOf(
1782 tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square,
1783 tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type,
1784 Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) ||
1785 Current.Previous->Tok.isLiteral()) {
1786 Current.setType(TT_NonNullAssertion);
1791 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1792 Current.setType(TT_NonNullAssertion);
1800 if (Current.is(Keywords.kw_instanceof)) {
1801 Current.setType(TT_BinaryOperator);
1802 }
else if (isStartOfName(Current) &&
1803 (!
Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1804 Contexts.back().FirstStartOfName = &Current;
1805 Current.setType(TT_StartOfName);
1806 }
else if (Current.is(tok::semi)) {
1810 Contexts.back().FirstStartOfName =
nullptr;
1811 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1813 }
else if (Current.is(tok::arrow) &&
1815 Current.setType(TT_LambdaArrow);
1816 }
else if (Current.is(tok::arrow) && AutoFound &&
Line.MustBeDeclaration &&
1817 Current.NestingLevel == 0 &&
1818 !Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
1820 Current.setType(TT_TrailingReturnArrow);
1821 }
else if (Current.is(tok::arrow) && Current.Previous &&
1822 Current.Previous->is(tok::r_brace)) {
1825 Current.setType(TT_TrailingReturnArrow);
1826 }
else if (isDeductionGuide(Current)) {
1828 Current.setType(TT_TrailingReturnArrow);
1829 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1830 Current.setType(determineStarAmpUsage(
1832 Contexts.back().CanBeExpression && Contexts.back().IsExpression,
1833 Contexts.back().ContextType == Context::TemplateArgument));
1834 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1835 Current.setType(determinePlusMinusCaretUsage(Current));
1836 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1837 Contexts.back().CaretFound =
true;
1838 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1839 Current.setType(determineIncrementUsage(Current));
1840 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1841 Current.setType(TT_UnaryOperator);
1842 }
else if (Current.is(tok::question)) {
1843 if (Style.isJavaScript() &&
Line.MustBeDeclaration &&
1844 !Contexts.back().IsExpression) {
1847 Current.setType(TT_JsTypeOptionalQuestion);
1849 Current.setType(TT_ConditionalExpr);
1851 }
else if (Current.isBinaryOperator() &&
1852 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1853 (!Current.is(tok::greater) &&
1855 Current.setType(TT_BinaryOperator);
1856 }
else if (Current.is(tok::comment)) {
1857 if (Current.TokenText.startswith(
"/*")) {
1858 if (Current.TokenText.endswith(
"*/")) {
1859 Current.setType(TT_BlockComment);
1863 Current.Tok.setKind(tok::unknown);
1866 Current.setType(TT_LineComment);
1868 }
else if (Current.is(tok::l_paren)) {
1869 if (lParenStartsCppCast(Current))
1870 Current.setType(TT_CppCastLParen);
1871 }
else if (Current.is(tok::r_paren)) {
1872 if (rParenEndsCast(Current))
1873 Current.setType(TT_CastRParen);
1874 if (Current.MatchingParen && Current.Next &&
1875 !Current.Next->isBinaryOperator() &&
1876 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1877 tok::comma, tok::period, tok::arrow,
1879 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1881 if (AfterParen->isNot(tok::caret)) {
1882 if (FormatToken *BeforeParen = Current.MatchingParen->Previous) {
1883 if (BeforeParen->is(tok::identifier) &&
1884 !BeforeParen->is(TT_TypenameMacro) &&
1885 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1886 (!BeforeParen->Previous ||
1887 BeforeParen->Previous->ClosesTemplateDeclaration)) {
1888 Current.setType(TT_FunctionAnnotationRParen);
1894 }
else if (Current.is(tok::at) && Current.Next && !Style.isJavaScript() &&
1898 switch (Current.Next->Tok.getObjCKeywordID()) {
1899 case tok::objc_interface:
1900 case tok::objc_implementation:
1901 case tok::objc_protocol:
1902 Current.setType(TT_ObjCDecl);
1904 case tok::objc_property:
1905 Current.setType(TT_ObjCProperty);
1910 }
else if (Current.is(tok::period)) {
1911 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1912 if (PreviousNoComment &&
1913 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) {
1914 Current.setType(TT_DesignatedInitializerPeriod);
1916 Current.Previous->isOneOf(TT_JavaAnnotation,
1917 TT_LeadingJavaAnnotation)) {
1918 Current.setType(Current.Previous->getType());
1920 }
else if (canBeObjCSelectorComponent(Current) &&
1923 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1924 Current.Previous->MatchingParen &&
1925 Current.Previous->MatchingParen->Previous &&
1926 Current.Previous->MatchingParen->Previous->is(
1927 TT_ObjCMethodSpecifier)) {
1931 Current.setType(TT_SelectorName);
1932 }
else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
1933 tok::kw_requires) &&
1935 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1936 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1939 Current.setType(TT_TrailingAnnotation);
1941 Style.isJavaScript()) &&
1943 if (Current.Previous->is(tok::at) &&
1944 Current.isNot(Keywords.kw_interface)) {
1945 const FormatToken &AtToken = *Current.Previous;
1946 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1948 Current.setType(TT_LeadingJavaAnnotation);
1950 Current.setType(TT_JavaAnnotation);
1951 }
else if (Current.Previous->is(tok::period) &&
1952 Current.Previous->isOneOf(TT_JavaAnnotation,
1953 TT_LeadingJavaAnnotation)) {
1954 Current.setType(Current.Previous->getType());
1964 bool isStartOfName(
const FormatToken &Tok) {
1965 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1968 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1972 if (Style.isJavaScript() && Tok.Previous->is(Keywords.kw_in))
1976 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1979 if (!Style.isJavaScript())
1980 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1981 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1983 if (!PreviousNotConst)
1986 if (PreviousNotConst->ClosesRequiresClause)
1989 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1990 PreviousNotConst->Previous &&
1991 PreviousNotConst->Previous->is(tok::hash);
1993 if (PreviousNotConst->is(TT_TemplateCloser)) {
1994 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1995 PreviousNotConst->MatchingParen->Previous &&
1996 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1997 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
2000 if (PreviousNotConst->is(tok::r_paren) &&
2001 PreviousNotConst->is(TT_TypeDeclarationParen)) {
2010 if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto))
2014 if (PreviousNotConst->is(TT_PointerOrReference))
2018 if (PreviousNotConst->isSimpleTypeSpecifier())
2022 return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const);
2026 bool lParenStartsCppCast(
const FormatToken &Tok) {
2031 FormatToken *LeftOfParens = Tok.getPreviousNonComment();
2032 if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) &&
2033 LeftOfParens->MatchingParen) {
2034 auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment();
2036 Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast,
2037 tok::kw_reinterpret_cast, tok::kw_static_cast)) {
2047 bool rParenEndsCast(
const FormatToken &Tok) {
2049 if (!Style.isCSharp() && !Style.isCpp() &&
2055 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
2058 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
2062 if (LeftOfParens->is(tok::r_paren) &&
2063 LeftOfParens->isNot(TT_CastRParen)) {
2064 if (!LeftOfParens->MatchingParen ||
2065 !LeftOfParens->MatchingParen->Previous) {
2068 LeftOfParens = LeftOfParens->MatchingParen->Previous;
2071 if (LeftOfParens->is(tok::r_square)) {
2073 auto MayBeArrayDelete = [](FormatToken *Tok) -> FormatToken * {
2074 if (Tok->isNot(tok::r_square))
2077 Tok = Tok->getPreviousNonComment();
2078 if (!Tok || Tok->isNot(tok::l_square))
2081 Tok = Tok->getPreviousNonComment();
2082 if (!Tok || Tok->isNot(tok::kw_delete))
2086 if (FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens))
2087 LeftOfParens = MaybeDelete;
2093 if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous &&
2094 LeftOfParens->Previous->is(tok::kw_operator)) {
2100 if (LeftOfParens->Tok.getIdentifierInfo() &&
2101 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
2108 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
2109 TT_TemplateCloser, tok::ellipsis)) {
2114 if (Tok.Next->is(tok::question))
2118 if (Tok.Next->is(Keywords.kw_in) && Style.isCSharp())
2123 if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
2124 tok::kw_requires, tok::kw_throw, tok::arrow,
2125 Keywords.kw_override, Keywords.kw_final) ||
2126 isCpp11AttributeSpecifier(*Tok.Next)) {
2136 if (Tok.Next->isNot(tok::string_literal) &&
2137 (Tok.Next->Tok.isLiteral() ||
2138 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof))) {
2143 auto IsQualifiedPointerOrReference = [](FormatToken *T) {
2145 assert(!T->isSimpleTypeSpecifier() &&
"Should have already been checked");
2149 if (T->is(TT_AttributeParen)) {
2151 if (T->MatchingParen && T->MatchingParen->Previous &&
2152 T->MatchingParen->Previous->is(tok::kw___attribute)) {
2153 T = T->MatchingParen->Previous->Previous;
2156 }
else if (T->is(TT_AttributeSquare)) {
2158 if (T->MatchingParen && T->MatchingParen->Previous) {
2159 T = T->MatchingParen->Previous;
2162 }
else if (T->canBePointerOrReferenceQualifier()) {
2168 return T && T->is(TT_PointerOrReference);
2170 bool ParensAreType =
2172 Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
2173 Tok.Previous->isSimpleTypeSpecifier() ||
2174 IsQualifiedPointerOrReference(Tok.Previous);
2175 bool ParensCouldEndDecl =
2176 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
2177 if (ParensAreType && !ParensCouldEndDecl)
2188 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
2189 Token = Token->Next) {
2190 if (Token->is(TT_BinaryOperator))
2196 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
2200 if (Tok.Next->is(tok::l_paren) && Tok.Previous && Tok.Previous->Previous) {
2201 if (Tok.Previous->is(tok::identifier) &&
2202 Tok.Previous->Previous->is(tok::l_paren)) {
2207 if (!Tok.Next->Next)
2214 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
2215 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
2216 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant)) {
2220 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
2221 Prev = Prev->Previous) {
2222 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
2229 bool determineUnaryOperatorByUsage(
const FormatToken &Tok) {
2230 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2240 if (PrevToken->isOneOf(
2241 TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
2242 tok::equal, tok::question, tok::l_square, tok::l_brace,
2243 tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
2244 tok::kw_delete, tok::kw_return, tok::kw_throw)) {
2251 if (PrevToken->is(tok::kw_sizeof))
2255 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
2259 if (PrevToken->is(TT_BinaryOperator))
2267 bool InTemplateArgument) {
2268 if (Style.isJavaScript())
2269 return TT_BinaryOperator;
2272 if (Style.isCSharp() && Tok.is(tok::ampamp))
2273 return TT_BinaryOperator;
2275 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2277 return TT_UnaryOperator;
2279 const FormatToken *NextToken = Tok.getNextNonComment();
2281 if (InTemplateArgument && NextToken && NextToken->is(tok::kw_noexcept))
2282 return TT_BinaryOperator;
2285 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_noexcept) ||
2286 NextToken->canBePointerOrReferenceQualifier() ||
2287 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) {
2288 return TT_PointerOrReference;
2291 if (PrevToken->is(tok::coloncolon))
2292 return TT_PointerOrReference;
2294 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
2295 return TT_PointerOrReference;
2297 if (determineUnaryOperatorByUsage(Tok))
2298 return TT_UnaryOperator;
2300 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
2301 return TT_PointerOrReference;
2303 return TT_PointerOrReference;
2304 if (NextToken->isOneOf(tok::comma, tok::semi))
2305 return TT_PointerOrReference;
2307 if (PrevToken->Tok.isLiteral() ||
2308 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
2309 tok::kw_false, tok::r_brace)) {
2310 return TT_BinaryOperator;
2313 const FormatToken *NextNonParen = NextToken;
2314 while (NextNonParen && NextNonParen->is(tok::l_paren))
2315 NextNonParen = NextNonParen->getNextNonComment();
2316 if (NextNonParen && (NextNonParen->Tok.isLiteral() ||
2317 NextNonParen->isOneOf(tok::kw_true, tok::kw_false) ||
2318 NextNonParen->isUnaryOperator())) {
2319 return TT_BinaryOperator;
2325 if (InTemplateArgument && NextToken->Tok.isAnyIdentifier())
2326 return TT_BinaryOperator;
2329 if (Tok.is(tok::ampamp) && NextToken->is(tok::l_paren))
2330 return TT_BinaryOperator;
2334 if (NextToken->Tok.isAnyIdentifier()) {
2335 const FormatToken *NextNextToken = NextToken->getNextNonComment();
2336 if (NextNextToken && NextNextToken->is(tok::arrow))
2337 return TT_BinaryOperator;
2343 return TT_BinaryOperator;
2345 return TT_PointerOrReference;
2348 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
2349 if (determineUnaryOperatorByUsage(Tok))
2350 return TT_UnaryOperator;
2352 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2354 return TT_UnaryOperator;
2356 if (PrevToken->is(tok::at))
2357 return TT_UnaryOperator;
2360 return TT_BinaryOperator;
2364 TokenType determineIncrementUsage(
const FormatToken &Tok) {
2365 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2366 if (!PrevToken || PrevToken->is(TT_CastRParen))
2367 return TT_UnaryOperator;
2368 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
2369 return TT_TrailingUnaryOperator;
2371 return TT_UnaryOperator;
2374 SmallVector<Context, 8> Contexts;
2376 const FormatStyle &Style;
2377 AnnotatedLine &
Line;
2378 FormatToken *CurrentToken;
2380 const AdditionalKeywords &Keywords;
2394 class ExpressionParser {
2396 ExpressionParser(
const FormatStyle &Style,
const AdditionalKeywords &Keywords,
2397 AnnotatedLine &
Line)
2401 void parse(
int Precedence = 0) {
2404 while (Current && (Current->is(tok::kw_return) ||
2405 (Current->is(tok::colon) &&
2406 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) {
2410 if (!Current || Precedence > PrecedenceArrowAndPeriod)
2415 parseConditionalExpr();
2421 if (Precedence == PrecedenceUnaryOperator) {
2422 parseUnaryOperator();
2426 FormatToken *Start = Current;
2427 FormatToken *LatestOperator =
nullptr;
2428 unsigned OperatorIndex = 0;
2432 parse(Precedence + 1);
2434 int CurrentPrecedence = getCurrentPrecedence();
2436 if (Precedence == CurrentPrecedence && Current &&
2437 Current->is(TT_SelectorName)) {
2439 addFakeParenthesis(Start,
prec::Level(Precedence));
2446 (Current->closesScope() &&
2447 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
2448 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
2457 if (Current->opensScope() ||
2458 Current->isOneOf(TT_RequiresClause,
2459 TT_RequiresClauseInARequiresExpression)) {
2462 while (Current && (!Current->closesScope() || Current->opensScope())) {
2469 if (CurrentPrecedence == Precedence) {
2471 LatestOperator->NextOperator = Current;
2472 LatestOperator = Current;
2473 Current->OperatorIndex = OperatorIndex;
2476 next(Precedence > 0);
2480 if (LatestOperator && (Current || Precedence > 0)) {
2486 Start->Previous->isOneOf(TT_RequiresClause,
2487 TT_RequiresClauseInARequiresExpression))
2489 auto Ret = Current ? Current :
Line.Last;
2490 while (!
Ret->ClosesRequiresClause &&
Ret->Previous)
2496 if (Precedence == PrecedenceArrowAndPeriod) {
2508 int getCurrentPrecedence() {
2510 const FormatToken *NextNonComment = Current->getNextNonComment();
2511 if (Current->is(TT_ConditionalExpr))
2513 if (NextNonComment && Current->is(TT_SelectorName) &&
2514 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
2517 NextNonComment->is(tok::less)))) {
2520 if (Current->is(TT_JsComputedPropertyName))
2522 if (Current->is(TT_LambdaArrow))
2524 if (Current->is(TT_FatArrow))
2526 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
2527 (Current->is(tok::comment) && NextNonComment &&
2528 NextNonComment->is(TT_SelectorName))) {
2531 if (Current->is(TT_RangeBasedForLoopColon))
2534 Current->is(Keywords.kw_instanceof)) {
2537 if (Style.isJavaScript() &&
2538 Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {
2541 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
2542 return Current->getPrecedence();
2543 if (Current->isOneOf(tok::period, tok::arrow))
2544 return PrecedenceArrowAndPeriod;
2546 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
2547 Keywords.kw_throws)) {
2554 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence,
2555 FormatToken *
End =
nullptr) {
2556 Start->FakeLParens.push_back(Precedence);
2558 Start->StartsBinaryExpression =
true;
2559 if (!
End && Current)
2560 End = Current->getPreviousNonComment();
2564 End->EndsBinaryExpression =
true;
2570 void parseUnaryOperator() {
2572 while (Current && Current->is(TT_UnaryOperator)) {
2573 Tokens.push_back(Current);
2576 parse(PrecedenceArrowAndPeriod);
2577 for (FormatToken *Token : llvm::reverse(Tokens)) {
2583 void parseConditionalExpr() {
2584 while (Current && Current->isTrailingComment())
2586 FormatToken *Start = Current;
2588 if (!Current || !Current->is(tok::question))
2592 if (!Current || Current->isNot(TT_ConditionalExpr))
2599 void next(
bool SkipPastLeadingComments =
true) {
2601 Current = Current->Next;
2603 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
2604 Current->isTrailingComment()) {
2605 Current = Current->Next;
2609 const FormatStyle &Style;
2610 const AdditionalKeywords &Keywords;
2611 const AnnotatedLine &
Line;
2612 FormatToken *Current;
2621 assert(
Line->First);
2625 if (NextNonCommentLine &&
Line->isComment() &&
2628 Line->First->OriginalColumn) {
2637 : NextNonCommentLine->
Level;
2639 NextNonCommentLine =
Line->First->isNot(tok::r_brace) ?
Line :
nullptr;
2647 unsigned Result = 0;
2648 for (
const auto *Tok =
Line.
First; Tok !=
nullptr; Tok = Tok->
Next)
2649 Result =
std::max(Result, Tok->NestingLevel);
2654 for (
auto &Child :
Line.Children)
2657 AnnotatingParser
Parser(Style,
Line, Keywords);
2670 ExpressionParser ExprParser(Style, Keywords,
Line);
2673 if (
Line.startsWith(TT_ObjCMethodSpecifier))
2675 else if (
Line.startsWith(TT_ObjCDecl))
2677 else if (
Line.startsWith(TT_ObjCProperty))
2680 Line.First->SpacesRequiredBefore = 1;
2681 Line.First->CanBreakBefore =
Line.First->MustBreakBefore;
2689 for (; Next; Next = Next->Next) {
2690 if (Next->is(TT_OverloadedOperatorLParen))
2692 if (Next->is(TT_OverloadedOperator))
2694 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
2697 Next->Next->startsSequence(tok::l_square, tok::r_square)) {
2698 Next = Next->Next->Next;
2702 if (Next->startsSequence(tok::l_square, tok::r_square)) {
2707 if ((Next->isSimpleTypeSpecifier() || Next->is(tok::identifier)) &&
2708 Next->Next && Next->Next->isOneOf(tok::star, tok::amp, tok::ampamp)) {
2713 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
2714 Next = Next->MatchingParen;
2725 if (Current.
is(tok::kw_operator)) {
2728 Next = skipOperatorName(Next);
2732 for (; Next; Next = Next->Next) {
2733 if (Next->is(TT_TemplateOpener)) {
2734 Next = Next->MatchingParen;
2735 }
else if (Next->is(tok::coloncolon)) {
2739 if (Next->is(tok::kw_operator)) {
2740 Next = skipOperatorName(Next->Next);
2743 if (!Next->is(tok::identifier))
2745 }
else if (Next->is(tok::l_paren)) {
2754 if (!Next || !Next->is(tok::l_paren) || !Next->MatchingParen)
2759 if (Next->Next == Next->MatchingParen)
2762 if (Next->MatchingParen->Next &&
2763 Next->MatchingParen->Next->is(TT_PointerOrReference)) {
2777 if (IsCpp && Next->Next && Next->Next->is(tok::identifier) &&
2782 for (
const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
2784 if (Tok->is(TT_TypeDeclarationParen))
2786 if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
2787 Tok = Tok->MatchingParen;
2790 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
2791 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
2794 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2795 Tok->Tok.isLiteral()) {
2802 bool TokenAnnotator::mustBreakForReturnType(
const AnnotatedLine &
Line)
const {
2803 assert(
Line.MightBeFunctionDecl);
2806 Style.AlwaysBreakAfterReturnType ==
2812 switch (Style.AlwaysBreakAfterReturnType) {
2820 return Line.mightBeFunctionDefinition();
2830 Line.First->TotalLength =
2831 Line.First->IsMultiline ? Style.ColumnLimit
2832 :
Line.FirstStartColumn +
Line.First->ColumnWidth;
2834 bool InFunctionDecl =
Line.MightBeFunctionDecl;
2835 bool AlignArrayOfStructures =
2838 if (AlignArrayOfStructures)
2839 calculateArrayInitializerColumnList(
Line);
2843 Current->setType(TT_FunctionDeclarationName);
2845 if (Current->is(TT_LineComment)) {
2847 Current->SpacesRequiredBefore =
2848 (Style.Cpp11BracedListStyle && !Style.SpacesInParentheses) ? 0 : 1;
2850 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
2860 if (!Current->HasUnescapedNewline) {
2863 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
2866 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
2874 }
else if (Current->SpacesRequiredBefore == 0 &&
2875 spaceRequiredBefore(
Line, *Current)) {
2876 Current->SpacesRequiredBefore = 1;
2879 const auto &Children = Prev->
Children;
2880 if (!Children.empty() && Children.back()->Last->is(TT_LineComment)) {
2881 Current->MustBreakBefore =
true;
2883 Current->MustBreakBefore =
2884 Current->MustBreakBefore || mustBreakBefore(
Line, *Current);
2885 if (!Current->MustBreakBefore && InFunctionDecl &&
2886 Current->is(TT_FunctionDeclarationName)) {
2887 Current->MustBreakBefore = mustBreakForReturnType(
Line);
2891 Current->CanBreakBefore =
2892 Current->MustBreakBefore || canBreakBefore(
Line, *Current);
2893 unsigned ChildSize = 0;
2899 if (Current->MustBreakBefore || Prev->
Children.size() > 1 ||
2901 Prev->
Children[0]->First->MustBreakBefore) ||
2902 Current->IsMultiline) {
2903 Current->TotalLength = Prev->
TotalLength + Style.ColumnLimit;
2905 Current->TotalLength = Prev->
TotalLength + Current->ColumnWidth +
2906 ChildSize + Current->SpacesRequiredBefore;
2909 if (Current->is(TT_CtorInitializerColon))
2910 InFunctionDecl =
false;
2921 Current->SplitPenalty = splitPenalty(
Line, *Current, InFunctionDecl);
2923 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
2924 if (Current->ParameterIndex == 1)
2925 Current->SplitPenalty += 5 * Current->BindingStrength;
2927 Current->SplitPenalty += 20 * Current->BindingStrength;
2930 Current = Current->Next;
2933 calculateUnbreakableTailLengths(
Line);
2934 unsigned IndentLevel =
Line.Level;
2935 for (Current =
Line.First; Current !=
nullptr; Current = Current->Next) {
2937 Current->Role->precomputeFormattingInfos(Current);
2938 if (Current->MatchingParen &&
2939 Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&
2943 Current->IndentLevel = IndentLevel;
2944 if (Current->opensBlockOrBlockTypeList(Style))
2948 LLVM_DEBUG({ printDebugInfo(
Line); });
2951 void TokenAnnotator::calculateUnbreakableTailLengths(
2953 unsigned UnbreakableTailLength = 0;
2956 Current->UnbreakableTailLength = UnbreakableTailLength;
2957 if (Current->CanBreakBefore ||
2958 Current->isOneOf(tok::comment, tok::string_literal)) {
2959 UnbreakableTailLength = 0;
2961 UnbreakableTailLength +=
2962 Current->ColumnWidth + Current->SpacesRequiredBefore;
2964 Current = Current->Previous;
2968 void TokenAnnotator::calculateArrayInitializerColumnList(
2969 AnnotatedLine &
Line)
const {
2972 auto *CurrentToken =
Line.First;
2973 CurrentToken->ArrayInitializerLineStart =
true;
2975 while (CurrentToken !=
nullptr && CurrentToken !=
Line.Last) {
2976 if (CurrentToken->is(tok::l_brace)) {
2977 CurrentToken->IsArrayInitializer =
true;
2978 if (CurrentToken->Next !=
nullptr)
2979 CurrentToken->Next->MustBreakBefore =
true;
2981 calculateInitializerColumnList(
Line, CurrentToken->Next,
Depth + 1);
2983 CurrentToken = CurrentToken->Next;
2988 FormatToken *TokenAnnotator::calculateInitializerColumnList(
2989 AnnotatedLine &
Line, FormatToken *CurrentToken,
unsigned Depth)
const {
2990 while (CurrentToken !=
nullptr && CurrentToken !=
Line.Last) {
2991 if (CurrentToken->is(tok::l_brace))
2993 else if (CurrentToken->is(tok::r_brace))
2995 if (
Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {
2996 CurrentToken = CurrentToken->Next;
2997 if (CurrentToken ==
nullptr)
2999 CurrentToken->StartsColumn =
true;
3000 CurrentToken = CurrentToken->Previous;
3002 CurrentToken = CurrentToken->Next;
3004 return CurrentToken;
3007 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &
Line,
3008 const FormatToken &Tok,
3009 bool InFunctionDecl)
const {
3010 const FormatToken &Left = *Tok.Previous;
3011 const FormatToken &Right = Tok;
3013 if (Left.is(tok::semi))
3017 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
3019 if (Right.is(Keywords.kw_implements))
3021 if (Left.is(tok::comma) && Left.NestingLevel == 0)
3023 }
else if (Style.isJavaScript()) {
3024 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
3026 if (Left.is(TT_JsTypeColon))
3028 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith(
"${")) ||
3029 (Right.is(TT_TemplateString) && Right.TokenText.startswith(
"}"))) {
3033 if (Left.opensScope() && Right.closesScope())
3037 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
3039 if (Right.is(tok::l_square)) {
3042 if (Left.is(tok::r_square))
3045 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
3047 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
3048 TT_ArrayInitializerLSquare,
3049 TT_DesignatedInitializerLSquare, TT_AttributeSquare)) {
3054 if (Left.is(tok::coloncolon) ||
3058 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3059 Right.is(tok::kw_operator)) {
3060 if (
Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
3062 if (Left.is(TT_StartOfName))
3064 if (InFunctionDecl && Right.NestingLevel == 0)
3065 return Style.PenaltyReturnTypeOnItsOwnLine;
3068 if (Right.is(TT_PointerOrReference))
3070 if (Right.is(TT_LambdaArrow))
3072 if (Left.is(tok::equal) && Right.is(tok::l_brace))
3074 if (Left.is(TT_CastRParen))
3076 if (Left.isOneOf(tok::kw_class, tok::kw_struct))
3078 if (Left.is(tok::comment))
3081 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
3082 TT_CtorInitializerColon)) {
3086 if (Right.isMemberAccess()) {
3106 return !Right.NextOperator || !Right.NextOperator->Previous->closesScope()
3111 if (Right.is(TT_TrailingAnnotation) &&
3112 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
3115 if (
Line.startsWith(TT_ObjCMethodSpecifier))
3122 bool is_short_annotation = Right.TokenText.size() < 10;
3123 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
3127 if (
Line.startsWith(tok::kw_for) && Left.is(tok::equal))
3132 if (Right.is(TT_SelectorName))
3134 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
3135 return Line.MightBeFunctionDecl ? 50 : 500;
3141 Left.Previous->isOneOf(tok::identifier, tok::greater)) {
3145 if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)
3146 return Style.PenaltyBreakOpenParenthesis;
3147 if (Left.is(tok::l_paren) && InFunctionDecl &&
3151 if (Left.is(tok::l_paren) && Left.Previous &&
3152 (Left.Previous->is(tok::kw_for) || Left.Previous->isIf())) {
3155 if (Left.is(tok::equal) && InFunctionDecl)
3157 if (Right.is(tok::r_brace))
3159 if (Left.is(TT_TemplateOpener))
3161 if (Left.opensScope()) {
3166 (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {
3169 if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle)
3171 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
3174 if (Left.is(TT_JavaAnnotation))
3177 if (Left.is(TT_UnaryOperator))
3179 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
3180 Left.Previous->isLabelString() &&
3181 (Left.NextOperator || Left.OperatorIndex != 0)) {
3184 if (Right.is(tok::plus) && Left.isLabelString() &&
3185 (Right.NextOperator || Right.OperatorIndex != 0)) {
3188 if (Left.is(tok::comma))
3190 if (Right.is(tok::lessless) && Left.isLabelString() &&
3191 (Right.NextOperator || Right.OperatorIndex != 1)) {
3194 if (Right.is(tok::lessless)) {
3196 if (!Left.is(tok::r_paren) || Right.OperatorIndex > 0) {
3202 if (Left.ClosesTemplateDeclaration)
3203 return Style.PenaltyBreakTemplateDeclaration;
3204 if (Left.ClosesRequiresClause)
3206 if (Left.is(TT_ConditionalExpr))
3210 Level = Right.getPrecedence();
3212 return Style.PenaltyBreakAssignment;
3219 bool TokenAnnotator::spaceRequiredBeforeParens(
const FormatToken &Right)
const {
3222 if (Right.is(TT_OverloadedOperatorLParen) &&
3223 Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {
3226 if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
3227 Right.ParameterCount > 0) {
3233 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &
Line,
3234 const FormatToken &Left,
3235 const FormatToken &Right)
const {
3236 if (Left.is(tok::kw_return) &&
3237 !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
3240 if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon))
3245 Left.Tok.getObjCKeywordID() == tok::objc_property) {
3248 if (Right.is(tok::hashhash))
3249 return Left.is(tok::hash);
3250 if (Left.isOneOf(tok::hashhash, tok::hash))
3251 return Right.is(tok::hash);
3252 if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) ||
3253 (Left.is(tok::l_brace) && Left.isNot(
BK_Block) &&
3254 Right.is(tok::r_brace) && Right.isNot(
BK_Block))) {
3255 return Style.SpaceInEmptyParentheses;
3257 if (Style.SpacesInConditionalStatement) {
3258 const FormatToken *LeftParen =
nullptr;
3259 if (Left.is(tok::l_paren))
3261 else if (Right.is(tok::r_paren) && Right.MatchingParen)
3262 LeftParen = Right.MatchingParen;
3263 if (LeftParen && LeftParen->Previous &&
3264 isKeywordWithCondition(*LeftParen->Previous)) {
3270 if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
3274 if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && Left.Previous &&
3275 Left.Previous->is(tok::kw_operator)) {
3279 if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
3280 !Right.isOneOf(tok::semi, tok::r_paren)) {
3284 if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
3285 return (Right.is(TT_CastRParen) ||
3286 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
3287 ? Style.SpacesInCStyleCastParentheses
3288 : Style.SpacesInParentheses;
3290 if (Right.isOneOf(tok::semi, tok::comma))
3293 bool IsLightweightGeneric = Right.MatchingParen &&
3294 Right.MatchingParen->Next &&
3295 Right.MatchingParen->Next->is(tok::colon);
3296 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
3298 if (Right.is(tok::less) && Left.is(tok::kw_template))
3299 return Style.SpaceAfterTemplateKeyword;
3300 if (Left.isOneOf(tok::exclaim, tok::tilde))
3302 if (Left.is(tok::at) &&
3303 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
3304 tok::numeric_constant, tok::l_paren, tok::l_brace,
3305 tok::kw_true, tok::kw_false)) {
3308 if (Left.is(tok::colon))
3309 return !Left.is(TT_ObjCMethodExpr);
3310 if (Left.is(tok::coloncolon))
3312 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
3315 (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
3317 if (Left.is(tok::less) && Right.is(tok::greater))
3319 return !Style.Cpp11BracedListStyle;
3323 if (Right.is(tok::ellipsis)) {
3324 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
3325 Left.Previous->is(tok::kw_case));
3327 if (Left.is(tok::l_square) && Right.is(tok::amp))
3328 return Style.SpacesInSquareBrackets;
3329 if (Right.is(TT_PointerOrReference)) {
3330 if (Left.is(tok::r_paren) &&
Line.MightBeFunctionDecl) {
3331 if (!Left.MatchingParen)
3333 FormatToken *TokenBeforeMatchingParen =
3334 Left.MatchingParen->getPreviousNonComment();
3335 if (!TokenBeforeMatchingParen || !Left.is(TT_TypeDeclarationParen))
3343 (Left.is(TT_AttributeParen) ||
3344 Left.canBePointerOrReferenceQualifier())) {
3347 if (Left.Tok.isLiteral())
3350 if (Left.isTypeOrIdentifier() && Right.Next && Right.Next->Next &&
3351 Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
3352 return getTokenPointerOrReferenceAlignment(Right) !=
3355 return !Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
3356 (getTokenPointerOrReferenceAlignment(Right) !=
3358 (
Line.IsMultiVariableDeclStmt &&
3359 (Left.NestingLevel == 0 ||
3360 (Left.NestingLevel == 1 && startsWithInitStatement(
Line)))));
3362 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
3363 (!Left.is(TT_PointerOrReference) ||
3365 !
Line.IsMultiVariableDeclStmt))) {
3368 if (Left.is(TT_PointerOrReference)) {
3373 Right.canBePointerOrReferenceQualifier()) {
3377 if (Right.Tok.isLiteral())
3380 if (Right.is(TT_BlockComment))
3383 if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
3384 !Right.is(TT_StartOfName)) {
3388 if (Right.is(tok::l_brace) && Right.is(
BK_Block))
3391 if (Left.Previous && Left.Previous->isTypeOrIdentifier() && Right.Next &&
3392 Right.Next->is(TT_RangeBasedForLoopColon)) {
3393 return getTokenPointerOrReferenceAlignment(Left) !=
3396 if (Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
3408 if (
Line.IsMultiVariableDeclStmt &&
3409 (Left.NestingLevel ==
Line.First->NestingLevel ||
3410 ((Left.NestingLevel ==
Line.First->NestingLevel + 1) &&
3411 startsWithInitStatement(
Line)))) {
3414 return Left.Previous && !Left.Previous->isOneOf(
3415 tok::l_paren, tok::coloncolon, tok::l_square);
3418 if (Left.is(tok::ellipsis) && Left.Previous &&
3419 Left.Previous->isOneOf(tok::star, tok::amp, tok::ampamp)) {
3423 if (Right.is(tok::star) && Left.is(tok::l_paren))
3425 if (Left.is(tok::star) && Right.isOneOf(tok::star, tok::amp, tok::ampamp))
3427 if (Right.isOneOf(tok::star, tok::amp, tok::ampamp)) {
3428 const FormatToken *
Previous = &Left;
3438 if (
Previous->is(tok::coloncolon)) {
3457 if (
Previous->endsSequence(tok::kw_operator))
3461 (Style.SpaceAroundPointerQualifiers ==
3467 const auto SpaceRequiredForArrayInitializerLSquare =
3468 [](
const FormatToken &LSquareTok,
const FormatStyle &Style) {
3469 return Style.SpacesInContainerLiterals ||
3472 !Style.Cpp11BracedListStyle &&
3473 LSquareTok.endsSequence(tok::l_square, tok::colon,
3476 if (Left.is(tok::l_square)) {
3477 return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&
3478 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
3479 (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
3480 TT_LambdaLSquare) &&
3481 Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
3483 if (Right.is(tok::r_square)) {
3484 return Right.MatchingParen &&
3485 ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
3486 SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,
3488 (Style.SpacesInSquareBrackets &&
3489 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
3490 TT_StructuredBindingLSquare,
3491 TT_LambdaLSquare)) ||
3492 Right.MatchingParen->is(TT_AttributeParen));
3494 if (Right.is(tok::l_square) &&
3495 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
3496 TT_DesignatedInitializerLSquare,
3497 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
3498 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral) &&
3499 !(!Left.is(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
3500 Right.is(TT_ArraySubscriptLSquare))) {
3503 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
3504 return !Left.Children.empty();
3505 if ((Left.is(tok::l_brace) && Left.isNot(
BK_Block)) ||
3506 (Right.is(tok::r_brace) && Right.MatchingParen &&
3507 Right.MatchingParen->isNot(
BK_Block))) {
3508 return Style.Cpp11BracedListStyle ? Style.SpacesInParentheses :
true;
3510 if (Left.is(TT_BlockComment)) {
3512 return Style.isJavaScript() || !Left.TokenText.endswith(
"=*/");
3517 if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeSquare))
3520 if (Right.is(tok::l_paren)) {
3521 if (Left.is(TT_TemplateCloser) && Right.isNot(TT_FunctionTypeLParen))
3522 return spaceRequiredBeforeParens(Right);
3523 if (Left.isOneOf(TT_RequiresClause,
3524 TT_RequiresClauseInARequiresExpression)) {
3525 return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||
3526 spaceRequiredBeforeParens(Right);
3528 if (Left.is(TT_RequiresExpression)) {
3529 return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
3530 spaceRequiredBeforeParens(Right);
3532 if ((Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) ||
3533 (Left.is(tok::r_square) && Left.is(TT_AttributeSquare))) {
3536 if (Left.is(TT_ForEachMacro)) {
3537 return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
3538 spaceRequiredBeforeParens(Right);
3540 if (Left.is(TT_IfMacro)) {
3541 return Style.SpaceBeforeParensOptions.AfterIfMacros ||
3542 spaceRequiredBeforeParens(Right);
3546 if (Left.is(tok::semi))
3548 if (Left.isOneOf(
tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
3549 tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||
3551 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
3552 spaceRequiredBeforeParens(Right);
3557 if (Right.is(TT_OverloadedOperatorLParen))
3558 return spaceRequiredBeforeParens(Right);
3560 if (
Line.MightBeFunctionDecl && (Left.is(TT_FunctionDeclarationName))) {
3561 if (
Line.mightBeFunctionDefinition()) {
3562 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
3563 spaceRequiredBeforeParens(Right);
3565 return Style.SpaceBeforeParensOptions.AfterFunctionDeclarationName ||
3566 spaceRequiredBeforeParens(Right);
3571 Left.MatchingParen && Left.MatchingParen->is(TT_LambdaLSquare)) {
3572 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
3573 spaceRequiredBeforeParens(Right);
3575 if (!Left.Previous || Left.Previous->isNot(tok::period)) {
3576 if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
3577 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
3578 spaceRequiredBeforeParens(Right);
3580 if (Left.isOneOf(tok::kw_new, tok::kw_delete)) {
3581 return ((!
Line.MightBeFunctionDecl || !Left.Previous) &&
3583 spaceRequiredBeforeParens(Right);
3586 if (Left.is(tok::r_square) && Left.MatchingParen &&
3587 Left.MatchingParen->Previous &&
3588 Left.MatchingParen->Previous->is(tok::kw_delete)) {
3590 spaceRequiredBeforeParens(Right);
3595 (Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) {
3596 return spaceRequiredBeforeParens(Right);
3600 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
3602 if (Right.is(TT_UnaryOperator)) {
3603 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
3604 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
3606 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
3608 Left.isSimpleTypeSpecifier()) &&
3609 Right.is(tok::l_brace) && Right.getNextNonComment() &&
3613 if (Left.is(tok::period) || Right.is(tok::period))
3617 if (Right.is(tok::hash) && Left.is(tok::identifier) &&
3618 (Left.TokenText ==
"L" || Left.TokenText ==
"u" ||
3619 Left.TokenText ==
"U" || Left.TokenText ==
"u8" ||
3620 Left.TokenText ==
"LR" || Left.TokenText ==
"uR" ||
3621 Left.TokenText ==
"UR" || Left.TokenText ==
"u8R")) {
3624 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
3625 Left.MatchingParen->Previous &&
3626 (Left.MatchingParen->Previous->is(tok::period) ||
3627 Left.MatchingParen->Previous->is(tok::coloncolon))) {
3633 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
3635 if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at)) {
3639 if (Right.is(tok::r_brace) && Right.MatchingParen &&
3640 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {
3644 if (Right.getType() == TT_TrailingAnnotation &&
3645 Right.isOneOf(tok::amp, tok::ampamp) &&
3646 Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
3647 (!Right.Next || Right.Next->is(tok::semi))) {
3657 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &
Line,
3658 const FormatToken &Right)
const {
3659 const FormatToken &Left = *Right.Previous;
3664 return Right.hasWhitespaceBefore();
3666 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
3671 if (Left.is(tok::star) && Right.is(tok::comment))
3674 if (Style.isCpp()) {
3677 if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis))
3680 if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
3681 Right.is(TT_ModulePartitionColon)) {
3685 if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))
3688 if (Left.is(TT_ModulePartitionColon) &&
3689 Right.isOneOf(tok::identifier, tok::kw_private)) {
3692 if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&
3693 Line.First->is(Keywords.kw_import)) {
3697 if (Left.is(TT_AttributeParen) && Right.is(tok::coloncolon))
3700 if (Left.is(tok::kw_operator))
3701 return Right.is(tok::coloncolon);
3703 !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {
3706 if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&
3707 Right.is(TT_TemplateOpener)) {
3712 if (Right.is(tok::period) &&
3713 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
3714 Keywords.kw_repeated, Keywords.kw_extend)) {
3717 if (Right.is(tok::l_paren) &&
3718 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {
3721 if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
3724 if (Left.is(tok::slash) || Right.is(tok::slash))
3726 if (Left.MatchingParen &&
3727 Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
3728 Right.isOneOf(tok::l_brace, tok::less)) {
3729 return !Style.Cpp11BracedListStyle;
3732 if (Left.is(tok::percent))
3736 if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
3737 return Right.hasWhitespaceBefore();
3738 }
else if (Style.isJson()) {
3739 if (Right.is(tok::colon))
3741 }
else if (Style.isCSharp()) {
3747 if (Left.is(tok::kw_this) && Right.is(tok::l_square))
3751 if (Left.is(tok::kw_new) && Right.is(tok::l_paren))
3755 if (Right.is(tok::l_brace))
3759 if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace))
3762 if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace))
3766 if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow))
3770 if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon))
3774 if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName))
3778 if (Left.is(tok::l_square) || Right.is(tok::r_square))
3779 return Style.SpacesInSquareBrackets;
3782 if (Right.is(TT_CSharpNullable))
3786 if (Right.is(TT_NonNullAssertion))
3790 if (Left.is(tok::comma) && Right.is(tok::comma))
3794 if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren))
3798 if (Right.is(tok::l_paren)) {
3799 if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
3800 Keywords.kw_lock)) {
3801 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
3802 spaceRequiredBeforeParens(Right);
3808 if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
3809 tok::kw_virtual, tok::kw_extern, tok::kw_static,
3810 Keywords.kw_internal, Keywords.kw_abstract,
3811 Keywords.kw_sealed, Keywords.kw_override,
3812 Keywords.kw_async, Keywords.kw_unsafe) &&
3813 Right.is(tok::l_paren)) {
3816 }
else if (Style.isJavaScript()) {
3817 if (Left.is(TT_FatArrow))
3820 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
3821 Left.Previous->is(tok::kw_for)) {
3824 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
3825 Right.MatchingParen) {
3826 const FormatToken *Next = Right.MatchingParen->getNextNonComment();
3829 if (Next && Next->is(TT_FatArrow))
3832 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith(
"${")) ||
3833 (Right.is(TT_TemplateString) && Right.TokenText.startswith(
"}"))) {
3838 if (Keywords.IsJavaScriptIdentifier(Left,
3840 Right.is(TT_TemplateString)) {
3843 if (Right.is(tok::star) &&
3844 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {
3847 if (Right.isOneOf(tok::l_brace, tok::l_square) &&
3848 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
3849 Keywords.kw_extends, Keywords.kw_implements)) {
3852 if (Right.is(tok::l_paren)) {
3854 if (
Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())
3858 if (Left.Previous && Left.Previous->is(tok::period) &&
3859 Left.Tok.getIdentifierInfo()) {
3863 if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
3869 if (Left.endsSequence(tok::kw_const, Keywords.kw_as))
3871 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
3876 (Left.is(Keywords.kw_of) && Left.Previous &&
3877 (Left.Previous->is(tok::identifier) ||
3878 Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) &&
3879 (!Left.Previous || !Left.Previous->is(tok::period))) {
3882 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
3883 Left.Previous->is(tok::period) && Right.is(tok::l_paren)) {
3886 if (Left.is(Keywords.kw_as) &&
3887 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
3890 if (Left.is(tok::kw_default) && Left.Previous &&
3891 Left.Previous->is(tok::kw_export)) {
3894 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
3896 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
3898 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
3900 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
3901 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {
3904 if (Left.is(tok::ellipsis))
3906 if (Left.is(TT_TemplateCloser) &&
3907 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
3908 Keywords.kw_implements, Keywords.kw_extends)) {
3914 if (Right.is(TT_NonNullAssertion))
3916 if (Left.is(TT_NonNullAssertion) &&
3917 Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {
3921 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
3923 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) {
3924 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
3925 spaceRequiredBeforeParens(Right);
3927 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
3928 tok::kw_protected) ||
3929 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
3930 Keywords.kw_native)) &&
3931 Right.is(TT_TemplateOpener)) {
3935 if (Left.is(TT_ImplicitStringLiteral))
3936 return Right.hasWhitespaceBefore();
3938 if (Left.is(TT_ObjCMethodSpecifier))
3940 if (Left.is(tok::r_paren) && canBeObjCSelectorComponent(Right)) {
3948 (Right.is(tok::equal) || Left.is(tok::equal))) {
3952 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
3953 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
3956 if (Left.is(tok::comma) && !Right.is(TT_OverloadedOperatorLParen))
3958 if (Right.is(tok::comma))
3960 if (Right.is(TT_ObjCBlockLParen))
3962 if (Right.is(TT_CtorInitializerColon))
3963 return Style.SpaceBeforeCtorInitializerColon;
3964 if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
3966 if (Right.is(TT_RangeBasedForLoopColon) &&
3967 !Style.SpaceBeforeRangeBasedForLoopColon) {
3970 if (Left.is(TT_BitFieldColon)) {
3974 if (Right.is(tok::colon)) {
3975 if (
Line.First->isOneOf(tok::kw_default, tok::kw_case))
3976 return Style.SpaceBeforeCaseColon;
3977 const FormatToken *Next = Right.getNextNonComment();
3978 if (!Next || Next->is(tok::semi))
3980 if (Right.is(TT_ObjCMethodExpr))
3982 if (Left.is(tok::question))
3984 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
3986 if (Right.is(TT_DictLiteral))
3987 return Style.SpacesInContainerLiterals;
3988 if (Right.is(TT_AttributeColon))
3990 if (Right.is(TT_CSharpNamedArgumentColon))
3992 if (Right.is(TT_BitFieldColon)) {
3999 if ((Left.isOneOf(tok::minus, tok::minusminus) &&
4000 Right.isOneOf(tok::minus, tok::minusminus)) ||
4001 (Left.isOneOf(tok::plus, tok::plusplus) &&
4002 Right.isOneOf(tok::plus, tok::plusplus))) {
4005 if (Left.is(TT_UnaryOperator)) {
4006 if (!Right.is(tok::l_paren)) {
4010 if (Left.is(tok::exclaim) && Left.TokenText ==
"not")
4012 if (Left.is(tok::tilde) && Left.TokenText ==
"compl")
4016 if (Left.is(tok::amp) && Right.is(tok::r_square))
4017 return Style.SpacesInSquareBrackets;
4019 return (Style.SpaceAfterLogicalNot && Left.is(tok::exclaim)) ||
4020 Right.is(TT_BinaryOperator);
4025 if (Left.is(TT_CastRParen)) {
4026 return Style.SpaceAfterCStyleCast ||
4027 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
4030 auto ShouldAddSpacesInAngles = [
this, &Right]() {
4034 return Right.hasWhitespaceBefore();
4038 if (Left.is(tok::greater) && Right.is(tok::greater)) {
4041 return !Style.Cpp11BracedListStyle;
4043 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
4045 ShouldAddSpacesInAngles());
4047 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
4048 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
4049 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) {
4052 if (!Style.SpaceBeforeAssignmentOperators && Left.isNot(TT_TemplateCloser) &&
4057 (Left.is(tok::identifier) || Left.is(tok::kw_this))) {
4060 if (Right.is(tok::coloncolon) && Left.is(tok::identifier)) {
4064 return Right.hasWhitespaceBefore();
4066 if (Right.is(tok::coloncolon) &&
4067 !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) {
4069 return (Left.is(TT_TemplateOpener) &&
4071 ShouldAddSpacesInAngles())) ||
4072 !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
4073 tok::kw___super, TT_TemplateOpener,
4074 TT_TemplateCloser)) ||
4075 (Left.is(tok::l_paren) && Style.SpacesInParentheses);
4077 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
4078 return ShouldAddSpacesInAngles();
4080 if (Right.is(TT_StructuredBindingLSquare)) {
4081 return !Left.isOneOf(tok::amp, tok::ampamp) ||
4085 if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&
4086 Right.isOneOf(tok::amp, tok::ampamp)) {
4089 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
4090 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
4091 !Right.is(tok::r_paren))) {
4094 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
4095 Left.MatchingParen &&
4096 Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {
4099 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
4100 Line.startsWith(tok::hash)) {
4103 if (Right.is(TT_TrailingUnaryOperator))
4105 if (Left.is(TT_RegexLiteral))
4107 return spaceRequiredBetween(
Line, Left, Right);
4113 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
4130 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
4138 if (Next->is(tok::comment))
4139 Next = Next->getNextNonComment();
4143 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &
Line,
4144 const FormatToken &Right)
const {
4145 const FormatToken &Left = *Right.Previous;
4146 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
4149 if (Style.isCSharp()) {
4150 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&
4151 Style.BraceWrapping.AfterFunction) {
4154 if (Right.is(TT_CSharpNamedArgumentColon) ||
4155 Left.is(TT_CSharpNamedArgumentColon)) {
4158 if (Right.is(TT_CSharpGenericTypeConstraint))
4160 if (Right.Next && Right.Next->is(TT_FatArrow) &&
4161 (Right.is(tok::numeric_constant) ||
4162 (Right.is(tok::identifier) && Right.TokenText ==
"_"))) {
4167 if (Left.is(TT_AttributeSquare) && Left.is(tok::r_square) &&
4168 (Right.isAccessSpecifier(
false) ||
4169 Right.is(Keywords.kw_internal))) {
4173 if (Left.is(TT_AttributeSquare) && Right.is(TT_AttributeSquare) &&
4174 Left.is(tok::r_square) && Right.is(tok::l_square)) {
4178 }
else if (Style.isJavaScript()) {
4180 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous &&
4181 Left.Previous->is(tok::string_literal)) {
4184 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) &&
Line.Level == 0 &&
4185 Left.Previous && Left.Previous->is(tok::equal) &&
4186 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
4190 !
Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) {
4195 if (Left.is(tok::l_brace) &&
Line.Level == 0 &&
4196 (
Line.startsWith(tok::kw_enum) ||
4197 Line.startsWith(tok::kw_const, tok::kw_enum) ||
4198 Line.startsWith(tok::kw_export, tok::kw_enum) ||
4199 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {
4204 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && Left.Previous &&
4205 Left.Previous->is(TT_FatArrow)) {
4207 switch (Style.AllowShortLambdasOnASingleLine) {
4213 return !Left.Children.empty();
4217 return (Left.NestingLevel == 0 &&
Line.Level == 0) &&
4218 !Left.Children.empty();
4220 llvm_unreachable(
"Unknown FormatStyle::ShortLambdaStyle enum");
4223 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
4224 !Left.Children.empty()) {
4228 (Left.NestingLevel == 0 &&
Line.Level == 0 &&
4229 Style.AllowShortFunctionsOnASingleLine &
4233 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
4234 Right.Next->is(tok::string_literal)) {
4242 if (Left.isStringLiteral() && Right.isStringLiteral())
4247 if (Style.isJson()) {
4251 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))
4256 if (Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
4257 !Right.is(tok::r_square)) {
4263 if (Left.is(tok::comma))
4272 const FormatToken *BeforeClosingBrace =
nullptr;
4273 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
4274 (Style.isJavaScript() && Left.is(tok::l_paren))) &&
4275 Left.isNot(
BK_Block) && Left.MatchingParen) {
4276 BeforeClosingBrace = Left.MatchingParen->Previous;
4277 }
else if (Right.MatchingParen &&
4278 (Right.MatchingParen->isOneOf(tok::l_brace,
4279 TT_ArrayInitializerLSquare) ||
4280 (Style.isJavaScript() &&
4281 Right.MatchingParen->is(tok::l_paren)))) {
4282 BeforeClosingBrace = &Left;
4284 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
4285 BeforeClosingBrace->isTrailingComment())) {
4290 if (Right.is(tok::comment)) {
4291 return Left.isNot(
BK_BracedInit) && Left.isNot(TT_CtorInitializerColon) &&
4292 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
4294 if (Left.isTrailingComment())
4296 if (Left.IsUnterminatedLiteral)
4298 if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
4299 Right.Next->is(tok::string_literal)) {
4302 if (Right.is(TT_RequiresClause)) {
4303 switch (Style.RequiresClausePosition) {
4312 if (Left.ClosesTemplateDeclaration && Left.MatchingParen &&
4313 Left.MatchingParen->NestingLevel == 0) {
4317 if (Right.is(tok::kw_concept))
4321 if (Left.ClosesRequiresClause && Right.isNot(tok::semi)) {
4322 switch (Style.RequiresClausePosition) {
4332 (Left.is(TT_CtorInitializerComma) ||
4333 Right.is(TT_CtorInitializerColon))) {
4338 Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {
4344 Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {
4349 Right.is(TT_InheritanceComma)) {
4353 Left.is(TT_InheritanceComma)) {
4356 if (Right.is(tok::string_literal) && Right.TokenText.startswith(
"R\"")) {
4360 return Right.IsMultiline && Right.NewlinesBefore > 0;
4362 if ((Left.is(tok::l_brace) || (Left.is(tok::less) && Left.Previous &&
4363 Left.Previous->is(tok::equal))) &&
4369 if (Right.is(TT_InlineASMBrace))
4370 return Right.HasUnescapedNewline;
4376 FirstNonComment->isOneOf(Keywords.kw_internal, tok::kw_public,
4377 tok::kw_private, tok::kw_protected);
4379 if (Style.BraceWrapping.AfterEnum) {
4380 if (
Line.startsWith(tok::kw_enum) ||
4381 Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
4386 FirstNonComment->Next->is(tok::kw_enum)) {
4392 if (Style.BraceWrapping.AfterClass &&
4394 FirstNonComment->Next->is(Keywords.kw_interface)) ||
4395 Line.startsWith(Keywords.kw_interface))) {
4399 return (
Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
4400 (
Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
4403 if (Left.is(TT_ObjCBlockLBrace) &&
4409 if (Left.is(TT_AttributeParen) && Right.is(TT_ObjCDecl))
4412 if (Left.is(TT_LambdaLBrace)) {
4420 (!Left.Children.empty() &&
4426 if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace) &&
4427 Left.isOneOf(tok::star, tok::amp, tok::ampamp, TT_TemplateCloser)) {
4433 Left.is(TT_LeadingJavaAnnotation) &&
4434 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
4435 (
Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
4439 if (Right.is(TT_ProtoExtensionLSquare))
4471 Right.is(TT_SelectorName) && !Right.is(tok::r_square) && Right.Next) {
4474 if (Left.is(tok::at))
4480 FormatToken *LBrace = Right.Next;
4481 if (LBrace && LBrace->is(tok::colon)) {
4482 LBrace = LBrace->Next;
4483 if (LBrace && LBrace->is(tok::at)) {
4484 LBrace = LBrace->Next;
4486 LBrace = LBrace->Next;
4498 ((LBrace->is(tok::l_brace) &&
4499 (LBrace->is(TT_DictLiteral) ||
4500 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
4501 LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) {
4508 if (Left.ParameterCount == 0)
4523 if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
4532 Left.is(tok::l_paren) && Left.BlockParameterCount > 0 &&
4533 !Right.isOneOf(tok::l_paren, TT_LambdaLSquare)) {
4535 if (Left.BlockParameterCount > 1)
4541 auto Comma = Left.Role->lastComma();
4544 auto Next =
Comma->getNextNonComment();
4547 if (!Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret))
4554 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &
Line,
4555 const FormatToken &Right)
const {
4556 const FormatToken &Left = *Right.Previous;
4558 if (Style.isCSharp()) {
4559 if (Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
4560 Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {
4564 if (
Line.First->is(TT_CSharpGenericTypeConstraint))
4565 return Left.is(TT_CSharpGenericTypeConstraintComma);
4567 if (Right.is(TT_CSharpNullable))
4570 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
4571 Keywords.kw_implements)) {
4574 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
4575 Keywords.kw_implements)) {
4578 }
else if (Style.isJavaScript()) {
4579 const FormatToken *NonComment = Right.getPreviousNonComment();
4581 NonComment->isOneOf(
4582 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
4583 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
4584 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
4585 Keywords.kw_readonly, Keywords.kw_override, Keywords.kw_abstract,
4586 Keywords.kw_get, Keywords.kw_set, Keywords.kw_async,
4587 Keywords.kw_await)) {
4590 if (Right.NestingLevel == 0 &&
4591 (Left.Tok.getIdentifierInfo() ||
4592 Left.isOneOf(tok::r_square, tok::r_paren)) &&
4593 Right.isOneOf(tok::l_square, tok::l_paren)) {
4596 if (NonComment && NonComment->is(tok::identifier) &&
4597 NonComment->TokenText ==
"asserts") {
4600 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace))
4602 if (Left.is(TT_JsTypeColon))
4605 if (Left.is(tok::exclaim) && Right.is(tok::colon))
4610 if (Right.is(Keywords.kw_is)) {
4611 const FormatToken *Next = Right.getNextNonComment();
4619 if (!Next || !Next->is(tok::colon))
4622 if (Left.is(Keywords.kw_in))
4624 if (Right.is(Keywords.kw_in))
4626 if (Right.is(Keywords.kw_as))
4628 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
4634 if (Left.is(Keywords.kw_as))
4636 if (Left.is(TT_NonNullAssertion))
4638 if (Left.is(Keywords.kw_declare) &&
4639 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
4640 Keywords.kw_function, tok::kw_class, tok::kw_enum,
4641 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
4642 Keywords.kw_let, tok::kw_const)) {
4647 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
4648 Right.isOneOf(tok::identifier, tok::string_literal)) {
4651 if (Right.is(TT_TemplateString) && Right.closesScope())
4655 if (Left.is(tok::identifier) && Right.is(TT_TemplateString))
4657 if (Left.is(TT_TemplateString) && Left.opensScope())
4661 if (Left.is(tok::at))
4663 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
4665 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
4666 return !Right.is(tok::l_paren);
4667 if (Right.is(TT_PointerOrReference)) {
4668 return Line.IsMultiVariableDeclStmt ||
4669 (getTokenPointerOrReferenceAlignment(Right) ==
4671 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
4673 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
4674 Right.is(tok::kw_operator)) {
4677 if (Left.is(TT_PointerOrReference))
4679 if (Right.isTrailingComment()) {
4686 (Left.is(TT_CtorInitializerColon) &&
4689 if (Left.is(tok::question) && Right.is(tok::colon))
4691 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
4692 return Style.BreakBeforeTernaryOperators;
4693 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
4694 return !Style.BreakBeforeTernaryOperators;
4695 if (Left.is(TT_InheritanceColon))
4697 if (Right.is(TT_InheritanceColon))
4699 if (Right.is(TT_ObjCMethodExpr) && !Right.is(tok::r_square) &&
4700 Left.isNot(TT_SelectorName)) {
4704 if (Right.is(tok::colon) &&
4705 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) {
4708 if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
4711 if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
4737 if (((Right.is(tok::l_brace) || Right.is(tok::less)) &&
4738 Right.is(TT_DictLiteral)) ||
4739 Right.is(TT_ArrayInitializerLSquare)) {
4745 if (Right.is(tok::r_square) && Right.MatchingParen &&
4746 Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {
4749 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
4750 Right.Next->is(TT_ObjCMethodExpr))) {
4751 return Left.isNot(tok::period);
4755 if (Right.is(tok::kw_concept))
4757 if (Right.is(TT_RequiresClause))
4759 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen))
4761 if (Left.ClosesRequiresClause)
4763 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
4764 TT_OverloadedOperator)) {
4767 if (Left.is(TT_RangeBasedForLoopColon))
4769 if (Right.is(TT_RangeBasedForLoopColon))
4771 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
4773 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
4774 (Left.is(tok::less) && Right.is(tok::less))) {
4777 if (Right.is(TT_BinaryOperator) &&
4783 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
4784 Left.is(tok::kw_operator)) {
4787 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
4791 if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
4792 !Style.Cpp11BracedListStyle) {
4795 if (Left.is(tok::l_paren) &&
4796 Left.isOneOf(TT_AttributeParen, TT_TypeDeclarationParen)) {
4799 if (Left.is(tok::l_paren) && Left.Previous &&
4800 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {
4803 if (Right.is(TT_ImplicitStringLiteral))
4806 if (Right.is(TT_TemplateCloser))
4808 if (Right.is(tok::r_square) && Right.MatchingParen &&
4809 Right.MatchingParen->is(TT_LambdaLSquare)) {
4815 if (Right.is(tok::r_brace))
4816 return Right.MatchingParen && Right.MatchingParen->is(
BK_Block);
4819 if (Right.is(tok::r_paren)) {
4821 !Right.MatchingParen) {
4824 const FormatToken *
Previous = Right.MatchingParen->Previous;
4830 if (Left.is(TT_TrailingAnnotation)) {
4831 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
4832 tok::less, tok::coloncolon);
4835 if (Right.is(tok::kw___attribute) ||
4836 (Right.is(tok::l_square) && Right.is(TT_AttributeSquare))) {
4837 return !Left.is(TT_AttributeSquare);
4840 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
4843 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
4846 if (Left.is(TT_CtorInitializerColon))
4848 if (Right.is(TT_CtorInitializerColon))
4850 if (Left.is(TT_CtorInitializerComma) &&
4854 if (Right.is(TT_CtorInitializerComma) &&
4858 if (Left.is(TT_InheritanceComma) &&
4862 if (Right.is(TT_InheritanceComma) &&
4866 if (Left.is(TT_ArrayInitializerLSquare))
4868 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
4870 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
4871 !Left.isOneOf(tok::arrowstar, tok::lessless) &&
4877 if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
4878 (Left.is(tok::r_square) && Right.is(TT_AttributeSquare))) {
4882 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
4883 if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace)) {
4890 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
4891 tok::kw_class, tok::kw_struct, tok::comment) ||
4892 Right.isMemberAccess() ||
4893 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
4894 tok::colon, tok::l_square, tok::at) ||
4895 (Left.is(tok::r_paren) &&
4896 Right.isOneOf(tok::identifier, tok::kw_const)) ||
4897 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
4898 (Left.is(TT_TemplateOpener) && !Right.is(TT_TemplateCloser));
4901 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &
Line)
const {
4902 llvm::errs() <<
"AnnotatedTokens(L=" <<
Line.Level <<
"):\n";
4903 const FormatToken *Tok =
Line.First;
4905 llvm::errs() <<
" M=" << Tok->MustBreakBefore
4906 <<
" C=" << Tok->CanBreakBefore
4908 <<
" S=" << Tok->SpacesRequiredBefore
4909 <<
" F=" << Tok->Finalized <<
" B=" << Tok->BlockParameterCount
4910 <<
" BK=" << Tok->getBlockKind() <<
" P=" << Tok->SplitPenalty
4911 <<
" Name=" << Tok->Tok.getName() <<
" L=" << Tok->TotalLength
4912 <<
" PPK=" << Tok->getPackingKind() <<
" FakeLParens=";
4914 llvm::errs() << LParen <<
"/";
4915 llvm::errs() <<
" FakeRParens=" << Tok->FakeRParens;
4916 llvm::errs() <<
" II=" << Tok->Tok.getIdentifierInfo();
4917 llvm::errs() <<
" Text='" << Tok->TokenText <<
"'\n";
4919 assert(Tok ==
Line.Last);
4922 llvm::errs() <<
"----\n";
4926 TokenAnnotator::getTokenReferenceAlignment(
const FormatToken &Reference)
const {
4927 assert(
Reference.isOneOf(tok::amp, tok::ampamp));
4928 switch (Style.ReferenceAlignment) {
4930 return Style.PointerAlignment;
4939 return Style.PointerAlignment;
4943 TokenAnnotator::getTokenPointerOrReferenceAlignment(
4944 const FormatToken &PointerOrReference)
const {
4945 if (PointerOrReference.isOneOf(tok::amp, tok::ampamp)) {
4946 switch (Style.ReferenceAlignment) {
4948 return Style.PointerAlignment;
4957 assert(PointerOrReference.is(tok::star));
4958 return Style.PointerAlignment;