blob: c02ac6357a9b90e3148a0970a2971dfbc9bd7a6f [file] [log] [blame]
Alexander Kornienko4b672072013-06-03 16:45:03 +00001//===--- FormatToken.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 contains the declaration of the FormatToken, a wrapper
12/// around Token with additional information related to formatting.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CLANG_FORMAT_FORMAT_TOKEN_H
17#define LLVM_CLANG_FORMAT_FORMAT_TOKEN_H
18
19#include "clang/Basic/OperatorPrecedence.h"
Daniel Jasper8de9ed02013-08-22 15:00:41 +000020#include "clang/Format/Format.h"
Alexander Kornienko4b672072013-06-03 16:45:03 +000021#include "clang/Lex/Lexer.h"
Daniel Jasper8de9ed02013-08-22 15:00:41 +000022#include "llvm/ADT/OwningPtr.h"
Alexander Kornienko4b672072013-06-03 16:45:03 +000023
24namespace clang {
25namespace format {
26
27enum TokenType {
28 TT_BinaryOperator,
29 TT_BlockComment,
30 TT_CastRParen,
31 TT_ConditionalExpr,
32 TT_CtorInitializerColon,
Daniel Jaspere33d4af2013-07-26 16:56:36 +000033 TT_CtorInitializerComma,
Alexander Kornienko4b672072013-06-03 16:45:03 +000034 TT_DesignatedInitializerPeriod,
35 TT_ImplicitStringLiteral,
36 TT_InlineASMColon,
37 TT_InheritanceColon,
38 TT_FunctionTypeLParen,
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +000039 TT_LambdaLSquare,
Alexander Kornienko4b672072013-06-03 16:45:03 +000040 TT_LineComment,
41 TT_ObjCArrayLiteral,
42 TT_ObjCBlockLParen,
43 TT_ObjCDecl,
44 TT_ObjCDictLiteral,
45 TT_ObjCForIn,
46 TT_ObjCMethodExpr,
47 TT_ObjCMethodSpecifier,
48 TT_ObjCProperty,
49 TT_ObjCSelectorName,
50 TT_OverloadedOperator,
51 TT_OverloadedOperatorLParen,
52 TT_PointerOrReference,
53 TT_PureVirtualSpecifier,
54 TT_RangeBasedForLoopColon,
55 TT_StartOfName,
56 TT_TemplateCloser,
57 TT_TemplateOpener,
Daniel Jasper6cdec7c2013-07-09 14:36:48 +000058 TT_TrailingReturnArrow,
Alexander Kornienko4b672072013-06-03 16:45:03 +000059 TT_TrailingUnaryOperator,
60 TT_UnaryOperator,
61 TT_Unknown
62};
63
Daniel Jasperb1f74a82013-07-09 09:06:29 +000064// Represents what type of block a set of braces open.
65enum BraceBlockKind {
66 BK_Unknown,
67 BK_Block,
68 BK_BracedInit
69};
70
Daniel Jasperb10cbc42013-07-10 14:02:49 +000071// The packing kind of a function's parameters.
72enum ParameterPackingKind {
73 PPK_BinPacked,
74 PPK_OnePerLine,
75 PPK_Inconclusive
76};
77
Daniel Jasper8de9ed02013-08-22 15:00:41 +000078class TokenRole;
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +000079class AnnotatedLine;
Daniel Jasper8de9ed02013-08-22 15:00:41 +000080
Alexander Kornienko4b672072013-06-03 16:45:03 +000081/// \brief A wrapper around a \c Token storing information about the
82/// whitespace characters preceeding it.
83struct FormatToken {
84 FormatToken()
Alexander Kornienko632abb92013-09-02 13:58:14 +000085 : NewlinesBefore(0), HasUnescapedNewline(false), LastNewlineOffset(0),
Alexander Kornienko39856b72013-09-10 09:38:25 +000086 ColumnWidth(0), LastLineColumnWidth(0), IsMultiline(false),
Alexander Kornienko632abb92013-09-02 13:58:14 +000087 IsFirst(false), MustBreakBefore(false), IsUnterminatedLiteral(false),
Alexander Kornienkod7b837e2013-08-29 17:32:57 +000088 BlockKind(BK_Unknown), Type(TT_Unknown), SpacesRequiredBefore(0),
89 CanBreakBefore(false), ClosesTemplateDeclaration(false),
90 ParameterCount(0), PackingKind(PPK_Inconclusive), TotalLength(0),
91 UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0),
Daniel Jasper562ecd42013-09-06 08:08:14 +000092 LongestObjCSelectorName(0), FakeRParens(0),
93 StartsBinaryExpression(false), EndsBinaryExpression(false),
94 LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false),
95 MatchingParen(NULL), Previous(NULL), Next(NULL) {}
Alexander Kornienko4b672072013-06-03 16:45:03 +000096
97 /// \brief The \c Token.
98 Token Tok;
99
100 /// \brief The number of newlines immediately before the \c Token.
101 ///
102 /// This can be used to determine what the user wrote in the original code
103 /// and thereby e.g. leave an empty line between two function definitions.
104 unsigned NewlinesBefore;
105
106 /// \brief Whether there is at least one unescaped newline before the \c
107 /// Token.
108 bool HasUnescapedNewline;
109
110 /// \brief The range of the whitespace immediately preceeding the \c Token.
111 SourceRange WhitespaceRange;
112
113 /// \brief The offset just past the last '\n' in this token's leading
114 /// whitespace (relative to \c WhiteSpaceStart). 0 if there is no '\n'.
115 unsigned LastNewlineOffset;
116
Alexander Kornienko39856b72013-09-10 09:38:25 +0000117 /// \brief The width of the non-whitespace parts of the token (or its first
118 /// line for multi-line tokens) in columns.
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000119 /// We need this to correctly measure number of columns a token spans.
Alexander Kornienko39856b72013-09-10 09:38:25 +0000120 unsigned ColumnWidth;
Alexander Kornienko4b672072013-06-03 16:45:03 +0000121
Alexander Kornienko39856b72013-09-10 09:38:25 +0000122 /// \brief Contains the width in columns of the last line of a multi-line
Alexander Kornienko632abb92013-09-02 13:58:14 +0000123 /// token.
Alexander Kornienkoebb43ca2013-09-05 14:08:34 +0000124 unsigned LastLineColumnWidth;
Alexander Kornienko632abb92013-09-02 13:58:14 +0000125
Alexander Kornienko39856b72013-09-10 09:38:25 +0000126 /// \brief Whether the token text contains newlines (escaped or not).
127 bool IsMultiline;
Alexander Kornienko632abb92013-09-02 13:58:14 +0000128
Alexander Kornienko4b672072013-06-03 16:45:03 +0000129 /// \brief Indicates that this is the first token.
130 bool IsFirst;
131
132 /// \brief Whether there must be a line break before this token.
133 ///
134 /// This happens for example when a preprocessor directive ended directly
135 /// before the token.
136 bool MustBreakBefore;
137
138 /// \brief Returns actual token start location without leading escaped
139 /// newlines and whitespace.
140 ///
141 /// This can be different to Tok.getLocation(), which includes leading escaped
142 /// newlines.
143 SourceLocation getStartOfNonWhitespace() const {
144 return WhitespaceRange.getEnd();
145 }
146
147 /// \brief The raw text of the token.
148 ///
149 /// Contains the raw token text without leading whitespace and without leading
150 /// escaped newlines.
151 StringRef TokenText;
152
Daniel Jasper8369aa52013-07-16 20:28:33 +0000153 /// \brief Set to \c true if this token is an unterminated literal.
154 bool IsUnterminatedLiteral;
155
Daniel Jasperb1f74a82013-07-09 09:06:29 +0000156 /// \brief Contains the kind of block if this token is a brace.
157 BraceBlockKind BlockKind;
158
Alexander Kornienko4b672072013-06-03 16:45:03 +0000159 TokenType Type;
160
Daniel Jasper8de9ed02013-08-22 15:00:41 +0000161 /// \brief The number of spaces that should be inserted before this token.
Alexander Kornienko4b672072013-06-03 16:45:03 +0000162 unsigned SpacesRequiredBefore;
Daniel Jasper8de9ed02013-08-22 15:00:41 +0000163
164 /// \brief \c true if it is allowed to break before this token.
Alexander Kornienko4b672072013-06-03 16:45:03 +0000165 bool CanBreakBefore;
166
167 bool ClosesTemplateDeclaration;
168
169 /// \brief Number of parameters, if this is "(", "[" or "<".
170 ///
171 /// This is initialized to 1 as we don't need to distinguish functions with
172 /// 0 parameters from functions with 1 parameter. Thus, we can simply count
173 /// the number of commas.
174 unsigned ParameterCount;
175
Daniel Jasper8de9ed02013-08-22 15:00:41 +0000176 /// \brief A token can have a special role that can carry extra information
177 /// about the token's formatting.
178 llvm::OwningPtr<TokenRole> Role;
179
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000180 /// \brief If this is an opening parenthesis, how are the parameters packed?
181 ParameterPackingKind PackingKind;
182
Manuel Klimek31c85922013-08-29 15:21:40 +0000183 /// \brief The total length of the unwrapped line up to and including this
184 /// token.
Alexander Kornienko4b672072013-06-03 16:45:03 +0000185 unsigned TotalLength;
186
Alexander Kornienko39856b72013-09-10 09:38:25 +0000187 /// \brief The original 0-based column of this token, including expanded tabs.
188 /// The configured TabWidth is used as tab width.
Manuel Klimek31c85922013-08-29 15:21:40 +0000189 unsigned OriginalColumn;
190
Alexander Kornienko4b672072013-06-03 16:45:03 +0000191 /// \brief The length of following tokens until the next natural split point,
192 /// or the next token that can be broken.
193 unsigned UnbreakableTailLength;
194
195 // FIXME: Come up with a 'cleaner' concept.
196 /// \brief The binding strength of a token. This is a combined value of
197 /// operator precedence, parenthesis nesting, etc.
198 unsigned BindingStrength;
199
200 /// \brief Penalty for inserting a line break before this token.
201 unsigned SplitPenalty;
202
203 /// \brief If this is the first ObjC selector name in an ObjC method
204 /// definition or call, this contains the length of the longest name.
205 unsigned LongestObjCSelectorName;
206
207 /// \brief Stores the number of required fake parentheses and the
208 /// corresponding operator precedence.
209 ///
210 /// If multiple fake parentheses start at a token, this vector stores them in
211 /// reverse order, i.e. inner fake parenthesis first.
212 SmallVector<prec::Level, 4> FakeLParens;
213 /// \brief Insert this many fake ) after this token for correct indentation.
214 unsigned FakeRParens;
215
Daniel Jasper562ecd42013-09-06 08:08:14 +0000216 /// \brief \c true if this token starts a binary expression, i.e. has at least
217 /// one fake l_paren with a precedence greater than prec::Unknown.
218 bool StartsBinaryExpression;
219 /// \brief \c true if this token ends a binary expression.
220 bool EndsBinaryExpression;
221
Alexander Kornienko4b672072013-06-03 16:45:03 +0000222 /// \brief Is this the last "." or "->" in a builder-type call?
223 bool LastInChainOfCalls;
224
225 /// \brief Is this token part of a \c DeclStmt defining multiple variables?
226 ///
227 /// Only set if \c Type == \c TT_StartOfName.
228 bool PartOfMultiVariableDeclStmt;
229
230 bool is(tok::TokenKind Kind) const { return Tok.is(Kind); }
231
232 bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
233 return is(K1) || is(K2);
234 }
235
236 bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const {
237 return is(K1) || is(K2) || is(K3);
238 }
239
240 bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3,
241 tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS,
242 tok::TokenKind K6 = tok::NUM_TOKENS,
243 tok::TokenKind K7 = tok::NUM_TOKENS,
244 tok::TokenKind K8 = tok::NUM_TOKENS,
245 tok::TokenKind K9 = tok::NUM_TOKENS,
246 tok::TokenKind K10 = tok::NUM_TOKENS,
247 tok::TokenKind K11 = tok::NUM_TOKENS,
248 tok::TokenKind K12 = tok::NUM_TOKENS) const {
249 return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) ||
250 is(K8) || is(K9) || is(K10) || is(K11) || is(K12);
251 }
252
253 bool isNot(tok::TokenKind Kind) const { return Tok.isNot(Kind); }
254
255 bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
256 return Tok.isObjCAtKeyword(Kind);
257 }
258
259 bool isAccessSpecifier(bool ColonRequired = true) const {
260 return isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private) &&
261 (!ColonRequired || (Next && Next->is(tok::colon)));
262 }
263
264 bool isObjCAccessSpecifier() const {
265 return is(tok::at) && Next && (Next->isObjCAtKeyword(tok::objc_public) ||
266 Next->isObjCAtKeyword(tok::objc_protected) ||
267 Next->isObjCAtKeyword(tok::objc_package) ||
268 Next->isObjCAtKeyword(tok::objc_private));
269 }
270
271 /// \brief Returns whether \p Tok is ([{ or a template opening <.
272 bool opensScope() const {
273 return isOneOf(tok::l_paren, tok::l_brace, tok::l_square) ||
274 Type == TT_TemplateOpener;
Alexander Kornienko4b672072013-06-03 16:45:03 +0000275 }
Nico Weber0f987a62013-06-25 19:25:12 +0000276 /// \brief Returns whether \p Tok is )]} or a template closing >.
Alexander Kornienko4b672072013-06-03 16:45:03 +0000277 bool closesScope() const {
278 return isOneOf(tok::r_paren, tok::r_brace, tok::r_square) ||
279 Type == TT_TemplateCloser;
280 }
281
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000282 /// \brief Returns \c true if this is a "." or "->" accessing a member.
283 bool isMemberAccess() const {
284 return isOneOf(tok::arrow, tok::period) &&
285 Type != TT_DesignatedInitializerPeriod;
286 }
287
Alexander Kornienko4b672072013-06-03 16:45:03 +0000288 bool isUnaryOperator() const {
289 switch (Tok.getKind()) {
290 case tok::plus:
291 case tok::plusplus:
292 case tok::minus:
293 case tok::minusminus:
294 case tok::exclaim:
295 case tok::tilde:
296 case tok::kw_sizeof:
297 case tok::kw_alignof:
298 return true;
299 default:
300 return false;
301 }
302 }
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000303
Alexander Kornienko4b672072013-06-03 16:45:03 +0000304 bool isBinaryOperator() const {
305 // Comma is a binary operator, but does not behave as such wrt. formatting.
306 return getPrecedence() > prec::Comma;
307 }
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000308
Alexander Kornienko4b672072013-06-03 16:45:03 +0000309 bool isTrailingComment() const {
310 return is(tok::comment) && (!Next || Next->NewlinesBefore > 0);
311 }
312
313 prec::Level getPrecedence() const {
314 return getBinOpPrecedence(Tok.getKind(), true, true);
315 }
316
317 /// \brief Returns the previous token ignoring comments.
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000318 FormatToken *getPreviousNonComment() const {
Alexander Kornienko4b672072013-06-03 16:45:03 +0000319 FormatToken *Tok = Previous;
320 while (Tok != NULL && Tok->is(tok::comment))
321 Tok = Tok->Previous;
322 return Tok;
323 }
324
325 /// \brief Returns the next token ignoring comments.
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000326 const FormatToken *getNextNonComment() const {
Alexander Kornienko4b672072013-06-03 16:45:03 +0000327 const FormatToken *Tok = Next;
328 while (Tok != NULL && Tok->is(tok::comment))
329 Tok = Tok->Next;
330 return Tok;
331 }
332
333 FormatToken *MatchingParen;
334
335 FormatToken *Previous;
336 FormatToken *Next;
337
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +0000338 SmallVector<AnnotatedLine *, 1> Children;
339
Alexander Kornienko4b672072013-06-03 16:45:03 +0000340private:
341 // Disallow copying.
Craig Topper411294d2013-07-01 04:07:34 +0000342 FormatToken(const FormatToken &) LLVM_DELETED_FUNCTION;
343 void operator=(const FormatToken &) LLVM_DELETED_FUNCTION;
Alexander Kornienko4b672072013-06-03 16:45:03 +0000344};
345
Daniel Jasper8de9ed02013-08-22 15:00:41 +0000346class ContinuationIndenter;
347struct LineState;
348
349class TokenRole {
350public:
351 TokenRole(const FormatStyle &Style) : Style(Style) {}
352 virtual ~TokenRole();
353
354 /// \brief After the \c TokenAnnotator has finished annotating all the tokens,
355 /// this function precomputes required information for formatting.
356 virtual void precomputeFormattingInfos(const FormatToken *Token);
357
358 /// \brief Apply the special formatting that the given role demands.
359 ///
360 /// Continues formatting from \p State leaving indentation to \p Indenter and
361 /// returns the total penalty that this formatting incurs.
362 virtual unsigned format(LineState &State, ContinuationIndenter *Indenter,
363 bool DryRun) {
364 return 0;
365 }
366
367 /// \brief Notifies the \c Role that a comma was found.
368 virtual void CommaFound(const FormatToken *Token) {}
369
370protected:
371 const FormatStyle &Style;
372};
373
374class CommaSeparatedList : public TokenRole {
375public:
376 CommaSeparatedList(const FormatStyle &Style) : TokenRole(Style) {}
377
378 virtual void precomputeFormattingInfos(const FormatToken *Token);
379
380 virtual unsigned format(LineState &State, ContinuationIndenter *Indenter,
381 bool DryRun);
382
383 /// \brief Adds \p Token as the next comma to the \c CommaSeparated list.
384 virtual void CommaFound(const FormatToken *Token) { Commas.push_back(Token); }
385
386private:
387 /// \brief A struct that holds information on how to format a given list with
388 /// a specific number of columns.
389 struct ColumnFormat {
390 /// \brief The number of columns to use.
391 unsigned Columns;
392
393 /// \brief The total width in characters.
394 unsigned TotalWidth;
395
396 /// \brief The number of lines required for this format.
397 unsigned LineCount;
398
399 /// \brief The size of each column in characters.
400 SmallVector<unsigned, 8> ColumnSizes;
401 };
402
403 /// \brief Calculate which \c ColumnFormat fits best into
404 /// \p RemainingCharacters.
405 const ColumnFormat *getColumnFormat(unsigned RemainingCharacters) const;
406
407 /// \brief The ordered \c FormatTokens making up the commas of this list.
408 SmallVector<const FormatToken *, 8> Commas;
409
410 /// \brief The length of each of the list's items in characters including the
411 /// trailing comma.
412 SmallVector<unsigned, 8> ItemLengths;
413
414 /// \brief Precomputed formats that can be used for this list.
415 SmallVector<ColumnFormat, 4> Formats;
416};
417
Alexander Kornienko4b672072013-06-03 16:45:03 +0000418} // namespace format
419} // namespace clang
420
421#endif // LLVM_CLANG_FORMAT_FORMAT_TOKEN_H