18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/Support/Debug.h"
21 #define DEBUG_TYPE "format-token-annotator"
33 class AnnotatingParser {
35 AnnotatingParser(
const FormatStyle &
Style, AnnotatedLine &
Line,
51 if (Previous.Previous) {
52 if (Previous.Previous->Tok.isLiteral())
54 if (Previous.Previous->is(tok::r_paren) &&
Contexts.size() > 1 &&
55 (!Previous.Previous->MatchingParen ||
56 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen)))
61 Left->ParentBracket =
Contexts.back().ContextKind;
62 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
66 bool InExprContext =
Contexts.back().IsExpression;
68 Contexts.back().IsExpression =
false;
72 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
91 if (
CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
92 (
CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
102 if (
CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
105 !Line.startsWith(tok::kw_template))
109 if (FormatToken *Previous =
CurrentToken->getPreviousNonComment()) {
112 Previous->isNot(tok::colon)))
113 Previous->Type = TT_SelectorName;
122 bool parseParens(
bool LookForDecls =
false) {
126 Left->ParentBracket =
Contexts.back().ContextKind;
127 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
130 Contexts.back().ColonIsForRangeExpr =
133 bool StartsObjCMethodExpr =
false;
136 Left->Type = TT_ObjCBlockLParen;
137 }
else if (FormatToken *MaybeSel = Left->Previous) {
139 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
140 MaybeSel->Previous->is(tok::at)) {
141 StartsObjCMethodExpr =
true;
145 if (Left->is(TT_OverloadedOperatorLParen)) {
146 Contexts.back().IsExpression =
false;
148 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
149 Line.startsWith(tok::kw_export, Keywords.kw_type,
153 Contexts.back().IsExpression =
false;
154 }
else if (Left->Previous &&
155 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
156 tok::kw_if, tok::kw_while, tok::l_paren,
158 Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) ||
159 Left->Previous->is(TT_BinaryOperator))) {
161 Contexts.back().IsExpression =
true;
163 (Left->Previous->is(Keywords.kw_function) ||
164 (Left->Previous->endsSequence(tok::identifier,
165 Keywords.kw_function)))) {
167 Contexts.back().IsExpression =
false;
169 Left->Previous->is(TT_JsTypeColon)) {
171 Contexts.back().IsExpression =
false;
172 }
else if (Left->Previous && Left->Previous->is(tok::r_square) &&
173 Left->Previous->MatchingParen &&
174 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) {
176 Contexts.back().IsExpression =
false;
177 }
else if (Line.InPPDirective &&
178 (!Left->Previous || !Left->Previous->is(tok::identifier))) {
179 Contexts.back().IsExpression =
true;
182 Contexts.back().IsExpression =
false;
183 }
else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
184 Left->Type = TT_AttributeParen;
185 }
else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
187 Contexts.back().IsForEachMacro =
true;
188 Contexts.back().IsExpression =
false;
189 }
else if (Left->Previous && Left->Previous->MatchingParen &&
190 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
191 Contexts.back().IsExpression =
false;
192 }
else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
194 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
195 Contexts.back().IsExpression = !IsForOrCatch;
198 if (StartsObjCMethodExpr) {
199 Contexts.back().ColonIsObjCMethodExpr =
true;
200 Left->Type = TT_ObjCMethodExpr;
204 bool ProbablyFunctionType =
CurrentToken->isOneOf(tok::star, tok::amp);
205 bool HasMultipleLines =
false;
206 bool HasMultipleParametersOnALine =
false;
207 bool MightBeObjCForRangeLoop =
208 Left->Previous && Left->Previous->is(tok::kw_for);
215 FormatToken *Prev =
CurrentToken->getPreviousNonComment();
217 FormatToken *PrevPrev = Prev->getPreviousNonComment();
219 if (PrevPrev && PrevPrev->is(tok::identifier) &&
220 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
221 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
222 Prev->Type = TT_BinaryOperator;
223 LookForDecls =
false;
228 if (
CurrentToken->Previous->is(TT_PointerOrReference) &&
231 ProbablyFunctionType =
true;
233 MightBeFunctionType =
false;
235 Contexts.back().IsExpression =
true;
237 if (MightBeFunctionType && ProbablyFunctionType &&
CurrentToken->Next &&
239 (
CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
240 Left->Type = TT_FunctionTypeLParen;
245 Left->Previous && Left->Previous->is(tok::l_paren)) {
249 for (FormatToken *Tok = Left; Tok !=
CurrentToken; Tok = Tok->Next) {
250 if (Tok->is(TT_BinaryOperator) &&
251 Tok->isOneOf(tok::star, tok::amp, tok::ampamp))
252 Tok->Type = TT_PointerOrReference;
256 if (StartsObjCMethodExpr) {
258 if (
Contexts.back().FirstObjCSelectorName) {
259 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
260 Contexts.back().LongestObjCSelectorName;
264 if (Left->is(TT_AttributeParen))
266 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
268 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
271 if (!HasMultipleLines)
273 else if (HasMultipleParametersOnALine)
285 Left->Type = TT_Unknown;
289 HasMultipleParametersOnALine =
true;
290 if ((
CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
293 Contexts.back().IsExpression =
false;
295 MightBeObjCForRangeLoop =
false;
296 if (MightBeObjCForRangeLoop &&
CurrentToken->is(Keywords.kw_in))
301 Contexts.back().CanBeExpression =
true;
306 updateParameterCount(Left, Tok);
308 HasMultipleLines =
true;
321 Left->ParentBracket =
Contexts.back().ContextKind;
322 FormatToken *Parent = Left->getPreviousNonComment();
327 bool CppArrayTemplates =
328 Style.isCpp() && Parent &&
329 Parent->is(TT_TemplateCloser) &&
331 Contexts.back().InTemplateArgument);
333 bool StartsObjCMethodExpr =
334 !CppArrayTemplates && Style.isCpp() &&
335 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
338 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
339 tok::kw_return, tok::kw_throw) ||
340 Parent->isUnaryOperator() ||
341 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
343 bool ColonFound =
false;
345 unsigned BindingIncrease = 1;
346 if (Left->is(TT_Unknown)) {
347 if (StartsObjCMethodExpr) {
348 Left->Type = TT_ObjCMethodExpr;
350 Contexts.back().ContextKind == tok::l_brace &&
351 Parent->isOneOf(tok::l_brace, tok::comma)) {
352 Left->Type = TT_JsComputedPropertyName;
353 }
else if (Style.isCpp() &&
Contexts.back().ContextKind == tok::l_brace &&
354 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
355 Left->Type = TT_DesignatedInitializerLSquare;
357 Parent->is(TT_TemplateCloser)) {
358 Left->Type = TT_ArraySubscriptLSquare;
360 (!CppArrayTemplates && Parent &&
361 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
362 tok::comma, tok::l_paren, tok::l_square,
363 tok::question, tok::colon, tok::kw_return,
366 Left->Type = TT_ArrayInitializerLSquare;
368 BindingIncrease = 10;
369 Left->Type = TT_ArraySubscriptLSquare;
373 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
374 Contexts.back().IsExpression =
true;
375 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
380 Left->is(TT_ObjCMethodExpr)) {
383 StartsObjCMethodExpr =
false;
384 Left->Type = TT_Unknown;
386 if (StartsObjCMethodExpr &&
CurrentToken->Previous != Left) {
391 if (Parent && Parent->is(TT_PointerOrReference))
392 Parent->Type = TT_BinaryOperator;
396 if (
Contexts.back().FirstObjCSelectorName) {
397 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
398 Contexts.back().LongestObjCSelectorName;
399 if (Left->BlockParameterCount > 1)
400 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
408 if (Left->isOneOf(TT_ArraySubscriptLSquare,
409 TT_DesignatedInitializerLSquare)) {
410 Left->Type = TT_ObjCMethodExpr;
411 StartsObjCMethodExpr =
true;
412 Contexts.back().ColonIsObjCMethodExpr =
true;
413 if (Parent && Parent->is(tok::r_paren))
414 Parent->Type = TT_CastRParen;
418 if (
CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
420 Left->Type = TT_ArrayInitializerLSquare;
424 updateParameterCount(Left, Tok);
432 Left->ParentBracket =
Contexts.back().ContextKind;
435 Left->Type = TT_ObjCBlockLBrace;
438 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
439 Contexts.back().ColonIsDictLiteral =
true;
441 Contexts.back().IsExpression =
true;
453 if (
CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
456 (!
Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
459 (Previous->Tok.getIdentifierInfo() ||
460 Previous->is(tok::string_literal)))
461 Previous->Type = TT_SelectorName;
464 Left->Type = TT_DictLiteral;
468 Left->Type = TT_DictLiteral;
476 void updateParameterCount(FormatToken *Left, FormatToken *
Current) {
477 if (Current->is(tok::l_brace) && Current->BlockKind ==
BK_Block)
478 ++Left->BlockParameterCount;
479 if (Current->is(tok::comma)) {
480 ++Left->ParameterCount;
482 Left->Role.reset(
new CommaSeparatedList(Style));
483 Left->Role->CommaFound(Current);
484 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
485 Left->ParameterCount = 1;
489 bool parseConditional() {
502 bool parseTemplateDeclaration() {
509 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
515 bool consumeToken() {
518 switch (Tok->Tok.getKind()) {
521 if (!Tok->Previous && Line.MustBeDeclaration)
522 Tok->Type = TT_ObjCMethodSpecifier;
529 if (
Contexts.back().ColonIsForRangeExpr ||
531 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
532 Contexts.back().ContextKind == tok::l_paren ||
533 Contexts.back().ContextKind == tok::l_square ||
535 Line.MustBeDeclaration)) {
536 Tok->Type = TT_JsTypeColon;
540 if (
Contexts.back().ColonIsDictLiteral ||
543 Tok->Type = TT_DictLiteral;
545 if (FormatToken *
Previous = Tok->getPreviousNonComment())
548 }
else if (
Contexts.back().ColonIsObjCMethodExpr ||
549 Line.startsWith(TT_ObjCMethodSpecifier)) {
550 Tok->Type = TT_ObjCMethodExpr;
551 const FormatToken *BeforePrevious = Tok->Previous->Previous;
552 if (!BeforePrevious ||
553 !(BeforePrevious->is(TT_CastRParen) ||
554 (BeforePrevious->is(TT_ObjCMethodExpr) &&
555 BeforePrevious->is(tok::colon))) ||
556 BeforePrevious->is(tok::r_square) ||
557 Contexts.back().LongestObjCSelectorName == 0) {
558 Tok->Previous->Type = TT_SelectorName;
559 if (Tok->Previous->ColumnWidth >
560 Contexts.back().LongestObjCSelectorName)
561 Contexts.back().LongestObjCSelectorName =
562 Tok->Previous->ColumnWidth;
563 if (!
Contexts.back().FirstObjCSelectorName)
564 Contexts.back().FirstObjCSelectorName = Tok->Previous;
566 }
else if (
Contexts.back().ColonIsForRangeExpr) {
567 Tok->Type = TT_RangeBasedForLoopColon;
569 Tok->Type = TT_BitFieldColon;
571 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
572 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren,
574 Tok->Type = TT_CtorInitializerColon;
576 Tok->Type = TT_InheritanceColon;
577 }
else if (Tok->Previous->is(tok::identifier) && Tok->Next &&
578 Tok->Next->isOneOf(tok::r_paren, tok::comma)) {
581 Tok->Type = TT_ObjCMethodExpr;
582 }
else if (
Contexts.back().ContextKind == tok::l_paren) {
583 Tok->Type = TT_InlineASMColon;
592 Tok->Type = TT_JsTypeOperator;
600 if (!parseParens(
true))
606 if (Tok->Previous && Tok->Previous->is(tok::period))
612 Contexts.back().ColonIsForRangeExpr =
true;
623 Tok->Previous->is(tok::r_paren) &&
624 Tok->Previous->MatchingParen &&
625 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
626 Tok->Previous->Type = TT_OverloadedOperator;
627 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
628 Tok->Type = TT_OverloadedOperatorLParen;
633 if (Line.MustBeDeclaration &&
Contexts.size() == 1 &&
634 !
Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
636 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
637 TT_LeadingJavaAnnotation)))
638 Line.MightBeFunctionDecl =
true;
646 FormatToken *
Previous =Tok->getPreviousNonComment();
647 if (Previous && Previous->Type != TT_DictLiteral)
648 Previous->Type = TT_SelectorName;
655 Tok->Type = TT_TemplateOpener;
657 FormatToken *
Previous = Tok->getPreviousNonComment();
658 if (Previous && Previous->Type != TT_DictLiteral)
659 Previous->Type = TT_SelectorName;
662 Tok->Type = TT_BinaryOperator;
677 Tok->Type = TT_BinaryOperator;
679 case tok::kw_operator:
681 !
CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
686 CurrentToken->Previous->isOneOf(TT_BinaryOperator, tok::comma))
697 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
703 Tok->Type = TT_JsTypeOptionalQuestion;
708 if (Line.MustBeDeclaration && !
Contexts.back().IsExpression &&
713 case tok::kw_template:
714 parseTemplateDeclaration();
717 if (
Contexts.back().InCtorInitializer)
718 Tok->Type = TT_CtorInitializerComma;
720 Tok->Type = TT_InheritanceComma;
722 (
Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
723 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
724 Line.IsMultiVariableDeclStmt =
true;
727 Contexts.back().IsExpression =
true;
729 case tok::identifier:
730 if (Tok->isOneOf(Keywords.kw___has_include,
731 Keywords.kw___has_include_next)) {
741 void parseIncludeDirective() {
755 void parseWarningOrError() {
769 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
774 if (IsMark ||
CurrentToken->Previous->is(TT_BinaryOperator))
781 void parseHasInclude() {
785 parseIncludeDirective();
789 LineType parsePreprocessorDirective() {
816 switch (
CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
817 case tok::pp_include:
818 case tok::pp_include_next:
821 parseIncludeDirective();
825 case tok::pp_warning:
826 parseWarningOrError();
833 Contexts.back().IsExpression =
true;
842 if (Tok->is(tok::l_paren))
844 else if (Tok->isOneOf(Keywords.kw___has_include,
845 Keywords.kw___has_include_next))
855 return parsePreprocessorDirective();
860 IdentifierInfo *Info =
CurrentToken->Tok.getIdentifierInfo();
863 (Info && Info->getPPKeywordID() == tok::pp_import &&
865 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
868 parseIncludeDirective();
874 if (
CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
875 parseIncludeDirective();
888 bool KeywordVirtualFound =
false;
889 bool ImportStatement =
false;
894 ImportStatement =
true;
898 KeywordVirtualFound =
true;
906 if (Line.First->is(tok::kw_export) &&
909 ImportStatement =
true;
911 ImportStatement =
true;
916 if (KeywordVirtualFound)
921 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
922 if (
Contexts.back().FirstObjCSelectorName)
923 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
924 Contexts.back().LongestObjCSelectorName;
932 bool isClosureImportStatement(
const FormatToken &Tok) {
935 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
936 Tok.Next->Next && (Tok.Next->Next->TokenText ==
"module" ||
937 Tok.Next->Next->TokenText ==
"provide" ||
938 Tok.Next->Next->TokenText ==
"require" ||
939 Tok.Next->Next->TokenText ==
"setTestOnly" ||
940 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
941 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
944 void resetTokenMetadata(FormatToken *
Token) {
950 if (!
CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
951 TT_FunctionLBrace, TT_ImplicitStringLiteral,
952 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
953 TT_OverloadedOperator, TT_RegexLiteral,
954 TT_TemplateString, TT_ObjCStringLiteral))
1001 struct ScopedContextCreator {
1002 AnnotatingParser &
P;
1007 P.Contexts.push_back(
Context(ContextKind,
1008 P.Contexts.back().BindingStrength + Increase,
1009 P.Contexts.back().IsExpression));
1012 ~ScopedContextCreator() {
P.Contexts.pop_back(); }
1015 void modifyContext(
const FormatToken &Current) {
1017 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1021 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1022 Line.startsWith(tok::kw_export, Keywords.kw_type,
1023 tok::identifier))) &&
1024 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1025 Contexts.back().IsExpression =
true;
1026 if (!Line.startsWith(TT_UnaryOperator)) {
1027 for (FormatToken *
Previous = Current.Previous;
1029 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1031 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
1038 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1039 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1041 Previous->Type = TT_PointerOrReference;
1044 }
else if (Current.is(tok::lessless) &&
1045 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1046 Contexts.back().IsExpression =
true;
1047 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1048 Contexts.back().IsExpression =
true;
1049 }
else if (Current.is(TT_TrailingReturnArrow)) {
1050 Contexts.back().IsExpression =
false;
1051 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1053 }
else if (Current.Previous &&
1054 Current.Previous->is(TT_CtorInitializerColon)) {
1055 Contexts.back().IsExpression =
true;
1056 Contexts.back().InCtorInitializer =
true;
1057 }
else if (Current.Previous &&
1058 Current.Previous->is(TT_InheritanceColon)) {
1059 Contexts.back().InInheritanceList =
true;
1060 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1061 for (FormatToken *
Previous = Current.Previous;
1064 Previous->Type = TT_PointerOrReference;
1065 if (Line.MustBeDeclaration && !
Contexts.front().InCtorInitializer)
1066 Contexts.back().IsExpression =
false;
1067 }
else if (Current.is(tok::kw_new)) {
1068 Contexts.back().CanBeExpression =
false;
1069 }
else if (Current.isOneOf(tok::semi, tok::exclaim)) {
1071 Contexts.back().IsExpression =
true;
1075 void determineTokenType(FormatToken &Current) {
1076 if (!Current.is(TT_Unknown))
1081 if (Current.is(tok::exclaim)) {
1082 if (Current.Previous &&
1083 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1084 tok::r_paren, tok::r_square,
1086 Current.Previous->Tok.isLiteral())) {
1087 Current.Type = TT_JsNonNullAssertion;
1091 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1092 Current.Type = TT_JsNonNullAssertion;
1101 if (Current.is(Keywords.kw_instanceof)) {
1102 Current.Type = TT_BinaryOperator;
1103 }
else if (isStartOfName(Current) &&
1104 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1106 Current.Type = TT_StartOfName;
1107 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1109 }
else if (Current.is(tok::arrow) &&
1111 Current.Type = TT_LambdaArrow;
1112 }
else if (Current.is(tok::arrow) &&
AutoFound && Line.MustBeDeclaration &&
1113 Current.NestingLevel == 0) {
1114 Current.Type = TT_TrailingReturnArrow;
1115 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1117 determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&
1119 Contexts.back().InTemplateArgument);
1120 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1121 Current.Type = determinePlusMinusCaretUsage(Current);
1122 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1124 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1125 Current.Type = determineIncrementUsage(Current);
1126 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1127 Current.Type = TT_UnaryOperator;
1128 }
else if (Current.is(tok::question)) {
1130 Line.MustBeDeclaration && !
Contexts.back().IsExpression) {
1133 Current.Type = TT_JsTypeOptionalQuestion;
1135 Current.Type = TT_ConditionalExpr;
1137 }
else if (Current.isBinaryOperator() &&
1138 (!Current.Previous || Current.Previous->isNot(tok::l_square))) {
1139 Current.Type = TT_BinaryOperator;
1140 }
else if (Current.is(tok::comment)) {
1141 if (Current.TokenText.startswith(
"/*")) {
1142 if (Current.TokenText.endswith(
"*/"))
1143 Current.Type = TT_BlockComment;
1147 Current.Tok.setKind(tok::unknown);
1149 Current.Type = TT_LineComment;
1151 }
else if (Current.is(tok::r_paren)) {
1152 if (rParenEndsCast(Current))
1153 Current.Type = TT_CastRParen;
1154 if (Current.MatchingParen && Current.Next &&
1155 !Current.Next->isBinaryOperator() &&
1156 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1157 tok::comma, tok::period, tok::arrow,
1159 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1161 if (AfterParen->Tok.isNot(tok::caret)) {
1162 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1163 if (BeforeParen->is(tok::identifier) &&
1164 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1165 (!BeforeParen->Previous ||
1166 BeforeParen->Previous->ClosesTemplateDeclaration))
1167 Current.Type = TT_FunctionAnnotationRParen;
1170 }
else if (Current.is(tok::at) && Current.Next &&
1175 switch (Current.Next->Tok.getObjCKeywordID()) {
1176 case tok::objc_interface:
1177 case tok::objc_implementation:
1178 case tok::objc_protocol:
1179 Current.Type = TT_ObjCDecl;
1181 case tok::objc_property:
1182 Current.Type = TT_ObjCProperty;
1187 }
else if (Current.is(tok::period)) {
1188 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1189 if (PreviousNoComment &&
1190 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1191 Current.Type = TT_DesignatedInitializerPeriod;
1193 Current.Previous->isOneOf(TT_JavaAnnotation,
1194 TT_LeadingJavaAnnotation)) {
1195 Current.Type = Current.Previous->Type;
1197 }
else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
1199 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1200 Line.MightBeFunctionDecl &&
Contexts.size() == 1) {
1203 Current.Type = TT_TrailingAnnotation;
1207 if (Current.Previous->is(tok::at) &&
1208 Current.isNot(Keywords.kw_interface)) {
1209 const FormatToken &AtToken = *Current.Previous;
1210 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1211 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1212 Current.Type = TT_LeadingJavaAnnotation;
1214 Current.Type = TT_JavaAnnotation;
1215 }
else if (Current.Previous->is(tok::period) &&
1216 Current.Previous->isOneOf(TT_JavaAnnotation,
1217 TT_LeadingJavaAnnotation)) {
1218 Current.Type = Current.Previous->Type;
1228 bool isStartOfName(
const FormatToken &Tok) {
1229 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1232 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1236 Tok.Previous->is(Keywords.kw_in))
1240 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1241 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1242 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1244 if (!PreviousNotConst)
1247 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1248 PreviousNotConst->Previous &&
1249 PreviousNotConst->Previous->is(tok::hash);
1251 if (PreviousNotConst->is(TT_TemplateCloser))
1252 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1253 PreviousNotConst->MatchingParen->Previous &&
1254 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1255 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1257 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1258 PreviousNotConst->MatchingParen->Previous &&
1259 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1262 return (!IsPPKeyword &&
1263 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1264 PreviousNotConst->is(TT_PointerOrReference) ||
1265 PreviousNotConst->isSimpleTypeSpecifier();
1269 bool rParenEndsCast(
const FormatToken &Tok) {
1275 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1278 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1282 if (LeftOfParens->is(tok::r_paren)) {
1283 if (!LeftOfParens->MatchingParen ||
1284 !LeftOfParens->MatchingParen->Previous)
1286 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1291 if (LeftOfParens->Tok.getIdentifierInfo() &&
1292 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1298 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1299 TT_TemplateCloser, tok::ellipsis))
1303 if (Tok.Next->is(tok::question))
1312 if (Tok.Next->isNot(tok::string_literal) &&
1313 (Tok.Next->Tok.isLiteral() ||
1314 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1318 bool ParensAreType =
1320 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1321 Tok.Previous->isSimpleTypeSpecifier();
1322 bool ParensCouldEndDecl =
1323 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1324 if (ParensAreType && !ParensCouldEndDecl)
1335 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1336 Token = Token->Next)
1337 if (Token->is(TT_BinaryOperator))
1342 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1345 if (!Tok.Next->Next)
1352 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1353 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1354 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1357 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1358 Prev = Prev->Previous) {
1359 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1369 return TT_BinaryOperator;
1371 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1373 return TT_UnaryOperator;
1375 const FormatToken *NextToken = Tok.getNextNonComment();
1377 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) ||
1378 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1379 return TT_PointerOrReference;
1381 if (PrevToken->is(tok::coloncolon))
1382 return TT_PointerOrReference;
1384 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1385 tok::comma, tok::semi, tok::kw_return, tok::colon,
1386 tok::equal, tok::kw_delete, tok::kw_sizeof,
1388 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1389 TT_UnaryOperator, TT_CastRParen))
1390 return TT_UnaryOperator;
1392 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1393 return TT_PointerOrReference;
1395 return TT_PointerOrReference;
1396 if (NextToken->isOneOf(tok::comma, tok::semi))
1397 return TT_PointerOrReference;
1399 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen &&
1400 PrevToken->MatchingParen->Previous &&
1401 PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof,
1403 return TT_PointerOrReference;
1405 if (PrevToken->Tok.isLiteral() ||
1406 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1407 tok::kw_false, tok::r_brace) ||
1408 NextToken->Tok.isLiteral() ||
1409 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1410 NextToken->isUnaryOperator() ||
1414 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1415 return TT_BinaryOperator;
1418 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1419 return TT_BinaryOperator;
1423 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1424 if (NextNextToken && NextNextToken->is(tok::arrow))
1425 return TT_BinaryOperator;
1429 if (IsExpression && !
Contexts.back().CaretFound)
1430 return TT_BinaryOperator;
1432 return TT_PointerOrReference;
1435 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1436 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1438 return TT_UnaryOperator;
1440 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator) &&
1441 !PrevToken->is(tok::exclaim))
1444 return TT_UnaryOperator;
1447 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1448 tok::question, tok::colon, tok::kw_return,
1449 tok::kw_case, tok::at, tok::l_brace))
1450 return TT_UnaryOperator;
1453 if (PrevToken->is(TT_BinaryOperator))
1454 return TT_UnaryOperator;
1457 return TT_BinaryOperator;
1461 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1462 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1463 if (!PrevToken || PrevToken->is(TT_CastRParen))
1464 return TT_UnaryOperator;
1465 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1466 return TT_TrailingUnaryOperator;
1468 return TT_UnaryOperator;
1491 class ExpressionParser {
1493 ExpressionParser(
const FormatStyle &Style,
const AdditionalKeywords &Keywords,
1494 AnnotatedLine &Line)
1498 void parse(
int Precedence = 0) {
1501 while (Current && (Current->is(tok::kw_return) ||
1502 (Current->is(tok::colon) &&
1503 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1506 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1511 parseConditionalExpr();
1517 if (Precedence == PrecedenceUnaryOperator) {
1518 parseUnaryOperator();
1523 FormatToken *LatestOperator =
nullptr;
1524 unsigned OperatorIndex = 0;
1528 parse(Precedence + 1);
1530 int CurrentPrecedence = getCurrentPrecedence();
1532 if (Current && Current->is(TT_SelectorName) &&
1533 Precedence == CurrentPrecedence) {
1535 addFakeParenthesis(Start,
prec::Level(Precedence));
1542 (Current->closesScope() &&
1543 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1544 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1551 if (Current->opensScope()) {
1554 while (Current && (!Current->closesScope() || Current->opensScope())) {
1561 if (CurrentPrecedence == Precedence) {
1563 LatestOperator->NextOperator =
Current;
1565 Current->OperatorIndex = OperatorIndex;
1568 next(Precedence > 0);
1572 if (LatestOperator && (Current || Precedence > 0)) {
1574 if (Precedence == PrecedenceArrowAndPeriod) {
1578 addFakeParenthesis(Start,
prec::Level(Precedence));
1586 int getCurrentPrecedence() {
1588 const FormatToken *NextNonComment = Current->getNextNonComment();
1589 if (Current->is(TT_ConditionalExpr))
1591 if (NextNonComment && Current->is(TT_SelectorName) &&
1592 (NextNonComment->is(TT_DictLiteral) ||
1595 NextNonComment->is(tok::less))))
1597 if (Current->is(TT_JsComputedPropertyName))
1599 if (Current->is(TT_LambdaArrow))
1601 if (Current->is(TT_JsFatArrow))
1603 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1604 (Current->is(tok::comment) && NextNonComment &&
1605 NextNonComment->is(TT_SelectorName)))
1607 if (Current->is(TT_RangeBasedForLoopColon))
1611 Current->is(Keywords.kw_instanceof))
1614 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
1616 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1617 return Current->getPrecedence();
1618 if (Current->isOneOf(tok::period, tok::arrow))
1619 return PrecedenceArrowAndPeriod;
1622 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1623 Keywords.kw_throws))
1629 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
1630 Start->FakeLParens.push_back(Precedence);
1632 Start->StartsBinaryExpression =
true;
1634 FormatToken *Previous = Current->Previous;
1635 while (Previous->is(tok::comment) && Previous->Previous)
1636 Previous = Previous->Previous;
1637 ++Previous->FakeRParens;
1639 Previous->EndsBinaryExpression =
true;
1645 void parseUnaryOperator() {
1646 if (!Current || Current->isNot(TT_UnaryOperator)) {
1647 parse(PrecedenceArrowAndPeriod);
1653 parseUnaryOperator();
1659 void parseConditionalExpr() {
1660 while (Current && Current->isTrailingComment()) {
1665 if (!Current || !Current->is(tok::question))
1669 if (!Current || Current->isNot(TT_ConditionalExpr))
1676 void next(
bool SkipPastLeadingComments =
true) {
1678 Current = Current->Next;
1680 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1681 Current->isTrailingComment())
1682 Current = Current->Next;
1685 const FormatStyle &
Style;
1686 const AdditionalKeywords &
Keywords;
1698 bool CommentLine =
true;
1700 if (!Tok->is(tok::comment)) {
1701 CommentLine =
false;
1706 if (NextNonCommentLine && CommentLine) {
1709 bool AlignedWithNextLine =
1712 (*I)->First->OriginalColumn;
1713 if (AlignedWithNextLine)
1714 (*I)->Level = NextNonCommentLine->
Level;
1716 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
1725 for (
const auto* Tok = Line.
First; Tok !=
nullptr; Tok = Tok->
Next)
1726 Result =
std::max(Result, Tok->NestingLevel);
1736 AnnotatingParser
Parser(Style, Line, Keywords);
1737 Line.
Type = Parser.parseLine();
1749 ExpressionParser ExprParser(Style, Keywords, Line);
1769 if (
Next->is(TT_OverloadedOperatorLParen))
1771 if (
Next->is(TT_OverloadedOperator))
1773 if (
Next->isOneOf(tok::kw_new, tok::kw_delete)) {
1775 if (
Next->Next &&
Next->Next->is(tok::l_square) &&
1776 Next->Next->Next &&
Next->Next->Next->is(tok::r_square))
1788 if (Current.
is(tok::kw_operator)) {
1791 Next = skipOperatorName(Next);
1796 if (Next->
is(TT_TemplateOpener)) {
1798 }
else if (Next->
is(tok::coloncolon)) {
1802 if (Next->
is(tok::kw_operator)) {
1803 Next = skipOperatorName(Next->
Next);
1806 if (!Next->
is(tok::identifier))
1808 }
else if (Next->
is(tok::l_paren)) {
1820 if (Line.
Last->
is(tok::l_brace))
1830 if (Tok->is(tok::l_paren) && Tok->MatchingParen) {
1831 Tok = Tok->MatchingParen;
1834 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
1835 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
1837 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
1838 Tok->Tok.isLiteral())
1844 bool TokenAnnotator::mustBreakForReturnType(
const AnnotatedLine &Line)
const {
1845 assert(Line.MightBeFunctionDecl);
1848 Style.AlwaysBreakAfterReturnType ==
1853 switch (Style.AlwaysBreakAfterReturnType) {
1861 return Line.mightBeFunctionDefinition();
1880 Current->
Type = TT_FunctionDeclarationName;
1881 if (Current->
is(TT_LineComment)) {
1898 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
1901 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
1909 spaceRequiredBefore(Line, *Current)) {
1917 Current->
is(TT_FunctionDeclarationName))
1922 unsigned ChildSize = 0;
1931 Prev->
Children[0]->First->MustBreakBefore) ||
1938 if (Current->
is(TT_CtorInitializerColon))
1939 InFunctionDecl =
false;
1945 splitPenalty(Line, *Current, InFunctionDecl);
1947 Current = Current->
Next;
1950 calculateUnbreakableTailLengths(Line);
1951 unsigned IndentLevel = Line.
Level;
1952 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
1954 Current->
Role->precomputeFormattingInfos(Current);
1957 assert(IndentLevel > 0);
1965 DEBUG({ printDebugInfo(Line); });
1968 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
1969 unsigned UnbreakableTailLength = 0;
1974 Current->
isOneOf(tok::comment, tok::string_literal)) {
1975 UnbreakableTailLength = 0;
1977 UnbreakableTailLength +=
1984 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
1985 const FormatToken &Tok,
1986 bool InFunctionDecl) {
1987 const FormatToken &Left = *Tok.
Previous;
1988 const FormatToken &Right = Tok;
1990 if (Left.is(tok::semi))
1994 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
1996 if (Right.is(Keywords.kw_implements))
1998 if (Left.is(tok::comma) && Left.NestingLevel == 0)
2001 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
2003 if (Left.is(TT_JsTypeColon))
2005 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith(
"${")) ||
2006 (Right.is(TT_TemplateString) && Right.TokenText.startswith(
"}")))
2010 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
2012 if (Right.is(tok::l_square)) {
2015 if (Left.is(tok::r_square))
2018 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
2020 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2021 TT_ArrayInitializerLSquare,
2022 TT_DesignatedInitializerLSquare))
2026 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2027 Right.is(tok::kw_operator)) {
2028 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
2030 if (Left.is(TT_StartOfName))
2032 if (InFunctionDecl && Right.NestingLevel == 0)
2033 return Style.PenaltyReturnTypeOnItsOwnLine;
2036 if (Right.is(TT_PointerOrReference))
2038 if (Right.is(TT_LambdaArrow))
2040 if (Left.is(tok::equal) && Right.is(tok::l_brace))
2042 if (Left.is(TT_CastRParen))
2044 if (Left.is(tok::coloncolon) ||
2047 if (Left.isOneOf(tok::kw_class, tok::kw_struct))
2049 if (Left.is(tok::comment))
2052 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon, TT_CtorInitializerColon))
2055 if (Right.isMemberAccess()) {
2080 if (Right.is(TT_TrailingAnnotation) &&
2081 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
2084 if (Line.startsWith(TT_ObjCMethodSpecifier))
2091 bool is_short_annotation = Right.TokenText.size() < 10;
2092 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2096 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
2101 if (Right.is(TT_SelectorName))
2103 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
2104 return Line.MightBeFunctionDecl ? 50 : 500;
2106 if (Left.is(tok::l_paren) && InFunctionDecl &&
2109 if (Left.is(tok::l_paren) && Left.Previous &&
2110 (Left.Previous->isOneOf(tok::kw_if, tok::kw_for)
2111 || Left.Previous->endsSequence(tok::kw_constexpr, tok::kw_if)))
2113 if (Left.is(tok::equal) && InFunctionDecl)
2115 if (Right.is(tok::r_brace))
2117 if (Left.is(TT_TemplateOpener))
2119 if (Left.opensScope()) {
2122 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
2125 if (Left.is(TT_JavaAnnotation))
2128 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
2129 Left.Previous->isLabelString() &&
2130 (Left.NextOperator || Left.OperatorIndex != 0))
2132 if (Right.is(tok::plus) && Left.isLabelString() &&
2133 (Right.NextOperator || Right.OperatorIndex != 0))
2135 if (Left.is(tok::comma))
2137 if (Right.is(tok::lessless) && Left.isLabelString() &&
2138 (Right.NextOperator || Right.OperatorIndex != 1))
2140 if (Right.is(tok::lessless)) {
2142 if (!Left.is(tok::r_paren) || Right.OperatorIndex > 0)
2147 if (Left.is(TT_ConditionalExpr))
2151 Level = Right.getPrecedence();
2153 return Style.PenaltyBreakAssignment;
2160 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
2161 const FormatToken &Left,
2162 const FormatToken &Right) {
2163 if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
2166 Left.Tok.getObjCKeywordID() == tok::objc_property)
2168 if (Right.is(tok::hashhash))
2169 return Left.is(tok::hash);
2170 if (Left.isOneOf(tok::hashhash, tok::hash))
2171 return Right.is(tok::hash);
2172 if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
2173 return Style.SpaceInEmptyParentheses;
2174 if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
2175 return (Right.is(TT_CastRParen) ||
2176 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
2177 ? Style.SpacesInCStyleCastParentheses
2178 : Style.SpacesInParentheses;
2179 if (Right.isOneOf(tok::semi, tok::comma))
2181 if (Right.is(tok::less) &&
2182 Line.Type ==
LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList)
2184 if (Right.is(tok::less) && Left.is(tok::kw_template))
2185 return Style.SpaceAfterTemplateKeyword;
2186 if (Left.isOneOf(tok::exclaim, tok::tilde))
2188 if (Left.is(tok::at) &&
2189 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2190 tok::numeric_constant, tok::l_paren, tok::l_brace,
2191 tok::kw_true, tok::kw_false))
2193 if (Left.is(tok::colon))
2194 return !Left.is(TT_ObjCMethodExpr);
2195 if (Left.is(tok::coloncolon))
2197 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
2199 if (Right.is(tok::ellipsis))
2200 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
2201 Left.Previous->is(tok::kw_case));
2202 if (Left.is(tok::l_square) && Right.is(tok::amp))
2204 if (Right.is(TT_PointerOrReference))
2205 return (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) ||
2206 (Left.Tok.isLiteral() || (Left.is(tok::kw_const) && Left.Previous &&
2207 Left.Previous->is(tok::r_paren)) ||
2208 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
2210 (Line.IsMultiVariableDeclStmt &&
2211 (Left.NestingLevel == 0 ||
2212 (Left.NestingLevel == 1 && Line.First->is(tok::kw_for)))))));
2213 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
2214 (!Left.is(TT_PointerOrReference) ||
2216 !Line.IsMultiVariableDeclStmt)))
2218 if (Left.is(TT_PointerOrReference))
2219 return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
2220 (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2221 !Right.is(TT_StartOfName)) ||
2222 (Right.is(tok::l_brace) && Right.BlockKind ==
BK_Block) ||
2223 (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2226 !Line.IsMultiVariableDeclStmt) &&
2228 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
2229 if (Right.is(tok::star) && Left.is(tok::l_paren))
2231 if (Left.is(tok::l_square))
2232 return (Left.is(TT_ArrayInitializerLSquare) &&
2233 Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) ||
2234 (Left.is(TT_ArraySubscriptLSquare) && Style.SpacesInSquareBrackets &&
2235 Right.isNot(tok::r_square));
2236 if (Right.is(tok::r_square))
2237 return Right.MatchingParen &&
2238 ((Style.SpacesInContainerLiterals &&
2239 Right.MatchingParen->is(TT_ArrayInitializerLSquare)) ||
2240 (Style.SpacesInSquareBrackets &&
2241 Right.MatchingParen->is(TT_ArraySubscriptLSquare)));
2242 if (Right.is(tok::l_square) &&
2243 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2244 TT_DesignatedInitializerLSquare) &&
2245 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral))
2247 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
2248 return !Left.Children.empty();
2249 if ((Left.is(tok::l_brace) && Left.BlockKind !=
BK_Block) ||
2250 (Right.is(tok::r_brace) && Right.MatchingParen &&
2251 Right.MatchingParen->BlockKind !=
BK_Block))
2252 return !Style.Cpp11BracedListStyle;
2253 if (Left.is(TT_BlockComment))
2254 return !Left.TokenText.endswith(
"=*/");
2255 if (Right.is(tok::l_paren)) {
2256 if (Left.is(tok::r_paren) && Left.is(TT_AttributeParen))
2258 return Line.Type ==
LT_ObjCDecl || Left.is(tok::semi) ||
2260 (Left.isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
2261 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2263 Left.endsSequence(tok::kw_constexpr, tok::kw_if) ||
2264 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2265 tok::kw_new, tok::kw_delete) &&
2266 (!Left.Previous || Left.Previous->isNot(tok::period))))) ||
2268 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() ||
2269 Left.is(tok::r_paren)) &&
2272 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
2274 if (Right.is(TT_UnaryOperator))
2275 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2276 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
2277 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
2279 Left.isSimpleTypeSpecifier()) &&
2280 Right.is(tok::l_brace) && Right.getNextNonComment() &&
2283 if (Left.is(tok::period) || Right.is(tok::period))
2285 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText ==
"L")
2287 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
2288 Left.MatchingParen->Previous &&
2289 Left.MatchingParen->Previous->is(tok::period))
2292 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
2297 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2298 const FormatToken &Right) {
2299 const FormatToken &Left = *Right.Previous;
2300 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
2302 if (Style.isCpp()) {
2303 if (Left.is(tok::kw_operator))
2304 return Right.is(tok::coloncolon);
2307 if (Right.is(tok::period) &&
2308 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
2309 Keywords.kw_repeated, Keywords.kw_extend))
2311 if (Right.is(tok::l_paren) &&
2312 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
2314 if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
2317 if (Left.is(TT_JsFatArrow))
2320 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) &&
2321 Left.Previous && Left.Previous->is(tok::kw_for))
2323 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
2324 Right.MatchingParen) {
2325 const FormatToken *
Next = Right.MatchingParen->getNextNonComment();
2328 if (Next && Next->is(TT_JsFatArrow))
2331 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith(
"${")) ||
2332 (Right.is(TT_TemplateString) && Right.TokenText.startswith(
"}")))
2337 if (Left.is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2338 Right.is(TT_TemplateString))
2340 if (Right.is(tok::star) &&
2341 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield))
2343 if (Right.isOneOf(tok::l_brace, tok::l_square) &&
2344 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield))
2347 if (Right.is(tok::l_paren) && Line.MustBeDeclaration &&
2348 Left.Tok.getIdentifierInfo())
2350 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2354 (Left.is(Keywords.kw_of) && Left.Previous &&
2355 Left.Previous->Tok.getIdentifierInfo())) &&
2356 (!Left.Previous || !Left.Previous->is(tok::period)))
2358 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
2359 Left.Previous->is(tok::period) && Right.is(tok::l_paren))
2361 if (Left.is(Keywords.kw_as) &&
2362 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2364 if (Left.is(tok::kw_default) && Left.Previous &&
2365 Left.Previous->is(tok::kw_export))
2367 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
2369 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2371 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
2373 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
2374 Line.First->isOneOf(Keywords.kw_import, tok::kw_export))
2376 if (Left.is(tok::ellipsis))
2378 if (Left.is(TT_TemplateCloser) &&
2379 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2380 Keywords.kw_implements, Keywords.kw_extends))
2385 if (Right.is(TT_JsNonNullAssertion))
2387 if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as))
2390 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
2392 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren))
2394 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2395 tok::kw_protected) ||
2396 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2397 Keywords.kw_native)) &&
2398 Right.is(TT_TemplateOpener))
2401 if (Left.is(TT_ImplicitStringLiteral))
2402 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
2404 if (Left.is(TT_ObjCMethodSpecifier))
2406 if (Left.is(tok::r_paren) && Right.is(tok::identifier))
2411 (Right.is(tok::equal) || Left.is(tok::equal)))
2414 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2415 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2417 if (Right.is(TT_OverloadedOperatorLParen))
2419 if (Left.is(tok::comma))
2421 if (Right.is(tok::comma))
2423 if (Right.isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen))
2425 if (Right.is(tok::colon)) {
2426 if (Line.First->isOneOf(tok::kw_case, tok::kw_default) ||
2427 !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi))
2429 if (Right.is(TT_ObjCMethodExpr))
2431 if (Left.is(tok::question))
2433 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
2435 if (Right.is(TT_DictLiteral))
2436 return Style.SpacesInContainerLiterals;
2439 if (Left.is(TT_UnaryOperator))
2440 return Right.is(TT_BinaryOperator);
2444 if (Left.is(TT_CastRParen))
2445 return Style.SpaceAfterCStyleCast ||
2446 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
2448 if (Left.is(tok::greater) && Right.is(tok::greater))
2449 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
2451 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
2452 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2453 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))
2455 if (!Style.SpaceBeforeAssignmentOperators &&
2458 if (Right.is(tok::coloncolon) && Left.is(tok::identifier))
2462 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
2463 if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment))
2464 return (Left.is(TT_TemplateOpener) &&
2466 !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
2467 tok::kw___super, TT_TemplateCloser, TT_TemplateOpener));
2468 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
2469 return Style.SpacesInAngles;
2470 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
2471 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2472 !Right.is(tok::r_paren)))
2474 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) &&
2475 Right.isNot(TT_FunctionTypeLParen))
2477 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
2478 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen))
2480 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
2481 Line.startsWith(tok::hash))
2483 if (Right.is(TT_TrailingUnaryOperator))
2485 if (Left.is(TT_RegexLiteral))
2487 return spaceRequiredBetween(Line, Left, Right);
2493 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
2496 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
2497 const FormatToken &Right) {
2498 const FormatToken &Left = *Right.Previous;
2499 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
2504 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous &&
2505 Left.Previous->is(tok::string_literal))
2507 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
2508 Left.Previous && Left.Previous->is(tok::equal) &&
2509 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
2513 !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let))
2517 if (Left.is(tok::l_brace) && Line.Level == 0 &&
2518 (Line.startsWith(tok::kw_enum) ||
2519 Line.startsWith(tok::kw_export, tok::kw_enum)))
2523 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
2524 !Left.Children.empty())
2528 (Left.NestingLevel == 0 && Line.Level == 0 &&
2529 Style.AllowShortFunctionsOnASingleLine &
2532 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
2533 Right.Next->is(tok::string_literal))
2538 if (Left.isStringLiteral() && Right.isStringLiteral())
2547 const FormatToken *BeforeClosingBrace =
nullptr;
2548 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2550 Left.is(tok::l_paren))) &&
2551 Left.BlockKind !=
BK_Block && Left.MatchingParen)
2552 BeforeClosingBrace = Left.MatchingParen->Previous;
2553 else if (Right.MatchingParen &&
2554 (Right.MatchingParen->isOneOf(tok::l_brace,
2555 TT_ArrayInitializerLSquare) ||
2557 Right.MatchingParen->is(tok::l_paren))))
2558 BeforeClosingBrace = &Left;
2559 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
2560 BeforeClosingBrace->isTrailingComment()))
2564 if (Right.is(tok::comment))
2566 Left.isNot(TT_CtorInitializerColon) &&
2567 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
2568 if (Left.isTrailingComment())
2570 if (Right.Previous->IsUnterminatedLiteral)
2572 if (Right.is(tok::lessless) && Right.Next &&
2573 Right.Previous->is(tok::string_literal) &&
2574 Right.Next->is(tok::string_literal))
2576 if (Right.Previous->ClosesTemplateDeclaration &&
2577 Right.Previous->MatchingParen &&
2578 Right.Previous->MatchingParen->NestingLevel == 0 &&
2579 Style.AlwaysBreakTemplateDeclarations)
2581 if (Right.is(TT_CtorInitializerComma) &&
2583 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
2585 if (Right.is(TT_CtorInitializerColon) &&
2587 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
2590 if (Style.BreakBeforeInheritanceComma &&
2591 Right.is(TT_InheritanceComma))
2593 if (Right.is(tok::string_literal) && Right.TokenText.startswith(
"R\""))
2597 return Right.NewlinesBefore > 0;
2598 if ((Right.Previous->is(tok::l_brace) ||
2599 (Right.Previous->is(tok::less) &&
2600 Right.Previous->Previous &&
2601 Right.Previous->Previous->is(tok::equal))
2608 if (Right.is(TT_InlineASMBrace))
2609 return Right.HasUnescapedNewline;
2611 return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
2612 (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
2613 (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
2614 if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine)
2619 Left.is(TT_LeadingJavaAnnotation) &&
2620 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
2621 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations))
2627 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
2628 const FormatToken &Right) {
2629 const FormatToken &Left = *Right.Previous;
2633 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
2634 Keywords.kw_implements))
2636 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
2637 Keywords.kw_implements))
2640 const FormatToken *NonComment = Right.getPreviousNonComment();
2642 NonComment->isOneOf(tok::kw_return, tok::kw_continue, tok::kw_break,
2643 tok::kw_throw, Keywords.kw_interface,
2644 Keywords.kw_type, tok::kw_static, tok::kw_public,
2645 tok::kw_private, tok::kw_protected,
2646 Keywords.kw_readonly, Keywords.kw_abstract,
2647 Keywords.kw_get, Keywords.kw_set))
2649 if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
2651 if (Left.is(TT_JsTypeColon))
2653 if (Right.NestingLevel == 0 && Right.is(Keywords.kw_is))
2655 if (Left.is(Keywords.kw_in))
2657 if (Right.is(Keywords.kw_in))
2659 if (Right.is(Keywords.kw_as))
2661 if (Left.is(Keywords.kw_as))
2663 if (Left.is(TT_JsNonNullAssertion))
2665 if (Left.is(Keywords.kw_declare) &&
2666 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
2667 Keywords.kw_function, tok::kw_class, tok::kw_enum,
2668 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
2669 Keywords.kw_let, tok::kw_const))
2673 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
2674 Right.isOneOf(tok::identifier, tok::string_literal))
2676 if (Right.is(TT_TemplateString) && Right.closesScope())
2678 if (Left.is(TT_TemplateString) && Left.opensScope())
2682 if (Left.is(tok::at))
2684 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
2686 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
2687 return !Right.is(tok::l_paren);
2688 if (Right.is(TT_PointerOrReference))
2689 return Line.IsMultiVariableDeclStmt ||
2691 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
2692 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2693 Right.is(tok::kw_operator))
2695 if (Left.is(TT_PointerOrReference))
2697 if (Right.isTrailingComment())
2704 (Left.is(TT_CtorInitializerColon) &&
2705 Style.BreakConstructorInitializers ==
2707 if (Left.is(tok::question) && Right.is(tok::colon))
2709 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
2710 return Style.BreakBeforeTernaryOperators;
2711 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
2712 return !Style.BreakBeforeTernaryOperators;
2713 if (Right.is(TT_InheritanceColon))
2715 if (Right.is(TT_ObjCMethodExpr) && !Right.is(tok::r_square) &&
2716 Left.isNot(TT_SelectorName))
2718 if (Right.is(tok::colon) &&
2719 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
2721 if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr))
2723 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
2724 Right.Next->is(TT_ObjCMethodExpr)))
2725 return Left.isNot(tok::period);
2728 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen))
2730 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
2731 TT_OverloadedOperator))
2733 if (Left.is(TT_RangeBasedForLoopColon))
2735 if (Right.is(TT_RangeBasedForLoopColon))
2737 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
2739 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
2740 Left.is(tok::kw_operator))
2742 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
2745 if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen))
2747 if (Left.is(tok::l_paren) && Left.Previous &&
2748 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen)))
2750 if (Right.is(TT_ImplicitStringLiteral))
2753 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser))
2755 if (Right.is(tok::r_square) && Right.MatchingParen &&
2756 Right.MatchingParen->is(TT_LambdaLSquare))
2761 if (Right.is(tok::r_brace))
2762 return Right.MatchingParen && Right.MatchingParen->BlockKind ==
BK_Block;
2766 if (Left.is(TT_TrailingAnnotation))
2767 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
2768 tok::less, tok::coloncolon);
2770 if (Right.is(tok::kw___attribute))
2773 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
2776 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
2779 if (Left.is(TT_CtorInitializerColon))
2781 if (Right.is(TT_CtorInitializerColon))
2783 if (Left.is(TT_CtorInitializerComma) &&
2786 if (Right.is(TT_CtorInitializerComma) &&
2789 if (Left.is(TT_InheritanceComma) && Style.BreakBeforeInheritanceComma)
2791 if (Right.is(TT_InheritanceComma) && Style.BreakBeforeInheritanceComma)
2793 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
2794 (Left.is(tok::less) && Right.is(tok::less)))
2796 if (Right.is(TT_BinaryOperator) &&
2801 if (Left.is(TT_ArrayInitializerLSquare))
2803 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
2805 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
2806 !Left.isOneOf(tok::arrowstar, tok::lessless) &&
2811 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
2812 tok::kw_class, tok::kw_struct, tok::comment) ||
2813 Right.isMemberAccess() ||
2814 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
2815 tok::colon, tok::l_square, tok::at) ||
2816 (Left.is(tok::r_paren) &&
2817 Right.isOneOf(tok::identifier, tok::kw_const)) ||
2818 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
2819 (Left.is(TT_TemplateOpener) && !Right.is(TT_TemplateCloser));
2822 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
2823 llvm::errs() <<
"AnnotatedTokens:\n";
2824 const FormatToken *Tok = Line.First;
2826 llvm::errs() <<
" M=" << Tok->MustBreakBefore
2827 <<
" C=" << Tok->CanBreakBefore
2829 <<
" S=" << Tok->SpacesRequiredBefore
2830 <<
" B=" << Tok->BlockParameterCount
2831 <<
" BK=" << Tok->BlockKind
2832 <<
" P=" << Tok->SplitPenalty <<
" Name=" << Tok->Tok.getName()
2833 <<
" L=" << Tok->TotalLength <<
" PPK=" << Tok->PackingKind
2835 for (
unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
2836 llvm::errs() << Tok->FakeLParens[i] <<
"/";
2837 llvm::errs() <<
" FakeRParens=" << Tok->FakeRParens;
2838 llvm::errs() <<
" Text='" << Tok->TokenText <<
"'\n";
2840 assert(Tok == Line.Last);
2843 llvm::errs() <<
"----\n";
Defines the SourceManager interface.
Parser - This implements a parser for the C family of languages.
FormatToken * CurrentToken
tok::TokenKind ContextKind
This file implements a token annotator, i.e.
llvm::SmallPtrSet< FormatToken *, 16 > NonTemplateLess
detail::InMemoryDirectory::const_iterator I
FormatToken * FirstStartOfName
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
bool ColonIsObjCMethodExpr
detail::InMemoryDirectory::const_iterator E
SmallVector< Context, 8 > Contexts
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
FormatToken * FirstObjCSelectorName
The parameter type of a method or function.
unsigned LongestObjCSelectorName
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.