1 //===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief This file implements a token annotator, i.e. creates
12 /// \c AnnotatedTokens out of \c FormatTokens with required extra information.
14 //===----------------------------------------------------------------------===//
16 #include "TokenAnnotator.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "llvm/Support/Debug.h"
20 #define DEBUG_TYPE "format-token-annotator"
27 /// \brief A parser that gathers additional information about tokens.
29 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
30 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
31 /// into template parameter lists.
32 class AnnotatingParser
{
34 AnnotatingParser(const FormatStyle
&Style
, AnnotatedLine
&Line
,
35 const AdditionalKeywords
&Keywords
)
36 : Style(Style
), Line(Line
), CurrentToken(Line
.First
), AutoFound(false),
38 Contexts
.push_back(Context(tok::unknown
, 1, /*IsExpression=*/false));
39 resetTokenMetadata(CurrentToken
);
46 ScopedContextCreator
ContextCreator(*this, tok::less
, 10);
47 FormatToken
*Left
= CurrentToken
->Previous
;
48 Contexts
.back().IsExpression
= false;
49 // If there's a template keyword before the opening angle bracket, this is a
50 // template parameter, not an argument.
51 Contexts
.back().InTemplateArgument
=
52 Left
->Previous
&& Left
->Previous
->Tok
.isNot(tok::kw_template
);
54 if (Style
.Language
== FormatStyle::LK_Java
&&
55 CurrentToken
->is(tok::question
))
58 while (CurrentToken
) {
59 if (CurrentToken
->is(tok::greater
)) {
60 Left
->MatchingParen
= CurrentToken
;
61 CurrentToken
->MatchingParen
= Left
;
62 CurrentToken
->Type
= TT_TemplateCloser
;
66 if (CurrentToken
->is(tok::question
) &&
67 Style
.Language
== FormatStyle::LK_Java
) {
71 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::r_brace
,
72 tok::colon
, tok::question
))
74 // If a && or || is found and interpreted as a binary operator, this set
75 // of angles is likely part of something like "a < b && c > d". If the
76 // angles are inside an expression, the ||/&& might also be a binary
77 // operator that was misinterpreted because we are parsing template
79 // FIXME: This is getting out of hand, write a decent parser.
80 if (CurrentToken
->Previous
->isOneOf(tok::pipepipe
, tok::ampamp
) &&
81 CurrentToken
->Previous
->is(TT_BinaryOperator
) &&
82 Contexts
[Contexts
.size() - 2].IsExpression
&&
83 Line
.First
->isNot(tok::kw_template
))
85 updateParameterCount(Left
, CurrentToken
);
92 bool parseParens(bool LookForDecls
= false) {
95 ScopedContextCreator
ContextCreator(*this, tok::l_paren
, 1);
97 // FIXME: This is a bit of a hack. Do better.
98 Contexts
.back().ColonIsForRangeExpr
=
99 Contexts
.size() == 2 && Contexts
[0].ColonIsForRangeExpr
;
101 bool StartsObjCMethodExpr
= false;
102 FormatToken
*Left
= CurrentToken
->Previous
;
103 if (CurrentToken
->is(tok::caret
)) {
104 // (^ can start a block type.
105 Left
->Type
= TT_ObjCBlockLParen
;
106 } else if (FormatToken
*MaybeSel
= Left
->Previous
) {
107 // @selector( starts a selector.
108 if (MaybeSel
->isObjCAtKeyword(tok::objc_selector
) && MaybeSel
->Previous
&&
109 MaybeSel
->Previous
->is(tok::at
)) {
110 StartsObjCMethodExpr
= true;
114 if (Left
->Previous
&&
115 (Left
->Previous
->isOneOf(tok::kw_static_assert
, tok::kw_if
,
116 tok::kw_while
, tok::l_paren
, tok::comma
) ||
117 Left
->Previous
->is(TT_BinaryOperator
))) {
118 // static_assert, if and while usually contain expressions.
119 Contexts
.back().IsExpression
= true;
120 } else if (Line
.InPPDirective
&&
122 !Left
->Previous
->isOneOf(tok::identifier
,
123 TT_OverloadedOperator
))) {
124 Contexts
.back().IsExpression
= true;
125 } else if (Left
->Previous
&& Left
->Previous
->is(tok::r_square
) &&
126 Left
->Previous
->MatchingParen
&&
127 Left
->Previous
->MatchingParen
->is(TT_LambdaLSquare
)) {
128 // This is a parameter list of a lambda expression.
129 Contexts
.back().IsExpression
= false;
130 } else if (Contexts
[Contexts
.size() - 2].CaretFound
) {
131 // This is the parameter list of an ObjC block.
132 Contexts
.back().IsExpression
= false;
133 } else if (Left
->Previous
&& Left
->Previous
->is(tok::kw___attribute
)) {
134 Left
->Type
= TT_AttributeParen
;
135 } else if (Left
->Previous
&& Left
->Previous
->IsForEachMacro
) {
136 // The first argument to a foreach macro is a declaration.
137 Contexts
.back().IsForEachMacro
= true;
138 Contexts
.back().IsExpression
= false;
139 } else if (Left
->Previous
&& Left
->Previous
->MatchingParen
&&
140 Left
->Previous
->MatchingParen
->is(TT_ObjCBlockLParen
)) {
141 Contexts
.back().IsExpression
= false;
144 if (StartsObjCMethodExpr
) {
145 Contexts
.back().ColonIsObjCMethodExpr
= true;
146 Left
->Type
= TT_ObjCMethodExpr
;
149 bool MightBeFunctionType
= CurrentToken
->is(tok::star
);
150 bool HasMultipleLines
= false;
151 bool HasMultipleParametersOnALine
= false;
152 while (CurrentToken
) {
153 // LookForDecls is set when "if (" has been seen. Check for
154 // 'identifier' '*' 'identifier' followed by not '=' -- this
155 // '*' has to be a binary operator but determineStarAmpUsage() will
156 // categorize it as an unary operator, so set the right type here.
157 if (LookForDecls
&& CurrentToken
->Next
) {
158 FormatToken
*Prev
= CurrentToken
->getPreviousNonComment();
160 FormatToken
*PrevPrev
= Prev
->getPreviousNonComment();
161 FormatToken
*Next
= CurrentToken
->Next
;
162 if (PrevPrev
&& PrevPrev
->is(tok::identifier
) &&
163 Prev
->isOneOf(tok::star
, tok::amp
, tok::ampamp
) &&
164 CurrentToken
->is(tok::identifier
) && Next
->isNot(tok::equal
)) {
165 Prev
->Type
= TT_BinaryOperator
;
166 LookForDecls
= false;
171 if (CurrentToken
->Previous
->is(TT_PointerOrReference
) &&
172 CurrentToken
->Previous
->Previous
->isOneOf(tok::l_paren
,
174 MightBeFunctionType
= true;
175 if (CurrentToken
->Previous
->is(TT_BinaryOperator
))
176 Contexts
.back().IsExpression
= true;
177 if (CurrentToken
->is(tok::r_paren
)) {
178 if (MightBeFunctionType
&& CurrentToken
->Next
&&
179 (CurrentToken
->Next
->is(tok::l_paren
) ||
180 (CurrentToken
->Next
->is(tok::l_square
) &&
181 !Contexts
.back().IsExpression
)))
182 Left
->Type
= TT_FunctionTypeLParen
;
183 Left
->MatchingParen
= CurrentToken
;
184 CurrentToken
->MatchingParen
= Left
;
186 if (StartsObjCMethodExpr
) {
187 CurrentToken
->Type
= TT_ObjCMethodExpr
;
188 if (Contexts
.back().FirstObjCSelectorName
) {
189 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
190 Contexts
.back().LongestObjCSelectorName
;
194 if (Left
->is(TT_AttributeParen
))
195 CurrentToken
->Type
= TT_AttributeParen
;
196 if (Left
->Previous
&& Left
->Previous
->is(TT_JavaAnnotation
))
197 CurrentToken
->Type
= TT_JavaAnnotation
;
198 if (Left
->Previous
&& Left
->Previous
->is(TT_LeadingJavaAnnotation
))
199 CurrentToken
->Type
= TT_LeadingJavaAnnotation
;
201 if (!HasMultipleLines
)
202 Left
->PackingKind
= PPK_Inconclusive
;
203 else if (HasMultipleParametersOnALine
)
204 Left
->PackingKind
= PPK_BinPacked
;
206 Left
->PackingKind
= PPK_OnePerLine
;
211 if (CurrentToken
->isOneOf(tok::r_square
, tok::r_brace
))
213 else if (CurrentToken
->is(tok::l_brace
))
214 Left
->Type
= TT_Unknown
; // Not TT_ObjCBlockLParen
215 if (CurrentToken
->is(tok::comma
) && CurrentToken
->Next
&&
216 !CurrentToken
->Next
->HasUnescapedNewline
&&
217 !CurrentToken
->Next
->isTrailingComment())
218 HasMultipleParametersOnALine
= true;
219 if (CurrentToken
->isOneOf(tok::kw_const
, tok::kw_auto
) ||
220 CurrentToken
->isSimpleTypeSpecifier())
221 Contexts
.back().IsExpression
= false;
222 FormatToken
*Tok
= CurrentToken
;
225 updateParameterCount(Left
, Tok
);
226 if (CurrentToken
&& CurrentToken
->HasUnescapedNewline
)
227 HasMultipleLines
= true;
236 // A '[' could be an index subscript (after an identifier or after
237 // ')' or ']'), it could be the start of an Objective-C method
238 // expression, or it could the the start of an Objective-C array literal.
239 FormatToken
*Left
= CurrentToken
->Previous
;
240 FormatToken
*Parent
= Left
->getPreviousNonComment();
241 bool StartsObjCMethodExpr
=
242 Contexts
.back().CanBeExpression
&& Left
->isNot(TT_LambdaLSquare
) &&
243 CurrentToken
->isNot(tok::l_brace
) &&
245 Parent
->isOneOf(tok::colon
, tok::l_square
, tok::l_paren
,
246 tok::kw_return
, tok::kw_throw
) ||
247 Parent
->isUnaryOperator() ||
248 Parent
->isOneOf(TT_ObjCForIn
, TT_CastRParen
) ||
249 getBinOpPrecedence(Parent
->Tok
.getKind(), true, true) > prec::Unknown
);
250 ScopedContextCreator
ContextCreator(*this, tok::l_square
, 10);
251 Contexts
.back().IsExpression
= true;
252 bool ColonFound
= false;
254 if (StartsObjCMethodExpr
) {
255 Contexts
.back().ColonIsObjCMethodExpr
= true;
256 Left
->Type
= TT_ObjCMethodExpr
;
257 } else if (Parent
&& Parent
->is(tok::at
)) {
258 Left
->Type
= TT_ArrayInitializerLSquare
;
259 } else if (Left
->is(TT_Unknown
)) {
260 Left
->Type
= TT_ArraySubscriptLSquare
;
263 while (CurrentToken
) {
264 if (CurrentToken
->is(tok::r_square
)) {
265 if (CurrentToken
->Next
&& CurrentToken
->Next
->is(tok::l_paren
) &&
266 Left
->is(TT_ObjCMethodExpr
)) {
267 // An ObjC method call is rarely followed by an open parenthesis.
268 // FIXME: Do we incorrectly label ":" with this?
269 StartsObjCMethodExpr
= false;
270 Left
->Type
= TT_Unknown
;
272 if (StartsObjCMethodExpr
&& CurrentToken
->Previous
!= Left
) {
273 CurrentToken
->Type
= TT_ObjCMethodExpr
;
274 // determineStarAmpUsage() thinks that '*' '[' is allocating an
275 // array of pointers, but if '[' starts a selector then '*' is a
277 if (Parent
&& Parent
->is(TT_PointerOrReference
))
278 Parent
->Type
= TT_BinaryOperator
;
280 Left
->MatchingParen
= CurrentToken
;
281 CurrentToken
->MatchingParen
= Left
;
282 if (Contexts
.back().FirstObjCSelectorName
) {
283 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
284 Contexts
.back().LongestObjCSelectorName
;
285 if (Left
->BlockParameterCount
> 1)
286 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
= 0;
291 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_brace
))
293 if (CurrentToken
->is(tok::colon
)) {
294 if (Left
->is(TT_ArraySubscriptLSquare
)) {
295 Left
->Type
= TT_ObjCMethodExpr
;
296 StartsObjCMethodExpr
= true;
297 Contexts
.back().ColonIsObjCMethodExpr
= true;
298 if (Parent
&& Parent
->is(tok::r_paren
))
299 Parent
->Type
= TT_CastRParen
;
303 if (CurrentToken
->is(tok::comma
) &&
304 Style
.Language
!= FormatStyle::LK_Proto
&&
305 (Left
->is(TT_ArraySubscriptLSquare
) ||
306 (Left
->is(TT_ObjCMethodExpr
) && !ColonFound
)))
307 Left
->Type
= TT_ArrayInitializerLSquare
;
308 FormatToken
*Tok
= CurrentToken
;
311 updateParameterCount(Left
, Tok
);
318 FormatToken
*Left
= CurrentToken
->Previous
;
320 if (Contexts
.back().CaretFound
)
321 Left
->Type
= TT_ObjCBlockLBrace
;
322 Contexts
.back().CaretFound
= false;
324 ScopedContextCreator
ContextCreator(*this, tok::l_brace
, 1);
325 Contexts
.back().ColonIsDictLiteral
= true;
326 if (Left
->BlockKind
== BK_BracedInit
)
327 Contexts
.back().IsExpression
= true;
329 while (CurrentToken
) {
330 if (CurrentToken
->is(tok::r_brace
)) {
331 Left
->MatchingParen
= CurrentToken
;
332 CurrentToken
->MatchingParen
= Left
;
336 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
))
338 updateParameterCount(Left
, CurrentToken
);
339 if (CurrentToken
->isOneOf(tok::colon
, tok::l_brace
)) {
340 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
341 if ((CurrentToken
->is(tok::colon
) ||
342 Style
.Language
== FormatStyle::LK_Proto
) &&
343 Previous
->is(tok::identifier
))
344 Previous
->Type
= TT_SelectorName
;
345 if (CurrentToken
->is(tok::colon
))
346 Left
->Type
= TT_DictLiteral
;
355 void updateParameterCount(FormatToken
*Left
, FormatToken
*Current
) {
356 if (Current
->is(TT_LambdaLSquare
) ||
357 (Current
->is(tok::caret
) && Current
->is(TT_UnaryOperator
)) ||
358 (Style
.Language
== FormatStyle::LK_JavaScript
&&
359 Current
->is(Keywords
.kw_function
))) {
360 ++Left
->BlockParameterCount
;
362 if (Current
->is(tok::comma
)) {
363 ++Left
->ParameterCount
;
365 Left
->Role
.reset(new CommaSeparatedList(Style
));
366 Left
->Role
->CommaFound(Current
);
367 } else if (Left
->ParameterCount
== 0 && Current
->isNot(tok::comment
)) {
368 Left
->ParameterCount
= 1;
372 bool parseConditional() {
373 while (CurrentToken
) {
374 if (CurrentToken
->is(tok::colon
)) {
375 CurrentToken
->Type
= TT_ConditionalExpr
;
385 bool parseTemplateDeclaration() {
386 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
387 CurrentToken
->Type
= TT_TemplateOpener
;
392 CurrentToken
->Previous
->ClosesTemplateDeclaration
= true;
398 bool consumeToken() {
399 FormatToken
*Tok
= CurrentToken
;
401 switch (Tok
->Tok
.getKind()) {
404 if (!Tok
->Previous
&& Line
.MustBeDeclaration
)
405 Tok
->Type
= TT_ObjCMethodSpecifier
;
410 // Colons from ?: are handled in parseConditional().
411 if (Tok
->Previous
->is(tok::r_paren
) && Contexts
.size() == 1 &&
412 Line
.First
->isNot(tok::kw_case
)) {
413 Tok
->Type
= TT_CtorInitializerColon
;
414 } else if (Contexts
.back().ColonIsDictLiteral
) {
415 Tok
->Type
= TT_DictLiteral
;
416 } else if (Contexts
.back().ColonIsObjCMethodExpr
||
417 Line
.First
->is(TT_ObjCMethodSpecifier
)) {
418 Tok
->Type
= TT_ObjCMethodExpr
;
419 Tok
->Previous
->Type
= TT_SelectorName
;
420 if (Tok
->Previous
->ColumnWidth
>
421 Contexts
.back().LongestObjCSelectorName
) {
422 Contexts
.back().LongestObjCSelectorName
= Tok
->Previous
->ColumnWidth
;
424 if (!Contexts
.back().FirstObjCSelectorName
)
425 Contexts
.back().FirstObjCSelectorName
= Tok
->Previous
;
426 } else if (Contexts
.back().ColonIsForRangeExpr
) {
427 Tok
->Type
= TT_RangeBasedForLoopColon
;
428 } else if (CurrentToken
&& CurrentToken
->is(tok::numeric_constant
)) {
429 Tok
->Type
= TT_BitFieldColon
;
430 } else if (Contexts
.size() == 1 &&
431 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
)) {
432 Tok
->Type
= TT_InheritanceColon
;
433 } else if (Tok
->Previous
->is(tok::identifier
) && Tok
->Next
&&
434 Tok
->Next
->isOneOf(tok::r_paren
, tok::comma
)) {
435 // This handles a special macro in ObjC code where selectors including
436 // the colon are passed as macro arguments.
437 Tok
->Type
= TT_ObjCMethodExpr
;
438 } else if (Contexts
.back().ContextKind
== tok::l_paren
) {
439 Tok
->Type
= TT_InlineASMColon
;
444 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
)) {
446 if (!parseParens(/*LookForDecls=*/true))
451 Contexts
.back().ColonIsForRangeExpr
= true;
459 if (Line
.MustBeDeclaration
&& Contexts
.size() == 1 &&
460 !Contexts
.back().IsExpression
&& Line
.First
->isNot(TT_ObjCProperty
) &&
462 !Tok
->Previous
->isOneOf(tok::kw_decltype
, TT_LeadingJavaAnnotation
)))
463 Line
.MightBeFunctionDecl
= true;
474 if ((!Tok
->Previous
||
475 (!Tok
->Previous
->Tok
.isLiteral() &&
476 !(Tok
->Previous
->is(tok::r_paren
) && Contexts
.size() > 1))) &&
478 Tok
->Type
= TT_TemplateOpener
;
480 Tok
->Type
= TT_BinaryOperator
;
489 // Lines can start with '}'.
494 Tok
->Type
= TT_BinaryOperator
;
496 case tok::kw_operator
:
497 while (CurrentToken
&&
498 !CurrentToken
->isOneOf(tok::l_paren
, tok::semi
, tok::r_paren
)) {
499 if (CurrentToken
->isOneOf(tok::star
, tok::amp
))
500 CurrentToken
->Type
= TT_PointerOrReference
;
502 if (CurrentToken
&& CurrentToken
->Previous
->is(TT_BinaryOperator
))
503 CurrentToken
->Previous
->Type
= TT_OverloadedOperator
;
506 CurrentToken
->Type
= TT_OverloadedOperatorLParen
;
507 if (CurrentToken
->Previous
->is(TT_BinaryOperator
))
508 CurrentToken
->Previous
->Type
= TT_OverloadedOperator
;
514 case tok::kw_template
:
515 parseTemplateDeclaration();
517 case tok::identifier
:
518 if (Line
.First
->is(tok::kw_for
) && Tok
->is(Keywords
.kw_in
) &&
519 Tok
->Previous
->isNot(tok::colon
))
520 Tok
->Type
= TT_ObjCForIn
;
523 if (Contexts
.back().FirstStartOfName
)
524 Contexts
.back().FirstStartOfName
->PartOfMultiVariableDeclStmt
= true;
525 if (Contexts
.back().InCtorInitializer
)
526 Tok
->Type
= TT_CtorInitializerComma
;
527 if (Contexts
.back().IsForEachMacro
)
528 Contexts
.back().IsExpression
= true;
536 void parseIncludeDirective() {
537 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
539 while (CurrentToken
) {
540 if (CurrentToken
->isNot(tok::comment
) || CurrentToken
->Next
)
541 CurrentToken
->Type
= TT_ImplicitStringLiteral
;
547 void parseWarningOrError() {
549 // We still want to format the whitespace left of the first token of the
552 while (CurrentToken
) {
553 CurrentToken
->Type
= TT_ImplicitStringLiteral
;
559 next(); // Consume "pragma".
560 if (CurrentToken
&& CurrentToken
->TokenText
== "mark") {
561 next(); // Consume "mark".
562 next(); // Consume first token (so we fix leading whitespace).
563 while (CurrentToken
) {
564 CurrentToken
->Type
= TT_ImplicitStringLiteral
;
570 LineType
parsePreprocessorDirective() {
571 LineType Type
= LT_PreprocessorDirective
;
575 if (CurrentToken
->Tok
.is(tok::numeric_constant
)) {
576 CurrentToken
->SpacesRequiredBefore
= 1;
579 // Hashes in the middle of a line can lead to any strange token
581 if (!CurrentToken
->Tok
.getIdentifierInfo())
583 switch (CurrentToken
->Tok
.getIdentifierInfo()->getPPKeywordID()) {
584 case tok::pp_include
:
587 parseIncludeDirective();
588 Type
= LT_ImportStatement
;
591 case tok::pp_warning
:
592 parseWarningOrError();
599 Contexts
.back().IsExpression
= true;
611 LineType
parseLine() {
612 if (CurrentToken
->is(tok::hash
)) {
613 return parsePreprocessorDirective();
616 // Directly allow to 'import <string-literal>' to support protocol buffer
617 // definitions (code.google.com/p/protobuf) or missing "#" (either way we
618 // should not break the line).
619 IdentifierInfo
*Info
= CurrentToken
->Tok
.getIdentifierInfo();
620 if ((Style
.Language
== FormatStyle::LK_Java
&&
621 CurrentToken
->is(Keywords
.kw_package
)) ||
622 (Info
&& Info
->getPPKeywordID() == tok::pp_import
&&
623 CurrentToken
->Next
&&
624 CurrentToken
->Next
->isOneOf(tok::string_literal
, tok::identifier
,
627 parseIncludeDirective();
628 return LT_ImportStatement
;
631 // If this line starts and ends in '<' and '>', respectively, it is likely
632 // part of "#define <a/b.h>".
633 if (CurrentToken
->is(tok::less
) && Line
.Last
->is(tok::greater
)) {
634 parseIncludeDirective();
635 return LT_ImportStatement
;
638 bool KeywordVirtualFound
= false;
639 bool ImportStatement
= false;
640 while (CurrentToken
) {
641 if (CurrentToken
->is(tok::kw_virtual
))
642 KeywordVirtualFound
= true;
643 if (IsImportStatement(*CurrentToken
))
644 ImportStatement
= true;
648 if (KeywordVirtualFound
)
649 return LT_VirtualFunctionDecl
;
651 return LT_ImportStatement
;
653 if (Line
.First
->is(TT_ObjCMethodSpecifier
)) {
654 if (Contexts
.back().FirstObjCSelectorName
)
655 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
656 Contexts
.back().LongestObjCSelectorName
;
657 return LT_ObjCMethodDecl
;
664 bool IsImportStatement(const FormatToken
&Tok
) {
665 // FIXME: Closure-library specific stuff should not be hard-coded but be
667 return Style
.Language
== FormatStyle::LK_JavaScript
&&
668 Tok
.TokenText
== "goog" && Tok
.Next
&& Tok
.Next
->is(tok::period
) &&
669 Tok
.Next
->Next
&& (Tok
.Next
->Next
->TokenText
== "module" ||
670 Tok
.Next
->Next
->TokenText
== "require" ||
671 Tok
.Next
->Next
->TokenText
== "provide") &&
672 Tok
.Next
->Next
->Next
&& Tok
.Next
->Next
->Next
->is(tok::l_paren
);
675 void resetTokenMetadata(FormatToken
*Token
) {
679 // Reset token type in case we have already looked at it and then
680 // recovered from an error (e.g. failure to find the matching >).
681 if (!CurrentToken
->isOneOf(TT_LambdaLSquare
, TT_FunctionLBrace
,
682 TT_ImplicitStringLiteral
, TT_RegexLiteral
,
683 TT_TrailingReturnArrow
))
684 CurrentToken
->Type
= TT_Unknown
;
685 CurrentToken
->Role
.reset();
686 CurrentToken
->FakeLParens
.clear();
687 CurrentToken
->FakeRParens
= 0;
692 CurrentToken
->NestingLevel
= Contexts
.size() - 1;
693 CurrentToken
->BindingStrength
= Contexts
.back().BindingStrength
;
694 modifyContext(*CurrentToken
);
695 determineTokenType(*CurrentToken
);
696 CurrentToken
= CurrentToken
->Next
;
699 resetTokenMetadata(CurrentToken
);
702 /// \brief A struct to hold information valid in a specific context, e.g.
703 /// a pair of parenthesis.
705 Context(tok::TokenKind ContextKind
, unsigned BindingStrength
,
707 : ContextKind(ContextKind
), BindingStrength(BindingStrength
),
708 LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
709 ColonIsDictLiteral(false), ColonIsObjCMethodExpr(false),
710 FirstObjCSelectorName(nullptr), FirstStartOfName(nullptr),
711 IsExpression(IsExpression
), CanBeExpression(true),
712 InTemplateArgument(false), InCtorInitializer(false),
713 CaretFound(false), IsForEachMacro(false) {}
715 tok::TokenKind ContextKind
;
716 unsigned BindingStrength
;
717 unsigned LongestObjCSelectorName
;
718 bool ColonIsForRangeExpr
;
719 bool ColonIsDictLiteral
;
720 bool ColonIsObjCMethodExpr
;
721 FormatToken
*FirstObjCSelectorName
;
722 FormatToken
*FirstStartOfName
;
724 bool CanBeExpression
;
725 bool InTemplateArgument
;
726 bool InCtorInitializer
;
731 /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
732 /// of each instance.
733 struct ScopedContextCreator
{
736 ScopedContextCreator(AnnotatingParser
&P
, tok::TokenKind ContextKind
,
739 P
.Contexts
.push_back(Context(ContextKind
,
740 P
.Contexts
.back().BindingStrength
+ Increase
,
741 P
.Contexts
.back().IsExpression
));
744 ~ScopedContextCreator() { P
.Contexts
.pop_back(); }
747 void modifyContext(const FormatToken
&Current
) {
748 if (Current
.getPrecedence() == prec::Assignment
&&
749 !Line
.First
->isOneOf(tok::kw_template
, tok::kw_using
,
751 (!Current
.Previous
|| Current
.Previous
->isNot(tok::kw_operator
))) {
752 Contexts
.back().IsExpression
= true;
753 for (FormatToken
*Previous
= Current
.Previous
;
754 Previous
&& !Previous
->isOneOf(tok::comma
, tok::semi
);
755 Previous
= Previous
->Previous
) {
756 if (Previous
->isOneOf(tok::r_square
, tok::r_paren
)) {
757 Previous
= Previous
->MatchingParen
;
761 if (Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
) &&
762 Previous
->isOneOf(tok::star
, tok::amp
) && Previous
->Previous
&&
763 Previous
->Previous
->isNot(tok::equal
))
764 Previous
->Type
= TT_PointerOrReference
;
766 } else if (Current
.isOneOf(tok::kw_return
, tok::kw_throw
)) {
767 Contexts
.back().IsExpression
= true;
768 } else if (Current
.is(TT_TrailingReturnArrow
)) {
769 Contexts
.back().IsExpression
= false;
770 } else if (Current
.is(tok::l_paren
) && !Line
.MustBeDeclaration
&&
771 !Line
.InPPDirective
&&
772 (!Current
.Previous
||
773 Current
.Previous
->isNot(tok::kw_decltype
))) {
774 bool ParametersOfFunctionType
=
775 Current
.Previous
&& Current
.Previous
->is(tok::r_paren
) &&
776 Current
.Previous
->MatchingParen
&&
777 Current
.Previous
->MatchingParen
->is(TT_FunctionTypeLParen
);
778 bool IsForOrCatch
= Current
.Previous
&&
779 Current
.Previous
->isOneOf(tok::kw_for
, tok::kw_catch
);
780 Contexts
.back().IsExpression
= !ParametersOfFunctionType
&& !IsForOrCatch
;
781 } else if (Current
.isOneOf(tok::r_paren
, tok::greater
, tok::comma
)) {
782 for (FormatToken
*Previous
= Current
.Previous
;
783 Previous
&& Previous
->isOneOf(tok::star
, tok::amp
);
784 Previous
= Previous
->Previous
)
785 Previous
->Type
= TT_PointerOrReference
;
786 if (Line
.MustBeDeclaration
)
787 Contexts
.back().IsExpression
= Contexts
.front().InCtorInitializer
;
788 } else if (Current
.Previous
&&
789 Current
.Previous
->is(TT_CtorInitializerColon
)) {
790 Contexts
.back().IsExpression
= true;
791 Contexts
.back().InCtorInitializer
= true;
792 } else if (Current
.is(tok::kw_new
)) {
793 Contexts
.back().CanBeExpression
= false;
794 } else if (Current
.is(tok::semi
) || Current
.is(tok::exclaim
)) {
795 // This should be the condition or increment in a for-loop.
796 Contexts
.back().IsExpression
= true;
800 void determineTokenType(FormatToken
&Current
) {
801 if (!Current
.is(TT_Unknown
))
802 // The token type is already known.
805 // Line.MightBeFunctionDecl can only be true after the parentheses of a
806 // function declaration have been found. In this case, 'Current' is a
807 // trailing token of this declaration and thus cannot be a name.
808 if (Current
.is(Keywords
.kw_instanceof
)) {
809 Current
.Type
= TT_BinaryOperator
;
810 } else if (isStartOfName(Current
) &&
811 (!Line
.MightBeFunctionDecl
|| Current
.NestingLevel
!= 0)) {
812 Contexts
.back().FirstStartOfName
= &Current
;
813 Current
.Type
= TT_StartOfName
;
814 } else if (Current
.is(tok::kw_auto
)) {
816 } else if (Current
.is(tok::arrow
) &&
817 Style
.Language
== FormatStyle::LK_Java
) {
818 Current
.Type
= TT_LambdaArrow
;
819 } else if (Current
.is(tok::arrow
) && AutoFound
&& Line
.MustBeDeclaration
&&
820 Current
.NestingLevel
== 0) {
821 Current
.Type
= TT_TrailingReturnArrow
;
822 } else if (Current
.isOneOf(tok::star
, tok::amp
, tok::ampamp
)) {
824 determineStarAmpUsage(Current
, Contexts
.back().CanBeExpression
&&
825 Contexts
.back().IsExpression
,
826 Contexts
.back().InTemplateArgument
);
827 } else if (Current
.isOneOf(tok::minus
, tok::plus
, tok::caret
)) {
828 Current
.Type
= determinePlusMinusCaretUsage(Current
);
829 if (Current
.is(TT_UnaryOperator
) && Current
.is(tok::caret
))
830 Contexts
.back().CaretFound
= true;
831 } else if (Current
.isOneOf(tok::minusminus
, tok::plusplus
)) {
832 Current
.Type
= determineIncrementUsage(Current
);
833 } else if (Current
.isOneOf(tok::exclaim
, tok::tilde
)) {
834 Current
.Type
= TT_UnaryOperator
;
835 } else if (Current
.is(tok::question
)) {
836 Current
.Type
= TT_ConditionalExpr
;
837 } else if (Current
.isBinaryOperator() &&
838 (!Current
.Previous
|| Current
.Previous
->isNot(tok::l_square
))) {
839 Current
.Type
= TT_BinaryOperator
;
840 } else if (Current
.is(tok::comment
)) {
841 if (Current
.TokenText
.startswith("//"))
842 Current
.Type
= TT_LineComment
;
844 Current
.Type
= TT_BlockComment
;
845 } else if (Current
.is(tok::r_paren
)) {
846 if (rParenEndsCast(Current
))
847 Current
.Type
= TT_CastRParen
;
848 } else if (Current
.is(tok::at
) && Current
.Next
) {
849 switch (Current
.Next
->Tok
.getObjCKeywordID()) {
850 case tok::objc_interface
:
851 case tok::objc_implementation
:
852 case tok::objc_protocol
:
853 Current
.Type
= TT_ObjCDecl
;
855 case tok::objc_property
:
856 Current
.Type
= TT_ObjCProperty
;
861 } else if (Current
.is(tok::period
)) {
862 FormatToken
*PreviousNoComment
= Current
.getPreviousNonComment();
863 if (PreviousNoComment
&&
864 PreviousNoComment
->isOneOf(tok::comma
, tok::l_brace
))
865 Current
.Type
= TT_DesignatedInitializerPeriod
;
866 else if (Style
.Language
== FormatStyle::LK_Java
&& Current
.Previous
&&
867 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
868 TT_LeadingJavaAnnotation
)) {
869 Current
.Type
= Current
.Previous
->Type
;
871 } else if (Current
.isOneOf(tok::identifier
, tok::kw_const
) &&
873 !Current
.Previous
->isOneOf(tok::equal
, tok::at
) &&
874 Line
.MightBeFunctionDecl
&& Contexts
.size() == 1) {
875 // Line.MightBeFunctionDecl can only be true after the parentheses of a
876 // function declaration have been found.
877 Current
.Type
= TT_TrailingAnnotation
;
878 } else if (Style
.Language
== FormatStyle::LK_Java
&& Current
.Previous
) {
879 if (Current
.Previous
->is(tok::at
) &&
880 Current
.isNot(Keywords
.kw_interface
)) {
881 const FormatToken
&AtToken
= *Current
.Previous
;
882 const FormatToken
*Previous
= AtToken
.getPreviousNonComment();
883 if (!Previous
|| Previous
->is(TT_LeadingJavaAnnotation
))
884 Current
.Type
= TT_LeadingJavaAnnotation
;
886 Current
.Type
= TT_JavaAnnotation
;
887 } else if (Current
.Previous
->is(tok::period
) &&
888 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
889 TT_LeadingJavaAnnotation
)) {
890 Current
.Type
= Current
.Previous
->Type
;
895 /// \brief Take a guess at whether \p Tok starts a name of a function or
896 /// variable declaration.
898 /// This is a heuristic based on whether \p Tok is an identifier following
899 /// something that is likely a type.
900 bool isStartOfName(const FormatToken
&Tok
) {
901 if (Tok
.isNot(tok::identifier
) || !Tok
.Previous
)
904 if (Tok
.Previous
->is(TT_LeadingJavaAnnotation
))
907 // Skip "const" as it does not have an influence on whether this is a name.
908 FormatToken
*PreviousNotConst
= Tok
.Previous
;
909 while (PreviousNotConst
&& PreviousNotConst
->is(tok::kw_const
))
910 PreviousNotConst
= PreviousNotConst
->Previous
;
912 if (!PreviousNotConst
)
915 bool IsPPKeyword
= PreviousNotConst
->is(tok::identifier
) &&
916 PreviousNotConst
->Previous
&&
917 PreviousNotConst
->Previous
->is(tok::hash
);
919 if (PreviousNotConst
->is(TT_TemplateCloser
))
920 return PreviousNotConst
&& PreviousNotConst
->MatchingParen
&&
921 PreviousNotConst
->MatchingParen
->Previous
&&
922 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::period
) &&
923 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::kw_template
);
925 if (PreviousNotConst
->is(tok::r_paren
) && PreviousNotConst
->MatchingParen
&&
926 PreviousNotConst
->MatchingParen
->Previous
&&
927 PreviousNotConst
->MatchingParen
->Previous
->is(tok::kw_decltype
))
930 return (!IsPPKeyword
&& PreviousNotConst
->is(tok::identifier
)) ||
931 PreviousNotConst
->is(TT_PointerOrReference
) ||
932 PreviousNotConst
->isSimpleTypeSpecifier();
935 /// \brief Determine whether ')' is ending a cast.
936 bool rParenEndsCast(const FormatToken
&Tok
) {
937 FormatToken
*LeftOfParens
= nullptr;
938 if (Tok
.MatchingParen
)
939 LeftOfParens
= Tok
.MatchingParen
->getPreviousNonComment();
940 if (LeftOfParens
&& LeftOfParens
->is(tok::r_paren
) &&
941 LeftOfParens
->MatchingParen
)
942 LeftOfParens
= LeftOfParens
->MatchingParen
->Previous
;
943 if (LeftOfParens
&& LeftOfParens
->is(tok::r_square
) &&
944 LeftOfParens
->MatchingParen
&&
945 LeftOfParens
->MatchingParen
->is(TT_LambdaLSquare
))
948 if (Tok
.Next
->is(tok::question
))
950 if (Style
.Language
== FormatStyle::LK_JavaScript
&&
951 Tok
.Next
->is(Keywords
.kw_in
))
953 if (Style
.Language
== FormatStyle::LK_Java
&& Tok
.Next
->is(tok::l_paren
))
957 bool ParensAreEmpty
= Tok
.Previous
== Tok
.MatchingParen
;
960 Tok
.Previous
->isOneOf(TT_PointerOrReference
, TT_TemplateCloser
) ||
961 Tok
.Previous
->isSimpleTypeSpecifier();
962 bool ParensCouldEndDecl
=
963 Tok
.Next
&& Tok
.Next
->isOneOf(tok::equal
, tok::semi
, tok::l_brace
);
964 bool IsSizeOfOrAlignOf
=
965 LeftOfParens
&& LeftOfParens
->isOneOf(tok::kw_sizeof
, tok::kw_alignof
);
966 if (ParensAreType
&& !ParensCouldEndDecl
&& !IsSizeOfOrAlignOf
&&
967 ((Contexts
.size() > 1 && Contexts
[Contexts
.size() - 2].IsExpression
) ||
968 (Tok
.Next
&& Tok
.Next
->isBinaryOperator())))
970 else if (Tok
.Next
&& Tok
.Next
->isNot(tok::string_literal
) &&
971 (Tok
.Next
->Tok
.isLiteral() ||
972 Tok
.Next
->isOneOf(tok::kw_sizeof
, tok::kw_alignof
)))
974 // If there is an identifier after the (), it is likely a cast, unless
975 // there is also an identifier before the ().
976 else if (LeftOfParens
&& Tok
.Next
&&
977 (LeftOfParens
->Tok
.getIdentifierInfo() == nullptr ||
978 LeftOfParens
->is(tok::kw_return
)) &&
979 !LeftOfParens
->isOneOf(TT_OverloadedOperator
, tok::at
,
980 TT_TemplateCloser
)) {
981 if (Tok
.Next
->isOneOf(tok::identifier
, tok::numeric_constant
)) {
984 // Use heuristics to recognize c style casting.
985 FormatToken
*Prev
= Tok
.Previous
;
986 if (Prev
&& Prev
->isOneOf(tok::amp
, tok::star
))
987 Prev
= Prev
->Previous
;
989 if (Prev
&& Tok
.Next
&& Tok
.Next
->Next
) {
990 bool NextIsUnary
= Tok
.Next
->isUnaryOperator() ||
991 Tok
.Next
->isOneOf(tok::amp
, tok::star
);
993 NextIsUnary
&& !Tok
.Next
->is(tok::plus
) &&
994 Tok
.Next
->Next
->isOneOf(tok::identifier
, tok::numeric_constant
);
997 for (; Prev
!= Tok
.MatchingParen
; Prev
= Prev
->Previous
) {
998 if (!Prev
|| !Prev
->isOneOf(tok::kw_const
, tok::identifier
)) {
1005 return IsCast
&& !ParensAreEmpty
;
1008 /// \brief Return the type of the given token assuming it is * or &.
1009 TokenType
determineStarAmpUsage(const FormatToken
&Tok
, bool IsExpression
,
1010 bool InTemplateArgument
) {
1011 if (Style
.Language
== FormatStyle::LK_JavaScript
)
1012 return TT_BinaryOperator
;
1014 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
1016 return TT_UnaryOperator
;
1018 const FormatToken
*NextToken
= Tok
.getNextNonComment();
1020 (NextToken
->is(tok::l_brace
) && !NextToken
->getNextNonComment()))
1023 if (PrevToken
->is(tok::coloncolon
))
1024 return TT_PointerOrReference
;
1026 if (PrevToken
->isOneOf(tok::l_paren
, tok::l_square
, tok::l_brace
,
1027 tok::comma
, tok::semi
, tok::kw_return
, tok::colon
,
1028 tok::equal
, tok::kw_delete
, tok::kw_sizeof
) ||
1029 PrevToken
->isOneOf(TT_BinaryOperator
, TT_ConditionalExpr
,
1030 TT_UnaryOperator
, TT_CastRParen
))
1031 return TT_UnaryOperator
;
1033 if (NextToken
->is(tok::l_square
) && NextToken
->isNot(TT_LambdaLSquare
))
1034 return TT_PointerOrReference
;
1035 if (NextToken
->isOneOf(tok::kw_operator
, tok::comma
))
1036 return TT_PointerOrReference
;
1038 if (PrevToken
->is(tok::r_paren
) && PrevToken
->MatchingParen
&&
1039 PrevToken
->MatchingParen
->Previous
&&
1040 PrevToken
->MatchingParen
->Previous
->isOneOf(tok::kw_typeof
,
1042 return TT_PointerOrReference
;
1044 if (PrevToken
->Tok
.isLiteral() ||
1045 PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::kw_true
,
1046 tok::kw_false
, tok::r_brace
) ||
1047 NextToken
->Tok
.isLiteral() ||
1048 NextToken
->isOneOf(tok::kw_true
, tok::kw_false
) ||
1049 NextToken
->isUnaryOperator() ||
1050 // If we know we're in a template argument, there are no named
1051 // declarations. Thus, having an identifier on the right-hand side
1052 // indicates a binary operator.
1053 (InTemplateArgument
&& NextToken
->Tok
.isAnyIdentifier()))
1054 return TT_BinaryOperator
;
1056 // "&&(" is quite unlikely to be two successive unary "&".
1057 if (Tok
.is(tok::ampamp
) && NextToken
&& NextToken
->is(tok::l_paren
))
1058 return TT_BinaryOperator
;
1060 // This catches some cases where evaluation order is used as control flow:
1062 const FormatToken
*NextNextToken
= NextToken
->getNextNonComment();
1063 if (NextNextToken
&& NextNextToken
->is(tok::arrow
))
1064 return TT_BinaryOperator
;
1066 // It is very unlikely that we are going to find a pointer or reference type
1067 // definition on the RHS of an assignment.
1068 if (IsExpression
&& !Contexts
.back().CaretFound
)
1069 return TT_BinaryOperator
;
1071 return TT_PointerOrReference
;
1074 TokenType
determinePlusMinusCaretUsage(const FormatToken
&Tok
) {
1075 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
1076 if (!PrevToken
|| PrevToken
->is(TT_CastRParen
))
1077 return TT_UnaryOperator
;
1079 // Use heuristics to recognize unary operators.
1080 if (PrevToken
->isOneOf(tok::equal
, tok::l_paren
, tok::comma
, tok::l_square
,
1081 tok::question
, tok::colon
, tok::kw_return
,
1082 tok::kw_case
, tok::at
, tok::l_brace
))
1083 return TT_UnaryOperator
;
1085 // There can't be two consecutive binary operators.
1086 if (PrevToken
->is(TT_BinaryOperator
))
1087 return TT_UnaryOperator
;
1089 // Fall back to marking the token as binary operator.
1090 return TT_BinaryOperator
;
1093 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements.
1094 TokenType
determineIncrementUsage(const FormatToken
&Tok
) {
1095 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
1096 if (!PrevToken
|| PrevToken
->is(TT_CastRParen
))
1097 return TT_UnaryOperator
;
1098 if (PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::identifier
))
1099 return TT_TrailingUnaryOperator
;
1101 return TT_UnaryOperator
;
1104 SmallVector
<Context
, 8> Contexts
;
1106 const FormatStyle
&Style
;
1107 AnnotatedLine
&Line
;
1108 FormatToken
*CurrentToken
;
1110 const AdditionalKeywords
&Keywords
;
1113 static int PrecedenceUnaryOperator
= prec::PointerToMember
+ 1;
1114 static int PrecedenceArrowAndPeriod
= prec::PointerToMember
+ 2;
1116 /// \brief Parses binary expressions by inserting fake parenthesis based on
1117 /// operator precedence.
1118 class ExpressionParser
{
1120 ExpressionParser(const FormatStyle
&Style
, const AdditionalKeywords
&Keywords
,
1121 AnnotatedLine
&Line
)
1122 : Style(Style
), Keywords(Keywords
), Current(Line
.First
) {}
1124 /// \brief Parse expressions with the given operatore precedence.
1125 void parse(int Precedence
= 0) {
1126 // Skip 'return' and ObjC selector colons as they are not part of a binary
1128 while (Current
&& (Current
->is(tok::kw_return
) ||
1129 (Current
->is(tok::colon
) &&
1130 Current
->isOneOf(TT_ObjCMethodExpr
, TT_DictLiteral
))))
1133 if (!Current
|| Precedence
> PrecedenceArrowAndPeriod
)
1136 // Conditional expressions need to be parsed separately for proper nesting.
1137 if (Precedence
== prec::Conditional
) {
1138 parseConditionalExpr();
1142 // Parse unary operators, which all have a higher precedence than binary
1144 if (Precedence
== PrecedenceUnaryOperator
) {
1145 parseUnaryOperator();
1149 FormatToken
*Start
= Current
;
1150 FormatToken
*LatestOperator
= nullptr;
1151 unsigned OperatorIndex
= 0;
1154 // Consume operators with higher precedence.
1155 parse(Precedence
+ 1);
1157 int CurrentPrecedence
= getCurrentPrecedence();
1159 if (Current
&& Current
->is(TT_SelectorName
) &&
1160 Precedence
== CurrentPrecedence
) {
1162 addFakeParenthesis(Start
, prec::Level(Precedence
));
1166 // At the end of the line or when an operator with higher precedence is
1167 // found, insert fake parenthesis and return.
1168 if (!Current
|| (Current
->closesScope() && Current
->MatchingParen
) ||
1169 (CurrentPrecedence
!= -1 && CurrentPrecedence
< Precedence
) ||
1170 (CurrentPrecedence
== prec::Conditional
&&
1171 Precedence
== prec::Assignment
&& Current
->is(tok::colon
))) {
1175 // Consume scopes: (), [], <> and {}
1176 if (Current
->opensScope()) {
1177 while (Current
&& !Current
->closesScope()) {
1184 if (CurrentPrecedence
== Precedence
) {
1185 LatestOperator
= Current
;
1186 Current
->OperatorIndex
= OperatorIndex
;
1189 next(/*SkipPastLeadingComments=*/Precedence
> 0);
1193 if (LatestOperator
&& (Current
|| Precedence
> 0)) {
1194 LatestOperator
->LastOperator
= true;
1195 if (Precedence
== PrecedenceArrowAndPeriod
) {
1196 // Call expressions don't have a binary operator precedence.
1197 addFakeParenthesis(Start
, prec::Unknown
);
1199 addFakeParenthesis(Start
, prec::Level(Precedence
));
1205 /// \brief Gets the precedence (+1) of the given token for binary operators
1206 /// and other tokens that we treat like binary operators.
1207 int getCurrentPrecedence() {
1209 const FormatToken
*NextNonComment
= Current
->getNextNonComment();
1210 if (Current
->is(TT_ConditionalExpr
))
1211 return prec::Conditional
;
1212 else if (NextNonComment
&& NextNonComment
->is(tok::colon
) &&
1213 NextNonComment
->is(TT_DictLiteral
))
1215 else if (Current
->is(TT_LambdaArrow
))
1217 else if (Current
->isOneOf(tok::semi
, TT_InlineASMColon
,
1219 (Current
->is(tok::comment
) && NextNonComment
&&
1220 NextNonComment
->is(TT_SelectorName
)))
1222 else if (Current
->is(TT_RangeBasedForLoopColon
))
1224 else if (Current
->is(TT_BinaryOperator
) || Current
->is(tok::comma
))
1225 return Current
->getPrecedence();
1226 else if (Current
->isOneOf(tok::period
, tok::arrow
))
1227 return PrecedenceArrowAndPeriod
;
1228 else if (Style
.Language
== FormatStyle::LK_Java
&&
1229 Current
->isOneOf(Keywords
.kw_extends
, Keywords
.kw_implements
,
1230 Keywords
.kw_throws
))
1236 void addFakeParenthesis(FormatToken
*Start
, prec::Level Precedence
) {
1237 Start
->FakeLParens
.push_back(Precedence
);
1238 if (Precedence
> prec::Unknown
)
1239 Start
->StartsBinaryExpression
= true;
1241 FormatToken
*Previous
= Current
->Previous
;
1242 while (Previous
->is(tok::comment
) && Previous
->Previous
)
1243 Previous
= Previous
->Previous
;
1244 ++Previous
->FakeRParens
;
1245 if (Precedence
> prec::Unknown
)
1246 Previous
->EndsBinaryExpression
= true;
1250 /// \brief Parse unary operator expressions and surround them with fake
1251 /// parentheses if appropriate.
1252 void parseUnaryOperator() {
1253 if (!Current
|| Current
->isNot(TT_UnaryOperator
)) {
1254 parse(PrecedenceArrowAndPeriod
);
1258 FormatToken
*Start
= Current
;
1260 parseUnaryOperator();
1262 // The actual precedence doesn't matter.
1263 addFakeParenthesis(Start
, prec::Unknown
);
1266 void parseConditionalExpr() {
1267 while (Current
&& Current
->isTrailingComment()) {
1270 FormatToken
*Start
= Current
;
1271 parse(prec::LogicalOr
);
1272 if (!Current
|| !Current
->is(tok::question
))
1275 parse(prec::Assignment
);
1276 if (!Current
|| Current
->isNot(TT_ConditionalExpr
))
1279 parse(prec::Assignment
);
1280 addFakeParenthesis(Start
, prec::Conditional
);
1283 void next(bool SkipPastLeadingComments
= true) {
1285 Current
= Current
->Next
;
1287 (Current
->NewlinesBefore
== 0 || SkipPastLeadingComments
) &&
1288 Current
->isTrailingComment())
1289 Current
= Current
->Next
;
1292 const FormatStyle
&Style
;
1293 const AdditionalKeywords
&Keywords
;
1294 FormatToken
*Current
;
1297 } // end anonymous namespace
1299 void TokenAnnotator::setCommentLineLevels(
1300 SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
1301 const AnnotatedLine
*NextNonCommentLine
= nullptr;
1302 for (SmallVectorImpl
<AnnotatedLine
*>::reverse_iterator I
= Lines
.rbegin(),
1305 if (NextNonCommentLine
&& (*I
)->First
->is(tok::comment
) &&
1306 (*I
)->First
->Next
== nullptr)
1307 (*I
)->Level
= NextNonCommentLine
->Level
;
1309 NextNonCommentLine
= (*I
)->First
->isNot(tok::r_brace
) ? (*I
) : nullptr;
1311 setCommentLineLevels((*I
)->Children
);
1315 void TokenAnnotator::annotate(AnnotatedLine
&Line
) {
1316 for (SmallVectorImpl
<AnnotatedLine
*>::iterator I
= Line
.Children
.begin(),
1317 E
= Line
.Children
.end();
1321 AnnotatingParser
Parser(Style
, Line
, Keywords
);
1322 Line
.Type
= Parser
.parseLine();
1323 if (Line
.Type
== LT_Invalid
)
1326 ExpressionParser
ExprParser(Style
, Keywords
, Line
);
1329 if (Line
.First
->is(TT_ObjCMethodSpecifier
))
1330 Line
.Type
= LT_ObjCMethodDecl
;
1331 else if (Line
.First
->is(TT_ObjCDecl
))
1332 Line
.Type
= LT_ObjCDecl
;
1333 else if (Line
.First
->is(TT_ObjCProperty
))
1334 Line
.Type
= LT_ObjCProperty
;
1336 Line
.First
->SpacesRequiredBefore
= 1;
1337 Line
.First
->CanBreakBefore
= Line
.First
->MustBreakBefore
;
1340 // This function heuristically determines whether 'Current' starts the name of a
1341 // function declaration.
1342 static bool isFunctionDeclarationName(const FormatToken
&Current
) {
1343 if (!Current
.is(TT_StartOfName
) || Current
.NestingLevel
!= 0)
1345 const FormatToken
*Next
= Current
.Next
;
1346 for (; Next
; Next
= Next
->Next
) {
1347 if (Next
->is(TT_TemplateOpener
)) {
1348 Next
= Next
->MatchingParen
;
1349 } else if (Next
->is(tok::coloncolon
)) {
1351 if (!Next
|| !Next
->is(tok::identifier
))
1353 } else if (Next
->is(tok::l_paren
)) {
1361 assert(Next
->is(tok::l_paren
));
1362 if (Next
->Next
== Next
->MatchingParen
)
1364 for (const FormatToken
*Tok
= Next
->Next
; Tok
!= Next
->MatchingParen
;
1366 if (Tok
->is(tok::kw_const
) || Tok
->isSimpleTypeSpecifier() ||
1367 Tok
->isOneOf(TT_PointerOrReference
, TT_StartOfName
))
1369 if (Tok
->isOneOf(tok::l_brace
, tok::string_literal
) || Tok
->Tok
.isLiteral())
1375 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine
&Line
) {
1376 for (SmallVectorImpl
<AnnotatedLine
*>::iterator I
= Line
.Children
.begin(),
1377 E
= Line
.Children
.end();
1379 calculateFormattingInformation(**I
);
1382 Line
.First
->TotalLength
=
1383 Line
.First
->IsMultiline
? Style
.ColumnLimit
: Line
.First
->ColumnWidth
;
1384 if (!Line
.First
->Next
)
1386 FormatToken
*Current
= Line
.First
->Next
;
1387 bool InFunctionDecl
= Line
.MightBeFunctionDecl
;
1389 if (isFunctionDeclarationName(*Current
))
1390 Current
->Type
= TT_FunctionDeclarationName
;
1391 if (Current
->is(TT_LineComment
)) {
1392 if (Current
->Previous
->BlockKind
== BK_BracedInit
&&
1393 Current
->Previous
->opensScope())
1394 Current
->SpacesRequiredBefore
= Style
.Cpp11BracedListStyle
? 0 : 1;
1396 Current
->SpacesRequiredBefore
= Style
.SpacesBeforeTrailingComments
;
1398 // If we find a trailing comment, iterate backwards to determine whether
1399 // it seems to relate to a specific parameter. If so, break before that
1400 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
1401 // to the previous line in:
1405 if (!Current
->HasUnescapedNewline
) {
1406 for (FormatToken
*Parameter
= Current
->Previous
; Parameter
;
1407 Parameter
= Parameter
->Previous
) {
1408 if (Parameter
->isOneOf(tok::comment
, tok::r_brace
))
1410 if (Parameter
->Previous
&& Parameter
->Previous
->is(tok::comma
)) {
1411 if (!Parameter
->Previous
->is(TT_CtorInitializerComma
) &&
1412 Parameter
->HasUnescapedNewline
)
1413 Parameter
->MustBreakBefore
= true;
1418 } else if (Current
->SpacesRequiredBefore
== 0 &&
1419 spaceRequiredBefore(Line
, *Current
)) {
1420 Current
->SpacesRequiredBefore
= 1;
1423 Current
->MustBreakBefore
=
1424 Current
->MustBreakBefore
|| mustBreakBefore(Line
, *Current
);
1426 if (Style
.AlwaysBreakAfterDefinitionReturnType
&& InFunctionDecl
&&
1427 Current
->is(TT_FunctionDeclarationName
) &&
1428 !Line
.Last
->isOneOf(tok::semi
, tok::comment
)) // Only for definitions.
1429 // FIXME: Line.Last points to other characters than tok::semi
1431 Current
->MustBreakBefore
= true;
1433 Current
->CanBreakBefore
=
1434 Current
->MustBreakBefore
|| canBreakBefore(Line
, *Current
);
1435 unsigned ChildSize
= 0;
1436 if (Current
->Previous
->Children
.size() == 1) {
1437 FormatToken
&LastOfChild
= *Current
->Previous
->Children
[0]->Last
;
1438 ChildSize
= LastOfChild
.isTrailingComment() ? Style
.ColumnLimit
1439 : LastOfChild
.TotalLength
+ 1;
1441 const FormatToken
*Prev
= Current
->Previous
;
1442 if (Current
->MustBreakBefore
|| Prev
->Children
.size() > 1 ||
1443 (Prev
->Children
.size() == 1 &&
1444 Prev
->Children
[0]->First
->MustBreakBefore
) ||
1445 Current
->IsMultiline
)
1446 Current
->TotalLength
= Prev
->TotalLength
+ Style
.ColumnLimit
;
1448 Current
->TotalLength
= Prev
->TotalLength
+ Current
->ColumnWidth
+
1449 ChildSize
+ Current
->SpacesRequiredBefore
;
1451 if (Current
->is(TT_CtorInitializerColon
))
1452 InFunctionDecl
= false;
1454 // FIXME: Only calculate this if CanBreakBefore is true once static
1455 // initializers etc. are sorted out.
1456 // FIXME: Move magic numbers to a better place.
1457 Current
->SplitPenalty
= 20 * Current
->BindingStrength
+
1458 splitPenalty(Line
, *Current
, InFunctionDecl
);
1460 Current
= Current
->Next
;
1463 calculateUnbreakableTailLengths(Line
);
1464 for (Current
= Line
.First
; Current
!= nullptr; Current
= Current
->Next
) {
1466 Current
->Role
->precomputeFormattingInfos(Current
);
1469 DEBUG({ printDebugInfo(Line
); });
1472 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine
&Line
) {
1473 unsigned UnbreakableTailLength
= 0;
1474 FormatToken
*Current
= Line
.Last
;
1476 Current
->UnbreakableTailLength
= UnbreakableTailLength
;
1477 if (Current
->CanBreakBefore
||
1478 Current
->isOneOf(tok::comment
, tok::string_literal
)) {
1479 UnbreakableTailLength
= 0;
1481 UnbreakableTailLength
+=
1482 Current
->ColumnWidth
+ Current
->SpacesRequiredBefore
;
1484 Current
= Current
->Previous
;
1488 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine
&Line
,
1489 const FormatToken
&Tok
,
1490 bool InFunctionDecl
) {
1491 const FormatToken
&Left
= *Tok
.Previous
;
1492 const FormatToken
&Right
= Tok
;
1494 if (Left
.is(tok::semi
))
1497 if (Style
.Language
== FormatStyle::LK_Java
) {
1498 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_throws
))
1500 if (Right
.is(Keywords
.kw_implements
))
1502 if (Left
.is(tok::comma
) && Left
.NestingLevel
== 0)
1504 } else if (Style
.Language
== FormatStyle::LK_JavaScript
) {
1505 if (Right
.is(Keywords
.kw_function
))
1509 if (Left
.is(tok::comma
) || (Right
.is(tok::identifier
) && Right
.Next
&&
1510 Right
.Next
->is(TT_DictLiteral
)))
1512 if (Right
.is(tok::l_square
)) {
1513 if (Style
.Language
== FormatStyle::LK_Proto
)
1515 if (!Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
))
1519 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
1520 Right
.is(tok::kw_operator
)) {
1521 if (Line
.First
->is(tok::kw_for
) && Right
.PartOfMultiVariableDeclStmt
)
1523 if (Left
.is(TT_StartOfName
))
1525 if (InFunctionDecl
&& Right
.NestingLevel
== 0)
1526 return Style
.PenaltyReturnTypeOnItsOwnLine
;
1529 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
))
1531 if (Left
.is(TT_CastRParen
))
1533 if (Left
.is(tok::coloncolon
) ||
1534 (Right
.is(tok::period
) && Style
.Language
== FormatStyle::LK_Proto
))
1536 if (Left
.isOneOf(tok::kw_class
, tok::kw_struct
))
1539 if (Left
.isOneOf(TT_RangeBasedForLoopColon
, TT_InheritanceColon
))
1542 if (Right
.isMemberAccess()) {
1543 if (Left
.is(tok::r_paren
) && Left
.MatchingParen
&&
1544 Left
.MatchingParen
->ParameterCount
> 0)
1545 return 20; // Should be smaller than breaking at a nested comma.
1549 if (Right
.is(TT_TrailingAnnotation
) &&
1550 (!Right
.Next
|| Right
.Next
->isNot(tok::l_paren
))) {
1551 // Moving trailing annotations to the next line is fine for ObjC method
1553 if (Line
.First
->is(TT_ObjCMethodSpecifier
))
1556 // Generally, breaking before a trailing annotation is bad unless it is
1557 // function-like. It seems to be especially preferable to keep standard
1558 // annotations (i.e. "const", "final" and "override") on the same line.
1559 // Use a slightly higher penalty after ")" so that annotations like
1560 // "const override" are kept together.
1561 bool is_short_annotation
= Right
.TokenText
.size() < 10;
1562 return (Left
.is(tok::r_paren
) ? 100 : 120) + (is_short_annotation
? 50 : 0);
1565 // In for-loops, prefer breaking at ',' and ';'.
1566 if (Line
.First
->is(tok::kw_for
) && Left
.is(tok::equal
))
1569 // In Objective-C method expressions, prefer breaking before "param:" over
1570 // breaking after it.
1571 if (Right
.is(TT_SelectorName
))
1573 if (Left
.is(tok::colon
) && Left
.is(TT_ObjCMethodExpr
))
1574 return Line
.MightBeFunctionDecl
? 50 : 500;
1576 if (Left
.is(tok::l_paren
) && InFunctionDecl
&& Style
.AlignAfterOpenBracket
)
1578 if (Left
.is(tok::equal
) && InFunctionDecl
)
1580 if (Right
.is(tok::r_brace
))
1582 if (Left
.is(TT_TemplateOpener
))
1584 if (Left
.opensScope()) {
1585 if (!Style
.AlignAfterOpenBracket
)
1587 return Left
.ParameterCount
> 1 ? Style
.PenaltyBreakBeforeFirstCallParameter
1590 if (Left
.is(TT_JavaAnnotation
))
1593 if (Right
.is(tok::lessless
)) {
1594 if (Left
.is(tok::string_literal
)) {
1595 StringRef Content
= Left
.TokenText
;
1596 if (Content
.startswith("\""))
1597 Content
= Content
.drop_front(1);
1598 if (Content
.endswith("\""))
1599 Content
= Content
.drop_back(1);
1600 Content
= Content
.trim();
1601 if (Content
.size() > 1 &&
1602 (Content
.back() == ':' || Content
.back() == '='))
1605 return 1; // Breaking at a << is really cheap.
1607 if (Left
.is(TT_ConditionalExpr
))
1608 return prec::Conditional
;
1609 prec::Level Level
= Left
.getPrecedence();
1611 if (Level
!= prec::Unknown
)
1617 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine
&Line
,
1618 const FormatToken
&Left
,
1619 const FormatToken
&Right
) {
1620 if (Left
.is(tok::kw_return
) && Right
.isNot(tok::semi
))
1622 if (Style
.ObjCSpaceAfterProperty
&& Line
.Type
== LT_ObjCProperty
&&
1623 Left
.Tok
.getObjCKeywordID() == tok::objc_property
)
1625 if (Right
.is(tok::hashhash
))
1626 return Left
.is(tok::hash
);
1627 if (Left
.isOneOf(tok::hashhash
, tok::hash
))
1628 return Right
.is(tok::hash
);
1629 if (Left
.is(tok::l_paren
) && Right
.is(tok::r_paren
))
1630 return Style
.SpaceInEmptyParentheses
;
1631 if (Left
.is(tok::l_paren
) || Right
.is(tok::r_paren
))
1632 return (Right
.is(TT_CastRParen
) ||
1633 (Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_CastRParen
)))
1634 ? Style
.SpacesInCStyleCastParentheses
1635 : Style
.SpacesInParentheses
;
1636 if (Right
.isOneOf(tok::semi
, tok::comma
))
1638 if (Right
.is(tok::less
) &&
1639 (Left
.isOneOf(tok::kw_template
, tok::r_paren
) ||
1640 (Line
.Type
== LT_ObjCDecl
&& Style
.ObjCSpaceBeforeProtocolList
)))
1642 if (Left
.isOneOf(tok::exclaim
, tok::tilde
))
1644 if (Left
.is(tok::at
) &&
1645 Right
.isOneOf(tok::identifier
, tok::string_literal
, tok::char_constant
,
1646 tok::numeric_constant
, tok::l_paren
, tok::l_brace
,
1647 tok::kw_true
, tok::kw_false
))
1649 if (Left
.is(tok::coloncolon
))
1651 if (Left
.is(tok::less
) || Right
.isOneOf(tok::greater
, tok::less
))
1653 if (Right
.is(tok::ellipsis
))
1654 return Left
.Tok
.isLiteral();
1655 if (Left
.is(tok::l_square
) && Right
.is(tok::amp
))
1657 if (Right
.is(TT_PointerOrReference
))
1658 return Left
.Tok
.isLiteral() ||
1659 (!Left
.isOneOf(TT_PointerOrReference
, tok::l_paren
) &&
1660 Style
.PointerAlignment
!= FormatStyle::PAS_Left
);
1661 if (Right
.is(TT_FunctionTypeLParen
) && Left
.isNot(tok::l_paren
) &&
1662 (!Left
.is(TT_PointerOrReference
) ||
1663 Style
.PointerAlignment
!= FormatStyle::PAS_Right
))
1665 if (Left
.is(TT_PointerOrReference
))
1666 return Right
.Tok
.isLiteral() || Right
.is(TT_BlockComment
) ||
1667 (!Right
.isOneOf(TT_PointerOrReference
, tok::l_paren
) &&
1668 Style
.PointerAlignment
!= FormatStyle::PAS_Right
&& Left
.Previous
&&
1669 !Left
.Previous
->isOneOf(tok::l_paren
, tok::coloncolon
));
1670 if (Right
.is(tok::star
) && Left
.is(tok::l_paren
))
1672 if (Left
.is(tok::l_square
))
1673 return (Left
.is(TT_ArrayInitializerLSquare
) &&
1674 Style
.SpacesInContainerLiterals
&& Right
.isNot(tok::r_square
)) ||
1675 (Left
.is(TT_ArraySubscriptLSquare
) && Style
.SpacesInSquareBrackets
&&
1676 Right
.isNot(tok::r_square
));
1677 if (Right
.is(tok::r_square
))
1678 return Right
.MatchingParen
&&
1679 ((Style
.SpacesInContainerLiterals
&&
1680 Right
.MatchingParen
->is(TT_ArrayInitializerLSquare
)) ||
1681 (Style
.SpacesInSquareBrackets
&&
1682 Right
.MatchingParen
->is(TT_ArraySubscriptLSquare
)));
1683 if (Right
.is(tok::l_square
) &&
1684 !Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
) &&
1685 !Left
.isOneOf(tok::numeric_constant
, TT_DictLiteral
))
1687 if (Left
.is(tok::colon
))
1688 return !Left
.is(TT_ObjCMethodExpr
);
1689 if (Left
.is(tok::l_brace
) && Right
.is(tok::r_brace
))
1690 return !Left
.Children
.empty(); // No spaces in "{}".
1691 if ((Left
.is(tok::l_brace
) && Left
.BlockKind
!= BK_Block
) ||
1692 (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
1693 Right
.MatchingParen
->BlockKind
!= BK_Block
))
1694 return !Style
.Cpp11BracedListStyle
;
1695 if (Left
.is(TT_BlockComment
))
1696 return !Left
.TokenText
.endswith("=*/");
1697 if (Right
.is(tok::l_paren
)) {
1698 if (Left
.is(tok::r_paren
) && Left
.is(TT_AttributeParen
))
1700 return Line
.Type
== LT_ObjCDecl
|| Left
.is(tok::semi
) ||
1701 (Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
&&
1702 (Left
.isOneOf(tok::kw_if
, tok::kw_for
, tok::kw_while
,
1703 tok::kw_switch
, tok::kw_case
) ||
1704 (Left
.isOneOf(tok::kw_try
, tok::kw_catch
, tok::kw_new
,
1706 (!Left
.Previous
|| Left
.Previous
->isNot(tok::period
))) ||
1707 Left
.IsForEachMacro
)) ||
1708 (Style
.SpaceBeforeParens
== FormatStyle::SBPO_Always
&&
1709 (Left
.is(tok::identifier
) || Left
.isFunctionLikeKeyword()) &&
1710 Line
.Type
!= LT_PreprocessorDirective
);
1712 if (Left
.is(tok::at
) && Right
.Tok
.getObjCKeywordID() != tok::objc_not_keyword
)
1714 if (Right
.is(TT_UnaryOperator
))
1715 return !Left
.isOneOf(tok::l_paren
, tok::l_square
, tok::at
) &&
1716 (Left
.isNot(tok::colon
) || Left
.isNot(TT_ObjCMethodExpr
));
1717 if ((Left
.isOneOf(tok::identifier
, tok::greater
, tok::r_square
,
1719 Left
.isSimpleTypeSpecifier()) &&
1720 Right
.is(tok::l_brace
) && Right
.getNextNonComment() &&
1721 Right
.BlockKind
!= BK_Block
)
1723 if (Left
.is(tok::period
) || Right
.is(tok::period
))
1725 if (Right
.is(tok::hash
) && Left
.is(tok::identifier
) && Left
.TokenText
== "L")
1727 if (Left
.is(TT_TemplateCloser
) && Left
.MatchingParen
&&
1728 Left
.MatchingParen
->Previous
&&
1729 Left
.MatchingParen
->Previous
->is(tok::period
))
1730 // A.<B>DoSomething();
1732 if (Left
.is(TT_TemplateCloser
) && Right
.is(tok::l_square
))
1737 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine
&Line
,
1738 const FormatToken
&Right
) {
1739 const FormatToken
&Left
= *Right
.Previous
;
1740 if (Style
.Language
== FormatStyle::LK_Proto
) {
1741 if (Right
.is(tok::period
) &&
1742 Left
.isOneOf(Keywords
.kw_optional
, Keywords
.kw_required
,
1743 Keywords
.kw_repeated
))
1745 if (Right
.is(tok::l_paren
) &&
1746 Left
.isOneOf(Keywords
.kw_returns
, Keywords
.kw_option
))
1748 } else if (Style
.Language
== FormatStyle::LK_JavaScript
) {
1749 if (Left
.is(Keywords
.kw_var
))
1751 } else if (Style
.Language
== FormatStyle::LK_Java
) {
1752 if (Left
.is(tok::r_square
) && Right
.is(tok::l_brace
))
1754 if (Left
.is(TT_LambdaArrow
) || Right
.is(TT_LambdaArrow
))
1756 if (Left
.is(Keywords
.kw_synchronized
) && Right
.is(tok::l_paren
))
1757 return Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
;
1758 if ((Left
.isOneOf(tok::kw_static
, tok::kw_public
, tok::kw_private
,
1759 tok::kw_protected
) ||
1760 Left
.isOneOf(Keywords
.kw_final
, Keywords
.kw_abstract
,
1761 Keywords
.kw_native
)) &&
1762 Right
.is(TT_TemplateOpener
))
1765 if (Right
.Tok
.getIdentifierInfo() && Left
.Tok
.getIdentifierInfo())
1766 return true; // Never ever merge two identifiers.
1767 if (Left
.is(TT_ImplicitStringLiteral
))
1768 return Right
.WhitespaceRange
.getBegin() != Right
.WhitespaceRange
.getEnd();
1769 if (Line
.Type
== LT_ObjCMethodDecl
) {
1770 if (Left
.is(TT_ObjCMethodSpecifier
))
1772 if (Left
.is(tok::r_paren
) && Right
.is(tok::identifier
))
1773 // Don't space between ')' and <id>
1776 if (Line
.Type
== LT_ObjCProperty
&&
1777 (Right
.is(tok::equal
) || Left
.is(tok::equal
)))
1780 if (Right
.is(TT_TrailingReturnArrow
) || Left
.is(TT_TrailingReturnArrow
))
1782 if (Left
.is(tok::comma
))
1784 if (Right
.is(tok::comma
))
1786 if (Right
.isOneOf(TT_CtorInitializerColon
, TT_ObjCBlockLParen
))
1788 if (Left
.is(tok::kw_operator
))
1789 return Right
.is(tok::coloncolon
);
1790 if (Right
.is(TT_OverloadedOperatorLParen
))
1792 if (Right
.is(tok::colon
))
1793 return !Line
.First
->isOneOf(tok::kw_case
, tok::kw_default
) &&
1794 Right
.getNextNonComment() && Right
.isNot(TT_ObjCMethodExpr
) &&
1795 !Left
.is(tok::question
) &&
1796 !(Right
.is(TT_InlineASMColon
) && Left
.is(tok::coloncolon
)) &&
1797 (Right
.isNot(TT_DictLiteral
) || Style
.SpacesInContainerLiterals
);
1798 if (Left
.is(TT_UnaryOperator
))
1799 return Right
.is(TT_BinaryOperator
);
1800 if (Left
.is(TT_CastRParen
))
1801 return Style
.SpaceAfterCStyleCast
|| Right
.is(TT_BinaryOperator
);
1802 if (Left
.is(tok::greater
) && Right
.is(tok::greater
)) {
1803 return Right
.is(TT_TemplateCloser
) && Left
.is(TT_TemplateCloser
) &&
1804 (Style
.Standard
!= FormatStyle::LS_Cpp11
|| Style
.SpacesInAngles
);
1806 if (Right
.isOneOf(tok::arrow
, tok::period
, tok::arrowstar
, tok::periodstar
) ||
1807 Left
.isOneOf(tok::arrow
, tok::period
, tok::arrowstar
, tok::periodstar
))
1809 if (!Style
.SpaceBeforeAssignmentOperators
&&
1810 Right
.getPrecedence() == prec::Assignment
)
1812 if (Right
.is(tok::coloncolon
) && Left
.isNot(tok::l_brace
))
1813 return (Left
.is(TT_TemplateOpener
) &&
1814 Style
.Standard
== FormatStyle::LS_Cpp03
) ||
1815 !(Left
.isOneOf(tok::identifier
, tok::l_paren
, tok::r_paren
) ||
1816 Left
.isOneOf(TT_TemplateCloser
, TT_TemplateOpener
));
1817 if ((Left
.is(TT_TemplateOpener
)) != (Right
.is(TT_TemplateCloser
)))
1818 return Style
.SpacesInAngles
;
1819 if ((Right
.is(TT_BinaryOperator
) && !Left
.is(tok::l_paren
)) ||
1820 Left
.isOneOf(TT_BinaryOperator
, TT_ConditionalExpr
))
1822 if (Left
.is(TT_TemplateCloser
) && Right
.is(tok::l_paren
))
1823 return Style
.SpaceBeforeParens
== FormatStyle::SBPO_Always
;
1824 if (Right
.is(TT_TemplateOpener
) && Left
.is(tok::r_paren
) &&
1825 Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_OverloadedOperatorLParen
))
1827 if (Right
.is(tok::less
) && Left
.isNot(tok::l_paren
) &&
1828 Line
.First
->is(tok::hash
))
1830 if (Right
.is(TT_TrailingUnaryOperator
))
1832 if (Left
.is(TT_RegexLiteral
))
1834 return spaceRequiredBetween(Line
, Left
, Right
);
1837 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
1838 static bool isAllmanBrace(const FormatToken
&Tok
) {
1839 return Tok
.is(tok::l_brace
) && Tok
.BlockKind
== BK_Block
&&
1840 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_DictLiteral
);
1843 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine
&Line
,
1844 const FormatToken
&Right
) {
1845 const FormatToken
&Left
= *Right
.Previous
;
1846 if (Right
.NewlinesBefore
> 1)
1849 // If the last token before a '}' is a comma or a trailing comment, the
1850 // intention is to insert a line break after it in order to make shuffling
1851 // around entries easier.
1852 const FormatToken
*BeforeClosingBrace
= nullptr;
1853 if (Left
.is(tok::l_brace
) && Left
.BlockKind
!= BK_Block
&& Left
.MatchingParen
)
1854 BeforeClosingBrace
= Left
.MatchingParen
->Previous
;
1855 else if (Right
.is(tok::r_brace
) && Right
.BlockKind
!= BK_Block
)
1856 BeforeClosingBrace
= &Left
;
1857 if (BeforeClosingBrace
&& (BeforeClosingBrace
->is(tok::comma
) ||
1858 BeforeClosingBrace
->isTrailingComment()))
1861 if (Right
.is(tok::comment
))
1862 return Left
.BlockKind
!= BK_BracedInit
&&
1863 Left
.isNot(TT_CtorInitializerColon
) &&
1864 (Right
.NewlinesBefore
> 0 && Right
.HasUnescapedNewline
);
1865 if (Right
.Previous
->isTrailingComment() ||
1866 (Right
.isStringLiteral() && Right
.Previous
->isStringLiteral()))
1868 if (Right
.Previous
->IsUnterminatedLiteral
)
1870 if (Right
.is(tok::lessless
) && Right
.Next
&&
1871 Right
.Previous
->is(tok::string_literal
) &&
1872 Right
.Next
->is(tok::string_literal
))
1874 if (Right
.Previous
->ClosesTemplateDeclaration
&&
1875 Right
.Previous
->MatchingParen
&&
1876 Right
.Previous
->MatchingParen
->NestingLevel
== 0 &&
1877 Style
.AlwaysBreakTemplateDeclarations
)
1879 if ((Right
.isOneOf(TT_CtorInitializerComma
, TT_CtorInitializerColon
)) &&
1880 Style
.BreakConstructorInitializersBeforeComma
&&
1881 !Style
.ConstructorInitializerAllOnOneLineOrOnePerLine
)
1883 if (Right
.is(tok::string_literal
) && Right
.TokenText
.startswith("R\""))
1884 // Raw string literals are special wrt. line breaks. The author has made a
1885 // deliberate choice and might have aligned the contents of the string
1886 // literal accordingly. Thus, we try keep existing line breaks.
1887 return Right
.NewlinesBefore
> 0;
1888 if (Right
.Previous
->is(tok::l_brace
) && Right
.NestingLevel
== 1 &&
1889 Style
.Language
== FormatStyle::LK_Proto
)
1890 // Don't put enums onto single lines in protocol buffers.
1892 if (Style
.Language
== FormatStyle::LK_JavaScript
&& Right
.is(tok::r_brace
) &&
1893 Left
.is(tok::l_brace
) && !Left
.Children
.empty())
1894 // Support AllowShortFunctionsOnASingleLine for JavaScript.
1895 return Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_None
||
1896 (Left
.NestingLevel
== 0 && Line
.Level
== 0 &&
1897 Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_Inline
);
1898 if (isAllmanBrace(Left
) || isAllmanBrace(Right
))
1899 return Style
.BreakBeforeBraces
== FormatStyle::BS_Allman
||
1900 Style
.BreakBeforeBraces
== FormatStyle::BS_GNU
;
1901 if (Style
.Language
== FormatStyle::LK_Proto
&& Left
.isNot(tok::l_brace
) &&
1902 Right
.is(TT_SelectorName
))
1904 if (Left
.is(TT_ObjCBlockLBrace
) && !Style
.AllowShortBlocksOnASingleLine
)
1906 if (Right
.is(tok::lessless
) && Left
.is(tok::identifier
) &&
1907 Left
.TokenText
== "endl")
1910 if (Style
.Language
== FormatStyle::LK_JavaScript
) {
1911 // FIXME: This might apply to other languages and token kinds.
1912 if (Right
.is(tok::char_constant
) && Left
.is(tok::plus
) && Left
.Previous
&&
1913 Left
.Previous
->is(tok::char_constant
))
1915 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
) &&
1916 Left
.NestingLevel
== 0)
1918 } else if (Style
.Language
== FormatStyle::LK_Java
) {
1919 if (Left
.is(TT_LeadingJavaAnnotation
) &&
1920 Right
.isNot(TT_LeadingJavaAnnotation
) && Right
.isNot(tok::l_paren
) &&
1921 Line
.Last
->is(tok::l_brace
))
1923 if (Right
.is(tok::plus
) && Left
.is(tok::string_literal
) && Right
.Next
&&
1924 Right
.Next
->is(tok::string_literal
))
1931 bool TokenAnnotator::canBreakBefore(const AnnotatedLine
&Line
,
1932 const FormatToken
&Right
) {
1933 const FormatToken
&Left
= *Right
.Previous
;
1935 if (Style
.Language
== FormatStyle::LK_Java
) {
1936 if (Left
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
1937 Keywords
.kw_implements
))
1939 if (Right
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
1940 Keywords
.kw_implements
))
1944 if (Left
.is(tok::at
))
1946 if (Left
.Tok
.getObjCKeywordID() == tok::objc_interface
)
1948 if (Left
.isOneOf(TT_JavaAnnotation
, TT_LeadingJavaAnnotation
))
1949 return !Right
.is(tok::l_paren
);
1950 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
1951 Right
.is(tok::kw_operator
))
1953 if (Right
.isTrailingComment())
1954 // We rely on MustBreakBefore being set correctly here as we should not
1955 // change the "binding" behavior of a comment.
1956 // The first comment in a braced lists is always interpreted as belonging to
1957 // the first list element. Otherwise, it should be placed outside of the
1959 return Left
.BlockKind
== BK_BracedInit
;
1960 if (Left
.is(tok::question
) && Right
.is(tok::colon
))
1962 if (Right
.is(TT_ConditionalExpr
) || Right
.is(tok::question
))
1963 return Style
.BreakBeforeTernaryOperators
;
1964 if (Left
.is(TT_ConditionalExpr
) || Left
.is(tok::question
))
1965 return !Style
.BreakBeforeTernaryOperators
;
1966 if (Right
.is(TT_InheritanceColon
))
1968 if (Right
.is(tok::colon
) &&
1969 !Right
.isOneOf(TT_CtorInitializerColon
, TT_InlineASMColon
))
1971 if (Left
.is(tok::colon
) && (Left
.isOneOf(TT_DictLiteral
, TT_ObjCMethodExpr
)))
1973 if (Right
.is(TT_SelectorName
))
1975 if (Left
.is(tok::r_paren
) && Line
.Type
== LT_ObjCProperty
)
1977 if (Left
.ClosesTemplateDeclaration
)
1979 if (Right
.isOneOf(TT_RangeBasedForLoopColon
, TT_OverloadedOperatorLParen
,
1980 TT_OverloadedOperator
))
1982 if (Left
.is(TT_RangeBasedForLoopColon
))
1984 if (Right
.is(TT_RangeBasedForLoopColon
))
1986 if (Left
.isOneOf(TT_PointerOrReference
, TT_TemplateCloser
,
1987 TT_UnaryOperator
) ||
1988 Left
.is(tok::kw_operator
))
1990 if (Left
.is(tok::equal
) && Line
.Type
== LT_VirtualFunctionDecl
)
1992 if (Left
.is(tok::l_paren
) && Left
.is(TT_AttributeParen
))
1994 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
1995 (Left
.Previous
->isOneOf(TT_BinaryOperator
, TT_CastRParen
) ||
1996 Left
.Previous
->is(tok::kw_if
)))
1998 if (Right
.is(TT_ImplicitStringLiteral
))
2001 if (Right
.is(tok::r_paren
) || Right
.is(TT_TemplateCloser
))
2004 // We only break before r_brace if there was a corresponding break before
2005 // the l_brace, which is tracked by BreakBeforeClosingBrace.
2006 if (Right
.is(tok::r_brace
))
2007 return Right
.MatchingParen
&& Right
.MatchingParen
->BlockKind
== BK_Block
;
2009 // Allow breaking after a trailing annotation, e.g. after a method
2011 if (Left
.is(TT_TrailingAnnotation
))
2012 return !Right
.isOneOf(tok::l_brace
, tok::semi
, tok::equal
, tok::l_paren
,
2013 tok::less
, tok::coloncolon
);
2015 if (Right
.is(tok::kw___attribute
))
2018 if (Left
.is(tok::identifier
) && Right
.is(tok::string_literal
))
2021 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
2024 if (Left
.is(TT_CtorInitializerComma
) &&
2025 Style
.BreakConstructorInitializersBeforeComma
)
2027 if (Right
.is(TT_CtorInitializerComma
) &&
2028 Style
.BreakConstructorInitializersBeforeComma
)
2030 if (Left
.is(tok::greater
) && Right
.is(tok::greater
) &&
2031 Left
.isNot(TT_TemplateCloser
))
2033 if (Right
.is(TT_BinaryOperator
) &&
2034 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
&&
2035 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_All
||
2036 Right
.getPrecedence() != prec::Assignment
))
2038 if (Left
.is(TT_ArrayInitializerLSquare
))
2040 if (Right
.is(tok::kw_typename
) && Left
.isNot(tok::kw_const
))
2042 if (Left
.isBinaryOperator() && !Left
.isOneOf(tok::arrowstar
, tok::lessless
) &&
2043 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_All
&&
2044 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
||
2045 Left
.getPrecedence() == prec::Assignment
))
2047 return Left
.isOneOf(tok::comma
, tok::coloncolon
, tok::semi
, tok::l_brace
,
2048 tok::kw_class
, tok::kw_struct
) ||
2049 Right
.isMemberAccess() || Right
.is(TT_TrailingReturnArrow
) ||
2050 Right
.isOneOf(tok::lessless
, tok::colon
, tok::l_square
, tok::at
) ||
2051 (Left
.is(tok::r_paren
) &&
2052 Right
.isOneOf(tok::identifier
, tok::kw_const
)) ||
2053 (Left
.is(tok::l_paren
) && !Right
.is(tok::r_paren
));
2056 void TokenAnnotator::printDebugInfo(const AnnotatedLine
&Line
) {
2057 llvm::errs() << "AnnotatedTokens:\n";
2058 const FormatToken
*Tok
= Line
.First
;
2060 llvm::errs() << " M=" << Tok
->MustBreakBefore
2061 << " C=" << Tok
->CanBreakBefore
<< " T=" << Tok
->Type
2062 << " S=" << Tok
->SpacesRequiredBefore
2063 << " B=" << Tok
->BlockParameterCount
2064 << " P=" << Tok
->SplitPenalty
<< " Name=" << Tok
->Tok
.getName()
2065 << " L=" << Tok
->TotalLength
<< " PPK=" << Tok
->PackingKind
2067 for (unsigned i
= 0, e
= Tok
->FakeLParens
.size(); i
!= e
; ++i
)
2068 llvm::errs() << Tok
->FakeLParens
[i
] << "/";
2069 llvm::errs() << " FakeRParens=" << Tok
->FakeRParens
<< "\n";
2071 assert(Tok
== Line
.Last
);
2074 llvm::errs() << "----\n";
2077 } // namespace format
2078 } // namespace clang