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