clang 8.0.0

TokenAnnotator.cpp
Go to the documentation of this file.
1 //===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements a token annotator, i.e. creates
12 /// \c AnnotatedTokens out of \c FormatTokens with required extra information.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #include "TokenAnnotator.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/Support/Debug.h"
20
21 #define DEBUG_TYPE "format-token-annotator"
22
23 namespace clang {
24 namespace format {
25
26 namespace {
27
28 /// Returns \c true if the token can be used as an identifier in
29 /// an Objective-C \c @selector, \c false otherwise.
30 ///
31 /// Because getFormattingLangOpts() always lexes source code as
32 /// Objective-C++, C++ keywords like \c new and \c delete are
33 /// lexed as tok::kw_*, not tok::identifier, even for Objective-C.
34 ///
35 /// For Objective-C and Objective-C++, both identifiers and keywords
36 /// are valid inside @selector(...) (or a macro which
37 /// invokes @selector(...)). So, we allow treat any identifier or
38 /// keyword as a potential Objective-C selector component.
39 static bool canBeObjCSelectorComponent(const FormatToken &Tok) {
40 return Tok.Tok.getIdentifierInfo() != nullptr;
41 }
42
43 /// A parser that gathers additional information about tokens.
44 ///
45 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
46 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
47 /// into template parameter lists.
48 class AnnotatingParser {
49 public:
50 AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,
51 const AdditionalKeywords &Keywords)
52 : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
53 Keywords(Keywords) {
54 Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
55 resetTokenMetadata(CurrentToken);
56 }
57
58 private:
59 bool parseAngle() {
60 if (!CurrentToken || !CurrentToken->Previous)
61 return false;
62 if (NonTemplateLess.count(CurrentToken->Previous))
63 return false;
64
65 const FormatToken &Previous = *CurrentToken->Previous; // The '<'.
66 if (Previous.Previous) {
67 if (Previous.Previous->Tok.isLiteral())
68 return false;
69 if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
70 (!Previous.Previous->MatchingParen ||
71 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen)))
72 return false;
73 }
74
75 FormatToken *Left = CurrentToken->Previous;
76 Left->ParentBracket = Contexts.back().ContextKind;
77 ScopedContextCreator ContextCreator(*this, tok::less, 12);
78
79 // If this angle is in the context of an expression, we need to be more
80 // hesitant to detect it as opening template parameters.
81 bool InExprContext = Contexts.back().IsExpression;
82
83 Contexts.back().IsExpression = false;
84 // If there's a template keyword before the opening angle bracket, this is a
85 // template parameter, not an argument.
86 Contexts.back().InTemplateArgument =
87 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
88
89 if (Style.Language == FormatStyle::LK_Java &&
90 CurrentToken->is(tok::question))
91 next();
92
93 while (CurrentToken) {
94 if (CurrentToken->is(tok::greater)) {
95 Left->MatchingParen = CurrentToken;
96 CurrentToken->MatchingParen = Left;
97 // In TT_Proto, we must distignuish between:
98 // map<key, value>
99 // msg < item: data >
100 // msg: < item: data >
101 // In TT_TextProto, map<key, value> does not occur.
102 if (Style.Language == FormatStyle::LK_TextProto ||
103 (Style.Language == FormatStyle::LK_Proto && Left->Previous &&
104 Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
105 CurrentToken->Type = TT_DictLiteral;
106 else
107 CurrentToken->Type = TT_TemplateCloser;
108 next();
109 return true;
110 }
111 if (CurrentToken->is(tok::question) &&
112 Style.Language == FormatStyle::LK_Java) {
113 next();
114 continue;
115 }
116 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
117 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
118 Style.Language != FormatStyle::LK_Proto &&
119 Style.Language != FormatStyle::LK_TextProto))
120 return false;
121 // If a && or || is found and interpreted as a binary operator, this set
122 // of angles is likely part of something like "a < b && c > d". If the
123 // angles are inside an expression, the ||/&& might also be a binary
124 // operator that was misinterpreted because we are parsing template
125 // parameters.
126 // FIXME: This is getting out of hand, write a decent parser.
127 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
128 CurrentToken->Previous->is(TT_BinaryOperator) &&
129 Contexts[Contexts.size() - 2].IsExpression &&
130 !Line.startsWith(tok::kw_template))
131 return false;
132 updateParameterCount(Left, CurrentToken);
133 if (Style.Language == FormatStyle::LK_Proto) {
134 if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
135 if (CurrentToken->is(tok::colon) ||
136 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
137 Previous->isNot(tok::colon)))
138 Previous->Type = TT_SelectorName;
139 }
140 }
141 if (!consumeToken())
142 return false;
143 }
144 return false;
145 }
146
147 bool parseParens(bool LookForDecls = false) {
148 if (!CurrentToken)
149 return false;
150 FormatToken *Left = CurrentToken->Previous;
151 Left->ParentBracket = Contexts.back().ContextKind;
152 ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
153
154 // FIXME: This is a bit of a hack. Do better.
155 Contexts.back().ColonIsForRangeExpr =
156 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
157
158 bool StartsObjCMethodExpr = false;
159 if (FormatToken *MaybeSel = Left->Previous) {
160 // @selector( starts a selector.
161 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
162 MaybeSel->Previous->is(tok::at)) {
163 StartsObjCMethodExpr = true;
164 }
165 }
166
167 if (Left->is(TT_OverloadedOperatorLParen)) {
168 Contexts.back().IsExpression = false;
169 } else if (Style.Language == FormatStyle::LK_JavaScript &&
170 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
171 Line.startsWith(tok::kw_export, Keywords.kw_type,
172 tok::identifier))) {
173 // type X = (...);
174 // export type X = (...);
175 Contexts.back().IsExpression = false;
176 } else if (Left->Previous &&
177 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
178 tok::kw_if, tok::kw_while, tok::l_paren,
179 tok::comma) ||
180 Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) ||
181 Left->Previous->is(TT_BinaryOperator))) {
182 // static_assert, if and while usually contain expressions.
183 Contexts.back().IsExpression = true;
184 } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
185 (Left->Previous->is(Keywords.kw_function) ||
186 (Left->Previous->endsSequence(tok::identifier,
187 Keywords.kw_function)))) {
188 // function(...) or function f(...)
189 Contexts.back().IsExpression = false;
190 } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
191 Left->Previous->is(TT_JsTypeColon)) {
192 // let x: (SomeType);
193 Contexts.back().IsExpression = false;
194 } else if (Left->Previous && Left->Previous->is(tok::r_square) &&
195 Left->Previous->MatchingParen &&
196 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) {
197 // This is a parameter list of a lambda expression.
198 Contexts.back().IsExpression = false;
199 } else if (Line.InPPDirective &&
200 (!Left->Previous || !Left->Previous->is(tok::identifier))) {
201 Contexts.back().IsExpression = true;
202 } else if (Contexts[Contexts.size() - 2].CaretFound) {
203 // This is the parameter list of an ObjC block.
204 Contexts.back().IsExpression = false;
205 } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
206 Left->Type = TT_AttributeParen;
207 } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
208 // The first argument to a foreach macro is a declaration.
209 Contexts.back().IsForEachMacro = true;
210 Contexts.back().IsExpression = false;
211 } else if (Left->Previous && Left->Previous->MatchingParen &&
212 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
213 Contexts.back().IsExpression = false;
214 } else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
215 bool IsForOrCatch =
216 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
217 Contexts.back().IsExpression = !IsForOrCatch;
218 }
219
220 if (StartsObjCMethodExpr) {
221 Contexts.back().ColonIsObjCMethodExpr = true;
222 Left->Type = TT_ObjCMethodExpr;
223 }
224
225 // MightBeFunctionType and ProbablyFunctionType are used for
226 // function pointer and reference types as well as Objective-C
227 // block types:
228 //
229 // void (*FunctionPointer)(void);
230 // void (&FunctionReference)(void);
231 // void (^ObjCBlock)(void);
232 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
233 bool ProbablyFunctionType =
234 CurrentToken->isOneOf(tok::star, tok::amp, tok::caret);
235 bool HasMultipleLines = false;
236 bool HasMultipleParametersOnALine = false;
237 bool MightBeObjCForRangeLoop =
238 Left->Previous && Left->Previous->is(tok::kw_for);
239 FormatToken *PossibleObjCForInToken = nullptr;
240 while (CurrentToken) {
241 // LookForDecls is set when "if (" has been seen. Check for
242 // 'identifier' '*' 'identifier' followed by not '=' -- this
243 // '*' has to be a binary operator but determineStarAmpUsage() will
244 // categorize it as an unary operator, so set the right type here.
245 if (LookForDecls && CurrentToken->Next) {
246 FormatToken *Prev = CurrentToken->getPreviousNonComment();
247 if (Prev) {
248 FormatToken *PrevPrev = Prev->getPreviousNonComment();
249 FormatToken *Next = CurrentToken->Next;
250 if (PrevPrev && PrevPrev->is(tok::identifier) &&
251 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
252 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
253 Prev->Type = TT_BinaryOperator;
254 LookForDecls = false;
255 }
256 }
257 }
258
259 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
260 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
261 tok::coloncolon))
262 ProbablyFunctionType = true;
263 if (CurrentToken->is(tok::comma))
264 MightBeFunctionType = false;
265 if (CurrentToken->Previous->is(TT_BinaryOperator))
266 Contexts.back().IsExpression = true;
267 if (CurrentToken->is(tok::r_paren)) {
268 if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next &&
269 (CurrentToken->Next->is(tok::l_paren) ||
270 (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
271 Left->Type = Left->Next->is(tok::caret) ? TT_ObjCBlockLParen
272 : TT_FunctionTypeLParen;
273 Left->MatchingParen = CurrentToken;
274 CurrentToken->MatchingParen = Left;
275
276 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
277 Left->Previous && Left->Previous->is(tok::l_paren)) {
278 // Detect the case where macros are used to generate lambdas or
279 // function bodies, e.g.:
280 // auto my_lambda = MARCO((Type *type, int i) { .. body .. });
281 for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) {
282 if (Tok->is(TT_BinaryOperator) &&
283 Tok->isOneOf(tok::star, tok::amp, tok::ampamp))
284 Tok->Type = TT_PointerOrReference;
285 }
286 }
287
288 if (StartsObjCMethodExpr) {
289 CurrentToken->Type = TT_ObjCMethodExpr;
290 if (Contexts.back().FirstObjCSelectorName) {
291 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
292 Contexts.back().LongestObjCSelectorName;
293 }
294 }
295
296 if (Left->is(TT_AttributeParen))
297 CurrentToken->Type = TT_AttributeParen;
298 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
299 CurrentToken->Type = TT_JavaAnnotation;
300 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
301 CurrentToken->Type = TT_LeadingJavaAnnotation;
302
303 if (!HasMultipleLines)
304 Left->PackingKind = PPK_Inconclusive;
305 else if (HasMultipleParametersOnALine)
306 Left->PackingKind = PPK_BinPacked;
307 else
308 Left->PackingKind = PPK_OnePerLine;
309
310 next();
311 return true;
312 }
313 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
314 return false;
315
316 if (CurrentToken->is(tok::l_brace))
317 Left->Type = TT_Unknown; // Not TT_ObjCBlockLParen
318 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
319 !CurrentToken->Next->HasUnescapedNewline &&
320 !CurrentToken->Next->isTrailingComment())
321 HasMultipleParametersOnALine = true;
322 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
323 CurrentToken->Previous->isSimpleTypeSpecifier()) &&
324 !CurrentToken->is(tok::l_brace))
325 Contexts.back().IsExpression = false;
326 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
327 MightBeObjCForRangeLoop = false;
328 if (PossibleObjCForInToken) {
329 PossibleObjCForInToken->Type = TT_Unknown;
330 PossibleObjCForInToken = nullptr;
331 }
332 }
333 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
334 PossibleObjCForInToken = CurrentToken;
335 PossibleObjCForInToken->Type = TT_ObjCForIn;
336 }
337 // When we discover a 'new', we set CanBeExpression to 'false' in order to
338 // parse the type correctly. Reset that after a comma.
339 if (CurrentToken->is(tok::comma))
340 Contexts.back().CanBeExpression = true;
341
342 FormatToken *Tok = CurrentToken;
343 if (!consumeToken())
344 return false;
345 updateParameterCount(Left, Tok);
346 if (CurrentToken && CurrentToken->HasUnescapedNewline)
347 HasMultipleLines = true;
348 }
349 return false;
350 }
351
352 bool isCpp11AttributeSpecifier(const FormatToken &Tok) {
353 if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square))
354 return false;
355 const FormatToken *AttrTok = Tok.Next->Next;
356 if (!AttrTok)
357 return false;
358 // C++17 '[[using ns: foo, bar(baz, blech)]]'
359 // We assume nobody will name an ObjC variable 'using'.
360 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
361 return true;
362 if (AttrTok->isNot(tok::identifier))
363 return false;
364 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
365 // ObjC message send. We assume nobody will use : in a C++11 attribute
366 // specifier parameter, although this is technically valid:
367 // [[foo(:)]]
368 if (AttrTok->is(tok::colon) ||
369 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
370 AttrTok->startsSequence(tok::r_paren, tok::identifier))
371 return false;
372 if (AttrTok->is(tok::ellipsis))
373 return true;
374 AttrTok = AttrTok->Next;
375 }
376 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
377 }
378
379 bool parseSquare() {
380 if (!CurrentToken)
381 return false;
382
383 // A '[' could be an index subscript (after an identifier or after
384 // ')' or ']'), it could be the start of an Objective-C method
385 // expression, it could the start of an Objective-C array literal,
386 // or it could be a C++ attribute specifier [[foo::bar]].
387 FormatToken *Left = CurrentToken->Previous;
388 Left->ParentBracket = Contexts.back().ContextKind;
389 FormatToken *Parent = Left->getPreviousNonComment();
390
391 // Cases where '>' is followed by '['.
392 // In C++, this can happen either in array of templates (foo<int>[10])
393 // or when array is a nested template type (unique_ptr<type1<type2>[]>).
394 bool CppArrayTemplates =
395 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
396 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
397 Contexts.back().InTemplateArgument);
398
399 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
400 Contexts.back().InCpp11AttributeSpecifier;
401
402 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
403 bool StartsObjCMethodExpr =
404 !InsideInlineASM && !CppArrayTemplates && Style.isCpp() &&
405 !IsCpp11AttributeSpecifier && Contexts.back().CanBeExpression &&
406 Left->isNot(TT_LambdaLSquare) &&
407 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
408 (!Parent ||
409 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
410 tok::kw_return, tok::kw_throw) ||
411 Parent->isUnaryOperator() ||
412 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
413 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
414 getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown);
415 bool ColonFound = false;
416
417 unsigned BindingIncrease = 1;
418 if (Left->isCppStructuredBinding(Style)) {
419 Left->Type = TT_StructuredBindingLSquare;
420 } else if (Left->is(TT_Unknown)) {
421 if (StartsObjCMethodExpr) {
422 Left->Type = TT_ObjCMethodExpr;
423 } else if (IsCpp11AttributeSpecifier) {
424 Left->Type = TT_AttributeSquare;
425 } else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
426 Contexts.back().ContextKind == tok::l_brace &&
427 Parent->isOneOf(tok::l_brace, tok::comma)) {
428 Left->Type = TT_JsComputedPropertyName;
429 } else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
430 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
431 Left->Type = TT_DesignatedInitializerLSquare;
432 } else if (CurrentToken->is(tok::r_square) && Parent &&
433 Parent->is(TT_TemplateCloser)) {
434 Left->Type = TT_ArraySubscriptLSquare;
435 } else if (Style.Language == FormatStyle::LK_Proto ||
436 Style.Language == FormatStyle::LK_TextProto) {
437 // Square braces in LK_Proto can either be message field attributes:
438 //
439 // optional Aaa aaa = 1 [
440 // (aaa) = aaa
441 // ];
442 //
443 // extensions 123 [
444 // (aaa) = aaa
445 // ];
446 //
447 // or text proto extensions (in options):
448 //
449 // option (Aaa.options) = {
450 // [type.type/type] {
451 // key: value
452 // }
453 // }
454 //
455 // or repeated fields (in options):
456 //
457 // option (Aaa.options) = {
458 // keys: [ 1, 2, 3 ]
459 // }
460 //
461 // In the first and the third case we want to spread the contents inside
462 // the square braces; in the second we want to keep them inline.
463 Left->Type = TT_ArrayInitializerLSquare;
464 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
465 tok::equal) &&
466 !Left->endsSequence(tok::l_square, tok::numeric_constant,
467 tok::identifier) &&
468 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
469 Left->Type = TT_ProtoExtensionLSquare;
470 BindingIncrease = 10;
471 }
472 } else if (!CppArrayTemplates && Parent &&
473 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
474 tok::comma, tok::l_paren, tok::l_square,
475 tok::question, tok::colon, tok::kw_return,
476 // Should only be relevant to JavaScript:
477 tok::kw_default)) {
478 Left->Type = TT_ArrayInitializerLSquare;
479 } else {
480 BindingIncrease = 10;
481 Left->Type = TT_ArraySubscriptLSquare;
482 }
483 }
484
485 ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease);
486 Contexts.back().IsExpression = true;
487 if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
488 Parent->is(TT_JsTypeColon))
489 Contexts.back().IsExpression = false;
490
491 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
492 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
493
494 while (CurrentToken) {
495 if (CurrentToken->is(tok::r_square)) {
496 if (IsCpp11AttributeSpecifier)
497 CurrentToken->Type = TT_AttributeSquare;
498 else if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
499 Left->is(TT_ObjCMethodExpr)) {
500 // An ObjC method call is rarely followed by an open parenthesis.
501 // FIXME: Do we incorrectly label ":" with this?
502 StartsObjCMethodExpr = false;
503 Left->Type = TT_Unknown;
504 }
505 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
506 CurrentToken->Type = TT_ObjCMethodExpr;
507 // If we haven't seen a colon yet, make sure the last identifier
508 // before the r_square is tagged as a selector name component.
509 if (!ColonFound && CurrentToken->Previous &&
510 CurrentToken->Previous->is(TT_Unknown) &&
511 canBeObjCSelectorComponent(*CurrentToken->Previous))
512 CurrentToken->Previous->Type = TT_SelectorName;
513 // determineStarAmpUsage() thinks that '*' '[' is allocating an
514 // array of pointers, but if '[' starts a selector then '*' is a
515 // binary operator.
516 if (Parent && Parent->is(TT_PointerOrReference))
517 Parent->Type = TT_BinaryOperator;
518 }
519 Left->MatchingParen = CurrentToken;
520 CurrentToken->MatchingParen = Left;
521 // FirstObjCSelectorName is set when a colon is found. This does
522 // not work, however, when the method has no parameters.
523 // Here, we set FirstObjCSelectorName when the end of the method call is
524 // reached, in case it was not set already.
525 if (!Contexts.back().FirstObjCSelectorName) {
526 FormatToken* Previous = CurrentToken->getPreviousNonComment();
527 if (Previous && Previous->is(TT_SelectorName)) {
528 Previous->ObjCSelectorNameParts = 1;
529 Contexts.back().FirstObjCSelectorName = Previous;
530 }
531 } else {
532 Left->ParameterCount =
533 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
534 }
535 if (Contexts.back().FirstObjCSelectorName) {
536 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
537 Contexts.back().LongestObjCSelectorName;
538 if (Left->BlockParameterCount > 1)
539 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
540 }
541 next();
542 return true;
543 }
544 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
545 return false;
546 if (CurrentToken->is(tok::colon)) {
547 if (IsCpp11AttributeSpecifier &&
548 CurrentToken->endsSequence(tok::colon, tok::identifier,
549 tok::kw_using)) {
550 // Remember that this is a [[using ns: foo]] C++ attribute, so we
551 // don't add a space before the colon (unlike other colons).
552 CurrentToken->Type = TT_AttributeColon;
553 } else if (Left->isOneOf(TT_ArraySubscriptLSquare,
554 TT_DesignatedInitializerLSquare)) {
555 Left->Type = TT_ObjCMethodExpr;
556 StartsObjCMethodExpr = true;
557 Contexts.back().ColonIsObjCMethodExpr = true;
558 if (Parent && Parent->is(tok::r_paren))
559 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
560 Parent->Type = TT_CastRParen;
561 }
562 ColonFound = true;
563 }
564 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
565 !ColonFound)
566 Left->Type = TT_ArrayInitializerLSquare;
567 FormatToken *Tok = CurrentToken;
568 if (!consumeToken())
569 return false;
570 updateParameterCount(Left, Tok);
571 }
572 return false;
573 }
574
575 bool parseBrace() {
576 if (CurrentToken) {
577 FormatToken *Left = CurrentToken->Previous;
578 Left->ParentBracket = Contexts.back().ContextKind;
579
580 if (Contexts.back().CaretFound)
581 Left->Type = TT_ObjCBlockLBrace;
582 Contexts.back().CaretFound = false;
583
584 ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
585 Contexts.back().ColonIsDictLiteral = true;
586 if (Left->BlockKind == BK_BracedInit)
587 Contexts.back().IsExpression = true;
588 if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
589 Left->Previous->is(TT_JsTypeColon))
590 Contexts.back().IsExpression = false;
591
592 while (CurrentToken) {
593 if (CurrentToken->is(tok::r_brace)) {
594 Left->MatchingParen = CurrentToken;
595 CurrentToken->MatchingParen = Left;
596 next();
597 return true;
598 }
599 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
600 return false;
601 updateParameterCount(Left, CurrentToken);
602 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
603 FormatToken *Previous = CurrentToken->getPreviousNonComment();
604 if (Previous->is(TT_JsTypeOptionalQuestion))
605 Previous = Previous->getPreviousNonComment();
606 if ((CurrentToken->is(tok::colon) &&
607 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
608 Style.Language == FormatStyle::LK_Proto ||
609 Style.Language == FormatStyle::LK_TextProto) {
610 Left->Type = TT_DictLiteral;
611 if (Previous->Tok.getIdentifierInfo() ||
612 Previous->is(tok::string_literal))
613 Previous->Type = TT_SelectorName;
614 }
615 if (CurrentToken->is(tok::colon) ||
616 Style.Language == FormatStyle::LK_JavaScript)
617 Left->Type = TT_DictLiteral;
618 }
619 if (CurrentToken->is(tok::comma) &&
620 Style.Language == FormatStyle::LK_JavaScript)
621 Left->Type = TT_DictLiteral;
622 if (!consumeToken())
623 return false;
624 }
625 }
626 return true;
627 }
628
629 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
630 // For ObjC methods, the number of parameters is calculated differently as
631 // method declarations have a different structure (the parameters are not
632 // inside a bracket scope).
633 if (Current->is(tok::l_brace) && Current->BlockKind == BK_Block)
634 ++Left->BlockParameterCount;
635 if (Current->is(tok::comma)) {
636 ++Left->ParameterCount;
637 if (!Left->Role)
638 Left->Role.reset(new CommaSeparatedList(Style));
639 Left->Role->CommaFound(Current);
640 } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
641 Left->ParameterCount = 1;
642 }
643 }
644
645 bool parseConditional() {
646 while (CurrentToken) {
647 if (CurrentToken->is(tok::colon)) {
648 CurrentToken->Type = TT_ConditionalExpr;
649 next();
650 return true;
651 }
652 if (!consumeToken())
653 return false;
654 }
655 return false;
656 }
657
658 bool parseTemplateDeclaration() {
659 if (CurrentToken && CurrentToken->is(tok::less)) {
660 CurrentToken->Type = TT_TemplateOpener;
661 next();
662 if (!parseAngle())
663 return false;
664 if (CurrentToken)
665 CurrentToken->Previous->ClosesTemplateDeclaration = true;
666 return true;
667 }
668 return false;
669 }
670
671 bool consumeToken() {
672 FormatToken *Tok = CurrentToken;
673 next();
674 switch (Tok->Tok.getKind()) {
675 case tok::plus:
676 case tok::minus:
677 if (!Tok->Previous && Line.MustBeDeclaration)
678 Tok->Type = TT_ObjCMethodSpecifier;
679 break;
680 case tok::colon:
681 if (!Tok->Previous)
682 return false;
683 // Colons from ?: are handled in parseConditional().
684 if (Style.Language == FormatStyle::LK_JavaScript) {
685 if (Contexts.back().ColonIsForRangeExpr || // colon in for loop
686 (Contexts.size() == 1 && // switch/case labels
687 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
688 Contexts.back().ContextKind == tok::l_paren || // function params
689 Contexts.back().ContextKind == tok::l_square || // array type
690 (!Contexts.back().IsExpression &&
691 Contexts.back().ContextKind == tok::l_brace) || // object type
692 (Contexts.size() == 1 &&
693 Line.MustBeDeclaration)) { // method/property declaration
694 Contexts.back().IsExpression = false;
695 Tok->Type = TT_JsTypeColon;
696 break;
697 }
698 }
699 if (Contexts.back().ColonIsDictLiteral ||
700 Style.Language == FormatStyle::LK_Proto ||
701 Style.Language == FormatStyle::LK_TextProto) {
702 Tok->Type = TT_DictLiteral;
703 if (Style.Language == FormatStyle::LK_TextProto) {
704 if (FormatToken *Previous = Tok->getPreviousNonComment())
705 Previous->Type = TT_SelectorName;
706 }
707 } else if (Contexts.back().ColonIsObjCMethodExpr ||
708 Line.startsWith(TT_ObjCMethodSpecifier)) {
709 Tok->Type = TT_ObjCMethodExpr;
710 const FormatToken *BeforePrevious = Tok->Previous->Previous;
711 // Ensure we tag all identifiers in method declarations as
712 // TT_SelectorName.
713 bool UnknownIdentifierInMethodDeclaration =
714 Line.startsWith(TT_ObjCMethodSpecifier) &&
715 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
716 if (!BeforePrevious ||
717 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
718 !(BeforePrevious->is(TT_CastRParen) ||
719 (BeforePrevious->is(TT_ObjCMethodExpr) &&
720 BeforePrevious->is(tok::colon))) ||
721 BeforePrevious->is(tok::r_square) ||
722 Contexts.back().LongestObjCSelectorName == 0 ||
723 UnknownIdentifierInMethodDeclaration) {
724 Tok->Previous->Type = TT_SelectorName;
725 if (!Contexts.back().FirstObjCSelectorName)
726 Contexts.back().FirstObjCSelectorName = Tok->Previous;
727 else if (Tok->Previous->ColumnWidth >
728 Contexts.back().LongestObjCSelectorName)
729 Contexts.back().LongestObjCSelectorName =
730 Tok->Previous->ColumnWidth;
731 Tok->Previous->ParameterIndex =
732 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
733 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
734 }
735 } else if (Contexts.back().ColonIsForRangeExpr) {
736 Tok->Type = TT_RangeBasedForLoopColon;
737 } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
738 Tok->Type = TT_BitFieldColon;
739 } else if (Contexts.size() == 1 &&
740 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
741 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren,
742 tok::kw_noexcept))
743 Tok->Type = TT_CtorInitializerColon;
744 else
745 Tok->Type = TT_InheritanceColon;
746 } else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
747 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
748 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
749 Tok->Next->Next->is(tok::colon)))) {
750 // This handles a special macro in ObjC code where selectors including
751 // the colon are passed as macro arguments.
752 Tok->Type = TT_ObjCMethodExpr;
753 } else if (Contexts.back().ContextKind == tok::l_paren) {
754 Tok->Type = TT_InlineASMColon;
755 }
756 break;
757 case tok::pipe:
758 case tok::amp:
759 // | and & in declarations/type expressions represent union and
760 // intersection types, respectively.
761 if (Style.Language == FormatStyle::LK_JavaScript &&
762 !Contexts.back().IsExpression)
763 Tok->Type = TT_JsTypeOperator;
764 break;
765 case tok::kw_if:
766 case tok::kw_while:
767 if (Tok->is(tok::kw_if) && CurrentToken &&
768 CurrentToken->is(tok::kw_constexpr))
769 next();
770 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
771 next();
772 if (!parseParens(/*LookForDecls=*/true))
773 return false;
774 }
775 break;
776 case tok::kw_for:
777 if (Style.Language == FormatStyle::LK_JavaScript) {
778 // x.for and {for: ...}
779 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
780 (Tok->Next && Tok->Next->is(tok::colon)))
781 break;
782 // JS' for await ( ...
783 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
784 next();
785 }
786 Contexts.back().ColonIsForRangeExpr = true;
787 next();
788 if (!parseParens())
789 return false;
790 break;
791 case tok::l_paren:
792 // When faced with 'operator()()', the kw_operator handler incorrectly
793 // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
794 // the first two parens OverloadedOperators and the second l_paren an
795 // OverloadedOperatorLParen.
796 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
797 Tok->Previous->MatchingParen &&
798 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
799 Tok->Previous->Type = TT_OverloadedOperator;
800 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
801 Tok->Type = TT_OverloadedOperatorLParen;
802 }
803
804 if (!parseParens())
805 return false;
806 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
807 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
808 (!Tok->Previous ||
809 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
810 TT_LeadingJavaAnnotation)))
811 Line.MightBeFunctionDecl = true;
812 break;
813 case tok::l_square:
814 if (!parseSquare())
815 return false;
816 break;
817 case tok::l_brace:
818 if (Style.Language == FormatStyle::LK_TextProto) {
819 FormatToken *Previous = Tok->getPreviousNonComment();
820 if (Previous && Previous->Type != TT_DictLiteral)
821 Previous->Type = TT_SelectorName;
822 }
823 if (!parseBrace())
824 return false;
825 break;
826 case tok::less:
827 if (parseAngle()) {
828 Tok->Type = TT_TemplateOpener;
829 // In TT_Proto, we must distignuish between:
830 // map<key, value>
831 // msg < item: data >
832 // msg: < item: data >
833 // In TT_TextProto, map<key, value> does not occur.
834 if (Style.Language == FormatStyle::LK_TextProto ||
835 (Style.Language == FormatStyle::LK_Proto && Tok->Previous &&
836 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
837 Tok->Type = TT_DictLiteral;
838 FormatToken *Previous = Tok->getPreviousNonComment();
839 if (Previous && Previous->Type != TT_DictLiteral)
840 Previous->Type = TT_SelectorName;
841 }
842 } else {
843 Tok->Type = TT_BinaryOperator;
844 NonTemplateLess.insert(Tok);
845 CurrentToken = Tok;
846 next();
847 }
848 break;
849 case tok::r_paren:
850 case tok::r_square:
851 return false;
852 case tok::r_brace:
853 // Lines can start with '}'.
854 if (Tok->Previous)
855 return false;
856 break;
857 case tok::greater:
858 if (Style.Language != FormatStyle::LK_TextProto)
859 Tok->Type = TT_BinaryOperator;
860 break;
861 case tok::kw_operator:
862 if (Style.Language == FormatStyle::LK_TextProto ||
863 Style.Language == FormatStyle::LK_Proto)
864 break;
865 while (CurrentToken &&
866 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
867 if (CurrentToken->isOneOf(tok::star, tok::amp))
868 CurrentToken->Type = TT_PointerOrReference;
869 consumeToken();
870 if (CurrentToken &&
871 CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator,
872 tok::comma))
873 CurrentToken->Previous->Type = TT_OverloadedOperator;
874 }
875 if (CurrentToken) {
876 CurrentToken->Type = TT_OverloadedOperatorLParen;
877 if (CurrentToken->Previous->is(TT_BinaryOperator))
878 CurrentToken->Previous->Type = TT_OverloadedOperator;
879 }
880 break;
881 case tok::question:
882 if (Style.Language == FormatStyle::LK_JavaScript && Tok->Next &&
883 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
884 tok::r_brace)) {
885 // Question marks before semicolons, colons, etc. indicate optional
886 // types (fields, parameters), e.g.
887 // function(x?: string, y?) {...}
888 // class X { y?; }
889 Tok->Type = TT_JsTypeOptionalQuestion;
890 break;
891 }
892 // Declarations cannot be conditional expressions, this can only be part
893 // of a type declaration.
894 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
895 Style.Language == FormatStyle::LK_JavaScript)
896 break;
897 parseConditional();
898 break;
899 case tok::kw_template:
900 parseTemplateDeclaration();
901 break;
902 case tok::comma:
903 if (Contexts.back().InCtorInitializer)
904 Tok->Type = TT_CtorInitializerComma;
905 else if (Contexts.back().InInheritanceList)
906 Tok->Type = TT_InheritanceComma;
907 else if (Contexts.back().FirstStartOfName &&
908 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
909 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
910 Line.IsMultiVariableDeclStmt = true;
911 }
912 if (Contexts.back().IsForEachMacro)
913 Contexts.back().IsExpression = true;
914 break;
915 case tok::identifier:
916 if (Tok->isOneOf(Keywords.kw___has_include,
917 Keywords.kw___has_include_next)) {
918 parseHasInclude();
919 }
920 break;
921 default:
922 break;
923 }
924 return true;
925 }
926
927 void parseIncludeDirective() {
928 if (CurrentToken && CurrentToken->is(tok::less)) {
929 next();
930 while (CurrentToken) {
931 // Mark tokens up to the trailing line comments as implicit string
932 // literals.
933 if (CurrentToken->isNot(tok::comment) &&
934 !CurrentToken->TokenText.startswith("//"))
935 CurrentToken->Type = TT_ImplicitStringLiteral;
936 next();
937 }
938 }
939 }
940
941 void parseWarningOrError() {
942 next();
943 // We still want to format the whitespace left of the first token of the
944 // warning or error.
945 next();
946 while (CurrentToken) {
947 CurrentToken->Type = TT_ImplicitStringLiteral;
948 next();
949 }
950 }
951
952 void parsePragma() {
953 next(); // Consume "pragma".
954 if (CurrentToken &&
955 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
956 bool IsMark = CurrentToken->is(Keywords.kw_mark);
957 next(); // Consume "mark".
958 next(); // Consume first token (so we fix leading whitespace).
959 while (CurrentToken) {
960 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
961 CurrentToken->Type = TT_ImplicitStringLiteral;
962 next();
963 }
964 }
965 }
966
967 void parseHasInclude() {
968 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
969 return;
970 next(); // '('
971 parseIncludeDirective();
972 next(); // ')'
973 }
974
975 LineType parsePreprocessorDirective() {
976 bool IsFirstToken = CurrentToken->IsFirst;
977 LineType Type = LT_PreprocessorDirective;
978 next();
979 if (!CurrentToken)
980 return Type;
981
982 if (Style.Language == FormatStyle::LK_JavaScript && IsFirstToken) {
983 // JavaScript files can contain shebang lines of the form:
984 // #!/usr/bin/env node
985 // Treat these like C++ #include directives.
986 while (CurrentToken) {
987 // Tokens cannot be comments here.
988 CurrentToken->Type = TT_ImplicitStringLiteral;
989 next();
990 }
991 return LT_ImportStatement;
992 }
993
994 if (CurrentToken->Tok.is(tok::numeric_constant)) {
995 CurrentToken->SpacesRequiredBefore = 1;
996 return Type;
997 }
998 // Hashes in the middle of a line can lead to any strange token
999 // sequence.
1000 if (!CurrentToken->Tok.getIdentifierInfo())
1001 return Type;
1002 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1003 case tok::pp_include:
1004 case tok::pp_include_next:
1005 case tok::pp_import:
1006 next();
1007 parseIncludeDirective();
1008 Type = LT_ImportStatement;
1009 break;
1010 case tok::pp_error:
1011 case tok::pp_warning:
1012 parseWarningOrError();
1013 break;
1014 case tok::pp_pragma:
1015 parsePragma();
1016 break;
1017 case tok::pp_if:
1018 case tok::pp_elif:
1019 Contexts.back().IsExpression = true;
1020 parseLine();
1021 break;
1022 default:
1023 break;
1024 }
1025 while (CurrentToken) {
1026 FormatToken *Tok = CurrentToken;
1027 next();
1028 if (Tok->is(tok::l_paren))
1029 parseParens();
1030 else if (Tok->isOneOf(Keywords.kw___has_include,
1031 Keywords.kw___has_include_next))
1032 parseHasInclude();
1033 }
1034 return Type;
1035 }
1036
1037 public:
1038 LineType parseLine() {
1039 NonTemplateLess.clear();
1040 if (CurrentToken->is(tok::hash))
1041 return parsePreprocessorDirective();
1042
1043 // Directly allow to 'import <string-literal>' to support protocol buffer
1044 // definitions (github.com/google/protobuf) or missing "#" (either way we
1045 // should not break the line).
1046 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1047 if ((Style.Language == FormatStyle::LK_Java &&
1048 CurrentToken->is(Keywords.kw_package)) ||
1049 (Info && Info->getPPKeywordID() == tok::pp_import &&
1050 CurrentToken->Next &&
1051 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1052 tok::kw_static))) {
1053 next();
1054 parseIncludeDirective();
1055 return LT_ImportStatement;
1056 }
1057
1058 // If this line starts and ends in '<' and '>', respectively, it is likely
1059 // part of "#define <a/b.h>".
1060 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
1061 parseIncludeDirective();
1062 return LT_ImportStatement;
1063 }
1064
1065 // In .proto files, top-level options are very similar to import statements
1066 // and should not be line-wrapped.
1067 if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&
1068 CurrentToken->is(Keywords.kw_option)) {
1069 next();
1070 if (CurrentToken && CurrentToken->is(tok::identifier))
1071 return LT_ImportStatement;
1072 }
1073
1074 bool KeywordVirtualFound = false;
1075 bool ImportStatement = false;
1076
1077 // import {...} from '...';
1078 if (Style.Language == FormatStyle::LK_JavaScript &&
1079 CurrentToken->is(Keywords.kw_import))
1080 ImportStatement = true;
1081
1082 while (CurrentToken) {
1083 if (CurrentToken->is(tok::kw_virtual))
1084 KeywordVirtualFound = true;
1085 if (Style.Language == FormatStyle::LK_JavaScript) {
1086 // export {...} from '...';
1087 // An export followed by "from 'some string';" is a re-export from
1088 // another module identified by a URI and is treated as a
1089 // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
1090 // Just "export {...};" or "export class ..." should not be treated as
1091 // an import in this sense.
1092 if (Line.First->is(tok::kw_export) &&
1093 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1094 CurrentToken->Next->isStringLiteral())
1095 ImportStatement = true;
1096 if (isClosureImportStatement(*CurrentToken))
1097 ImportStatement = true;
1098 }
1099 if (!consumeToken())
1100 return LT_Invalid;
1101 }
1102 if (KeywordVirtualFound)
1103 return LT_VirtualFunctionDecl;
1104 if (ImportStatement)
1105 return LT_ImportStatement;
1106
1107 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
1108 if (Contexts.back().FirstObjCSelectorName)
1109 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1110 Contexts.back().LongestObjCSelectorName;
1111 return LT_ObjCMethodDecl;
1112 }
1113
1114 return LT_Other;
1115 }
1116
1117 private:
1118 bool isClosureImportStatement(const FormatToken &Tok) {
1119 // FIXME: Closure-library specific stuff should not be hard-coded but be
1120 // configurable.
1121 return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
1122 Tok.Next->Next &&
1123 (Tok.Next->Next->TokenText == "module" ||
1124 Tok.Next->Next->TokenText == "provide" ||
1125 Tok.Next->Next->TokenText == "require" ||
1126 Tok.Next->Next->TokenText == "requireType" ||
1127 Tok.Next->Next->TokenText == "forwardDeclare") &&
1128 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1129 }
1130
1131 void resetTokenMetadata(FormatToken *Token) {
1132 if (!Token)
1133 return;
1134
1135 // Reset token type in case we have already looked at it and then
1136 // recovered from an error (e.g. failure to find the matching >).
1137 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
1138 TT_FunctionLBrace, TT_ImplicitStringLiteral,
1139 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
1140 TT_OverloadedOperator, TT_RegexLiteral,
1141 TT_TemplateString, TT_ObjCStringLiteral))
1142 CurrentToken->Type = TT_Unknown;
1143 CurrentToken->Role.reset();
1144 CurrentToken->MatchingParen = nullptr;
1145 CurrentToken->FakeLParens.clear();
1146 CurrentToken->FakeRParens = 0;
1147 }
1148
1149 void next() {
1150 if (CurrentToken) {
1151 CurrentToken->NestingLevel = Contexts.size() - 1;
1152 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1153 modifyContext(*CurrentToken);
1154 determineTokenType(*CurrentToken);
1155 CurrentToken = CurrentToken->Next;
1156 }
1157
1158 resetTokenMetadata(CurrentToken);
1159 }
1160
1161 /// A struct to hold information valid in a specific context, e.g.
1162 /// a pair of parenthesis.
1163 struct Context {
1164 Context(tok::TokenKind ContextKind, unsigned BindingStrength,
1165 bool IsExpression)
1166 : ContextKind(ContextKind), BindingStrength(BindingStrength),
1167 IsExpression(IsExpression) {}
1168
1169 tok::TokenKind ContextKind;
1170 unsigned BindingStrength;
1171 bool IsExpression;
1172 unsigned LongestObjCSelectorName = 0;
1173 bool ColonIsForRangeExpr = false;
1174 bool ColonIsDictLiteral = false;
1175 bool ColonIsObjCMethodExpr = false;
1176 FormatToken *FirstObjCSelectorName = nullptr;
1177 FormatToken *FirstStartOfName = nullptr;
1178 bool CanBeExpression = true;
1179 bool InTemplateArgument = false;
1180 bool InCtorInitializer = false;
1181 bool InInheritanceList = false;
1182 bool CaretFound = false;
1183 bool IsForEachMacro = false;
1184 bool InCpp11AttributeSpecifier = false;
1185 };
1186
1187 /// Puts a new \c Context onto the stack \c Contexts for the lifetime
1188 /// of each instance.
1189 struct ScopedContextCreator {
1190 AnnotatingParser &P;
1191
1192 ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,
1193 unsigned Increase)
1194 : P(P) {
1195 P.Contexts.push_back(Context(ContextKind,
1196 P.Contexts.back().BindingStrength + Increase,
1197 P.Contexts.back().IsExpression));
1198 }
1199
1200 ~ScopedContextCreator() { P.Contexts.pop_back(); }
1201 };
1202
1203 void modifyContext(const FormatToken &Current) {
1204 if (Current.getPrecedence() == prec::Assignment &&
1205 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1206 // Type aliases use `type X = ...;` in TypeScript and can be exported
1207 // using `export type ...`.
1208 !(Style.Language == FormatStyle::LK_JavaScript &&
1209 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1210 Line.startsWith(tok::kw_export, Keywords.kw_type,
1211 tok::identifier))) &&
1212 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1213 Contexts.back().IsExpression = true;
1214 if (!Line.startsWith(TT_UnaryOperator)) {
1215 for (FormatToken *Previous = Current.Previous;
1216 Previous && Previous->Previous &&
1217 !Previous->Previous->isOneOf(tok::comma, tok::semi);
1218 Previous = Previous->Previous) {
1219 if (Previous->isOneOf(tok::r_square, tok::r_paren)) {
1220 Previous = Previous->MatchingParen;
1221 if (!Previous)
1222 break;
1223 }
1224 if (Previous->opensScope())
1225 break;
1226 if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1227 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1228 Previous->Previous && Previous->Previous->isNot(tok::equal))
1229 Previous->Type = TT_PointerOrReference;
1230 }
1231 }
1232 } else if (Current.is(tok::lessless) &&
1233 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1234 Contexts.back().IsExpression = true;
1235 } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1236 Contexts.back().IsExpression = true;
1237 } else if (Current.is(TT_TrailingReturnArrow)) {
1238 Contexts.back().IsExpression = false;
1239 } else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1240 Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java;
1241 } else if (Current.Previous &&
1242 Current.Previous->is(TT_CtorInitializerColon)) {
1243 Contexts.back().IsExpression = true;
1244 Contexts.back().InCtorInitializer = true;
1245 } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1246 Contexts.back().InInheritanceList = true;
1247 } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1248 for (FormatToken *Previous = Current.Previous;
1249 Previous && Previous->isOneOf(tok::star, tok::amp);
1250 Previous = Previous->Previous)
1251 Previous->Type = TT_PointerOrReference;
1252 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer)
1253 Contexts.back().IsExpression = false;
1254 } else if (Current.is(tok::kw_new)) {
1255 Contexts.back().CanBeExpression = false;
1256 } else if (Current.isOneOf(tok::semi, tok::exclaim)) {
1257 // This should be the condition or increment in a for-loop.
1258 Contexts.back().IsExpression = true;
1259 }
1260 }
1261
1262 void determineTokenType(FormatToken &Current) {
1263 if (!Current.is(TT_Unknown))
1264 // The token type is already known.
1265 return;
1266
1267 if (Style.Language == FormatStyle::LK_JavaScript) {
1268 if (Current.is(tok::exclaim)) {
1269 if (Current.Previous &&
1270 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1271 tok::r_paren, tok::r_square,
1272 tok::r_brace) ||
1273 Current.Previous->Tok.isLiteral())) {
1274 Current.Type = TT_JsNonNullAssertion;
1275 return;
1276 }
1277 if (Current.Next &&
1278 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1279 Current.Type = TT_JsNonNullAssertion;
1280 return;
1281 }
1282 }
1283 }
1284
1285 // Line.MightBeFunctionDecl can only be true after the parentheses of a
1286 // function declaration have been found. In this case, 'Current' is a
1287 // trailing token of this declaration and thus cannot be a name.
1288 if (Current.is(Keywords.kw_instanceof)) {
1289 Current.Type = TT_BinaryOperator;
1290 } else if (isStartOfName(Current) &&
1291 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1292 Contexts.back().FirstStartOfName = &Current;
1293 Current.Type = TT_StartOfName;
1294 } else if (Current.is(tok::semi)) {
1295 // Reset FirstStartOfName after finding a semicolon so that a for loop
1296 // with multiple increment statements is not confused with a for loop
1297 // having multiple variable declarations.
1298 Contexts.back().FirstStartOfName = nullptr;
1299 } else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1300 AutoFound = true;
1301 } else if (Current.is(tok::arrow) &&
1302 Style.Language == FormatStyle::LK_Java) {
1303 Current.Type = TT_LambdaArrow;
1304 } else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1305 Current.NestingLevel == 0) {
1306 Current.Type = TT_TrailingReturnArrow;
1307 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1308 Current.Type = determineStarAmpUsage(Current,
1309 Contexts.back().CanBeExpression &&
1310 Contexts.back().IsExpression,
1311 Contexts.back().InTemplateArgument);
1312 } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1313 Current.Type = determinePlusMinusCaretUsage(Current);
1314 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1315 Contexts.back().CaretFound = true;
1316 } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1317 Current.Type = determineIncrementUsage(Current);
1318 } else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1319 Current.Type = TT_UnaryOperator;
1320 } else if (Current.is(tok::question)) {
1321 if (Style.Language == FormatStyle::LK_JavaScript &&
1322 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1323 // In JavaScript, `interface X { foo?(): bar; }` is an optional method
1324 // on the interface, not a ternary expression.
1325 Current.Type = TT_JsTypeOptionalQuestion;
1326 } else {
1327 Current.Type = TT_ConditionalExpr;
1328 }
1329 } else if (Current.isBinaryOperator() &&
1330 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1331 (!Current.is(tok::greater) &&
1332 Style.Language != FormatStyle::LK_TextProto)) {
1333 Current.Type = TT_BinaryOperator;
1334 } else if (Current.is(tok::comment)) {
1335 if (Current.TokenText.startswith("/*")) {
1336 if (Current.TokenText.endswith("*/"))
1337 Current.Type = TT_BlockComment;
1338 else
1339 // The lexer has for some reason determined a comment here. But we
1340 // cannot really handle it, if it isn't properly terminated.
1341 Current.Tok.setKind(tok::unknown);
1342 } else {
1343 Current.Type = TT_LineComment;
1344 }
1345 } else if (Current.is(tok::r_paren)) {
1346 if (rParenEndsCast(Current))
1347 Current.Type = TT_CastRParen;
1348 if (Current.MatchingParen && Current.Next &&
1349 !Current.Next->isBinaryOperator() &&
1350 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1351 tok::comma, tok::period, tok::arrow,
1352 tok::coloncolon))
1353 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1354 // Make sure this isn't the return type of an Obj-C block declaration
1355 if (AfterParen->Tok.isNot(tok::caret)) {
1356 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1357 if (BeforeParen->is(tok::identifier) &&
1358 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1359 (!BeforeParen->Previous ||
1360 BeforeParen->Previous->ClosesTemplateDeclaration))
1361 Current.Type = TT_FunctionAnnotationRParen;
1362 }
1363 }
1364 } else if (Current.is(tok::at) && Current.Next &&
1365 Style.Language != FormatStyle::LK_JavaScript &&
1366 Style.Language != FormatStyle::LK_Java) {
1367 // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it
1368 // marks declarations and properties that need special formatting.
1369 switch (Current.Next->Tok.getObjCKeywordID()) {
1370 case tok::objc_interface:
1371 case tok::objc_implementation:
1372 case tok::objc_protocol:
1373 Current.Type = TT_ObjCDecl;
1374 break;
1375 case tok::objc_property:
1376 Current.Type = TT_ObjCProperty;
1377 break;
1378 default:
1379 break;
1380 }
1381 } else if (Current.is(tok::period)) {
1382 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1383 if (PreviousNoComment &&
1384 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1385 Current.Type = TT_DesignatedInitializerPeriod;
1386 else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
1387 Current.Previous->isOneOf(TT_JavaAnnotation,
1388 TT_LeadingJavaAnnotation)) {
1389 Current.Type = Current.Previous->Type;
1390 }
1391 } else if (canBeObjCSelectorComponent(Current) &&
1392 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
1393 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1394 Current.Previous->MatchingParen &&
1395 Current.Previous->MatchingParen->Previous &&
1396 Current.Previous->MatchingParen->Previous->is(
1397 TT_ObjCMethodSpecifier)) {
1398 // This is the first part of an Objective-C selector name. (If there's no
1399 // colon after this, this is the only place which annotates the identifier
1400 // as a selector.)
1401 Current.Type = TT_SelectorName;
1402 } else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
1403 Current.Previous &&
1404 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1405 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1406 // Line.MightBeFunctionDecl can only be true after the parentheses of a
1407 // function declaration have been found.
1408 Current.Type = TT_TrailingAnnotation;
1409 } else if ((Style.Language == FormatStyle::LK_Java ||
1410 Style.Language == FormatStyle::LK_JavaScript) &&
1411 Current.Previous) {
1412 if (Current.Previous->is(tok::at) &&
1413 Current.isNot(Keywords.kw_interface)) {
1414 const FormatToken &AtToken = *Current.Previous;
1415 const FormatToken *Previous = AtToken.getPreviousNonComment();
1416 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1417 Current.Type = TT_LeadingJavaAnnotation;
1418 else
1419 Current.Type = TT_JavaAnnotation;
1420 } else if (Current.Previous->is(tok::period) &&
1421 Current.Previous->isOneOf(TT_JavaAnnotation,
1422 TT_LeadingJavaAnnotation)) {
1423 Current.Type = Current.Previous->Type;
1424 }
1425 }
1426 }
1427
1428 /// Take a guess at whether \p Tok starts a name of a function or
1429 /// variable declaration.
1430 ///
1431 /// This is a heuristic based on whether \p Tok is an identifier following
1432 /// something that is likely a type.
1433 bool isStartOfName(const FormatToken &Tok) {
1434 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1435 return false;
1436
1437 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1438 Keywords.kw_as))
1439 return false;
1440 if (Style.Language == FormatStyle::LK_JavaScript &&
1441 Tok.Previous->is(Keywords.kw_in))
1442 return false;
1443
1444 // Skip "const" as it does not have an influence on whether this is a name.
1445 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1446 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1447 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1448
1449 if (!PreviousNotConst)
1450 return false;
1451
1452 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1453 PreviousNotConst->Previous &&
1454 PreviousNotConst->Previous->is(tok::hash);
1455
1456 if (PreviousNotConst->is(TT_TemplateCloser))
1457 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1458 PreviousNotConst->MatchingParen->Previous &&
1459 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1460 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1461
1462 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1463 PreviousNotConst->MatchingParen->Previous &&
1464 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1465 return true;
1466
1467 return (!IsPPKeyword &&
1468 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1469 PreviousNotConst->is(TT_PointerOrReference) ||
1470 PreviousNotConst->isSimpleTypeSpecifier();
1471 }
1472
1473 /// Determine whether ')' is ending a cast.
1474 bool rParenEndsCast(const FormatToken &Tok) {
1475 // C-style casts are only used in C++ and Java.
1476 if (!Style.isCpp() && Style.Language != FormatStyle::LK_Java)
1477 return false;
1478
1479 // Empty parens aren't casts and there are no casts at the end of the line.
1480 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1481 return false;
1482
1483 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1484 if (LeftOfParens) {
1485 // If there is a closing parenthesis left of the current parentheses,
1486 // look past it as these might be chained casts.
1487 if (LeftOfParens->is(tok::r_paren)) {
1488 if (!LeftOfParens->MatchingParen ||
1489 !LeftOfParens->MatchingParen->Previous)
1490 return false;
1491 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1492 }
1493
1494 // If there is an identifier (or with a few exceptions a keyword) right
1495 // before the parentheses, this is unlikely to be a cast.
1496 if (LeftOfParens->Tok.getIdentifierInfo() &&
1497 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1498 tok::kw_delete))
1499 return false;
1500
1501 // Certain other tokens right before the parentheses are also signals that
1502 // this cannot be a cast.
1503 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1504 TT_TemplateCloser, tok::ellipsis))
1505 return false;
1506 }
1507
1508 if (Tok.Next->is(tok::question))
1509 return false;
1510
1511 // As Java has no function types, a "(" after the ")" likely means that this
1512 // is a cast.
1513 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren))
1514 return true;
1515
1516 // If a (non-string) literal follows, this is likely a cast.
1517 if (Tok.Next->isNot(tok::string_literal) &&
1518 (Tok.Next->Tok.isLiteral() ||
1519 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1520 return true;
1521
1522 // Heuristically try to determine whether the parentheses contain a type.
1523 bool ParensAreType =
1524 !Tok.Previous ||
1525 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1526 Tok.Previous->isSimpleTypeSpecifier();
1527 bool ParensCouldEndDecl =
1528 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1529 if (ParensAreType && !ParensCouldEndDecl)
1530 return true;
1531
1532 // At this point, we heuristically assume that there are no casts at the
1533 // start of the line. We assume that we have found most cases where there
1534 // are by the logic above, e.g. "(void)x;".
1535 if (!LeftOfParens)
1536 return false;
1537
1538 // Certain token types inside the parentheses mean that this can't be a
1539 // cast.
1540 for (const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1541 Token = Token->Next)
1542 if (Token->is(TT_BinaryOperator))
1543 return false;
1544
1545 // If the following token is an identifier or 'this', this is a cast. All
1546 // cases where this can be something else are handled above.
1547 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1548 return true;
1549
1550 if (!Tok.Next->Next)
1551 return false;
1552
1553 // If the next token after the parenthesis is a unary operator, assume
1554 // that this is cast, unless there are unexpected tokens inside the
1555 // parenthesis.
1556 bool NextIsUnary =
1557 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1558 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1559 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1560 return false;
1561 // Search for unexpected tokens.
1562 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1563 Prev = Prev->Previous) {
1564 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1565 return false;
1566 }
1567 return true;
1568 }
1569
1570 /// Return the type of the given token assuming it is * or &.
1571 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
1572 bool InTemplateArgument) {
1573 if (Style.Language == FormatStyle::LK_JavaScript)
1574 return TT_BinaryOperator;
1575
1576 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1577 if (!PrevToken)
1578 return TT_UnaryOperator;
1579
1580 const FormatToken *NextToken = Tok.getNextNonComment();
1581 if (!NextToken ||
1582 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) ||
1583 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1584 return TT_PointerOrReference;
1585
1586 if (PrevToken->is(tok::coloncolon))
1587 return TT_PointerOrReference;
1588
1589 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1590 tok::comma, tok::semi, tok::kw_return, tok::colon,
1591 tok::equal, tok::kw_delete, tok::kw_sizeof,
1592 tok::kw_throw) ||
1593 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1594 TT_UnaryOperator, TT_CastRParen))
1595 return TT_UnaryOperator;
1596
1597 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1598 return TT_PointerOrReference;
1599 if (NextToken->is(tok::kw_operator) && !IsExpression)
1600 return TT_PointerOrReference;
1601 if (NextToken->isOneOf(tok::comma, tok::semi))
1602 return TT_PointerOrReference;
1603
1604 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
1605 FormatToken *TokenBeforeMatchingParen =
1606 PrevToken->MatchingParen->getPreviousNonComment();
1607 if (TokenBeforeMatchingParen &&
1608 TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype))
1609 return TT_PointerOrReference;
1610 }
1611
1612 if (PrevToken->Tok.isLiteral() ||
1613 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1614 tok::kw_false, tok::r_brace) ||
1615 NextToken->Tok.isLiteral() ||
1616 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1617 NextToken->isUnaryOperator() ||
1618 // If we know we're in a template argument, there are no named
1619 // declarations. Thus, having an identifier on the right-hand side
1620 // indicates a binary operator.
1621 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1622 return TT_BinaryOperator;
1623
1624 // "&&(" is quite unlikely to be two successive unary "&".
1625 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1626 return TT_BinaryOperator;
1627
1628 // This catches some cases where evaluation order is used as control flow:
1629 // aaa && aaa->f();
1630 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1631 if (NextNextToken && NextNextToken->is(tok::arrow))
1632 return TT_BinaryOperator;
1633
1634 // It is very unlikely that we are going to find a pointer or reference type
1635 // definition on the RHS of an assignment.
1636 if (IsExpression && !Contexts.back().CaretFound)
1637 return TT_BinaryOperator;
1638
1639 return TT_PointerOrReference;
1640 }
1641
1642 TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
1643 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1644 if (!PrevToken)
1645 return TT_UnaryOperator;
1646
1647 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
1648 // This must be a sequence of leading unary operators.
1649 return TT_UnaryOperator;
1650
1651 // Use heuristics to recognize unary operators.
1652 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1653 tok::question, tok::colon, tok::kw_return,
1654 tok::kw_case, tok::at, tok::l_brace))
1655 return TT_UnaryOperator;
1656
1657 // There can't be two consecutive binary operators.
1658 if (PrevToken->is(TT_BinaryOperator))
1659 return TT_UnaryOperator;
1660
1661 // Fall back to marking the token as binary operator.
1662 return TT_BinaryOperator;
1663 }
1664
1665 /// Determine whether ++/-- are pre- or post-increments/-decrements.
1666 TokenType determineIncrementUsage(const FormatToken &Tok) {
1667 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1668 if (!PrevToken || PrevToken->is(TT_CastRParen))
1669 return TT_UnaryOperator;
1670 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1671 return TT_TrailingUnaryOperator;
1672
1673 return TT_UnaryOperator;
1674 }
1675
1676 SmallVector<Context, 8> Contexts;
1677
1678 const FormatStyle &Style;
1679 AnnotatedLine &Line;
1680 FormatToken *CurrentToken;
1681 bool AutoFound;
1682 const AdditionalKeywords &Keywords;
1683
1684 // Set of "<" tokens that do not open a template parameter list. If parseAngle
1685 // determines that a specific token can't be a template opener, it will make
1686 // same decision irrespective of the decisions for tokens leading up to it.
1687 // Store this information to prevent this from causing exponential runtime.
1688 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
1689 };
1690
1691 static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
1692 static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;
1693
1694 /// Parses binary expressions by inserting fake parenthesis based on
1695 /// operator precedence.
1696 class ExpressionParser {
1697 public:
1698 ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords,
1699 AnnotatedLine &Line)
1700 : Style(Style), Keywords(Keywords), Current(Line.First) {}
1701
1702 /// Parse expressions with the given operator precedence.
1703 void parse(int Precedence = 0) {
1704 // Skip 'return' and ObjC selector colons as they are not part of a binary
1705 // expression.
1706 while (Current && (Current->is(tok::kw_return) ||
1707 (Current->is(tok::colon) &&
1708 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1709 next();
1710
1711 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1712 return;
1713
1714 // Conditional expressions need to be parsed separately for proper nesting.
1715 if (Precedence == prec::Conditional) {
1716 parseConditionalExpr();
1717 return;
1718 }
1719
1720 // Parse unary operators, which all have a higher precedence than binary
1721 // operators.
1722 if (Precedence == PrecedenceUnaryOperator) {
1723 parseUnaryOperator();
1724 return;
1725 }
1726
1727 FormatToken *Start = Current;
1728 FormatToken *LatestOperator = nullptr;
1729 unsigned OperatorIndex = 0;
1730
1731 while (Current) {
1732 // Consume operators with higher precedence.
1733 parse(Precedence + 1);
1734
1735 int CurrentPrecedence = getCurrentPrecedence();
1736
1737 if (Current && Current->is(TT_SelectorName) &&
1738 Precedence == CurrentPrecedence) {
1739 if (LatestOperator)
1740 addFakeParenthesis(Start, prec::Level(Precedence));
1741 Start = Current;
1742 }
1743
1744 // At the end of the line or when an operator with higher precedence is
1745 // found, insert fake parenthesis and return.
1746 if (!Current ||
1747 (Current->closesScope() &&
1748 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1749 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1750 (CurrentPrecedence == prec::Conditional &&
1751 Precedence == prec::Assignment && Current->is(tok::colon))) {
1752 break;
1753 }
1754
1755 // Consume scopes: (), [], <> and {}
1756 if (Current->opensScope()) {
1757 // In fragment of a JavaScript template string can look like '}..${' and
1758 // thus close a scope and open a new one at the same time.
1759 while (Current && (!Current->closesScope() || Current->opensScope())) {
1760 next();
1761 parse();
1762 }
1763 next();
1764 } else {
1765 // Operator found.
1766 if (CurrentPrecedence == Precedence) {
1767 if (LatestOperator)
1768 LatestOperator->NextOperator = Current;
1769 LatestOperator = Current;
1770 Current->OperatorIndex = OperatorIndex;
1771 ++OperatorIndex;
1772 }
1773 next(/*SkipPastLeadingComments=*/Precedence > 0);
1774 }
1775 }
1776
1777 if (LatestOperator && (Current || Precedence > 0)) {
1778 // LatestOperator->LastOperator = true;
1779 if (Precedence == PrecedenceArrowAndPeriod) {
1780 // Call expressions don't have a binary operator precedence.
1781 addFakeParenthesis(Start, prec::Unknown);
1782 } else {
1783 addFakeParenthesis(Start, prec::Level(Precedence));
1784 }
1785 }
1786 }
1787
1788 private:
1789 /// Gets the precedence (+1) of the given token for binary operators
1790 /// and other tokens that we treat like binary operators.
1791 int getCurrentPrecedence() {
1792 if (Current) {
1793 const FormatToken *NextNonComment = Current->getNextNonComment();
1794 if (Current->is(TT_ConditionalExpr))
1795 return prec::Conditional;
1796 if (NextNonComment && Current->is(TT_SelectorName) &&
1797 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
1798 ((Style.Language == FormatStyle::LK_Proto ||
1799 Style.Language == FormatStyle::LK_TextProto) &&
1800 NextNonComment->is(tok::less))))
1801 return prec::Assignment;
1802 if (Current->is(TT_JsComputedPropertyName))
1803 return prec::Assignment;
1804 if (Current->is(TT_LambdaArrow))
1805 return prec::Comma;
1806 if (Current->is(TT_JsFatArrow))
1807 return prec::Assignment;
1808 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1809 (Current->is(tok::comment) && NextNonComment &&
1810 NextNonComment->is(TT_SelectorName)))
1811 return 0;
1812 if (Current->is(TT_RangeBasedForLoopColon))
1813 return prec::Comma;
1814 if ((Style.Language == FormatStyle::LK_Java ||
1815 Style.Language == FormatStyle::LK_JavaScript) &&
1816 Current->is(Keywords.kw_instanceof))
1817 return prec::Relational;
1818 if (Style.Language == FormatStyle::LK_JavaScript &&
1819 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
1820 return prec::Relational;
1821 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1822 return Current->getPrecedence();
1823 if (Current->isOneOf(tok::period, tok::arrow))
1824 return PrecedenceArrowAndPeriod;
1825 if ((Style.Language == FormatStyle::LK_Java ||
1826 Style.Language == FormatStyle::LK_JavaScript) &&
1827 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1828 Keywords.kw_throws))
1829 return 0;
1830 }
1831 return -1;
1832 }
1833
1834 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) {
1835 Start->FakeLParens.push_back(Precedence);
1836 if (Precedence > prec::Unknown)
1837 Start->StartsBinaryExpression = true;
1838 if (Current) {
1839 FormatToken *Previous = Current->Previous;
1840 while (Previous->is(tok::comment) && Previous->Previous)
1841 Previous = Previous->Previous;
1842 ++Previous->FakeRParens;
1843 if (Precedence > prec::Unknown)
1844 Previous->EndsBinaryExpression = true;
1845 }
1846 }
1847
1848 /// Parse unary operator expressions and surround them with fake
1849 /// parentheses if appropriate.
1850 void parseUnaryOperator() {
1851 llvm::SmallVector<FormatToken *, 2> Tokens;
1852 while (Current && Current->is(TT_UnaryOperator)) {
1853 Tokens.push_back(Current);
1854 next();
1855 }
1856 parse(PrecedenceArrowAndPeriod);
1857 for (FormatToken *Token : llvm::reverse(Tokens))
1858 // The actual precedence doesn't matter.
1859 addFakeParenthesis(Token, prec::Unknown);
1860 }
1861
1862 void parseConditionalExpr() {
1863 while (Current && Current->isTrailingComment()) {
1864 next();
1865 }
1866 FormatToken *Start = Current;
1867 parse(prec::LogicalOr);
1868 if (!Current || !Current->is(tok::question))
1869 return;
1870 next();
1871 parse(prec::Assignment);
1872 if (!Current || Current->isNot(TT_ConditionalExpr))
1873 return;
1874 next();
1875 parse(prec::Assignment);
1876 addFakeParenthesis(Start, prec::Conditional);
1877 }
1878
1879 void next(bool SkipPastLeadingComments = true) {
1880 if (Current)
1881 Current = Current->Next;
1882 while (Current &&
1883 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1884 Current->isTrailingComment())
1885 Current = Current->Next;
1886 }
1887
1888 const FormatStyle &Style;
1889 const AdditionalKeywords &Keywords;
1890 FormatToken *Current;
1891 };
1892
1893 } // end anonymous namespace
1894
1895 void TokenAnnotator::setCommentLineLevels(
1896 SmallVectorImpl<AnnotatedLine *> &Lines) {
1897 const AnnotatedLine *NextNonCommentLine = nullptr;
1898 for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
1899 E = Lines.rend();
1900 I != E; ++I) {
1901 bool CommentLine = true;
1902 for (const FormatToken *Tok = (*I)->First; Tok; Tok = Tok->Next) {
1903 if (!Tok->is(tok::comment)) {
1904 CommentLine = false;
1905 break;
1906 }
1907 }
1908
1909 // If the comment is currently aligned with the line immediately following
1910 // it, that's probably intentional and we should keep it.
1911 if (NextNonCommentLine && CommentLine &&
1912 NextNonCommentLine->First->NewlinesBefore <= 1 &&
1913 NextNonCommentLine->First->OriginalColumn ==
1914 (*I)->First->OriginalColumn) {
1915 // Align comments for preprocessor lines with the # in column 0.
1916 // Otherwise, align with the next line.
1917 (*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective ||
1918 NextNonCommentLine->Type == LT_ImportStatement)
1919 ? 0
1920 : NextNonCommentLine->Level;
1921 } else {
1922 NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
1923 }
1924
1925 setCommentLineLevels((*I)->Children);
1926 }
1927 }
1928
1929 static unsigned maxNestingDepth(const AnnotatedLine &Line) {
1930 unsigned Result = 0;
1931 for (const auto *Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
1932 Result = std::max(Result, Tok->NestingLevel);
1933 return Result;
1934 }
1935
1936 void TokenAnnotator::annotate(AnnotatedLine &Line) {
1937 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
1938 E = Line.Children.end();
1939 I != E; ++I) {
1940 annotate(**I);
1941 }
1942 AnnotatingParser Parser(Style, Line, Keywords);
1943 Line.Type = Parser.parseLine();
1944
1945 // With very deep nesting, ExpressionParser uses lots of stack and the
1946 // formatting algorithm is very slow. We're not going to do a good job here
1947 // anyway - it's probably generated code being formatted by mistake.
1948 // Just skip the whole line.
1949 if (maxNestingDepth(Line) > 50)
1950 Line.Type = LT_Invalid;
1951
1952 if (Line.Type == LT_Invalid)
1953 return;
1954
1955 ExpressionParser ExprParser(Style, Keywords, Line);
1956 ExprParser.parse();
1957
1958 if (Line.startsWith(TT_ObjCMethodSpecifier))
1959 Line.Type = LT_ObjCMethodDecl;
1960 else if (Line.startsWith(TT_ObjCDecl))
1961 Line.Type = LT_ObjCDecl;
1962 else if (Line.startsWith(TT_ObjCProperty))
1963 Line.Type = LT_ObjCProperty;
1964
1965 Line.First->SpacesRequiredBefore = 1;
1966 Line.First->CanBreakBefore = Line.First->MustBreakBefore;
1967 }
1968
1969 // This function heuristically determines whether 'Current' starts the name of a
1970 // function declaration.
1971 static bool isFunctionDeclarationName(const FormatToken &Current,
1972 const AnnotatedLine &Line) {
1973 auto skipOperatorName = [](const FormatToken *Next) -> const FormatToken * {
1974 for (; Next; Next = Next->Next) {
1975 if (Next->is(TT_OverloadedOperatorLParen))
1976 return Next;
1977 if (Next->is(TT_OverloadedOperator))
1978 continue;
1979 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
1980 // For 'new[]' and 'delete[]'.
1981 if (Next->Next && Next->Next->is(tok::l_square) && Next->Next->Next &&
1982 Next->Next->Next->is(tok::r_square))
1983 Next = Next->Next->Next;
1984 continue;
1985 }
1986
1987 break;
1988 }
1989 return nullptr;
1990 };
1991
1992 // Find parentheses of parameter list.
1993 const FormatToken *Next = Current.Next;
1994 if (Current.is(tok::kw_operator)) {
1995 if (Current.Previous && Current.Previous->is(tok::coloncolon))
1996 return false;
1997 Next = skipOperatorName(Next);
1998 } else {
1999 if (!Current.is(TT_StartOfName) || Current.NestingLevel != 0)
2000 return false;
2001 for (; Next; Next = Next->Next) {
2002 if (Next->is(TT_TemplateOpener)) {
2003 Next = Next->MatchingParen;
2004 } else if (Next->is(tok::coloncolon)) {
2005 Next = Next->Next;
2006 if (!Next)
2007 return false;
2008 if (Next->is(tok::kw_operator)) {
2009 Next = skipOperatorName(Next->Next);
2010 break;
2011 }
2012 if (!Next->is(tok::identifier))
2013 return false;
2014 } else if (Next->is(tok::l_paren)) {
2015 break;
2016 } else {
2017 return false;
2018 }
2019 }
2020 }
2021
2022 // Check whether parameter list can belong to a function declaration.
2023 if (!Next || !Next->is(tok::l_paren) || !Next->MatchingParen)
2024 return false;
2025 // If the lines ends with "{", this is likely an function definition.
2026 if (Line.Last->is(tok::l_brace))
2027 return true;
2028 if (Next->Next == Next->MatchingParen)
2029 return true; // Empty parentheses.
2030 // If there is an &/&& after the r_paren, this is likely a function.
2031 if (Next->MatchingParen->Next &&
2032 Next->MatchingParen->Next->is(TT_PointerOrReference))
2033 return true;
2034 for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
2035 Tok = Tok->Next) {
2036 if (Tok->is(tok::l_paren) && Tok->MatchingParen) {
2037 Tok = Tok->MatchingParen;
2038 continue;
2039 }
2040 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
2041 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
2042 return true;
2043 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2044 Tok->Tok.isLiteral())
2045 return false;
2046 }
2047 return false;
2048 }
2049
2050 bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const {
2051 assert(Line.MightBeFunctionDecl);
2052
2053 if ((Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
2054 Style.AlwaysBreakAfterReturnType ==
2055 FormatStyle::RTBS_TopLevelDefinitions) &&
2056 Line.Level > 0)
2057 return false;
2058
2059 switch (Style.AlwaysBreakAfterReturnType) {
2060 case FormatStyle::RTBS_None:
2061 return false;
2062 case FormatStyle::RTBS_All:
2063 case FormatStyle::RTBS_TopLevel:
2064 return true;
2065 case FormatStyle::RTBS_AllDefinitions:
2066 case FormatStyle::RTBS_TopLevelDefinitions:
2067 return Line.mightBeFunctionDefinition();
2068 }
2069
2070 return false;
2071 }
2072
2073 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
2074 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
2075 E = Line.Children.end();
2076 I != E; ++I) {
2077 calculateFormattingInformation(**I);
2078 }
2079
2080 Line.First->TotalLength =
2081 Line.First->IsMultiline ? Style.ColumnLimit
2082 : Line.FirstStartColumn + Line.First->ColumnWidth;
2083 FormatToken *Current = Line.First->Next;
2084 bool InFunctionDecl = Line.MightBeFunctionDecl;
2085 while (Current) {
2086 if (isFunctionDeclarationName(*Current, Line))
2087 Current->Type = TT_FunctionDeclarationName;
2088 if (Current->is(TT_LineComment)) {
2089 if (Current->Previous->BlockKind == BK_BracedInit &&
2090 Current->Previous->opensScope())
2091 Current->SpacesRequiredBefore = Style.Cpp11BracedListStyle ? 0 : 1;
2092 else
2093 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
2094
2095 // If we find a trailing comment, iterate backwards to determine whether
2096 // it seems to relate to a specific parameter. If so, break before that
2097 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
2098 // to the previous line in:
2099 // SomeFunction(a,
2100 // b, // comment
2101 // c);
2102 if (!Current->HasUnescapedNewline) {
2103 for (FormatToken *Parameter = Current->Previous; Parameter;
2104 Parameter = Parameter->Previous) {
2105 if (Parameter->isOneOf(tok::comment, tok::r_brace))
2106 break;
2107 if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {
2108 if (!Parameter->Previous->is(TT_CtorInitializerComma) &&
2109 Parameter->HasUnescapedNewline)
2110 Parameter->MustBreakBefore = true;
2111 break;
2112 }
2113 }
2114 }
2115 } else if (Current->SpacesRequiredBefore == 0 &&
2116 spaceRequiredBefore(Line, *Current)) {
2117 Current->SpacesRequiredBefore = 1;
2118 }
2119
2120 Current->MustBreakBefore =
2121 Current->MustBreakBefore || mustBreakBefore(Line, *Current);
2122
2123 if (!Current->MustBreakBefore && InFunctionDecl &&
2124 Current->is(TT_FunctionDeclarationName))
2125 Current->MustBreakBefore = mustBreakForReturnType(Line);
2126
2127 Current->CanBreakBefore =
2128 Current->MustBreakBefore || canBreakBefore(Line, *Current);
2129 unsigned ChildSize = 0;
2130 if (Current->Previous->Children.size() == 1) {
2131 FormatToken &LastOfChild = *Current->Previous->Children[0]->Last;
2132 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
2133 : LastOfChild.TotalLength + 1;
2134 }
2135 const FormatToken *Prev = Current->Previous;
2136 if (Current->MustBreakBefore || Prev->Children.size() > 1 ||
2137 (Prev->Children.size() == 1 &&
2138 Prev->Children[0]->First->MustBreakBefore) ||
2139 Current->IsMultiline)
2140 Current->TotalLength = Prev->TotalLength + Style.ColumnLimit;
2141 else
2142 Current->TotalLength = Prev->TotalLength + Current->ColumnWidth +
2143 ChildSize + Current->SpacesRequiredBefore;
2144
2145 if (Current->is(TT_CtorInitializerColon))
2146 InFunctionDecl = false;
2147
2148 // FIXME: Only calculate this if CanBreakBefore is true once static
2149 // initializers etc. are sorted out.
2150 // FIXME: Move magic numbers to a better place.
2151
2152 // Reduce penalty for aligning ObjC method arguments using the colon
2153 // alignment as this is the canonical way (still prefer fitting everything
2154 // into one line if possible). Trying to fit a whole expression into one
2155 // line should not force other line breaks (e.g. when ObjC method
2156 // expression is a part of other expression).
2157 Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
2158 if (Style.Language == FormatStyle::LK_ObjC &&
2159 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
2160 if (Current->ParameterIndex == 1)
2161 Current->SplitPenalty += 5 * Current->BindingStrength;
2162 } else {
2163 Current->SplitPenalty += 20 * Current->BindingStrength;
2164 }
2165
2166 Current = Current->Next;
2167 }
2168
2169 calculateUnbreakableTailLengths(Line);
2170 unsigned IndentLevel = Line.Level;
2171 for (Current = Line.First; Current != nullptr; Current = Current->Next) {
2172 if (Current->Role)
2173 Current->Role->precomputeFormattingInfos(Current);
2174 if (Current->MatchingParen &&
2175 Current->MatchingParen->opensBlockOrBlockTypeList(Style)) {
2176 assert(IndentLevel > 0);
2177 --IndentLevel;
2178 }
2179 Current->IndentLevel = IndentLevel;
2180 if (Current->opensBlockOrBlockTypeList(Style))
2181 ++IndentLevel;
2182 }
2183
2184 LLVM_DEBUG({ printDebugInfo(Line); });
2185 }
2186
2187 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {
2188 unsigned UnbreakableTailLength = 0;
2189 FormatToken *Current = Line.Last;
2190 while (Current) {
2191 Current->UnbreakableTailLength = UnbreakableTailLength;
2192 if (Current->CanBreakBefore ||
2193 Current->isOneOf(tok::comment, tok::string_literal)) {
2194 UnbreakableTailLength = 0;
2195 } else {
2196 UnbreakableTailLength +=
2197 Current->ColumnWidth + Current->SpacesRequiredBefore;
2198 }
2199 Current = Current->Previous;
2200 }
2201 }
2202
2203 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
2204 const FormatToken &Tok,
2205 bool InFunctionDecl) {
2206 const FormatToken &Left = *Tok.Previous;
2207 const FormatToken &Right = Tok;
2208
2209 if (Left.is(tok::semi))
2210 return 0;
2211
2212 if (Style.Language == FormatStyle::LK_Java) {
2213 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2214 return 1;
2215 if (Right.is(Keywords.kw_implements))
2216 return 2;
2217 if (Left.is(tok::comma) && Left.NestingLevel == 0)
2218 return 3;
2219 } else if (Style.Language == FormatStyle::LK_JavaScript) {
2220 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
2221 return 100;
2222 if (Left.is(TT_JsTypeColon))
2223 return 35;
2224 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) ||
2225 (Right.is(TT_TemplateString) && Right.TokenText.startswith("}")))
2226 return 100;
2227 // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
2228 if (Left.opensScope() && Right.closesScope())
2229 return 200;
2230 }
2231
2232 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
2233 return 1;
2234 if (Right.is(tok::l_square)) {
2235 if (Style.Language == FormatStyle::LK_Proto)
2236 return 1;
2237 if (Left.is(tok::r_square))
2238 return 200;
2239 // Slightly prefer formatting local lambda definitions like functions.
2240 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
2241 return 35;
2242 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2243 TT_ArrayInitializerLSquare,
2244 TT_DesignatedInitializerLSquare, TT_AttributeSquare))
2245 return 500;
2246 }
2247
2248 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2249 Right.is(tok::kw_operator)) {
2250 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
2251 return 3;
2252 if (Left.is(TT_StartOfName))
2253 return 110;
2254 if (InFunctionDecl && Right.NestingLevel == 0)
2255 return Style.PenaltyReturnTypeOnItsOwnLine;
2256 return 200;
2257 }
2258 if (Right.is(TT_PointerOrReference))
2259 return 190;
2260 if (Right.is(TT_LambdaArrow))
2261 return 110;
2262 if (Left.is(tok::equal) && Right.is(tok::l_brace))
2263 return 160;
2264 if (Left.is(TT_CastRParen))
2265 return 100;
2266 if (Left.is(tok::coloncolon) ||
2267 (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto))
2268 return 500;
2269 if (Left.isOneOf(tok::kw_class, tok::kw_struct))
2270 return 5000;
2271 if (Left.is(tok::comment))
2272 return 1000;
2273
2274 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2275 TT_CtorInitializerColon))
2276 return 2;
2277
2278 if (Right.isMemberAccess()) {
2279 // Breaking before the "./->" of a chained call/member access is reasonably
2280 // cheap, as formatting those with one call per line is generally
2281 // desirable. In particular, it should be cheaper to break before the call
2282 // than it is to break inside a call's parameters, which could lead to weird
2283 // "hanging" indents. The exception is the very last "./->" to support this
2284 // frequent pattern:
2285 //
2286 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
2287 // dddddddd);
2288 //
2289 // which might otherwise be blown up onto many lines. Here, clang-format
2290 // won't produce "hanging" indents anyway as there is no other trailing
2291 // call.
2292 //
2293 // Also apply higher penalty is not a call as that might lead to a wrapping
2294 // like:
2295 //
2296 // aaaaaaa
2297 // .aaaaaaaaa.bbbbbbbb(cccccccc);
2298 return !Right.NextOperator || !Right.NextOperator->Previous->closesScope()
2299 ? 150
2300 : 35;
2301 }
2302
2303 if (Right.is(TT_TrailingAnnotation) &&
2304 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
2305 // Moving trailing annotations to the next line is fine for ObjC method
2306 // declarations.
2307 if (Line.startsWith(TT_ObjCMethodSpecifier))
2308 return 10;
2309 // Generally, breaking before a trailing annotation is bad unless it is
2310 // function-like. It seems to be especially preferable to keep standard
2311 // annotations (i.e. "const", "final" and "override") on the same line.
2312 // Use a slightly higher penalty after ")" so that annotations like
2313 // "const override" are kept together.
2314 bool is_short_annotation = Right.TokenText.size() < 10;
2315 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2316 }
2317
2318 // In for-loops, prefer breaking at ',' and ';'.
2319 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
2320 return 4;
2321
2322 // In Objective-C method expressions, prefer breaking before "param:" over
2323 // breaking after it.
2324 if (Right.is(TT_SelectorName))
2325 return 0;
2326 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
2327 return Line.MightBeFunctionDecl ? 50 : 500;
2328
2329 // In Objective-C type declarations, avoid breaking after the category's
2330 // open paren (we'll prefer breaking after the protocol list's opening
2331 // angle bracket, if present).
2332 if (Line.Type == LT_ObjCDecl && Left.is(tok::l_paren) && Left.Previous &&
2333 Left.Previous->isOneOf(tok::identifier, tok::greater))
2334 return 500;
2335
2336 if (Left.is(tok::l_paren) && InFunctionDecl &&
2337 Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign)
2338 return 100;
2339 if (Left.is(tok::l_paren) && Left.Previous &&
2340 (Left.Previous->isOneOf(tok::kw_if, tok::kw_for) ||
2341 Left.Previous->endsSequence(tok::kw_constexpr, tok::kw_if)))
2342 return 1000;
2343 if (Left.is(tok::equal) && InFunctionDecl)
2344 return 110;
2345 if (Right.is(tok::r_brace))
2346 return 1;
2347 if (Left.is(TT_TemplateOpener))
2348 return 100;
2349 if (Left.opensScope()) {
2350 if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign)
2351 return 0;
2352 if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle)
2353 return 19;
2354 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
2355 : 19;
2356 }
2357 if (Left.is(TT_JavaAnnotation))
2358 return 50;
2359
2360 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
2361 Left.Previous->isLabelString() &&
2362 (Left.NextOperator || Left.OperatorIndex != 0))
2363 return 50;
2364 if (Right.is(tok::plus) && Left.isLabelString() &&
2365 (Right.NextOperator || Right.OperatorIndex != 0))
2366 return 25;
2367 if (Left.is(tok::comma))
2368 return 1;
2369 if (Right.is(tok::lessless) && Left.isLabelString() &&
2370 (Right.NextOperator || Right.OperatorIndex != 1))
2371 return 25;
2372 if (Right.is(tok::lessless)) {
2373 // Breaking at a << is really cheap.
2374 if (!Left.is(tok::r_paren) || Right.OperatorIndex > 0)
2375 // Slightly prefer to break before the first one in log-like statements.
2376 return 2;
2377 return 1;
2378 }
2379 if (Left.ClosesTemplateDeclaration)
2380 return Style.PenaltyBreakTemplateDeclaration;
2381 if (Left.is(TT_ConditionalExpr))
2382 return prec::Conditional;
2383 prec::Level Level = Left.getPrecedence();
2384 if (Level == prec::Unknown)
2385 Level = Right.getPrecedence();
2386 if (Level == prec::Assignment)
2387 return Style.PenaltyBreakAssignment;
2388 if (Level != prec::Unknown)
2389 return Level;
2390
2391 return 3;
2392 }
2393
2394 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
2395 const FormatToken &Left,
2396 const FormatToken &Right) {
2397 if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
2398 return true;
2399 if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)
2400 return true;
2401 if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
2402 Left.Tok.getObjCKeywordID() == tok::objc_property)
2403 return true;
2404 if (Right.is(tok::hashhash))
2405 return Left.is(tok::hash);
2406 if (Left.isOneOf(tok::hashhash, tok::hash))
2407 return Right.is(tok::hash);
2408 if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
2409 return Style.SpaceInEmptyParentheses;
2410 if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
2411 return (Right.is(TT_CastRParen) ||
2412 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
2413 ? Style.SpacesInCStyleCastParentheses
2414 : Style.SpacesInParentheses;
2415 if (Right.isOneOf(tok::semi, tok::comma))
2416 return false;
2417 if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {
2418 bool IsLightweightGeneric =
2419 Right.MatchingParen && Right.MatchingParen->Next &&
2420 Right.MatchingParen->Next->is(tok::colon);
2421 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
2422 }
2423 if (Right.is(tok::less) && Left.is(tok::kw_template))
2424 return Style.SpaceAfterTemplateKeyword;
2425 if (Left.isOneOf(tok::exclaim, tok::tilde))
2426 return false;
2427 if (Left.is(tok::at) &&
2428 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2429 tok::numeric_constant, tok::l_paren, tok::l_brace,
2430 tok::kw_true, tok::kw_false))
2431 return false;
2432 if (Left.is(tok::colon))
2433 return !Left.is(TT_ObjCMethodExpr);
2434 if (Left.is(tok::coloncolon))
2435 return false;
2436 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
2437 if (Style.Language == FormatStyle::LK_TextProto ||
2438 (Style.Language == FormatStyle::LK_Proto &&
2439 (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
2440 // Format empty list as `<>`.
2441 if (Left.is(tok::less) && Right.is(tok::greater))
2442 return false;
2443 return !Style.Cpp11BracedListStyle;
2444 }
2445 return false;
2446 }
2447 if (Right.is(tok::ellipsis))
2448 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
2449 Left.Previous->is(tok::kw_case));
2450 if (Left.is(tok::l_square) && Right.is(tok::amp))
2451 return false;
2452 if (Right.is(TT_PointerOrReference)) {
2453 if (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) {
2454 if (!Left.MatchingParen)
2455 return true;
2456 FormatToken *TokenBeforeMatchingParen =
2457 Left.MatchingParen->getPreviousNonComment();
2458 if (!TokenBeforeMatchingParen ||
2459 !TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype))
2460 return true;
2461 }
2462 return (Left.Tok.isLiteral() ||
2463 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
2464 (Style.PointerAlignment != FormatStyle::PAS_Left ||
2465 (Line.IsMultiVariableDeclStmt &&
2466 (Left.NestingLevel == 0 ||
2467 (Left.NestingLevel == 1 && Line.First->is(tok::kw_for)))))));
2468 }
2469 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
2470 (!Left.is(TT_PointerOrReference) ||
2471 (Style.PointerAlignment != FormatStyle::PAS_Right &&
2472 !Line.IsMultiVariableDeclStmt)))
2473 return true;
2474 if (Left.is(TT_PointerOrReference))
2475 return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
2476 (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2477 !Right.is(TT_StartOfName)) ||
2478 (Right.is(tok::l_brace) && Right.BlockKind == BK_Block) ||
2479 (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2480 tok::l_paren) &&
2481 (Style.PointerAlignment != FormatStyle::PAS_Right &&
2482 !Line.IsMultiVariableDeclStmt) &&
2483 Left.Previous &&
2484 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
2485 if (Right.is(tok::star) && Left.is(tok::l_paren))
2486 return false;
2487 const auto SpaceRequiredForArrayInitializerLSquare =
2488 [](const FormatToken &LSquareTok, const FormatStyle &Style) {
2489 return Style.SpacesInContainerLiterals ||
2490 ((Style.Language == FormatStyle::LK_Proto ||
2491 Style.Language == FormatStyle::LK_TextProto) &&
2492 !Style.Cpp11BracedListStyle &&
2493 LSquareTok.endsSequence(tok::l_square, tok::colon,
2494 TT_SelectorName));
2495 };
2496 if (Left.is(tok::l_square))
2497 return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&
2498 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
2499 (Left.isOneOf(TT_ArraySubscriptLSquare,
2500 TT_StructuredBindingLSquare) &&
2501 Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
2502 if (Right.is(tok::r_square))
2503 return Right.MatchingParen &&
2504 ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
2505 SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,
2506 Style)) ||
2507 (Style.SpacesInSquareBrackets &&
2508 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
2509 TT_StructuredBindingLSquare)) ||
2510 Right.MatchingParen->is(TT_AttributeParen));
2511 if (Right.is(tok::l_square) &&
2512 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2513 TT_DesignatedInitializerLSquare,
2514 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
2515 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral))
2516 return false;
2517 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
2518 return !Left.Children.empty(); // No spaces in "{}".
2519 if ((Left.is(tok::l_brace) && Left.BlockKind != BK_Block) ||
2520 (Right.is(tok::r_brace) && Right.MatchingParen &&
2521 Right.MatchingParen->BlockKind != BK_Block))
2522 return !Style.Cpp11BracedListStyle;
2523 if (Left.is(TT_BlockComment))
2524 // No whitespace in x(/*foo=*/1), except for JavaScript.
2525 return Style.Language == FormatStyle::LK_JavaScript ||
2526 !Left.TokenText.endswith("=*/");
2527 if (Right.is(tok::l_paren)) {
2528 if ((Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) ||
2529 (Left.is(tok::r_square) && Left.is(TT_AttributeSquare)))
2530 return true;
2531 return Line.Type == LT_ObjCDecl || Left.is(tok::semi) ||
2532 (Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
2533 (Left.isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
2534 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2535 TT_ObjCForIn) ||
2536 Left.endsSequence(tok::kw_constexpr, tok::kw_if) ||
2537 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2538 tok::kw_new, tok::kw_delete) &&
2539 (!Left.Previous || Left.Previous->isNot(tok::period))))) ||
2540 (Style.SpaceBeforeParens == FormatStyle::SBPO_Always &&
2541 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() ||
2542 Left.is(tok::r_paren)) &&
2543 Line.Type != LT_PreprocessorDirective);
2544 }
2545 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
2546 return false;
2547 if (Right.is(TT_UnaryOperator))
2548 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2549 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
2550 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
2551 tok::r_paren) ||
2552 Left.isSimpleTypeSpecifier()) &&
2553 Right.is(tok::l_brace) && Right.getNextNonComment() &&
2554 Right.BlockKind != BK_Block)
2555 return false;
2556 if (Left.is(tok::period) || Right.is(tok::period))
2557 return false;
2558 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L")
2559 return false;
2560 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
2561 Left.MatchingParen->Previous &&
2562 (Left.MatchingParen->Previous->is(tok::period) ||
2563 Left.MatchingParen->Previous->is(tok::coloncolon)))
2564 // Java call to generic function with explicit type:
2565 // A.<B<C<...>>>DoSomething();
2566 // A::<B<C<...>>>DoSomething(); // With a Java 8 method reference.
2567 return false;
2568 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
2569 return false;
2570 if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at))
2571 // Objective-C dictionary literal -> no space after opening brace.
2572 return false;
2573 if (Right.is(tok::r_brace) && Right.MatchingParen &&
2574 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at))
2575 // Objective-C dictionary literal -> no space before closing brace.
2576 return false;
2577 return true;
2578 }
2579
2580 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
2581 const FormatToken &Right) {
2582 const FormatToken &Left = *Right.Previous;
2583 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
2584 return true; // Never ever merge two identifiers.
2585 if (Style.isCpp()) {
2586 if (Left.is(tok::kw_operator))
2587 return Right.is(tok::coloncolon);
2588 if (Right.is(tok::l_brace) && Right.BlockKind == BK_BracedInit &&
2589 !Left.opensScope() && Style.SpaceBeforeCpp11BracedList)
2590 return true;
2591 } else if (Style.Language == FormatStyle::LK_Proto ||
2592 Style.Language == FormatStyle::LK_TextProto) {
2593 if (Right.is(tok::period) &&
2594 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
2595 Keywords.kw_repeated, Keywords.kw_extend))
2596 return true;
2597 if (Right.is(tok::l_paren) &&
2598 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
2599 return true;
2600 if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
2601 return true;
2602 // Slashes occur in text protocol extension syntax: [type/type] { ... }.
2603 if (Left.is(tok::slash) || Right.is(tok::slash))
2604 return false;
2605 if (Left.MatchingParen && Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
2606 Right.isOneOf(tok::l_brace, tok::less))
2607 return !Style.Cpp11BracedListStyle;
2608 // A percent is probably part of a formatting specification, such as %lld.
2609 if (Left.is(tok::percent))
2610 return false;
2611 // Preserve the existence of a space before a percent for cases like 0x%04x
2612 // and "%d %d"
2613 if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
2614 return Right.WhitespaceRange.getEnd() != Right.WhitespaceRange.getBegin();
2615 } else if (Style.Language == FormatStyle::LK_JavaScript) {
2616 if (Left.is(TT_JsFatArrow))
2617 return true;
2618 // for await ( ...
2619 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
2620 Left.Previous->is(tok::kw_for))
2621 return true;
2622 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
2623 Right.MatchingParen) {
2624 const FormatToken *Next = Right.MatchingParen->getNextNonComment();
2625 // An async arrow function, for example: `x = async () => foo();`,
2626 // as opposed to calling a function called async: `x = async();`
2627 if (Next && Next->is(TT_JsFatArrow))
2628 return true;
2629 }
2630 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) ||
2631 (Right.is(TT_TemplateString) && Right.TokenText.startswith("}")))
2632 return false;
2633 // In tagged template literals ("html`bar baz`"), there is no space between
2634 // the tag identifier and the template string. getIdentifierInfo makes sure
2635 // that the identifier is not a pseudo keyword like `yield`, either.
2636 if (Left.is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2637 Right.is(TT_TemplateString))
2638 return false;
2639 if (Right.is(tok::star) &&
2640 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield))
2641 return false;
2642 if (Right.isOneOf(tok::l_brace, tok::l_square) &&
2643 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
2644 Keywords.kw_extends, Keywords.kw_implements))
2645 return true;
2646 if (Right.is(tok::l_paren)) {
2647 // JS methods can use some keywords as names (e.g. `delete()`).
2648 if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())
2649 return false;
2650 // Valid JS method names can include keywords, e.g. `foo.delete()` or
2651 // `bar.instanceof()`. Recognize call positions by preceding period.
2652 if (Left.Previous && Left.Previous->is(tok::period) &&
2653 Left.Tok.getIdentifierInfo())
2654 return false;
2655 // Additional unary JavaScript operators that need a space after.
2656 if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
2657 tok::kw_void))
2658 return true;
2659 }
2660 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2661 tok::kw_const) ||
2662 // "of" is only a keyword if it appears after another identifier
2663 // (e.g. as "const x of y" in a for loop), or after a destructuring
2664 // operation (const [x, y] of z, const {a, b} of c).
2665 (Left.is(Keywords.kw_of) && Left.Previous &&
2666 (Left.Previous->Tok.is(tok::identifier) ||
2667 Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) &&
2668 (!Left.Previous || !Left.Previous->is(tok::period)))
2669 return true;
2670 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
2671 Left.Previous->is(tok::period) && Right.is(tok::l_paren))
2672 return false;
2673 if (Left.is(Keywords.kw_as) &&
2674 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2675 return true;
2676 if (Left.is(tok::kw_default) && Left.Previous &&
2677 Left.Previous->is(tok::kw_export))
2678 return true;
2679 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
2680 return true;
2681 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2682 return false;
2683 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
2684 return false;
2685 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
2686 Line.First->isOneOf(Keywords.kw_import, tok::kw_export))
2687 return false;
2688 if (Left.is(tok::ellipsis))
2689 return false;
2690 if (Left.is(TT_TemplateCloser) &&
2691 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2692 Keywords.kw_implements, Keywords.kw_extends))
2693 // Type assertions ('<type>expr') are not followed by whitespace. Other
2694 // locations that should have whitespace following are identified by the
2695 // above set of follower tokens.
2696 return false;
2697 if (Right.is(TT_JsNonNullAssertion))
2698 return false;
2699 if (Left.is(TT_JsNonNullAssertion) &&
2700 Right.isOneOf(Keywords.kw_as, Keywords.kw_in))
2701 return true; // "x! as string", "x! in y"
2702 } else if (Style.Language == FormatStyle::LK_Java) {
2703 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
2704 return true;
2705 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren))
2706 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never;
2707 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2708 tok::kw_protected) ||
2709 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2710 Keywords.kw_native)) &&
2711 Right.is(TT_TemplateOpener))
2712 return true;
2713 }
2714 if (Left.is(TT_ImplicitStringLiteral))
2715 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
2716 if (Line.Type == LT_ObjCMethodDecl) {
2717 if (Left.is(TT_ObjCMethodSpecifier))
2718 return true;
2719 if (Left.is(tok::r_paren) && canBeObjCSelectorComponent(Right))
2720 // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
2721 // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
2722 // method declaration.
2723 return false;
2724 }
2725 if (Line.Type == LT_ObjCProperty &&
2726 (Right.is(tok::equal) || Left.is(tok::equal)))
2727 return false;
2728
2729 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2730 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2731 return true;
2732 if (Right.is(TT_OverloadedOperatorLParen))
2733 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always;
2734 if (Left.is(tok::comma))
2735 return true;
2736 if (Right.is(tok::comma))
2737 return false;
2738 if (Right.is(TT_ObjCBlockLParen))
2739 return true;
2740 if (Right.is(TT_CtorInitializerColon))
2741 return Style.SpaceBeforeCtorInitializerColon;
2742 if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
2743 return false;
2744 if (Right.is(TT_RangeBasedForLoopColon) &&
2745 !Style.SpaceBeforeRangeBasedForLoopColon)
2746 return false;
2747 if (Right.is(tok::colon)) {
2748 if (Line.First->isOneOf(tok::kw_case, tok::kw_default) ||
2749 !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi))
2750 return false;
2751 if (Right.is(TT_ObjCMethodExpr))
2752 return false;
2753 if (Left.is(tok::question))
2754 return false;
2755 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
2756 return false;
2757 if (Right.is(TT_DictLiteral))
2758 return Style.SpacesInContainerLiterals;
2759 if (Right.is(TT_AttributeColon))
2760 return false;
2761 return true;
2762 }
2763 if (Left.is(TT_UnaryOperator))
2764 return Right.is(TT_BinaryOperator);
2765
2766 // If the next token is a binary operator or a selector name, we have
2767 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
2768 if (Left.is(TT_CastRParen))
2769 return Style.SpaceAfterCStyleCast ||
2770 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
2771
2772 if (Left.is(tok::greater) && Right.is(tok::greater)) {
2773 if (Style.Language == FormatStyle::LK_TextProto ||
2774 (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral)))
2775 return !Style.Cpp11BracedListStyle;
2776 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
2777 (Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
2778 }
2779 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
2780 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2781 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))
2782 return false;
2783 if (!Style.SpaceBeforeAssignmentOperators &&
2784 Right.getPrecedence() == prec::Assignment)
2785 return false;
2786 if (Style.Language == FormatStyle::LK_Java && Right.is(tok::coloncolon) &&
2787 (Left.is(tok::identifier) || Left.is(tok::kw_this)))
2788 return false;
2789 if (Right.is(tok::coloncolon) && Left.is(tok::identifier))
2790 // Generally don't remove existing spaces between an identifier and "::".
2791 // The identifier might actually be a macro name such as ALWAYS_INLINE. If
2792 // this turns out to be too lenient, add analysis of the identifier itself.
2793 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
2794 if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment))
2795 return (Left.is(TT_TemplateOpener) &&
2796 Style.Standard == FormatStyle::LS_Cpp03) ||
2797 !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
2798 tok::kw___super, TT_TemplateCloser,
2799 TT_TemplateOpener)) ||
2800 (Left.is(tok ::l_paren) && Style.SpacesInParentheses);
2801 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
2802 return Style.SpacesInAngles;
2803 // Space before TT_StructuredBindingLSquare.
2804 if (Right.is(TT_StructuredBindingLSquare))
2805 return !Left.isOneOf(tok::amp, tok::ampamp) ||
2806 Style.PointerAlignment != FormatStyle::PAS_Right;
2807 // Space before & or && following a TT_StructuredBindingLSquare.
2808 if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&
2809 Right.isOneOf(tok::amp, tok::ampamp))
2810 return Style.PointerAlignment != FormatStyle::PAS_Left;
2811 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
2812 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2813 !Right.is(tok::r_paren)))
2814 return true;
2815 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) &&
2816 Right.isNot(TT_FunctionTypeLParen))
2817 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always;
2818 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
2819 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen))
2820 return false;
2821 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
2822 Line.startsWith(tok::hash))
2823 return true;
2824 if (Right.is(TT_TrailingUnaryOperator))
2825 return false;
2826 if (Left.is(TT_RegexLiteral))
2827 return false;
2828 return spaceRequiredBetween(Line, Left, Right);
2829 }
2830
2831 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
2832 static bool isAllmanBrace(const FormatToken &Tok) {
2833 return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block &&
2834 !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
2835 }
2836
2837 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
2838 const FormatToken &Right) {
2839 const FormatToken &Left = *Right.Previous;
2840 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
2841 return true;
2842
2843 if (Style.Language == FormatStyle::LK_JavaScript) {
2844 // FIXME: This might apply to other languages and token kinds.
2845 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous &&
2846 Left.Previous->is(tok::string_literal))
2847 return true;
2848 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
2849 Left.Previous && Left.Previous->is(tok::equal) &&
2850 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
2851 tok::kw_const) &&
2852 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
2853 // above.
2854 !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let))
2855 // Object literals on the top level of a file are treated as "enum-style".
2856 // Each key/value pair is put on a separate line, instead of bin-packing.
2857 return true;
2858 if (Left.is(tok::l_brace) && Line.Level == 0 &&
2859 (Line.startsWith(tok::kw_enum) ||
2860 Line.startsWith(tok::kw_const, tok::kw_enum) ||
2861 Line.startsWith(tok::kw_export, tok::kw_enum) ||
2862 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
2863 // JavaScript top-level enum key/value pairs are put on separate lines
2864 // instead of bin-packing.
2865 return true;
2866 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
2867 !Left.Children.empty())
2868 // Support AllowShortFunctionsOnASingleLine for JavaScript.
2869 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
2870 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
2871 (Left.NestingLevel == 0 && Line.Level == 0 &&
2872 Style.AllowShortFunctionsOnASingleLine &
2873 FormatStyle::SFS_InlineOnly);
2874 } else if (Style.Language == FormatStyle::LK_Java) {
2875 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
2876 Right.Next->is(tok::string_literal))
2877 return true;
2878 } else if (Style.Language == FormatStyle::LK_Cpp ||
2879 Style.Language == FormatStyle::LK_ObjC ||
2880 Style.Language == FormatStyle::LK_Proto ||
2881 Style.Language == FormatStyle::LK_TableGen ||
2882 Style.Language == FormatStyle::LK_TextProto) {
2883 if (Left.isStringLiteral() && Right.isStringLiteral())
2884 return true;
2885 }
2886
2887 // If the last token before a '}', ']', or ')' is a comma or a trailing
2888 // comment, the intention is to insert a line break after it in order to make
2889 // shuffling around entries easier. Import statements, especially in
2890 // JavaScript, can be an exception to this rule.
2891 if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) {
2892 const FormatToken *BeforeClosingBrace = nullptr;
2893 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2894 (Style.Language == FormatStyle::LK_JavaScript &&
2895 Left.is(tok::l_paren))) &&
2896 Left.BlockKind != BK_Block && Left.MatchingParen)
2897 BeforeClosingBrace = Left.MatchingParen->Previous;
2898 else if (Right.MatchingParen &&
2899 (Right.MatchingParen->isOneOf(tok::l_brace,
2900 TT_ArrayInitializerLSquare) ||
2901 (Style.Language == FormatStyle::LK_JavaScript &&
2902 Right.MatchingParen->is(tok::l_paren))))
2903 BeforeClosingBrace = &Left;
2904 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
2905 BeforeClosingBrace->isTrailingComment()))
2906 return true;
2907 }
2908
2909 if (Right.is(tok::comment))
2910 return Left.BlockKind != BK_BracedInit &&
2911 Left.isNot(TT_CtorInitializerColon) &&
2912 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
2913 if (Left.isTrailingComment())
2914 return true;
2915 if (Right.Previous->IsUnterminatedLiteral)
2916 return true;
2917 if (Right.is(tok::lessless) && Right.Next &&
2918 Right.Previous->is(tok::string_literal) &&
2919 Right.Next->is(tok::string_literal))
2920 return true;
2921 if (Right.Previous->ClosesTemplateDeclaration &&
2922 Right.Previous->MatchingParen &&
2923 Right.Previous->MatchingParen->NestingLevel == 0 &&
2924 Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes)
2925 return true;
2926 if (Right.is(TT_CtorInitializerComma) &&
2927 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
2928 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
2929 return true;
2930 if (Right.is(TT_CtorInitializerColon) &&
2931 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
2932 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
2933 return true;
2934 // Break only if we have multiple inheritance.
2935 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
2936 Right.is(TT_InheritanceComma))
2937 return true;
2938 if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\""))
2939 // Multiline raw string literals are special wrt. line breaks. The author
2940 // has made a deliberate choice and might have aligned the contents of the
2941 // string literal accordingly. Thus, we try keep existing line breaks.
2942 return Right.IsMultiline && Right.NewlinesBefore > 0;
2943 if ((Right.Previous->is(tok::l_brace) ||
2944 (Right.Previous->is(tok::less) && Right.Previous->Previous &&
2945 Right.Previous->Previous->is(tok::equal))) &&
2946 Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
2947 // Don't put enums or option definitions onto single lines in protocol
2948 // buffers.
2949 return true;
2950 }
2951 if (Right.is(TT_InlineASMBrace))
2952 return Right.HasUnescapedNewline;
2953 if (isAllmanBrace(Left) || isAllmanBrace(Right))
2954 return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
2955 (Line.startsWith(tok::kw_typedef, tok::kw_enum) &&
2956 Style.BraceWrapping.AfterEnum) ||
2957 (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
2958 (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
2959 if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine)
2960 return true;
2961
2962 if ((Style.Language == FormatStyle::LK_Java ||
2963 Style.Language == FormatStyle::LK_JavaScript) &&
2964 Left.is(TT_LeadingJavaAnnotation) &&
2965 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
2966 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations))
2967 return true;
2968
2969 if (Right.is(TT_ProtoExtensionLSquare))
2970 return true;
2971
2972 // In text proto instances if a submessage contains at least 2 entries and at
2973 // least one of them is a submessage, like A { ... B { ... } ... },
2974 // put all of the entries of A on separate lines by forcing the selector of
2975 // the submessage B to be put on a newline.
2976 //
2977 // Example: these can stay on one line:
2978 // a { scalar_1: 1 scalar_2: 2 }
2979 // a { b { key: value } }
2980 //
2981 // and these entries need to be on a new line even if putting them all in one
2982 // line is under the column limit:
2983 // a {
2984 // scalar: 1
2985 // b { key: value }
2986 // }
2987 //
2988 // We enforce this by breaking before a submessage field that has previous
2989 // siblings, *and* breaking before a field that follows a submessage field.
2990 //
2991 // Be careful to exclude the case [proto.ext] { ... } since the `]` is
2992 // the TT_SelectorName there, but we don't want to break inside the brackets.
2993 //
2994 // Another edge case is @submessage { key: value }, which is a common
2995 // substitution placeholder. In this case we want to keep `@` and `submessage`
2996 // together.
2997 //
2998 // We ensure elsewhere that extensions are always on their own line.
2999 if ((Style.Language == FormatStyle::LK_Proto ||
3000 Style.Language == FormatStyle::LK_TextProto) &&
3001 Right.is(TT_SelectorName) && !Right.is(tok::r_square) && Right.Next) {
3002 // Keep `@submessage` together in:
3003 // @submessage { key: value }
3004 if (Right.Previous && Right.Previous->is(tok::at))
3005 return false;
3006 // Look for the scope opener after selector in cases like:
3007 // selector { ...
3008 // selector: { ...
3009 // selector: @base { ...
3010 FormatToken *LBrace = Right.Next;
3011 if (LBrace && LBrace->is(tok::colon)) {
3012 LBrace = LBrace->Next;
3013 if (LBrace && LBrace->is(tok::at)) {
3014 LBrace = LBrace->Next;
3015 if (LBrace)
3016 LBrace = LBrace->Next;
3017 }
3018 }
3019 if (LBrace &&
3020 // The scope opener is one of {, [, <:
3021 // selector { ... }
3022 // selector [ ... ]
3023 // selector < ... >
3024 //
3025 // In case of selector { ... }, the l_brace is TT_DictLiteral.
3026 // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
3027 // so we check for immediately following r_brace.
3028 ((LBrace->is(tok::l_brace) &&
3029 (LBrace->is(TT_DictLiteral) ||
3030 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
3031 LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) {
3032 // If Left.ParameterCount is 0, then this submessage entry is not the
3033 // first in its parent submessage, and we want to break before this entry.
3034 // If Left.ParameterCount is greater than 0, then its parent submessage
3035 // might contain 1 or more entries and we want to break before this entry
3036 // if it contains at least 2 entries. We deal with this case later by
3037 // detecting and breaking before the next entry in the parent submessage.
3038 if (Left.ParameterCount == 0)
3039 return true;
3040 // However, if this submessage is the first entry in its parent
3041 // submessage, Left.ParameterCount might be 1 in some cases.
3042 // We deal with this case later by detecting an entry
3043 // following a closing paren of this submessage.
3044 }
3045
3046 // If this is an entry immediately following a submessage, it will be
3047 // preceded by a closing paren of that submessage, like in:
3048 // left---. .---right
3049 // v v
3050 // sub: { ... } key: value
3051 // If there was a comment between `}` an `key` above, then `key` would be
3052 // put on a new line anyways.
3053 if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
3054 return true;
3055 }
3056
3057 // Deal with lambda arguments in C++ - we want consistent line breaks whether
3058 // they happen to be at arg0, arg1 or argN. The selection is a bit nuanced
3059 // as aggressive line breaks are placed when the lambda is not the last arg.
3060 if ((Style.Language == FormatStyle::LK_Cpp ||
3061 Style.Language == FormatStyle::LK_ObjC) &&
3062 Left.is(tok::l_paren) && Left.BlockParameterCount > 0 &&
3063 !Right.isOneOf(tok::l_paren, TT_LambdaLSquare)) {
3064 // Multiple lambdas in the same function call force line breaks.
3065 if (Left.BlockParameterCount > 1)
3066 return true;
3067
3068 // A lambda followed by another arg forces a line break.
3069 if (!Left.Role)
3070 return false;
3071 auto Comma = Left.Role->lastComma();
3072 if (!Comma)
3073 return false;
3074 auto Next = Comma->getNextNonComment();
3075 if (!Next)
3076 return false;
3077 if (!Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret))
3078 return true;
3079 }
3080
3081 return false;
3082 }
3083
3084 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
3085 const FormatToken &Right) {
3086 const FormatToken &Left = *Right.Previous;
3087
3088 // Language-specific stuff.
3089 if (Style.Language == FormatStyle::LK_Java) {
3090 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3091 Keywords.kw_implements))
3092 return false;
3093 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3094 Keywords.kw_implements))
3095 return true;
3096 } else if (Style.Language == FormatStyle::LK_JavaScript) {
3097 const FormatToken *NonComment = Right.getPreviousNonComment();
3098 if (NonComment &&
3099 NonComment->isOneOf(
3100 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
3101 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
3102 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
3103 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
3104 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
3105 return false; // Otherwise automatic semicolon insertion would trigger.
3106 if (Right.NestingLevel == 0 &&
3107 (Left.Tok.getIdentifierInfo() ||
3108 Left.isOneOf(tok::r_square, tok::r_paren)) &&
3109 Right.isOneOf(tok::l_square, tok::l_paren))
3110 return false; // Otherwise automatic semicolon insertion would trigger.
3111 if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
3112 return false;
3113 if (Left.is(TT_JsTypeColon))
3114 return true;
3115 // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
3116 if (Left.is(tok::exclaim) && Right.is(tok::colon))
3117 return false;
3118 // Look for is type annotations like:
3119 // function f(): a is B { ... }
3120 // Do not break before is in these cases.
3121 if (Right.is(Keywords.kw_is)) {
3122 const FormatToken* Next = Right.getNextNonComment();
3123 // If `is` is followed by a colon, it's likely that it's a dict key, so
3124 // ignore it for this check.
3125 // For example this is common in Polymer:
3126 // Polymer({
3127 // is: 'name',
3128 // ...
3129 // });
3130 if (!Next || !Next->is(tok::colon))
3131 return false;
3132 }
3133 if (Left.is(Keywords.kw_in))
3134 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
3135 if (Right.is(Keywords.kw_in))
3136 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
3137 if (Right.is(Keywords.kw_as))
3138 return false; // must not break before as in 'x as type' casts
3139 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
3140 // extends and infer can appear as keywords in conditional types:
3141 // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
3142 // do not break before them, as the expressions are subject to ASI.
3143 return false;
3144 }
3145 if (Left.is(Keywords.kw_as))
3146 return true;
3147 if (Left.is(TT_JsNonNullAssertion))
3148 return true;
3149 if (Left.is(Keywords.kw_declare) &&
3150 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
3151 Keywords.kw_function, tok::kw_class, tok::kw_enum,
3152 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
3153 Keywords.kw_let, tok::kw_const))
3154 // See grammar for 'declare' statements at:
3155 // https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10
3156 return false;
3157 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
3158 Right.isOneOf(tok::identifier, tok::string_literal))
3159 return false; // must not break in "module foo { ...}"
3160 if (Right.is(TT_TemplateString) && Right.closesScope())
3161 return false;
3162 if (Left.is(TT_TemplateString) && Left.opensScope())
3163 return true;
3164 }
3165
3166 if (Left.is(tok::at))
3167 return false;
3168 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
3169 return false;
3170 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
3171 return !Right.is(tok::l_paren);
3172 if (Right.is(TT_PointerOrReference))
3173 return Line.IsMultiVariableDeclStmt ||
3174 (Style.PointerAlignment == FormatStyle::PAS_Right &&
3175 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
3176 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3177 Right.is(tok::kw_operator))
3178 return true;
3179 if (Left.is(TT_PointerOrReference))
3180 return false;
3181 if (Right.isTrailingComment())
3182 // We rely on MustBreakBefore being set correctly here as we should not
3183 // change the "binding" behavior of a comment.
3184 // The first comment in a braced lists is always interpreted as belonging to
3185 // the first list element. Otherwise, it should be placed outside of the
3186 // list.
3187 return Left.BlockKind == BK_BracedInit ||
3188 (Left.is(TT_CtorInitializerColon) &&
3189 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
3190 if (Left.is(tok::question) && Right.is(tok::colon))
3191 return false;
3192 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
3193 return Style.BreakBeforeTernaryOperators;
3194 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
3195 return !Style.BreakBeforeTernaryOperators;
3196 if (Left.is(TT_InheritanceColon))
3197 return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
3198 if (Right.is(TT_InheritanceColon))
3199 return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
3200 if (Right.is(TT_ObjCMethodExpr) && !Right.is(tok::r_square) &&
3201 Left.isNot(TT_SelectorName))
3202 return true;
3203
3204 if (Right.is(tok::colon) &&
3205 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
3206 return false;
3207 if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
3208 if (Style.Language == FormatStyle::LK_Proto ||
3209 Style.Language == FormatStyle::LK_TextProto) {
3210 if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
3211 return false;
3212 // Prevent cases like:
3213 //
3214 // submessage:
3215 // { key: valueeeeeeeeeeee }
3216 //
3217 // when the snippet does not fit into one line.
3218 // Prefer:
3219 //
3220 // submessage: {
3221 // key: valueeeeeeeeeeee
3222 // }
3223 //
3224 // instead, even if it is longer by one line.
3225 //
3226 // Note that this allows allows the "{" to go over the column limit
3227 // when the column limit is just between ":" and "{", but that does
3228 // not happen too often and alternative formattings in this case are
3229 // not much better.
3230 //
3231 // The code covers the cases:
3232 //
3233 // submessage: { ... }
3234 // submessage: < ... >
3235 // repeated: [ ... ]
3236 if (((Right.is(tok::l_brace) || Right.is(tok::less)) &&
3237 Right.is(TT_DictLiteral)) ||
3238 Right.is(TT_ArrayInitializerLSquare))
3239 return false;
3240 }
3241 return true;
3242 }
3243 if (Right.is(tok::r_square) && Right.MatchingParen &&
3244 Right.MatchingParen->is(TT_ProtoExtensionLSquare))
3245 return false;
3246 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
3247 Right.Next->is(TT_ObjCMethodExpr)))
3248 return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls.
3249 if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
3250 return true;
3251 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen))
3252 return true;
3253 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
3254 TT_OverloadedOperator))
3255 return false;
3256 if (Left.is(TT_RangeBasedForLoopColon))
3257 return true;
3258 if (Right.is(TT_RangeBasedForLoopColon))
3259 return false;
3260 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
3261 return true;
3262 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
3263 Left.is(tok::kw_operator))
3264 return false;
3265 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
3266 Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0)
3267 return false;
3268 if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
3269 !Style.Cpp11BracedListStyle)
3270 return false;
3271 if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen))
3272 return false;
3273 if (Left.is(tok::l_paren) && Left.Previous &&
3274 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen)))
3275 return false;
3276 if (Right.is(TT_ImplicitStringLiteral))
3277 return false;
3278
3279 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser))
3280 return false;
3281 if (Right.is(tok::r_square) && Right.MatchingParen &&
3282 Right.MatchingParen->is(TT_LambdaLSquare))
3283 return false;
3284
3285 // We only break before r_brace if there was a corresponding break before
3286 // the l_brace, which is tracked by BreakBeforeClosingBrace.
3287 if (Right.is(tok::r_brace))
3288 return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block;
3289
3290 // Allow breaking after a trailing annotation, e.g. after a method
3291 // declaration.
3292 if (Left.is(TT_TrailingAnnotation))
3293 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
3294 tok::less, tok::coloncolon);
3295
3296 if (Right.is(tok::kw___attribute) ||
3297 (Right.is(tok::l_square) && Right.is(TT_AttributeSquare)))
3298 return true;
3299
3300 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
3301 return true;
3302
3303 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
3304 return true;
3305
3306 if (Left.is(TT_CtorInitializerColon))
3307 return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
3308 if (Right.is(TT_CtorInitializerColon))
3309 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
3310 if (Left.is(TT_CtorInitializerComma) &&
3311 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
3312 return false;
3313 if (Right.is(TT_CtorInitializerComma) &&
3314 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
3315 return true;
3316 if (Left.is(TT_InheritanceComma) &&
3317 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
3318 return false;
3319 if (Right.is(TT_InheritanceComma) &&
3320 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
3321 return true;
3322 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
3323 (Left.is(tok::less) && Right.is(tok::less)))
3324 return false;
3325 if (Right.is(TT_BinaryOperator) &&
3326 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
3327 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
3328 Right.getPrecedence() != prec::Assignment))
3329 return true;
3330 if (Left.is(TT_ArrayInitializerLSquare))
3331 return true;
3332 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
3333 return true;
3334 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
3335 !Left.isOneOf(tok::arrowstar, tok::lessless) &&
3336 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
3337 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
3338 Left.getPrecedence() == prec::Assignment))
3339 return true;
3340 if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
3341 (Left.is(tok::r_square) && Right.is(TT_AttributeSquare)))
3342 return false;
3343 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
3344 tok::kw_class, tok::kw_struct, tok::comment) ||
3345 Right.isMemberAccess() ||
3346 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
3347 tok::colon, tok::l_square, tok::at) ||
3348 (Left.is(tok::r_paren) &&
3349 Right.isOneOf(tok::identifier, tok::kw_const)) ||
3350 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
3351 (Left.is(TT_TemplateOpener) && !Right.is(TT_TemplateCloser));
3352 }
3353
3354 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
3355 llvm::errs() << "AnnotatedTokens(L=" << Line.Level << "):\n";
3356 const FormatToken *Tok = Line.First;
3357 while (Tok) {
3358 llvm::errs() << " M=" << Tok->MustBreakBefore
3359 << " C=" << Tok->CanBreakBefore
3360 << " T=" << getTokenTypeName(Tok->Type)
3361 << " S=" << Tok->SpacesRequiredBefore
3362 << " B=" << Tok->BlockParameterCount
3363 << " BK=" << Tok->BlockKind << " P=" << Tok->SplitPenalty
3364 << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength
3365 << " PPK=" << Tok->PackingKind << " FakeLParens=";
3366 for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
3367 llvm::errs() << Tok->FakeLParens[i] << "/";
3368 llvm::errs() << " FakeRParens=" << Tok->FakeRParens;
3369 llvm::errs() << " II=" << Tok->Tok.getIdentifierInfo();
3370 llvm::errs() << " Text='" << Tok->TokenText << "'\n";
3371 if (!Tok->Next)
3372 assert(Tok == Line.Last);
3373 Tok = Tok->Next;
3374 }
3375 llvm::errs() << "----\n";
3376 }
3377
3378 } // namespace format
3379 } // namespace clang
clang::format::FormatStyle::BTDS_Yes
Always break after template declaration.
Definition: Format.h:389
clang::format::FormatStyle::RTBS_TopLevelDefinitions
Always break after the return type of top-level definitions.
Definition: Format.h:332
clang::format::FormatToken::endsSequence
bool endsSequence(A K1, Ts... Tokens) const
true if this token ends a sequence with the given tokens in order, following the Previous pointers...
Definition: FormatToken.h:343
clang::if
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
clang::format::AnnotatedLine::FirstStartColumn
unsigned FirstStartColumn
Definition: TokenAnnotator.h:140
clang::format::FormatToken::NestingLevel
unsigned NestingLevel
The nesting level of this token, i.e.
Definition: FormatToken.h:228
clang::format::FormatStyle::BILS_AfterColon
Break inheritance list after the colon and commas.
Definition: Format.h:921
clang::format::FormatStyle::AlwaysBreakBeforeMultilineStrings
bool AlwaysBreakBeforeMultilineStrings
If true, always break before multiline string literals.
Definition: Format.h:354
clang::format::FormatStyle::PenaltyBreakBeforeFirstCallParameter
unsigned PenaltyBreakBeforeFirstCallParameter
The penalty for breaking a function call after call(.
Definition: Format.h:1378
clang::format::FormatToken::Tok
Token Tok
The Token.
Definition: FormatToken.h:128
clang::prec::Unknown
Definition: OperatorPrecedence.h:28
clang::format::FormatStyle::LK_Proto
Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).
Definition: Format.h:1231
clang::Token::is
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
Definition: Token.h:95
SourceManager.h
Defines the SourceManager interface.
clang::format::FormatStyle::SpaceBeforeRangeBasedForLoopColon
bool SpaceBeforeRangeBasedForLoopColon
If false, spaces will be removed before range-based for loop colon.
Definition: Format.h:1610
clang::format::FormatToken::Role
std::unique_ptr< TokenRole > Role
A token can have a special role that can carry extra information about the token&#39;s formatting...
Definition: FormatToken.h:204
clang::format::FormatStyle::BCIS_BeforeComma
Break constructor initializers before the colon and commas, and align the commas with the colon...
Definition: Format.h:854
clang::format::AnnotatedLine::MustBeDeclaration
bool MustBeDeclaration
Definition: TokenAnnotator.h:125
clang::format::FormatToken::OriginalColumn
unsigned OriginalColumn
The original 0-based column of this token, including expanded tabs.
Definition: FormatToken.h:215
clang::format::printDebugInfo
static LLVM_ATTRIBUTE_UNUSED void printDebugInfo(const UnwrappedLine &Line, StringRef Prefix="")
Definition: UnwrappedLineParser.cpp:2360
clang::format::FormatToken::isMemberAccess
bool isMemberAccess() const
Returns true if this is a "." or "->" accessing a member.
Definition: FormatToken.h:391
clang::format::FormatToken::isFunctionLikeKeyword
bool isFunctionLikeKeyword() const
Returns true if this is a keyword that can be used like a function call (e.g.
Definition: FormatToken.h:425
clang::format::FormatToken::getNextNonComment
const FormatToken * getNextNonComment() const
Returns the next token ignoring comments.
Definition: FormatToken.h:481
clang::format::BK_Block
Definition: FormatToken.h:112
clang::Parser
Parser - This implements a parser for the C family of languages.
Definition: Parser.h:58
clang::format::FormatStyle::SpaceAfterTemplateKeyword
bool SpaceAfterTemplateKeyword
If true, a space will be inserted after the &#39;template&#39; keyword.
Definition: Format.h:1530
clang::format::FormatStyle::PointerAlignment
PointerAlignmentStyle PointerAlignment
Pointer and reference alignment style.
Definition: Format.h:1419
clang::format::FormatStyle::PAS_Left
Align pointer to the left.
Definition: Format.h:1405
clang::format::FormatStyle::LK_Cpp
Should be used for C, C++.
Definition: Format.h:1222
clang::format::FormatToken::IsMultiline
bool IsMultiline
Whether the token text contains newlines (escaped or not).
Definition: FormatToken.h:157
clang::format::FormatStyle::BraceWrappingFlags::AfterEnum
bool AfterEnum
Wrap enum definitions.
Definition: Format.h:663
clang::format::FormatToken::TotalLength
unsigned TotalLength
The total length of the unwrapped line up to and including this token.
Definition: FormatToken.h:211
clang::format::FormatToken::isBinaryOperator
bool isBinaryOperator() const
Definition: FormatToken.h:413
clang::format::AnnotatedLine::Last
FormatToken * Last
Definition: TokenAnnotator.h:116
clang::format::FormatToken::NewlinesBefore
unsigned NewlinesBefore
The number of newlines immediately before the Token.
Definition: FormatToken.h:134
clang::format::FormatToken::Next
FormatToken * Next
The next token in the unwrapped line.
Definition: FormatToken.h:293
clang::format::FormatStyle::BOS_None
Break after operators.
Definition: Format.h:451
clang::Token::isLiteral
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
Definition: Token.h:113
CanBeExpression
bool CanBeExpression
Definition: TokenAnnotator.cpp:1178
ContextKind
tok::TokenKind ContextKind
Definition: TokenAnnotator.cpp:1169
clang::format::FormatToken::UnbreakableTailLength
unsigned UnbreakableTailLength
The length of following tokens until the next natural split point, or the next token that can be brok...
Definition: FormatToken.h:219
clang::format::FormatToken::closesScope
bool closesScope() const
Returns whether Tok is )]} or a closing > of a template or in protos.
Definition: FormatToken.h:381
clang::format::PPK_BinPacked
Definition: FormatToken.h:115
clang::format::FormatStyle::JavaScriptWrapImports
bool JavaScriptWrapImports
Whether to wrap JavaScript import/export statements.
Definition: Format.h:1201
clang::prec::Relational
Definition: OperatorPrecedence.h:38
clang::format::FormatStyle::RTBS_All
Always break after the return type.
Definition: Format.h:292
clang::format::FormatToken::SplitPenalty
unsigned SplitPenalty
Penalty for inserting a line break before this token.
Definition: FormatToken.h:234
ColonIsForRangeExpr
bool ColonIsForRangeExpr
Definition: TokenAnnotator.cpp:1173
clang::format::FormatToken::getPrecedence
prec::Level getPrecedence() const
Definition: FormatToken.h:467
clang::format::FormatToken::ParameterCount
unsigned ParameterCount
Number of parameters, if this is "(", "[" or "<".
Definition: FormatToken.h:192
clang::format::FormatToken::FakeRParens
unsigned FakeRParens
Insert this many fake ) after this token for correct indentation.
Definition: FormatToken.h:260
clang::format::FormatStyle::SpaceInEmptyParentheses
bool SpaceInEmptyParentheses
If true, spaces may be inserted into ().
Definition: Format.h:1622
clang::format::FormatToken::CanBreakBefore
bool CanBreakBefore
true if it is allowed to break before this token.
Definition: FormatToken.h:186
clang::format::FormatStyle::LK_Java
Should be used for Java.
Definition: Format.h:1224
clang::format::FormatToken::Previous
FormatToken * Previous
The previous token in the unwrapped line.
Definition: FormatToken.h:290
clang::format::FormatStyle::RTBS_AllDefinitions
Always break after the return type of function definitions.
Definition: Format.h:320
clang::format::FormatStyle::SFS_InlineOnly
Only merge functions defined inside a class.
Definition: Format.h:211
TokenAnnotator.h
This file implements a token annotator, i.e.
clang::format::FormatStyle::BreakAfterJavaFieldAnnotations
bool BreakAfterJavaFieldAnnotations
Break after each annotation on a field in Java files.
Definition: Format.h:874
clang::format::FormatStyle::ConstructorInitializerAllOnOneLineOrOnePerLine
bool ConstructorInitializerAllOnOneLineOrOnePerLine
If the constructor initializers don&#39;t fit on a line, put each initializer on its own line...
Definition: Format.h:966
clang::format::FormatToken::OperatorIndex
unsigned OperatorIndex
If this is an operator (or "."/"->") in a sequence of operators with the same precedence, contains the 0-based operator index.
Definition: FormatToken.h:270
llvm::SmallVectorImpl
Definition: LLVM.h:37
clang::format::FormatToken::SpacesRequiredBefore
unsigned SpacesRequiredBefore
The number of spaces that should be inserted before this token.
Definition: FormatToken.h:183
clang::format::LineType
LineType
Definition: TokenAnnotator.h:27
clang::format::FormatToken::isNot
bool isNot(T Kind) const
Definition: FormatToken.h:323
clang::format::FormatStyle::ObjCSpaceAfterProperty
bool ObjCSpaceAfterProperty
Definition: Format.h:1368
clang::format::FormatStyle::SpacesInParentheses
bool SpacesInParentheses
If true, spaces will be inserted after ( and before ).
Definition: Format.h:1670
clang::format::Tok
const FormatToken & Tok
Definition: BreakableToken.h:244
clang::format::FormatStyle::AlwaysBreakAfterReturnType
ReturnTypeBreakingStyle AlwaysBreakAfterReturnType
The function declaration return type breaking style to use.
Definition: Format.h:340
clang::format::FormatToken::BlockParameterCount
unsigned BlockParameterCount
Number of parameters that are nested blocks, if this is "(", "[" or "<".
Definition: FormatToken.h:196
InInheritanceList
bool InInheritanceList
Definition: TokenAnnotator.cpp:1181
clang::format::FormatStyle::SpaceBeforeAssignmentOperators
bool SpaceBeforeAssignmentOperators
If false, spaces will be removed before assignment operators.
Definition: Format.h:1538
clang::format::FormatStyle::SpaceBeforeParens
SpaceBeforeParensOptions SpaceBeforeParens
Defines in which cases to put a space before opening parentheses.
Definition: Format.h:1602
clang::prec::LogicalOr
Definition: OperatorPrecedence.h:32
clang::format::LT_ObjCMethodDecl
Definition: TokenAnnotator.h:31
clang::format::FormatStyle::SpaceBeforeCtorInitializerColon
bool SpaceBeforeCtorInitializerColon
If false, spaces will be removed before constructor initializer colon.
Definition: Format.h:1557
clang::format::FormatStyle::PenaltyBreakAssignment
unsigned PenaltyBreakAssignment
The penalty for breaking around an assignment operator.
Definition: Format.h:1375
clang::Token::getName
const char * getName() const
Definition: Token.h:166
clang::format::FormatStyle::SBPO_Always
Always put a space before opening parentheses, except when it&#39;s prohibited by the syntax rules (in fu...
Definition: Format.h:1598
clang::format::AnnotatedLine::mightBeFunctionDefinition
bool mightBeFunctionDefinition() const
true if this line looks like a function definition instead of a function declaration.
Definition: TokenAnnotator.h:101
clang::format::FormatStyle::ColumnLimit
unsigned ColumnLimit
The column limit.
Definition: Format.h:884
clang::format::FormatStyle::SFS_None
Never merge functions into a single line.
Definition: Format.h:197
clang::prec::Assignment
Definition: OperatorPrecedence.h:30
clang::format::FormatToken::getPreviousNonComment
FormatToken * getPreviousNonComment() const
Returns the previous token ignoring comments.
Definition: FormatToken.h:473
P
AnnotatingParser & P
Definition: TokenAnnotator.cpp:1190
clang::format::FormatStyle::AlignAfterOpenBracket
BracketAlignmentStyle AlignAfterOpenBracket
If true, horizontally aligns arguments after an open bracket.
Definition: Format.h:81
Parent
NodeId Parent
Definition: ASTDiff.cpp:192
clang::format::FormatToken::isLabelString
bool isLabelString() const
Returns true if this is a string literal that&#39;s like a label, e.g.
Definition: FormatToken.h:445
clang::format::FormatToken::isOneOf
bool isOneOf(A K1, B K2) const
Definition: FormatToken.h:316
clang::format::AnnotatedLine::Type
LineType Type
Definition: TokenAnnotator.h:120
clang::format::FormatStyle::RTBS_None
Break after return type automatically.
Definition: Format.h:276
clang::format::FormatStyle::SFS_Empty
Only merge empty functions.
Definition: Format.h:219
clang::format::FormatStyle::LK_JavaScript
Should be used for JavaScript.
Definition: Format.h:1226
clang::format::BK_BracedInit
Definition: FormatToken.h:112
Line
const AnnotatedLine * Line
Definition: UsingDeclarationsSorter.cpp:69
Previous
StateNode * Previous
Definition: UnwrappedLineFormatter.cpp:879
clang::format::AnnotatedLine::Children
SmallVector< AnnotatedLine *, 0 > Children
Definition: TokenAnnotator.h:118
clang::format::LT_ImportStatement
Definition: TokenAnnotator.h:29
clang::format::FormatToken::PackingKind
ParameterPackingKind PackingKind
If this is an opening parenthesis, how are the parameters packed?
Definition: FormatToken.h:207
clang::format::FormatStyle::SpacesInContainerLiterals
bool SpacesInContainerLiterals
If true, spaces are inserted inside container literals (e.g.
Definition: Format.h:1656
clang::format::FormatStyle::BraceWrapping
BraceWrappingFlags BraceWrapping
Control of individual brace wrapping cases.
Definition: Format.h:822
clang::format::FormatStyle::SpacesInAngles
bool SpacesInAngles
If true, spaces will be inserted after < and before > in template argument lists. ...
Definition: Format.h:1647
clang::prec::Conditional
Definition: OperatorPrecedence.h:31
clang::format::FormatToken
A wrapper around a Token storing information about the whitespace characters preceding it...
Definition: FormatToken.h:124
clang::format::PPK_OnePerLine
Definition: FormatToken.h:115
clang::format::LT_ObjCDecl
Definition: TokenAnnotator.h:30
clang::format::TokenAnnotator::setCommentLineLevels
void setCommentLineLevels(SmallVectorImpl< AnnotatedLine *> &Lines)
Adapts the indent levels of comment lines to the indent of the subsequent line.
Definition: TokenAnnotator.cpp:1895
clang::format::maxNestingDepth
static unsigned maxNestingDepth(const AnnotatedLine &Line)
Definition: TokenAnnotator.cpp:1929
FirstStartOfName
FormatToken * FirstStartOfName
Definition: TokenAnnotator.cpp:1177
clang::format::AnnotatedLine
Definition: TokenAnnotator.h:38
clang::SourceRange::getEnd
SourceLocation getEnd() const
Definition: SourceLocation.h:208
clang::format::FormatToken::isTrailingComment
bool isTrailingComment() const
Definition: FormatToken.h:418
clang::format::TokenAnnotator::annotate
void annotate(AnnotatedLine &Line)
Definition: TokenAnnotator.cpp:1936
clang::format::LT_Other
Definition: TokenAnnotator.h:33
clang::format::AnnotatedLine::Level
unsigned Level
Definition: TokenAnnotator.h:121
clang::format::FormatStyle::BAS_DontAlign
Don&#39;t align, instead use ContinuationIndentWidth, e.g.
Definition: Format.h:67
clang::format::getTokenTypeName
const char * getTokenTypeName(TokenType Type)
Determines the name of a token type.
Definition: FormatToken.cpp:25
clang::format::LT_Invalid
Definition: TokenAnnotator.h:28
clang::prec::PointerToMember
Definition: OperatorPrecedence.h:43
clang::format::isAllmanBrace
static bool isAllmanBrace(const FormatToken &Tok)
Definition: TokenAnnotator.cpp:2832
clang::format::FormatToken::is
bool is(tok::TokenKind Kind) const
Definition: FormatToken.h:307
InCpp11AttributeSpecifier
bool InCpp11AttributeSpecifier
Definition: TokenAnnotator.cpp:1184
clang::Token::getIdentifierInfo
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:177
clang::format::FormatStyle::BCIS_AfterColon
Break constructor initializers after the colon and commas.
Definition: Format.h:861
clang::format::FormatStyle::BreakBeforeTernaryOperators
bool BreakBeforeTernaryOperators
If true, ternary operators will be placed after line breaks.
Definition: Format.h:836
clang::format::AnnotatedLine::First
FormatToken * First
Definition: TokenAnnotator.h:115
clang::format::FormatToken::WhitespaceRange
SourceRange WhitespaceRange
The range of the whitespace immediately preceding the Token.
Definition: FormatToken.h:141
clang::tok::TokenKind
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
clang::format::FormatStyle::SpacesInCStyleCastParentheses
bool SpacesInCStyleCastParentheses
If true, spaces may be inserted into C style casts.
Definition: Format.h:1663
clang::format::FormatToken::IsUnterminatedLiteral
bool IsUnterminatedLiteral
Set to true if this token is an unterminated literal.
Definition: FormatToken.h:175
llvm::SmallVector
Definition: LLVM.h:36
clang::format::AnnotatedLine::startsWith
bool startsWith(Ts... Tokens) const
true if this line starts with the given tokens in order, ignoring comments.
Definition: TokenAnnotator.h:87
clang::format::FormatStyle::SpacesInSquareBrackets
bool SpacesInSquareBrackets
If true, spaces will be inserted after [ and before ].
Definition: Format.h:1679
clang::format::FormatToken::TokenText
StringRef TokenText
The raw text of the token.
Definition: FormatToken.h:172
clang::format::LT_VirtualFunctionDecl
Definition: TokenAnnotator.h:35
clang::format::FormatToken::FakeLParens
SmallVector< prec::Level, 4 > FakeLParens
Stores the number of required fake parentheses and the corresponding operator precedence.
Definition: FormatToken.h:258
clang::Token::getObjCKeywordID
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
Definition: Lexer.cpp:67
clang::format::FormatStyle::AlwaysBreakTemplateDeclarations
BreakTemplateDeclarationsStyle AlwaysBreakTemplateDeclarations
The template declaration breaking style to use.
Definition: Format.h:393
clang::format::FormatToken::isSimpleTypeSpecifier
bool isSimpleTypeSpecifier() const
Determine whether the token is a simple-type-specifier.
Definition: FormatToken.cpp:40
clang::format::FormatStyle
The FormatStyle is used to configure the formatting to follow specific guidelines.
Definition: Format.h:50
clang::format::FormatStyle::SBPO_Never
Never put a space before opening parentheses.
Definition: Format.h:1576
clang::format::AnnotatedLine::IsMultiVariableDeclStmt
bool IsMultiVariableDeclStmt
Definition: TokenAnnotator.h:127
clang::format::FormatStyle::PenaltyReturnTypeOnItsOwnLine
unsigned PenaltyReturnTypeOnItsOwnLine
Penalty for putting the return type of a function onto its own line.
Definition: Format.h:1397
clang::format::FormatToken::IndentLevel
unsigned IndentLevel
The indent level of this token. Copied from the surrounding line.
Definition: FormatToken.h:231
clang::format::FormatStyle::Language
LanguageKind Language
Language, this format style is targeted at.
Definition: Format.h:1241
Type
Optional< types::ID > Type
Definition: InterpolatingCompilationDatabase.cpp:128
ColonIsObjCMethodExpr
bool ColonIsObjCMethodExpr
Definition: TokenAnnotator.cpp:1175
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::format::FormatStyle::AllowShortFunctionsOnASingleLine
ShortFunctionStyle AllowShortFunctionsOnASingleLine
Dependent on the value, int f() { return 0; } can be put on a single line.
Definition: Format.h:243
clang::format::FormatToken::ColumnWidth
unsigned ColumnWidth
The width of the non-whitespace parts of the token (or its first line for multi-line tokens) in colum...
Definition: FormatToken.h:150
clang::format::PPK_Inconclusive
Definition: FormatToken.h:115
clang::format::FormatStyle::BreakInheritanceList
BreakInheritanceListStyle BreakInheritanceList
The inheritance list style to use.
Definition: Format.h:925
clang::format::FormatStyle::LS_Cpp03
Use C++03-compatible syntax.
Definition: Format.h:1684
clang::format::FormatStyle::RTBS_TopLevel
Always break after the return types of top-level functions.
Definition: Format.h:305
clang::format::FormatStyle::LK_TableGen
Should be used for TableGen code.
Definition: Format.h:1233
IsExpression
bool IsExpression
Definition: TokenAnnotator.cpp:1171
clang::format::FormatStyle::LS_Cpp11
Use features of C++11, C++14 and C++1z (e.g.
Definition: Format.h:1687
clang::format::FormatStyle::Cpp11BracedListStyle
bool Cpp11BracedListStyle
If true, format braced lists as best suited for C++11 braced lists.
Definition: Format.h:1002
clang::format::isFunctionDeclarationName
static bool isFunctionDeclarationName(const FormatToken &Current, const AnnotatedLine &Line)
Definition: TokenAnnotator.cpp:1971
clang::format::FormatToken::Type
TokenType Type
Definition: FormatToken.h:180
clang::format::FormatStyle::SpaceBeforeCpp11BracedList
bool SpaceBeforeCpp11BracedList
If true, a space will be inserted before a C++11 braced list used to initialize an object (after the ...
Definition: Format.h:1549
clang::format::FormatStyle::BraceWrappingFlags::AfterStruct
bool AfterStruct
Wrap struct definitions.
Definition: Format.h:713
clang::format::LT_ObjCProperty
Definition: TokenAnnotator.h:32
clang::format::FormatStyle::BILS_BeforeComma
Break inheritance list before the colon and commas, and align the commas with the colon...
Definition: Format.h:913
clang::format::TokenAnnotator::calculateFormattingInformation
void calculateFormattingInformation(AnnotatedLine &Line)
Definition: TokenAnnotator.cpp:2073
clang::format::FormatStyle::SpaceAfterCStyleCast
bool SpaceAfterCStyleCast
If true, a space is inserted after C style casts.
Definition: Format.h:1523
clang::format::FormatStyle::LK_ObjC
Should be used for Objective-C, Objective-C++.
Definition: Format.h:1228
clang::format::FormatStyle::Standard
LanguageStandard Standard
Format compatible with this standard, e.g.
Definition: Format.h:1694
clang::format::FormatToken::NextOperator
FormatToken * NextOperator
If this is an operator (or "."/"->") in a sequence of operators with the same precedence, points to the next operator.
Definition: FormatToken.h:274
clang::format::FormatStyle::BreakConstructorInitializers
BreakConstructorInitializersStyle BreakConstructorInitializers
The constructor initializers style to use.
Definition: Format.h:865
BindingStrength
unsigned BindingStrength
Definition: TokenAnnotator.cpp:1170
clang::format::AnnotatedLine::MightBeFunctionDecl
bool MightBeFunctionDecl
Definition: TokenAnnotator.h:126
clang::format::FormatToken::ClosesTemplateDeclaration
bool ClosesTemplateDeclaration
true if this is the ">" of "template<..>".
Definition: FormatToken.h:189
clang::format::FormatToken::MatchingParen
FormatToken * MatchingParen
If this is a bracket, this points to the matching one.
Definition: FormatToken.h:287
clang::format::FormatToken::Children
SmallVector< AnnotatedLine *, 1 > Children
If this token starts a block, this contains all the unwrapped lines in it.
Definition: FormatToken.h:297
FirstObjCSelectorName
FormatToken * FirstObjCSelectorName
Definition: TokenAnnotator.cpp:1176
InTemplateArgument
bool InTemplateArgument
Definition: TokenAnnotator.cpp:1179
ColonIsDictLiteral
bool ColonIsDictLiteral
Definition: TokenAnnotator.cpp:1174
clang::ObjCSubstitutionContext::Parameter
The parameter type of a method or function.
clang::format::FormatStyle::BreakBeforeBinaryOperators
BinaryOperatorStyle BreakBeforeBinaryOperators
The way to wrap binary operators.
Definition: Format.h:479
clang::format::FormatToken::opensBlockOrBlockTypeList
bool opensBlockOrBlockTypeList(const FormatStyle &Style) const
Returns true if this tokens starts a block-type list, i.e.
Definition: FormatToken.h:490
clang::format::FormatStyle::BOS_All
Break before operators.
Definition: Format.h:475
clang::format::FormatStyle::ObjCSpaceBeforeProtocolList
bool ObjCSpaceBeforeProtocolList
Add a space in front of an Objective-C protocol list, i.e.
Definition: Format.h:1372
clang::format::FormatStyle::SpacesBeforeTrailingComments
unsigned SpacesBeforeTrailingComments
The number of spaces before trailing line comments (// - comments).
Definition: Format.h:1638
clang::format::FormatToken::opensScope
bool opensScope() const
Returns whether Tok is ([{ or an opening < of a template or in protos.
Definition: FormatToken.h:371
clang::format::FormatStyle::SpaceBeforeInheritanceColon
bool SpaceBeforeInheritanceColon
If false, spaces will be removed before inheritance colon.
Definition: Format.h:1564
clang::format::FormatStyle::AllowShortBlocksOnASingleLine
bool AllowShortBlocksOnASingleLine
Allows contracting simple braced statements to a single line.
Definition: Format.h:178
clang::format::FormatStyle::isCpp
bool isCpp() const
Definition: Format.h:1238
LongestObjCSelectorName
unsigned LongestObjCSelectorName
Definition: TokenAnnotator.cpp:1172
clang::format::FormatToken::MustBreakBefore
bool MustBreakBefore
Whether there must be a line break before this token.
Definition: FormatToken.h:166
clang::format::FormatStyle::PenaltyBreakTemplateDeclaration
unsigned PenaltyBreakTemplateDeclaration
The penalty for breaking after template declaration.
Definition: Format.h:1390
max
__DEVICE__ int max(int __a, int __b)
Definition: __clang_cuda_device_functions.h:1611
clang::format::FormatStyle::BraceWrappingFlags::AfterClass
bool AfterClass
Wrap class definitions.
Definition: Format.h:633
clang::format::FormatStyle::LK_TextProto
Should be used for Protocol Buffer messages in text format (https://developers.google.com/protocol-buffers/).
Definition: Format.h:1236
clang::getBinOpPrecedence
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
Definition: OperatorPrecedence.cpp:18
clang::format::TokenType
TokenType
Definition: FormatToken.h:101
clang::prec::Comma
Definition: OperatorPrecedence.h:29
clang::format::FormatStyle::PAS_Right
Align pointer to the right.
Definition: Format.h:1410
clang::format::LT_PreprocessorDirective
Definition: TokenAnnotator.h:34
clang::format::FormatToken::BindingStrength
unsigned BindingStrength
The binding strength of a token.
Definition: FormatToken.h:224
CaretFound
bool CaretFound
Definition: TokenAnnotator.cpp:1182
InCtorInitializer
bool InCtorInitializer
Definition: TokenAnnotator.cpp:1180
clang::prec::Level
Level
Definition: OperatorPrecedence.h:27
clang::format::FormatToken::isStringLiteral
bool isStringLiteral() const
Definition: FormatToken.h:347
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:207
clang::format::FormatStyle::MaxEmptyLinesToKeep
unsigned MaxEmptyLinesToKeep
The maximum number of consecutive empty lines to keep.
Definition: Format.h:1285
clang::format::FormatToken::HasUnescapedNewline
bool HasUnescapedNewline
Whether there is at least one unescaped newline before the Token.
Definition: FormatToken.h:138
clang::format::FormatToken::BlockKind
BraceBlockKind BlockKind
Contains the kind of block if this token is a brace.
Definition: FormatToken.h:178
clang::format::FormatToken::PartOfMultiVariableDeclStmt
bool PartOfMultiVariableDeclStmt
Is this token part of a DeclStmt defining multiple variables?
Definition: FormatToken.h:279
clang::format::FormatToken::ParameterIndex
unsigned ParameterIndex
The 0-based index of the parameter/argument.
Definition: FormatToken.h:251
IsForEachMacro
bool IsForEachMacro
Definition: TokenAnnotator.cpp:1183
clang::format::Style
const FormatStyle & Style
Definition: BreakableToken.h:247