blob: dc3e3086fdf1d6068921941cb211e5a088055a0e [file] [log] [blame]
Daniel Jasperde0328a2013-08-16 11:20:30 +00001//===--- ContinuationIndenter.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 an indenter that manages the indentation of
12/// continuations.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
17#define LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
18
19#include "Encoding.h"
20#include "clang/Format/Format.h"
Alexander Kornienkoce9161a2014-01-02 15:13:14 +000021#include "llvm/Support/Regex.h"
Daniel Jasperde0328a2013-08-16 11:20:30 +000022
23namespace clang {
24class SourceManager;
25
26namespace format {
27
28class AnnotatedLine;
29struct FormatToken;
30struct LineState;
31struct ParenState;
32class WhitespaceManager;
33
34class ContinuationIndenter {
35public:
36 /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in
37 /// column \p FirstIndent.
38 ContinuationIndenter(const FormatStyle &Style, SourceManager &SourceMgr,
Daniel Jasperde0328a2013-08-16 11:20:30 +000039 WhitespaceManager &Whitespaces,
40 encoding::Encoding Encoding,
41 bool BinPackInconclusiveFunctions);
42
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +000043 /// \brief Get the initial state, i.e. the state after placing \p Line's
44 /// first token at \p FirstIndent.
Daniel Jasper1c5d9df2013-09-06 07:54:20 +000045 LineState getInitialState(unsigned FirstIndent, const AnnotatedLine *Line,
46 bool DryRun);
Daniel Jasperde0328a2013-08-16 11:20:30 +000047
48 // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a
49 // better home.
50 /// \brief Returns \c true, if a line break after \p State is allowed.
51 bool canBreak(const LineState &State);
52
53 /// \brief Returns \c true, if a line break after \p State is mandatory.
54 bool mustBreak(const LineState &State);
55
56 /// \brief Appends the next token to \p State and updates information
57 /// necessary for indentation.
58 ///
59 /// Puts the token on the current line if \p Newline is \c false and adds a
60 /// line break and necessary indentation otherwise.
61 ///
62 /// If \p DryRun is \c false, also creates and stores the required
63 /// \c Replacement.
Daniel Jasper8de9ed02013-08-22 15:00:41 +000064 unsigned addTokenToState(LineState &State, bool Newline, bool DryRun,
65 unsigned ExtraSpaces = 0);
Daniel Jasperde0328a2013-08-16 11:20:30 +000066
67 /// \brief Get the column limit for this line. This is the style's column
68 /// limit, potentially reduced for preprocessor definitions.
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +000069 unsigned getColumnLimit(const LineState &State) const;
Daniel Jasperde0328a2013-08-16 11:20:30 +000070
71private:
72 /// \brief Mark the next token as consumed in \p State and modify its stacks
73 /// accordingly.
74 unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
75
76 /// \brief If the current token sticks out over the end of the line, break
77 /// it if possible.
78 ///
79 /// \returns An extra penalty if a token was broken, otherwise 0.
80 ///
81 /// The returned penalty will cover the cost of the additional line breaks and
82 /// column limit violation in all lines except for the last one. The penalty
83 /// for the column limit violation in the last line (and in single line
84 /// tokens) is handled in \c addNextStateToQueue.
85 unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
86 bool DryRun);
87
Alexander Kornienko1f803962013-10-01 14:41:18 +000088 /// \brief Appends the next token to \p State and updates information
89 /// necessary for indentation.
90 ///
91 /// Puts the token on the current line.
92 ///
93 /// If \p DryRun is \c false, also creates and stores the required
94 /// \c Replacement.
Daniel Jasper48437ce2013-11-20 14:54:39 +000095 void addTokenOnCurrentLine(LineState &State, bool DryRun,
96 unsigned ExtraSpaces);
Alexander Kornienko1f803962013-10-01 14:41:18 +000097
98 /// \brief Appends the next token to \p State and updates information
99 /// necessary for indentation.
100 ///
101 /// Adds a line break and necessary indentation.
102 ///
103 /// If \p DryRun is \c false, also creates and stores the required
104 /// \c Replacement.
105 unsigned addTokenOnNewLine(LineState &State, bool DryRun);
106
Daniel Jasper9f388d02014-03-27 14:33:30 +0000107 /// \brief Calculate the new column for a line wrap before the next token.
108 unsigned getNewLineColumn(const LineState &State);
109
Alexander Kornienko917f9e02013-09-10 12:29:48 +0000110 /// \brief Adds a multiline token to the \p State.
Alexander Kornienkod7b837e2013-08-29 17:32:57 +0000111 ///
112 /// \returns Extra penalty for the first line of the literal: last line is
113 /// handled in \c addNextStateToQueue, and the penalty for other lines doesn't
114 /// matter, as we don't change them.
Alexander Kornienko917f9e02013-09-10 12:29:48 +0000115 unsigned addMultilineToken(const FormatToken &Current, LineState &State);
Alexander Kornienkod7b837e2013-08-29 17:32:57 +0000116
Daniel Jasperf438cb72013-08-23 11:57:34 +0000117 /// \brief Returns \c true if the next token starts a multiline string
118 /// literal.
119 ///
120 /// This includes implicitly concatenated strings, strings that will be broken
121 /// by clang-format and string literals with escaped newlines.
Daniel Jasperc39b56f2013-12-16 07:23:08 +0000122 bool nextIsMultilineString(const LineState &State);
Daniel Jasperf438cb72013-08-23 11:57:34 +0000123
Daniel Jasperde0328a2013-08-16 11:20:30 +0000124 FormatStyle Style;
125 SourceManager &SourceMgr;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000126 WhitespaceManager &Whitespaces;
127 encoding::Encoding Encoding;
128 bool BinPackInconclusiveFunctions;
Alexander Kornienkoce9161a2014-01-02 15:13:14 +0000129 llvm::Regex CommentPragmasRegex;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000130};
131
132struct ParenState {
Alexander Kornienkoe2e03872013-10-14 00:46:35 +0000133 ParenState(unsigned Indent, unsigned IndentLevel, unsigned LastSpace,
134 bool AvoidBinPacking, bool NoLineBreak)
135 : Indent(Indent), IndentLevel(IndentLevel), LastSpace(LastSpace),
136 FirstLessLess(0), BreakBeforeClosingBrace(false), QuestionColumn(0),
Daniel Jasperde0328a2013-08-16 11:20:30 +0000137 AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
Daniel Jasperc0d606a2014-04-14 11:08:45 +0000138 NoLineBreak(NoLineBreak), LastOperatorWrapped(true), ColonPos(0),
139 StartOfFunctionCall(0), StartOfArraySubscripts(0),
140 NestedNameSpecifierContinuation(0), CallContinuation(0), VariablePos(0),
141 ContainsLineBreak(false), ContainsUnwrappedBuilder(0),
Daniel Jasperb16b9692014-05-21 12:51:23 +0000142 AlignColons(true), ObjCSelectorNameFound(false), LambdasFound(0),
143 JSFunctionInlined(false) {}
Daniel Jasperde0328a2013-08-16 11:20:30 +0000144
145 /// \brief The position to which a specific parenthesis level needs to be
146 /// indented.
147 unsigned Indent;
148
Alexander Kornienkoe2e03872013-10-14 00:46:35 +0000149 /// \brief The number of indentation levels of the block.
150 unsigned IndentLevel;
151
Daniel Jasperde0328a2013-08-16 11:20:30 +0000152 /// \brief The position of the last space on each level.
153 ///
154 /// Used e.g. to break like:
155 /// functionCall(Parameter, otherCall(
156 /// OtherParameter));
157 unsigned LastSpace;
158
159 /// \brief The position the first "<<" operator encountered on each level.
160 ///
161 /// Used to align "<<" operators. 0 if no such operator has been encountered
162 /// on a level.
163 unsigned FirstLessLess;
164
165 /// \brief Whether a newline needs to be inserted before the block's closing
166 /// brace.
167 ///
168 /// We only want to insert a newline before the closing brace if there also
169 /// was a newline after the beginning left brace.
170 bool BreakBeforeClosingBrace;
171
172 /// \brief The column of a \c ? in a conditional expression;
173 unsigned QuestionColumn;
174
175 /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
176 /// lines, in this context.
177 bool AvoidBinPacking;
178
179 /// \brief Break after the next comma (or all the commas in this context if
180 /// \c AvoidBinPacking is \c true).
181 bool BreakBeforeParameter;
182
183 /// \brief Line breaking in this context would break a formatting rule.
184 bool NoLineBreak;
185
Daniel Jasperc0d606a2014-04-14 11:08:45 +0000186 /// \brief True if the last binary operator on this level was wrapped to the
187 /// next line.
188 bool LastOperatorWrapped;
189
Daniel Jasperde0328a2013-08-16 11:20:30 +0000190 /// \brief The position of the colon in an ObjC method declaration/call.
191 unsigned ColonPos;
192
193 /// \brief The start of the most recent function in a builder-type call.
194 unsigned StartOfFunctionCall;
195
196 /// \brief Contains the start of array subscript expressions, so that they
197 /// can be aligned.
198 unsigned StartOfArraySubscripts;
199
200 /// \brief If a nested name specifier was broken over multiple lines, this
201 /// contains the start column of the second line. Otherwise 0.
202 unsigned NestedNameSpecifierContinuation;
203
204 /// \brief If a call expression was broken over multiple lines, this
205 /// contains the start column of the second line. Otherwise 0.
206 unsigned CallContinuation;
207
208 /// \brief The column of the first variable name in a variable declaration.
209 ///
210 /// Used to align further variables if necessary.
211 unsigned VariablePos;
212
213 /// \brief \c true if this \c ParenState already contains a line-break.
214 ///
215 /// The first line break in a certain \c ParenState causes extra penalty so
216 /// that clang-format prefers similar breaks, i.e. breaks in the same
217 /// parenthesis.
218 bool ContainsLineBreak;
219
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000220 /// \brief \c true if this \c ParenState contains multiple segments of a
221 /// builder-type call on one line.
222 bool ContainsUnwrappedBuilder;
223
Daniel Jasperb88b25f2013-12-23 07:29:06 +0000224 /// \brief \c true if the colons of the curren ObjC method expression should
225 /// be aligned.
226 ///
227 /// Not considered for memoization as it will always have the same value at
228 /// the same token.
229 bool AlignColons;
230
231 /// \brief \c true if at least one selector name was found in the current
232 /// ObjC method expression.
233 ///
234 /// Not considered for memoization as it will always have the same value at
235 /// the same token.
236 bool ObjCSelectorNameFound;
237
Daniel Jasper3ae6f5a2014-04-09 12:08:39 +0000238 /// \brief Counts the number of lambda introducers found on this level.
239 ///
240 /// Not considered for memoization as it will always have the same value at
241 /// the same token.
242 unsigned LambdasFound;
243
Daniel Jasperb16b9692014-05-21 12:51:23 +0000244 // \brief The previous JavaScript 'function' keyword is not wrapped to a new
245 // line.
246 bool JSFunctionInlined;
247
Daniel Jasperde0328a2013-08-16 11:20:30 +0000248 bool operator<(const ParenState &Other) const {
249 if (Indent != Other.Indent)
250 return Indent < Other.Indent;
251 if (LastSpace != Other.LastSpace)
252 return LastSpace < Other.LastSpace;
253 if (FirstLessLess != Other.FirstLessLess)
254 return FirstLessLess < Other.FirstLessLess;
255 if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
256 return BreakBeforeClosingBrace;
257 if (QuestionColumn != Other.QuestionColumn)
258 return QuestionColumn < Other.QuestionColumn;
259 if (AvoidBinPacking != Other.AvoidBinPacking)
260 return AvoidBinPacking;
261 if (BreakBeforeParameter != Other.BreakBeforeParameter)
262 return BreakBeforeParameter;
263 if (NoLineBreak != Other.NoLineBreak)
264 return NoLineBreak;
Daniel Jasperc0d606a2014-04-14 11:08:45 +0000265 if (LastOperatorWrapped != Other.LastOperatorWrapped)
266 return LastOperatorWrapped;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000267 if (ColonPos != Other.ColonPos)
268 return ColonPos < Other.ColonPos;
269 if (StartOfFunctionCall != Other.StartOfFunctionCall)
270 return StartOfFunctionCall < Other.StartOfFunctionCall;
271 if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
272 return StartOfArraySubscripts < Other.StartOfArraySubscripts;
273 if (CallContinuation != Other.CallContinuation)
274 return CallContinuation < Other.CallContinuation;
275 if (VariablePos != Other.VariablePos)
276 return VariablePos < Other.VariablePos;
277 if (ContainsLineBreak != Other.ContainsLineBreak)
278 return ContainsLineBreak < Other.ContainsLineBreak;
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000279 if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
280 return ContainsUnwrappedBuilder < Other.ContainsUnwrappedBuilder;
Daniel Jasperb16b9692014-05-21 12:51:23 +0000281 if (JSFunctionInlined != Other.JSFunctionInlined)
282 return JSFunctionInlined < Other.JSFunctionInlined;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000283 return false;
284 }
285};
286
287/// \brief The current state when indenting a unwrapped line.
288///
289/// As the indenting tries different combinations this is copied by value.
290struct LineState {
291 /// \brief The number of used columns in the current line.
292 unsigned Column;
293
294 /// \brief The token that needs to be next formatted.
Manuel Klimek71814b42013-10-11 21:25:45 +0000295 FormatToken *NextToken;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000296
297 /// \brief \c true if this line contains a continued for-loop section.
298 bool LineContainsContinuedForLoopSection;
299
Daniel Jasper05cd5862014-05-08 12:21:30 +0000300 /// \brief The \c NestingLevel at the start of this line.
Daniel Jasperde0328a2013-08-16 11:20:30 +0000301 unsigned StartOfLineLevel;
302
Daniel Jasper05cd5862014-05-08 12:21:30 +0000303 /// \brief The lowest \c NestingLevel on the current line.
Daniel Jasperde0328a2013-08-16 11:20:30 +0000304 unsigned LowestLevelOnLine;
305
306 /// \brief The start column of the string literal, if we're in a string
307 /// literal sequence, 0 otherwise.
308 unsigned StartOfStringLiteral;
309
310 /// \brief A stack keeping track of properties applying to parenthesis
311 /// levels.
312 std::vector<ParenState> Stack;
313
314 /// \brief Ignore the stack of \c ParenStates for state comparison.
315 ///
316 /// In long and deeply nested unwrapped lines, the current algorithm can
317 /// be insufficient for finding the best formatting with a reasonable amount
318 /// of time and memory. Setting this flag will effectively lead to the
319 /// algorithm not analyzing some combinations. However, these combinations
320 /// rarely contain the optimal solution: In short, accepting a higher
321 /// penalty early would need to lead to different values in the \c
322 /// ParenState stack (in an otherwise identical state) and these different
323 /// values would need to lead to a significant amount of avoided penalty
324 /// later.
325 ///
326 /// FIXME: Come up with a better algorithm instead.
327 bool IgnoreStackForComparison;
328
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +0000329 /// \brief The indent of the first token.
330 unsigned FirstIndent;
331
332 /// \brief The line that is being formatted.
333 ///
334 /// Does not need to be considered for memoization because it doesn't change.
335 const AnnotatedLine *Line;
336
Daniel Jasperde0328a2013-08-16 11:20:30 +0000337 /// \brief Comparison operator to be able to used \c LineState in \c map.
338 bool operator<(const LineState &Other) const {
339 if (NextToken != Other.NextToken)
340 return NextToken < Other.NextToken;
341 if (Column != Other.Column)
342 return Column < Other.Column;
343 if (LineContainsContinuedForLoopSection !=
344 Other.LineContainsContinuedForLoopSection)
345 return LineContainsContinuedForLoopSection;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000346 if (StartOfLineLevel != Other.StartOfLineLevel)
347 return StartOfLineLevel < Other.StartOfLineLevel;
348 if (LowestLevelOnLine != Other.LowestLevelOnLine)
349 return LowestLevelOnLine < Other.LowestLevelOnLine;
350 if (StartOfStringLiteral != Other.StartOfStringLiteral)
351 return StartOfStringLiteral < Other.StartOfStringLiteral;
352 if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
353 return false;
354 return Stack < Other.Stack;
355 }
356};
357
358} // end namespace format
359} // end namespace clang
360
361#endif // LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H