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))
100 if (
CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
103 !Line.startsWith(tok::kw_template))
112 bool parseParens(
bool LookForDecls =
false) {
116 Left->ParentBracket =
Contexts.back().ContextKind;
117 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
120 Contexts.back().ColonIsForRangeExpr =
123 bool StartsObjCMethodExpr =
false;
126 Left->Type = TT_ObjCBlockLParen;
127 }
else if (FormatToken *MaybeSel = Left->Previous) {
129 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
130 MaybeSel->Previous->is(tok::at)) {
131 StartsObjCMethodExpr =
true;
135 if (Left->is(TT_OverloadedOperatorLParen)) {
136 Contexts.back().IsExpression =
false;
138 Line.startsWith(Keywords.kw_type, tok::identifier)) {
140 Contexts.back().IsExpression =
false;
141 }
else if (Left->Previous &&
142 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
143 tok::kw_if, tok::kw_while, tok::l_paren,
145 Left->Previous->is(TT_BinaryOperator))) {
147 Contexts.back().IsExpression =
true;
149 (Left->Previous->is(Keywords.kw_function) ||
150 (Left->Previous->endsSequence(tok::identifier,
151 Keywords.kw_function)))) {
153 Contexts.back().IsExpression =
false;
155 Left->Previous->is(TT_JsTypeColon)) {
157 Contexts.back().IsExpression =
false;
158 }
else if (Left->Previous && Left->Previous->is(tok::r_square) &&
159 Left->Previous->MatchingParen &&
160 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) {
162 Contexts.back().IsExpression =
false;
163 }
else if (Line.InPPDirective &&
164 (!Left->Previous || !Left->Previous->is(tok::identifier))) {
165 Contexts.back().IsExpression =
true;
168 Contexts.back().IsExpression =
false;
169 }
else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
170 Left->Type = TT_AttributeParen;
171 }
else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
173 Contexts.back().IsForEachMacro =
true;
174 Contexts.back().IsExpression =
false;
175 }
else if (Left->Previous && Left->Previous->MatchingParen &&
176 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
177 Contexts.back().IsExpression =
false;
178 }
else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
180 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
181 Contexts.back().IsExpression = !IsForOrCatch;
184 if (StartsObjCMethodExpr) {
185 Contexts.back().ColonIsObjCMethodExpr =
true;
186 Left->Type = TT_ObjCMethodExpr;
190 bool ProbablyFunctionType =
CurrentToken->isOneOf(tok::star, tok::amp);
191 bool HasMultipleLines =
false;
192 bool HasMultipleParametersOnALine =
false;
193 bool MightBeObjCForRangeLoop =
194 Left->Previous && Left->Previous->is(tok::kw_for);
201 FormatToken *Prev =
CurrentToken->getPreviousNonComment();
203 FormatToken *PrevPrev = Prev->getPreviousNonComment();
205 if (PrevPrev && PrevPrev->is(tok::identifier) &&
206 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
207 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
208 Prev->Type = TT_BinaryOperator;
209 LookForDecls =
false;
214 if (
CurrentToken->Previous->is(TT_PointerOrReference) &&
217 ProbablyFunctionType =
true;
219 MightBeFunctionType =
false;
221 Contexts.back().IsExpression =
true;
223 if (MightBeFunctionType && ProbablyFunctionType &&
CurrentToken->Next &&
225 (
CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
226 Left->Type = TT_FunctionTypeLParen;
231 Left->Previous && Left->Previous->is(tok::l_paren)) {
235 for (FormatToken *Tok = Left; Tok !=
CurrentToken; Tok = Tok->Next) {
236 if (Tok->is(TT_BinaryOperator) &&
237 Tok->isOneOf(tok::star, tok::amp, tok::ampamp))
238 Tok->Type = TT_PointerOrReference;
242 if (StartsObjCMethodExpr) {
244 if (
Contexts.back().FirstObjCSelectorName) {
245 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
246 Contexts.back().LongestObjCSelectorName;
250 if (Left->is(TT_AttributeParen))
252 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
254 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
257 if (!HasMultipleLines)
259 else if (HasMultipleParametersOnALine)
271 Left->Type = TT_Unknown;
275 HasMultipleParametersOnALine =
true;
276 if (
CurrentToken->isOneOf(tok::kw_const, tok::kw_auto) ||
278 Contexts.back().IsExpression =
false;
280 MightBeObjCForRangeLoop =
false;
281 if (MightBeObjCForRangeLoop &&
CurrentToken->is(Keywords.kw_in))
286 Contexts.back().CanBeExpression =
true;
291 updateParameterCount(Left, Tok);
293 HasMultipleLines =
true;
306 Left->ParentBracket =
Contexts.back().ContextKind;
307 FormatToken *Parent = Left->getPreviousNonComment();
308 bool StartsObjCMethodExpr =
310 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
313 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
314 tok::kw_return, tok::kw_throw) ||
315 Parent->isUnaryOperator() ||
316 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
318 bool ColonFound =
false;
320 unsigned BindingIncrease = 1;
321 if (Left->is(TT_Unknown)) {
322 if (StartsObjCMethodExpr) {
323 Left->Type = TT_ObjCMethodExpr;
325 Contexts.back().ContextKind == tok::l_brace &&
326 Parent->isOneOf(tok::l_brace, tok::comma)) {
327 Left->Type = TT_JsComputedPropertyName;
330 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
331 tok::comma, tok::l_paren, tok::l_square,
332 tok::question, tok::colon, tok::kw_return,
335 Left->Type = TT_ArrayInitializerLSquare;
337 BindingIncrease = 10;
338 Left->Type = TT_ArraySubscriptLSquare;
342 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
343 Contexts.back().IsExpression =
true;
344 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
349 Left->is(TT_ObjCMethodExpr)) {
352 StartsObjCMethodExpr =
false;
353 Left->Type = TT_Unknown;
355 if (StartsObjCMethodExpr &&
CurrentToken->Previous != Left) {
360 if (Parent && Parent->is(TT_PointerOrReference))
361 Parent->Type = TT_BinaryOperator;
365 if (
Contexts.back().FirstObjCSelectorName) {
366 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
367 Contexts.back().LongestObjCSelectorName;
368 if (Left->BlockParameterCount > 1)
369 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
377 if (Left->is(TT_ArraySubscriptLSquare)) {
378 Left->Type = TT_ObjCMethodExpr;
379 StartsObjCMethodExpr =
true;
380 Contexts.back().ColonIsObjCMethodExpr =
true;
381 if (Parent && Parent->is(tok::r_paren))
382 Parent->Type = TT_CastRParen;
386 if (
CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
388 Left->Type = TT_ArrayInitializerLSquare;
392 updateParameterCount(Left, Tok);
400 Left->ParentBracket =
Contexts.back().ContextKind;
403 Left->Type = TT_ObjCBlockLBrace;
406 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
407 Contexts.back().ColonIsDictLiteral =
true;
409 Contexts.back().IsExpression =
true;
424 (!
Contexts.back().ColonIsDictLiteral ||
427 (Previous->Tok.getIdentifierInfo() ||
428 Previous->is(tok::string_literal)))
429 Previous->Type = TT_SelectorName;
432 Left->Type = TT_DictLiteral;
441 void updateParameterCount(FormatToken *Left, FormatToken *
Current) {
442 if (Current->is(tok::l_brace) && Current->BlockKind ==
BK_Block)
443 ++Left->BlockParameterCount;
444 if (Current->is(tok::comma)) {
445 ++Left->ParameterCount;
447 Left->Role.reset(
new CommaSeparatedList(Style));
448 Left->Role->CommaFound(Current);
449 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
450 Left->ParameterCount = 1;
454 bool parseConditional() {
467 bool parseTemplateDeclaration() {
474 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
480 bool consumeToken() {
483 switch (Tok->Tok.getKind()) {
486 if (!Tok->Previous && Line.MustBeDeclaration)
487 Tok->Type = TT_ObjCMethodSpecifier;
494 if (
Contexts.back().ColonIsForRangeExpr ||
496 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
497 Contexts.back().ContextKind == tok::l_paren ||
498 Contexts.back().ContextKind == tok::l_square ||
500 Line.MustBeDeclaration)) {
501 Tok->Type = TT_JsTypeColon;
505 if (
Contexts.back().ColonIsDictLiteral ||
507 Tok->Type = TT_DictLiteral;
508 }
else if (
Contexts.back().ColonIsObjCMethodExpr ||
509 Line.startsWith(TT_ObjCMethodSpecifier)) {
510 Tok->Type = TT_ObjCMethodExpr;
511 Tok->Previous->Type = TT_SelectorName;
512 if (Tok->Previous->ColumnWidth >
513 Contexts.back().LongestObjCSelectorName)
514 Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth;
515 if (!
Contexts.back().FirstObjCSelectorName)
516 Contexts.back().FirstObjCSelectorName = Tok->Previous;
517 }
else if (
Contexts.back().ColonIsForRangeExpr) {
518 Tok->Type = TT_RangeBasedForLoopColon;
520 Tok->Type = TT_BitFieldColon;
522 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
523 if (Tok->Previous->isOneOf(tok::r_paren, tok::kw_noexcept))
524 Tok->Type = TT_CtorInitializerColon;
526 Tok->Type = TT_InheritanceColon;
527 }
else if (Tok->Previous->is(tok::identifier) && Tok->Next &&
528 Tok->Next->isOneOf(tok::r_paren, tok::comma)) {
531 Tok->Type = TT_ObjCMethodExpr;
532 }
else if (
Contexts.back().ContextKind == tok::l_paren) {
533 Tok->Type = TT_InlineASMColon;
542 Tok->Type = TT_JsTypeOperator;
548 if (!parseParens(
true))
554 Tok->Previous->is(tok::period))
556 Contexts.back().ColonIsForRangeExpr =
true;
567 Tok->Previous->is(tok::r_paren) &&
568 Tok->Previous->MatchingParen &&
569 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
570 Tok->Previous->Type = TT_OverloadedOperator;
571 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
572 Tok->Type = TT_OverloadedOperatorLParen;
577 if (Line.MustBeDeclaration &&
Contexts.size() == 1 &&
578 !
Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
580 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
581 TT_LeadingJavaAnnotation)))
582 Line.MightBeFunctionDecl =
true;
594 Tok->Type = TT_TemplateOpener;
596 Tok->Type = TT_BinaryOperator;
611 Tok->Type = TT_BinaryOperator;
613 case tok::kw_operator:
615 !
CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
620 CurrentToken->Previous->isOneOf(TT_BinaryOperator, tok::comma))
631 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
637 Tok->Type = TT_JsTypeOptionalQuestion;
642 if (Line.MustBeDeclaration && !
Contexts.back().IsExpression &&
647 case tok::kw_template:
648 parseTemplateDeclaration();
651 if (
Contexts.back().InCtorInitializer)
652 Tok->Type = TT_CtorInitializerComma;
654 (
Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
655 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
656 Line.IsMultiVariableDeclStmt =
true;
659 Contexts.back().IsExpression =
true;
667 void parseIncludeDirective() {
678 void parseWarningOrError() {
692 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
697 if (IsMark ||
CurrentToken->Previous->is(TT_BinaryOperator))
704 LineType parsePreprocessorDirective() {
731 switch (
CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
732 case tok::pp_include:
733 case tok::pp_include_next:
736 parseIncludeDirective();
740 case tok::pp_warning:
741 parseWarningOrError();
748 Contexts.back().IsExpression =
true;
763 return parsePreprocessorDirective();
768 IdentifierInfo *Info =
CurrentToken->Tok.getIdentifierInfo();
771 (Info && Info->getPPKeywordID() == tok::pp_import &&
773 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
776 parseIncludeDirective();
782 if (
CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
783 parseIncludeDirective();
796 bool KeywordVirtualFound =
false;
797 bool ImportStatement =
false;
802 ImportStatement =
true;
806 KeywordVirtualFound =
true;
814 if (Line.First->is(tok::kw_export) &&
817 ImportStatement =
true;
819 ImportStatement =
true;
824 if (KeywordVirtualFound)
829 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
830 if (
Contexts.back().FirstObjCSelectorName)
831 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
832 Contexts.back().LongestObjCSelectorName;
840 bool isClosureImportStatement(
const FormatToken &Tok) {
843 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
844 Tok.Next->Next && (Tok.Next->Next->TokenText ==
"module" ||
845 Tok.Next->Next->TokenText ==
"provide" ||
846 Tok.Next->Next->TokenText ==
"require" ||
847 Tok.Next->Next->TokenText ==
"setTestOnly" ||
848 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
849 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
852 void resetTokenMetadata(FormatToken *
Token) {
858 if (!
CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
859 TT_FunctionLBrace, TT_ImplicitStringLiteral,
860 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
907 struct ScopedContextCreator {
913 P.Contexts.push_back(
Context(ContextKind,
914 P.Contexts.back().BindingStrength + Increase,
915 P.Contexts.back().IsExpression));
918 ~ScopedContextCreator() {
P.Contexts.pop_back(); }
921 void modifyContext(
const FormatToken &Current) {
923 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
926 Line.startsWith(Keywords.kw_type, tok::identifier)) &&
927 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
928 Contexts.back().IsExpression =
true;
929 if (!Line.startsWith(TT_UnaryOperator)) {
930 for (FormatToken *
Previous = Current.Previous;
932 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
934 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
941 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
942 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
944 Previous->Type = TT_PointerOrReference;
947 }
else if (Current.is(tok::lessless) &&
948 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
949 Contexts.back().IsExpression =
true;
950 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
951 Contexts.back().IsExpression =
true;
952 }
else if (Current.is(TT_TrailingReturnArrow)) {
953 Contexts.back().IsExpression =
false;
954 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
956 }
else if (Current.Previous &&
957 Current.Previous->is(TT_CtorInitializerColon)) {
958 Contexts.back().IsExpression =
true;
959 Contexts.back().InCtorInitializer =
true;
960 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
961 for (FormatToken *
Previous = Current.Previous;
964 Previous->Type = TT_PointerOrReference;
965 if (Line.MustBeDeclaration && !
Contexts.front().InCtorInitializer)
966 Contexts.back().IsExpression =
false;
967 }
else if (Current.is(tok::kw_new)) {
968 Contexts.back().CanBeExpression =
false;
969 }
else if (Current.isOneOf(tok::semi, tok::exclaim)) {
971 Contexts.back().IsExpression =
true;
975 void determineTokenType(FormatToken &Current) {
976 if (!Current.is(TT_Unknown))
983 if (Current.is(Keywords.kw_instanceof)) {
984 Current.Type = TT_BinaryOperator;
985 }
else if (isStartOfName(Current) &&
986 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
988 Current.Type = TT_StartOfName;
989 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
991 }
else if (Current.is(tok::arrow) &&
993 Current.Type = TT_LambdaArrow;
994 }
else if (Current.is(tok::arrow) &&
AutoFound && Line.MustBeDeclaration &&
995 Current.NestingLevel == 0) {
996 Current.Type = TT_TrailingReturnArrow;
997 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
999 determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&
1001 Contexts.back().InTemplateArgument);
1002 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1003 Current.Type = determinePlusMinusCaretUsage(Current);
1004 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1006 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1007 Current.Type = determineIncrementUsage(Current);
1008 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1009 Current.Type = TT_UnaryOperator;
1010 }
else if (Current.is(tok::question)) {
1012 Line.MustBeDeclaration && !
Contexts.back().IsExpression) {
1015 Current.Type = TT_JsTypeOptionalQuestion;
1017 Current.Type = TT_ConditionalExpr;
1019 }
else if (Current.isBinaryOperator() &&
1020 (!Current.Previous || Current.Previous->isNot(tok::l_square))) {
1021 Current.Type = TT_BinaryOperator;
1022 }
else if (Current.is(tok::comment)) {
1023 if (Current.TokenText.startswith(
"/*")) {
1024 if (Current.TokenText.endswith(
"*/"))
1025 Current.Type = TT_BlockComment;
1029 Current.Tok.setKind(tok::unknown);
1031 Current.Type = TT_LineComment;
1033 }
else if (Current.is(tok::r_paren)) {
1034 if (rParenEndsCast(Current))
1035 Current.Type = TT_CastRParen;
1036 if (Current.MatchingParen && Current.Next &&
1037 !Current.Next->isBinaryOperator() &&
1038 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1039 tok::period, tok::arrow, tok::coloncolon))
1040 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1041 if (BeforeParen->is(tok::identifier) &&
1042 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1043 (!BeforeParen->Previous ||
1044 BeforeParen->Previous->ClosesTemplateDeclaration))
1045 Current.Type = TT_FunctionAnnotationRParen;
1046 }
else if (Current.is(tok::at) && Current.Next) {
1047 if (Current.Next->isStringLiteral()) {
1048 Current.Type = TT_ObjCStringLiteral;
1050 switch (Current.Next->Tok.getObjCKeywordID()) {
1051 case tok::objc_interface:
1052 case tok::objc_implementation:
1053 case tok::objc_protocol:
1054 Current.Type = TT_ObjCDecl;
1056 case tok::objc_property:
1057 Current.Type = TT_ObjCProperty;
1063 }
else if (Current.is(tok::period)) {
1064 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1065 if (PreviousNoComment &&
1066 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1067 Current.Type = TT_DesignatedInitializerPeriod;
1069 Current.Previous->isOneOf(TT_JavaAnnotation,
1070 TT_LeadingJavaAnnotation)) {
1071 Current.Type = Current.Previous->Type;
1073 }
else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
1075 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1076 Line.MightBeFunctionDecl &&
Contexts.size() == 1) {
1079 Current.Type = TT_TrailingAnnotation;
1083 if (Current.Previous->is(tok::at) &&
1084 Current.isNot(Keywords.kw_interface)) {
1085 const FormatToken &AtToken = *Current.Previous;
1086 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1087 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1088 Current.Type = TT_LeadingJavaAnnotation;
1090 Current.Type = TT_JavaAnnotation;
1091 }
else if (Current.Previous->is(tok::period) &&
1092 Current.Previous->isOneOf(TT_JavaAnnotation,
1093 TT_LeadingJavaAnnotation)) {
1094 Current.Type = Current.Previous->Type;
1104 bool isStartOfName(
const FormatToken &Tok) {
1105 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1108 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof))
1111 Tok.Previous->is(Keywords.kw_in))
1115 FormatToken *PreviousNotConst = Tok.Previous;
1116 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1117 PreviousNotConst = PreviousNotConst->Previous;
1119 if (!PreviousNotConst)
1122 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1123 PreviousNotConst->Previous &&
1124 PreviousNotConst->Previous->is(tok::hash);
1126 if (PreviousNotConst->is(TT_TemplateCloser))
1127 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1128 PreviousNotConst->MatchingParen->Previous &&
1129 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1130 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1132 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1133 PreviousNotConst->MatchingParen->Previous &&
1134 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1137 return (!IsPPKeyword &&
1138 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1139 PreviousNotConst->is(TT_PointerOrReference) ||
1140 PreviousNotConst->isSimpleTypeSpecifier();
1144 bool rParenEndsCast(
const FormatToken &Tok) {
1151 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1154 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1158 if (LeftOfParens->is(tok::r_paren)) {
1159 if (!LeftOfParens->MatchingParen ||
1160 !LeftOfParens->MatchingParen->Previous)
1162 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1167 if (LeftOfParens->Tok.getIdentifierInfo() &&
1168 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1174 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1175 TT_TemplateCloser, tok::ellipsis))
1179 if (Tok.Next->is(tok::question))
1188 if (Tok.Next->isNot(tok::string_literal) &&
1189 (Tok.Next->Tok.isLiteral() ||
1190 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1194 bool ParensAreType =
1196 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1197 Tok.Previous->isSimpleTypeSpecifier();
1198 bool ParensCouldEndDecl =
1199 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1200 if (ParensAreType && !ParensCouldEndDecl)
1211 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1214 if (!Tok.Next->Next)
1221 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1222 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1223 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1226 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1227 Prev = Prev->Previous) {
1228 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1238 return TT_BinaryOperator;
1240 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1242 return TT_UnaryOperator;
1244 const FormatToken *NextToken = Tok.getNextNonComment();
1246 NextToken->isOneOf(tok::arrow, Keywords.kw_final,
1247 Keywords.kw_override) ||
1248 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1249 return TT_PointerOrReference;
1251 if (PrevToken->is(tok::coloncolon))
1252 return TT_PointerOrReference;
1254 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1255 tok::comma, tok::semi, tok::kw_return, tok::colon,
1256 tok::equal, tok::kw_delete, tok::kw_sizeof) ||
1257 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1258 TT_UnaryOperator, TT_CastRParen))
1259 return TT_UnaryOperator;
1261 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1262 return TT_PointerOrReference;
1264 return TT_PointerOrReference;
1265 if (NextToken->isOneOf(tok::comma, tok::semi))
1266 return TT_PointerOrReference;
1268 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen &&
1269 PrevToken->MatchingParen->Previous &&
1270 PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof,
1272 return TT_PointerOrReference;
1274 if (PrevToken->Tok.isLiteral() ||
1275 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1276 tok::kw_false, tok::r_brace) ||
1277 NextToken->Tok.isLiteral() ||
1278 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1279 NextToken->isUnaryOperator() ||
1283 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1284 return TT_BinaryOperator;
1287 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1288 return TT_BinaryOperator;
1292 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1293 if (NextNextToken && NextNextToken->is(tok::arrow))
1294 return TT_BinaryOperator;
1298 if (IsExpression && !
Contexts.back().CaretFound)
1299 return TT_BinaryOperator;
1301 return TT_PointerOrReference;
1304 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1305 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1306 if (!PrevToken || PrevToken->is(TT_CastRParen))
1307 return TT_UnaryOperator;
1310 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1311 tok::question, tok::colon, tok::kw_return,
1312 tok::kw_case, tok::at, tok::l_brace))
1313 return TT_UnaryOperator;
1316 if (PrevToken->is(TT_BinaryOperator))
1317 return TT_UnaryOperator;
1320 return TT_BinaryOperator;
1324 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1325 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1326 if (!PrevToken || PrevToken->is(TT_CastRParen))
1327 return TT_UnaryOperator;
1328 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1329 return TT_TrailingUnaryOperator;
1331 return TT_UnaryOperator;
1354 class ExpressionParser {
1356 ExpressionParser(
const FormatStyle &Style,
const AdditionalKeywords &Keywords,
1357 AnnotatedLine &Line)
1361 void parse(
int Precedence = 0) {
1364 while (Current && (Current->is(tok::kw_return) ||
1365 (Current->is(tok::colon) &&
1366 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1369 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1374 parseConditionalExpr();
1380 if (Precedence == PrecedenceUnaryOperator) {
1381 parseUnaryOperator();
1386 FormatToken *LatestOperator =
nullptr;
1387 unsigned OperatorIndex = 0;
1391 parse(Precedence + 1);
1393 int CurrentPrecedence = getCurrentPrecedence();
1395 if (Current && Current->is(TT_SelectorName) &&
1396 Precedence == CurrentPrecedence) {
1398 addFakeParenthesis(Start,
prec::Level(Precedence));
1404 if (!Current || (Current->closesScope() && Current->MatchingParen) ||
1405 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1412 if (Current->opensScope()) {
1413 while (Current && !Current->closesScope()) {
1420 if (CurrentPrecedence == Precedence) {
1422 LatestOperator->NextOperator =
Current;
1424 Current->OperatorIndex = OperatorIndex;
1427 next(Precedence > 0);
1431 if (LatestOperator && (Current || Precedence > 0)) {
1433 if (Precedence == PrecedenceArrowAndPeriod) {
1437 addFakeParenthesis(Start,
prec::Level(Precedence));
1445 int getCurrentPrecedence() {
1447 const FormatToken *NextNonComment = Current->getNextNonComment();
1448 if (Current->is(TT_ConditionalExpr))
1450 if (NextNonComment && NextNonComment->is(tok::colon) &&
1451 NextNonComment->is(TT_DictLiteral))
1453 if (Current->is(TT_LambdaArrow))
1455 if (Current->is(TT_JsFatArrow))
1457 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName,
1458 TT_JsComputedPropertyName) ||
1459 (Current->is(tok::comment) && NextNonComment &&
1460 NextNonComment->is(TT_SelectorName)))
1462 if (Current->is(TT_RangeBasedForLoopColon))
1466 Current->is(Keywords.kw_instanceof))
1469 Current->is(Keywords.kw_in))
1471 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1472 return Current->getPrecedence();
1473 if (Current->isOneOf(tok::period, tok::arrow))
1474 return PrecedenceArrowAndPeriod;
1477 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1478 Keywords.kw_throws))
1484 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
1485 Start->FakeLParens.push_back(Precedence);
1487 Start->StartsBinaryExpression =
true;
1489 FormatToken *Previous = Current->Previous;
1490 while (Previous->is(tok::comment) && Previous->Previous)
1491 Previous = Previous->Previous;
1492 ++Previous->FakeRParens;
1494 Previous->EndsBinaryExpression =
true;
1500 void parseUnaryOperator() {
1501 if (!Current || Current->isNot(TT_UnaryOperator)) {
1502 parse(PrecedenceArrowAndPeriod);
1508 parseUnaryOperator();
1514 void parseConditionalExpr() {
1515 while (Current && Current->isTrailingComment()) {
1520 if (!Current || !Current->is(tok::question))
1524 if (!Current || Current->isNot(TT_ConditionalExpr))
1531 void next(
bool SkipPastLeadingComments =
true) {
1533 Current = Current->Next;
1535 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1536 Current->isTrailingComment())
1537 Current = Current->Next;
1540 const FormatStyle &
Style;
1541 const AdditionalKeywords &
Keywords;
1553 if (NextNonCommentLine && (*I)->
First->
is(tok::comment) &&
1554 (*I)->First->Next ==
nullptr)
1557 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
1569 AnnotatingParser
Parser(Style, Line, Keywords);
1570 Line.
Type = Parser.parseLine();
1574 ExpressionParser ExprParser(Style, Keywords, Line);
1594 if (
Next->is(TT_OverloadedOperatorLParen))
1596 if (
Next->is(TT_OverloadedOperator))
1598 if (
Next->isOneOf(tok::kw_new, tok::kw_delete)) {
1600 if (
Next->Next &&
Next->Next->is(tok::l_square) &&
1601 Next->Next->Next &&
Next->Next->Next->is(tok::r_square))
1613 if (Current.
is(tok::kw_operator)) {
1616 Next = skipOperatorName(Next);
1621 if (Next->
is(TT_TemplateOpener)) {
1623 }
else if (Next->
is(tok::coloncolon)) {
1627 if (Next->
is(tok::kw_operator)) {
1628 Next = skipOperatorName(Next->
Next);
1631 if (!Next->
is(tok::identifier))
1633 }
else if (Next->
is(tok::l_paren)) {
1645 if (Line.
Last->
is(tok::l_brace))
1655 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
1656 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
1658 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
1659 Tok->Tok.isLiteral())
1665 bool TokenAnnotator::mustBreakForReturnType(
const AnnotatedLine &Line)
const {
1666 assert(Line.MightBeFunctionDecl);
1669 Style.AlwaysBreakAfterReturnType ==
1674 switch (Style.AlwaysBreakAfterReturnType) {
1682 return Line.mightBeFunctionDefinition();
1703 Current->
Type = TT_FunctionDeclarationName;
1704 if (Current->
is(TT_LineComment)) {
1721 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
1724 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
1732 spaceRequiredBefore(Line, *Current)) {
1740 Current->
is(TT_FunctionDeclarationName))
1745 unsigned ChildSize = 0;
1754 Prev->
Children[0]->First->MustBreakBefore) ||
1761 if (Current->
is(TT_CtorInitializerColon))
1762 InFunctionDecl =
false;
1768 splitPenalty(Line, *Current, InFunctionDecl);
1770 Current = Current->
Next;
1773 calculateUnbreakableTailLengths(Line);
1774 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
1776 Current->
Role->precomputeFormattingInfos(Current);
1779 DEBUG({ printDebugInfo(Line); });
1782 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
1783 unsigned UnbreakableTailLength = 0;
1788 Current->
isOneOf(tok::comment, tok::string_literal)) {
1789 UnbreakableTailLength = 0;
1791 UnbreakableTailLength +=
1798 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
1799 const FormatToken &Tok,
1800 bool InFunctionDecl) {
1801 const FormatToken &Left = *Tok.
Previous;
1802 const FormatToken &Right = Tok;
1804 if (Left.is(tok::semi))
1808 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
1810 if (Right.is(Keywords.kw_implements))
1812 if (Left.is(tok::comma) && Left.NestingLevel == 0)
1815 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
1817 if (Left.is(TT_JsTypeColon))
1821 if (Left.is(tok::comma) || (Right.is(tok::identifier) && Right.Next &&
1822 Right.Next->is(TT_DictLiteral)))
1824 if (Right.is(tok::l_square)) {
1827 if (Left.is(tok::r_square))
1830 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
1832 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
1833 TT_ArrayInitializerLSquare))
1837 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
1838 Right.is(tok::kw_operator)) {
1839 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
1841 if (Left.is(TT_StartOfName))
1843 if (InFunctionDecl && Right.NestingLevel == 0)
1844 return Style.PenaltyReturnTypeOnItsOwnLine;
1847 if (Right.is(TT_PointerOrReference))
1849 if (Right.is(TT_LambdaArrow))
1851 if (Left.is(tok::equal) && Right.is(tok::l_brace))
1853 if (Left.is(TT_CastRParen))
1855 if (Left.is(tok::coloncolon) ||
1858 if (Left.isOneOf(tok::kw_class, tok::kw_struct))
1860 if (Left.is(tok::comment))
1863 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon))
1866 if (Right.isMemberAccess()) {
1891 if (Right.is(TT_TrailingAnnotation) &&
1892 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
1895 if (Line.startsWith(TT_ObjCMethodSpecifier))
1902 bool is_short_annotation = Right.TokenText.size() < 10;
1903 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
1907 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
1912 if (Right.is(TT_SelectorName))
1914 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
1915 return Line.MightBeFunctionDecl ? 50 : 500;
1917 if (Left.is(tok::l_paren) && InFunctionDecl &&
1920 if (Left.is(tok::l_paren) && Left.Previous &&
1921 Left.Previous->isOneOf(tok::kw_if, tok::kw_for))
1923 if (Left.is(tok::equal) && InFunctionDecl)
1925 if (Right.is(tok::r_brace))
1927 if (Left.is(TT_TemplateOpener))
1929 if (Left.opensScope()) {
1932 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
1935 if (Left.is(TT_JavaAnnotation))
1938 if (Right.is(tok::lessless)) {
1939 if (Left.is(tok::string_literal) &&
1940 (Right.NextOperator || Right.OperatorIndex != 1)) {
1941 StringRef Content = Left.TokenText;
1942 if (Content.startswith(
"\""))
1943 Content = Content.drop_front(1);
1944 if (Content.endswith(
"\""))
1945 Content = Content.drop_back(1);
1946 Content = Content.trim();
1947 if (Content.size() > 1 &&
1948 (Content.back() ==
':' || Content.back() ==
'='))
1953 if (Left.is(TT_ConditionalExpr))
1958 Level = Right.getPrecedence();
1965 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
1966 const FormatToken &Left,
1967 const FormatToken &Right) {
1968 if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
1971 Left.Tok.getObjCKeywordID() == tok::objc_property)
1973 if (Right.is(tok::hashhash))
1974 return Left.is(tok::hash);
1975 if (Left.isOneOf(tok::hashhash, tok::hash))
1976 return Right.is(tok::hash);
1977 if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
1978 return Style.SpaceInEmptyParentheses;
1979 if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
1980 return (Right.is(TT_CastRParen) ||
1981 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
1982 ? Style.SpacesInCStyleCastParentheses
1983 : Style.SpacesInParentheses;
1984 if (Right.isOneOf(tok::semi, tok::comma))
1986 if (Right.is(tok::less) &&
1987 (Left.is(tok::kw_template) ||
1988 (Line.Type ==
LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList)))
1990 if (Left.isOneOf(tok::exclaim, tok::tilde))
1992 if (Left.is(tok::at) &&
1993 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
1994 tok::numeric_constant, tok::l_paren, tok::l_brace,
1995 tok::kw_true, tok::kw_false))
1997 if (Left.is(tok::colon))
1998 return !Left.is(TT_ObjCMethodExpr);
1999 if (Left.is(tok::coloncolon))
2001 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
2003 if (Right.is(tok::ellipsis))
2004 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
2005 Left.Previous->is(tok::kw_case));
2006 if (Left.is(tok::l_square) && Right.is(tok::amp))
2008 if (Right.is(TT_PointerOrReference))
2009 return (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) ||
2010 (Left.Tok.isLiteral() || (Left.is(tok::kw_const) && Left.Previous &&
2011 Left.Previous->is(tok::r_paren)) ||
2012 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
2014 Line.IsMultiVariableDeclStmt)));
2015 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
2016 (!Left.is(TT_PointerOrReference) ||
2018 !Line.IsMultiVariableDeclStmt)))
2020 if (Left.is(TT_PointerOrReference))
2021 return Right.Tok.isLiteral() ||
2022 Right.isOneOf(TT_BlockComment, Keywords.kw_final,
2023 Keywords.kw_override) ||
2024 (Right.is(tok::l_brace) && Right.BlockKind ==
BK_Block) ||
2025 (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2028 !Line.IsMultiVariableDeclStmt) &&
2030 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
2031 if (Right.is(tok::star) && Left.is(tok::l_paren))
2033 if (Left.is(tok::l_square))
2034 return (Left.is(TT_ArrayInitializerLSquare) &&
2035 Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) ||
2036 (Left.is(TT_ArraySubscriptLSquare) && Style.SpacesInSquareBrackets &&
2037 Right.isNot(tok::r_square));
2038 if (Right.is(tok::r_square))
2039 return Right.MatchingParen &&
2040 ((Style.SpacesInContainerLiterals &&
2041 Right.MatchingParen->is(TT_ArrayInitializerLSquare)) ||
2042 (Style.SpacesInSquareBrackets &&
2043 Right.MatchingParen->is(TT_ArraySubscriptLSquare)));
2044 if (Right.is(tok::l_square) &&
2045 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare) &&
2046 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral))
2048 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
2049 return !Left.Children.empty();
2050 if ((Left.is(tok::l_brace) && Left.BlockKind !=
BK_Block) ||
2051 (Right.is(tok::r_brace) && Right.MatchingParen &&
2052 Right.MatchingParen->BlockKind !=
BK_Block))
2053 return !Style.Cpp11BracedListStyle;
2054 if (Left.is(TT_BlockComment))
2055 return !Left.TokenText.endswith(
"=*/");
2056 if (Right.is(tok::l_paren)) {
2057 if (Left.is(tok::r_paren) && Left.is(TT_AttributeParen))
2059 return Line.Type ==
LT_ObjCDecl || Left.is(tok::semi) ||
2061 (Left.isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
2062 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2064 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2065 tok::kw_new, tok::kw_delete) &&
2066 (!Left.Previous || Left.Previous->isNot(tok::period))))) ||
2068 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() ||
2069 Left.is(tok::r_paren)) &&
2072 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
2074 if (Right.is(TT_UnaryOperator))
2075 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2076 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
2077 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
2079 Left.isSimpleTypeSpecifier()) &&
2080 Right.is(tok::l_brace) && Right.getNextNonComment() &&
2083 if (Left.is(tok::period) || Right.is(tok::period))
2085 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText ==
"L")
2087 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
2088 Left.MatchingParen->Previous &&
2089 Left.MatchingParen->Previous->is(tok::period))
2092 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
2097 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2098 const FormatToken &Right) {
2099 const FormatToken &Left = *Right.Previous;
2100 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
2103 if (Left.is(tok::kw_operator))
2104 return Right.is(tok::coloncolon);
2106 if (Right.is(tok::period) &&
2107 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
2108 Keywords.kw_repeated, Keywords.kw_extend))
2110 if (Right.is(tok::l_paren) &&
2111 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
2114 if (Left.is(TT_JsFatArrow))
2116 if (Right.is(tok::star) &&
2117 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield))
2119 if (Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2120 Keywords.kw_of, tok::kw_const) &&
2121 (!Left.Previous || !Left.Previous->is(tok::period)))
2123 if (Left.is(tok::kw_default) && Left.Previous &&
2124 Left.Previous->is(tok::kw_export))
2126 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
2128 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2130 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
2132 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
2133 Line.First->isOneOf(Keywords.kw_import, tok::kw_export))
2135 if (Left.is(tok::ellipsis))
2137 if (Left.is(TT_TemplateCloser) &&
2138 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2139 Keywords.kw_implements, Keywords.kw_extends))
2145 if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren,
2146 tok::r_square, tok::r_brace) ||
2147 Left.Tok.isLiteral()))
2150 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
2152 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren))
2154 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2155 tok::kw_protected) ||
2156 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2157 Keywords.kw_native)) &&
2158 Right.is(TT_TemplateOpener))
2161 if (Left.is(TT_ImplicitStringLiteral))
2162 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
2164 if (Left.is(TT_ObjCMethodSpecifier))
2166 if (Left.is(tok::r_paren) && Right.is(tok::identifier))
2171 (Right.is(tok::equal) || Left.is(tok::equal)))
2174 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2175 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2177 if (Right.is(TT_OverloadedOperatorLParen))
2179 if (Left.is(tok::comma))
2181 if (Right.is(tok::comma))
2183 if (Right.isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen))
2185 if (Right.is(tok::colon)) {
2186 if (Line.First->isOneOf(tok::kw_case, tok::kw_default) ||
2187 !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi))
2189 if (Right.is(TT_ObjCMethodExpr))
2191 if (Left.is(tok::question))
2193 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
2195 if (Right.is(TT_DictLiteral))
2196 return Style.SpacesInContainerLiterals;
2199 if (Left.is(TT_UnaryOperator))
2200 return Right.is(TT_BinaryOperator);
2204 if (Left.is(TT_CastRParen))
2205 return Style.SpaceAfterCStyleCast ||
2206 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
2208 if (Left.is(tok::greater) && Right.is(tok::greater))
2209 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
2211 if (Right.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2212 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar))
2214 if (!Style.SpaceBeforeAssignmentOperators &&
2217 if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment))
2218 return (Left.is(TT_TemplateOpener) &&
2220 !(Left.isOneOf(tok::identifier, tok::l_paren, tok::r_paren,
2222 Left.isOneOf(TT_TemplateCloser, TT_TemplateOpener));
2223 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
2224 return Style.SpacesInAngles;
2225 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
2226 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2227 !Right.is(tok::r_paren)))
2229 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) &&
2230 Right.isNot(TT_FunctionTypeLParen))
2232 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
2233 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen))
2235 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
2236 Line.startsWith(tok::hash))
2238 if (Right.is(TT_TrailingUnaryOperator))
2240 if (Left.is(TT_RegexLiteral))
2242 return spaceRequiredBetween(Line, Left, Right);
2248 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
2251 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
2252 const FormatToken &Right) {
2253 const FormatToken &Left = *Right.Previous;
2254 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
2259 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous &&
2260 Left.Previous->is(tok::string_literal))
2262 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
2263 Left.Previous && Left.Previous->is(tok::equal) &&
2264 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
2268 !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let))
2272 if (Left.is(tok::l_brace) && Line.Level == 0 &&
2273 (Line.startsWith(tok::kw_enum) ||
2274 Line.startsWith(tok::kw_export, tok::kw_enum)))
2278 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
2279 !Left.Children.empty())
2283 (Left.NestingLevel == 0 && Line.Level == 0 &&
2284 Style.AllowShortFunctionsOnASingleLine ==
2287 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
2288 Right.Next->is(tok::string_literal))
2295 const FormatToken *BeforeClosingBrace =
nullptr;
2296 if (Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
2297 Left.BlockKind !=
BK_Block && Left.MatchingParen)
2298 BeforeClosingBrace = Left.MatchingParen->Previous;
2299 else if (Right.MatchingParen &&
2300 Right.MatchingParen->isOneOf(tok::l_brace,
2301 TT_ArrayInitializerLSquare))
2302 BeforeClosingBrace = &Left;
2303 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
2304 BeforeClosingBrace->isTrailingComment()))
2307 if (Right.is(tok::comment))
2309 Left.isNot(TT_CtorInitializerColon) &&
2310 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
2311 if (Left.isTrailingComment())
2313 if (Left.isStringLiteral() &&
2314 (Right.isStringLiteral() || Right.is(TT_ObjCStringLiteral)))
2316 if (Right.Previous->IsUnterminatedLiteral)
2318 if (Right.is(tok::lessless) && Right.Next &&
2319 Right.Previous->is(tok::string_literal) &&
2320 Right.Next->is(tok::string_literal))
2322 if (Right.Previous->ClosesTemplateDeclaration &&
2323 Right.Previous->MatchingParen &&
2324 Right.Previous->MatchingParen->NestingLevel == 0 &&
2325 Style.AlwaysBreakTemplateDeclarations)
2327 if ((Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) &&
2328 Style.BreakConstructorInitializersBeforeComma &&
2329 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
2331 if (Right.is(tok::string_literal) && Right.TokenText.startswith(
"R\""))
2335 return Right.NewlinesBefore > 0;
2336 if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 &&
2340 if (Right.is(TT_InlineASMBrace))
2341 return Right.HasUnescapedNewline;
2343 return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
2344 (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
2345 (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
2346 if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine)
2351 Left.is(TT_LeadingJavaAnnotation) &&
2352 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
2353 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations))
2359 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
2360 const FormatToken &Right) {
2361 const FormatToken &Left = *Right.Previous;
2365 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
2366 Keywords.kw_implements))
2368 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
2369 Keywords.kw_implements))
2372 if (Left.is(tok::kw_return))
2374 if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
2376 if (Left.is(TT_JsTypeColon))
2378 if (Right.NestingLevel == 0 && Right.is(Keywords.kw_is))
2380 if (Left.is(Keywords.kw_in))
2382 if (Right.is(Keywords.kw_in))
2384 if (Right.is(Keywords.kw_as))
2388 if (Left.is(tok::at))
2390 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
2392 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
2393 return !Right.is(tok::l_paren);
2394 if (Right.is(TT_PointerOrReference))
2395 return Line.IsMultiVariableDeclStmt ||
2397 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
2398 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2399 Right.is(tok::kw_operator))
2401 if (Left.is(TT_PointerOrReference))
2403 if (Right.isTrailingComment())
2410 if (Left.is(tok::question) && Right.is(tok::colon))
2412 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
2413 return Style.BreakBeforeTernaryOperators;
2414 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
2415 return !Style.BreakBeforeTernaryOperators;
2416 if (Right.is(TT_InheritanceColon))
2418 if (Right.is(tok::colon) &&
2419 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
2421 if (Left.is(tok::colon) && (Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))
2423 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
2424 Right.Next->is(TT_ObjCMethodExpr)))
2425 return Left.isNot(tok::period);
2428 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen))
2430 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
2431 TT_OverloadedOperator))
2433 if (Left.is(TT_RangeBasedForLoopColon))
2435 if (Right.is(TT_RangeBasedForLoopColon))
2437 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
2438 Left.is(tok::kw_operator))
2440 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
2443 if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen))
2445 if (Left.is(tok::l_paren) && Left.Previous &&
2446 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen)))
2448 if (Right.is(TT_ImplicitStringLiteral))
2451 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser))
2453 if (Right.is(tok::r_square) && Right.MatchingParen &&
2454 Right.MatchingParen->is(TT_LambdaLSquare))
2459 if (Right.is(tok::r_brace))
2460 return Right.MatchingParen && Right.MatchingParen->BlockKind ==
BK_Block;
2464 if (Left.is(TT_TrailingAnnotation))
2465 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
2466 tok::less, tok::coloncolon);
2468 if (Right.is(tok::kw___attribute))
2471 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
2474 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
2477 if (Left.is(TT_CtorInitializerComma) &&
2478 Style.BreakConstructorInitializersBeforeComma)
2480 if (Right.is(TT_CtorInitializerComma) &&
2481 Style.BreakConstructorInitializersBeforeComma)
2483 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
2484 (Left.is(tok::less) && Right.is(tok::less)))
2486 if (Right.is(TT_BinaryOperator) &&
2491 if (Left.is(TT_ArrayInitializerLSquare))
2493 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
2495 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
2496 !Left.isOneOf(tok::arrowstar, tok::lessless) &&
2501 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
2502 tok::kw_class, tok::kw_struct, tok::comment) ||
2503 Right.isMemberAccess() ||
2504 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
2505 tok::colon, tok::l_square, tok::at) ||
2506 (Left.is(tok::r_paren) &&
2507 Right.isOneOf(tok::identifier, tok::kw_const)) ||
2508 (Left.is(tok::l_paren) && !Right.is(tok::r_paren));
2511 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
2512 llvm::errs() <<
"AnnotatedTokens:\n";
2513 const FormatToken *Tok = Line.First;
2515 llvm::errs() <<
" M=" << Tok->MustBreakBefore
2516 <<
" C=" << Tok->CanBreakBefore
2518 <<
" S=" << Tok->SpacesRequiredBefore
2519 <<
" B=" << Tok->BlockParameterCount
2520 <<
" P=" << Tok->SplitPenalty <<
" Name=" << Tok->Tok.getName()
2521 <<
" L=" << Tok->TotalLength <<
" PPK=" << Tok->PackingKind
2523 for (
unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
2524 llvm::errs() << Tok->FakeLParens[i] <<
"/";
2525 llvm::errs() <<
" FakeRParens=" << Tok->FakeRParens <<
"\n";
2527 assert(Tok == Line.Last);
2530 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
const FormatStyle & Style
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
bool ColonIsObjCMethodExpr
const AdditionalKeywords & Keywords
detail::InMemoryDirectory::const_iterator E
SmallVector< Context, 8 > Contexts
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.