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