]> granicus.if.org Git - clang/blob - lib/Format/TokenAnnotator.h
Formatter/ObjC: In dictionary literals, break after ':', not before it.
[clang] / lib / Format / TokenAnnotator.h
1 //===--- TokenAnnotator.h - Format C++ code ---------------------*- C++ -*-===//
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 #ifndef LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
17 #define LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
18
19 #include "UnwrappedLineParser.h"
20 #include "clang/Basic/OperatorPrecedence.h"
21 #include "clang/Format/Format.h"
22 #include <string>
23
24 namespace clang {
25 class Lexer;
26 class SourceManager;
27
28 namespace format {
29
30 enum TokenType {
31   TT_BinaryOperator,
32   TT_BlockComment,
33   TT_CastRParen,
34   TT_ConditionalExpr,
35   TT_CtorInitializerColon,
36   TT_ImplicitStringLiteral,
37   TT_InlineASMColon,
38   TT_InheritanceColon,
39   TT_LineComment,
40   TT_ObjCArrayLiteral,
41   TT_ObjCBlockLParen,
42   TT_ObjCDecl,
43   TT_ObjCDictLiteral,
44   TT_ObjCForIn,
45   TT_ObjCMethodExpr,
46   TT_ObjCMethodSpecifier,
47   TT_ObjCProperty,
48   TT_ObjCSelectorName,
49   TT_OverloadedOperator,
50   TT_OverloadedOperatorLParen,
51   TT_PointerOrReference,
52   TT_PureVirtualSpecifier,
53   TT_RangeBasedForLoopColon,
54   TT_StartOfName,
55   TT_TemplateCloser,
56   TT_TemplateOpener,
57   TT_TrailingUnaryOperator,
58   TT_UnaryOperator,
59   TT_Unknown
60 };
61
62 enum LineType {
63   LT_Invalid,
64   LT_Other,
65   LT_BuilderTypeCall,
66   LT_PreprocessorDirective,
67   LT_VirtualFunctionDecl,
68   LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
69   LT_ObjCMethodDecl,
70   LT_ObjCProperty // An @property line.
71 };
72
73 class AnnotatedToken {
74 public:
75   explicit AnnotatedToken(const FormatToken &FormatTok)
76       : FormatTok(FormatTok), Type(TT_Unknown), SpacesRequiredBefore(0),
77         CanBreakBefore(false), MustBreakBefore(false),
78         ClosesTemplateDeclaration(false), MatchingParen(NULL),
79         ParameterCount(0), TotalLength(FormatTok.TokenLength),
80         UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0),
81         LongestObjCSelectorName(0), DefinesFunctionType(false), Parent(NULL),
82         FakeRParens(0), LastInChainOfCalls(false),
83         PartOfMultiVariableDeclStmt(false) {}
84
85   bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); }
86
87   bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
88     return is(K1) || is(K2);
89   }
90
91   bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const {
92     return is(K1) || is(K2) || is(K3);
93   }
94
95   bool isOneOf(
96       tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3,
97       tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS,
98       tok::TokenKind K6 = tok::NUM_TOKENS, tok::TokenKind K7 = tok::NUM_TOKENS,
99       tok::TokenKind K8 = tok::NUM_TOKENS, tok::TokenKind K9 = tok::NUM_TOKENS,
100       tok::TokenKind K10 = tok::NUM_TOKENS,
101       tok::TokenKind K11 = tok::NUM_TOKENS,
102       tok::TokenKind K12 = tok::NUM_TOKENS) const {
103     return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) ||
104            is(K8) || is(K9) || is(K10) || is(K11) || is(K12);
105   }
106
107   bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); }
108
109   bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
110     return FormatTok.Tok.isObjCAtKeyword(Kind);
111   }
112
113   bool isAccessSpecifier(bool ColonRequired = true) const {
114     return isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private) &&
115            (!ColonRequired ||
116             (!Children.empty() && Children[0].is(tok::colon)));
117   }
118
119   bool isObjCAccessSpecifier() const {
120     return is(tok::at) && !Children.empty() &&
121            (Children[0].isObjCAtKeyword(tok::objc_public) ||
122             Children[0].isObjCAtKeyword(tok::objc_protected) ||
123             Children[0].isObjCAtKeyword(tok::objc_package) ||
124             Children[0].isObjCAtKeyword(tok::objc_private));
125   }
126
127   /// \brief Returns whether \p Tok is ([{ or a template opening <.
128   bool opensScope() const;
129   /// \brief Returns whether \p Tok is )]} or a template opening >.
130   bool closesScope() const;
131
132   bool isUnaryOperator() const;
133   bool isBinaryOperator() const;
134   bool isTrailingComment() const;
135
136   FormatToken FormatTok;
137
138   TokenType Type;
139
140   unsigned SpacesRequiredBefore;
141   bool CanBreakBefore;
142   bool MustBreakBefore;
143
144   bool ClosesTemplateDeclaration;
145
146   AnnotatedToken *MatchingParen;
147
148   /// \brief Number of parameters, if this is "(", "[" or "<".
149   ///
150   /// This is initialized to 1 as we don't need to distinguish functions with
151   /// 0 parameters from functions with 1 parameter. Thus, we can simply count
152   /// the number of commas.
153   unsigned ParameterCount;
154
155   /// \brief The total length of the line up to and including this token.
156   unsigned TotalLength;
157
158   /// \brief The length of following tokens until the next natural split point,
159   /// or the next token that can be broken.
160   unsigned UnbreakableTailLength;
161
162   // FIXME: Come up with a 'cleaner' concept.
163   /// \brief The binding strength of a token. This is a combined value of
164   /// operator precedence, parenthesis nesting, etc.
165   unsigned BindingStrength;
166
167   /// \brief Penalty for inserting a line break before this token.
168   unsigned SplitPenalty;
169
170   /// \brief If this is the first ObjC selector name in an ObjC method
171   /// definition or call, this contains the length of the longest name.
172   unsigned LongestObjCSelectorName;
173
174   /// \brief \c true if this is a "(" that starts a function type definition.
175   bool DefinesFunctionType;
176
177   std::vector<AnnotatedToken> Children;
178   AnnotatedToken *Parent;
179
180   /// \brief Stores the number of required fake parentheses and the
181   /// corresponding operator precedence.
182   ///
183   /// If multiple fake parentheses start at a token, this vector stores them in
184   /// reverse order, i.e. inner fake parenthesis first.
185   SmallVector<prec::Level, 4>  FakeLParens;
186   /// \brief Insert this many fake ) after this token for correct indentation.
187   unsigned FakeRParens;
188
189   /// \brief Is this the last "." or "->" in a builder-type call?
190   bool LastInChainOfCalls;
191
192   /// \brief Is this token part of a \c DeclStmt defining multiple variables?
193   ///
194   /// Only set if \c Type == \c TT_StartOfName.
195   bool PartOfMultiVariableDeclStmt;
196
197   /// \brief Returns the previous token ignoring comments.
198   AnnotatedToken *getPreviousNoneComment() const;
199
200   /// \brief Returns the next token ignoring comments.
201   const AnnotatedToken *getNextNoneComment() const;
202 };
203
204 class AnnotatedLine {
205 public:
206   AnnotatedLine(const UnwrappedLine &Line)
207       : First(Line.Tokens.front()), Level(Line.Level),
208         InPPDirective(Line.InPPDirective),
209         MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
210         StartsDefinition(false) {
211     assert(!Line.Tokens.empty());
212     AnnotatedToken *Current = &First;
213     for (std::list<FormatToken>::const_iterator I = ++Line.Tokens.begin(),
214                                                 E = Line.Tokens.end();
215          I != E; ++I) {
216       Current->Children.push_back(AnnotatedToken(*I));
217       Current->Children[0].Parent = Current;
218       Current = &Current->Children[0];
219     }
220     Last = Current;
221   }
222   AnnotatedLine(const AnnotatedLine &Other)
223       : First(Other.First), Type(Other.Type), Level(Other.Level),
224         InPPDirective(Other.InPPDirective),
225         MustBeDeclaration(Other.MustBeDeclaration),
226         MightBeFunctionDecl(Other.MightBeFunctionDecl),
227         StartsDefinition(Other.StartsDefinition) {
228     Last = &First;
229     while (!Last->Children.empty()) {
230       Last->Children[0].Parent = Last;
231       Last = &Last->Children[0];
232     }
233   }
234
235   AnnotatedToken First;
236   AnnotatedToken *Last;
237
238   LineType Type;
239   unsigned Level;
240   bool InPPDirective;
241   bool MustBeDeclaration;
242   bool MightBeFunctionDecl;
243   bool StartsDefinition;
244 };
245
246 inline prec::Level getPrecedence(const AnnotatedToken &Tok) {
247   return getBinOpPrecedence(Tok.FormatTok.Tok.getKind(), true, true);
248 }
249
250 /// \brief Determines extra information about the tokens comprising an
251 /// \c UnwrappedLine.
252 class TokenAnnotator {
253 public:
254   TokenAnnotator(const FormatStyle &Style, SourceManager &SourceMgr, Lexer &Lex,
255                  IdentifierInfo &Ident_in)
256       : Style(Style), SourceMgr(SourceMgr), Lex(Lex), Ident_in(Ident_in) {
257   }
258
259   void annotate(AnnotatedLine &Line);
260   void calculateFormattingInformation(AnnotatedLine &Line);
261
262 private:
263   /// \brief Calculate the penalty for splitting before \c Tok.
264   unsigned splitPenalty(const AnnotatedLine &Line, const AnnotatedToken &Tok);
265
266   bool spaceRequiredBetween(const AnnotatedLine &Line,
267                             const AnnotatedToken &Left,
268                             const AnnotatedToken &Right);
269
270   bool spaceRequiredBefore(const AnnotatedLine &Line,
271                            const AnnotatedToken &Tok);
272
273   bool canBreakBefore(const AnnotatedLine &Line, const AnnotatedToken &Right);
274
275   void printDebugInfo(const AnnotatedLine &Line);
276
277   void calculateUnbreakableTailLengths(AnnotatedLine &Line);
278
279   const FormatStyle &Style;
280   SourceManager &SourceMgr;
281   Lexer &Lex;
282
283   // Contextual keywords:
284   IdentifierInfo &Ident_in;
285 };
286
287 } // end namespace format
288 } // end namespace clang
289
290 #endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H