blob: 41f3f4b88084d547c32c22f9187d02763e6088b9 [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"
21
22namespace clang {
23class SourceManager;
24
25namespace format {
26
27class AnnotatedLine;
28struct FormatToken;
29struct LineState;
30struct ParenState;
31class WhitespaceManager;
32
33class ContinuationIndenter {
34public:
35 /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in
36 /// column \p FirstIndent.
37 ContinuationIndenter(const FormatStyle &Style, SourceManager &SourceMgr,
Daniel Jasperde0328a2013-08-16 11:20:30 +000038 WhitespaceManager &Whitespaces,
39 encoding::Encoding Encoding,
40 bool BinPackInconclusiveFunctions);
41
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +000042 /// \brief Get the initial state, i.e. the state after placing \p Line's
43 /// first token at \p FirstIndent.
Daniel Jasper1c5d9df2013-09-06 07:54:20 +000044 LineState getInitialState(unsigned FirstIndent, const AnnotatedLine *Line,
45 bool DryRun);
Daniel Jasperde0328a2013-08-16 11:20:30 +000046
47 // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a
48 // better home.
49 /// \brief Returns \c true, if a line break after \p State is allowed.
50 bool canBreak(const LineState &State);
51
52 /// \brief Returns \c true, if a line break after \p State is mandatory.
53 bool mustBreak(const LineState &State);
54
55 /// \brief Appends the next token to \p State and updates information
56 /// necessary for indentation.
57 ///
58 /// Puts the token on the current line if \p Newline is \c false and adds a
59 /// line break and necessary indentation otherwise.
60 ///
61 /// If \p DryRun is \c false, also creates and stores the required
62 /// \c Replacement.
Daniel Jasper8de9ed02013-08-22 15:00:41 +000063 unsigned addTokenToState(LineState &State, bool Newline, bool DryRun,
64 unsigned ExtraSpaces = 0);
Daniel Jasperde0328a2013-08-16 11:20:30 +000065
66 /// \brief Get the column limit for this line. This is the style's column
67 /// limit, potentially reduced for preprocessor definitions.
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +000068 unsigned getColumnLimit(const LineState &State) const;
Daniel Jasperde0328a2013-08-16 11:20:30 +000069
70private:
71 /// \brief Mark the next token as consumed in \p State and modify its stacks
72 /// accordingly.
73 unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
74
75 /// \brief If the current token sticks out over the end of the line, break
76 /// it if possible.
77 ///
78 /// \returns An extra penalty if a token was broken, otherwise 0.
79 ///
80 /// The returned penalty will cover the cost of the additional line breaks and
81 /// column limit violation in all lines except for the last one. The penalty
82 /// for the column limit violation in the last line (and in single line
83 /// tokens) is handled in \c addNextStateToQueue.
84 unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
85 bool DryRun);
86
Alexander Kornienko1f803962013-10-01 14:41:18 +000087 /// \brief Appends the next token to \p State and updates information
88 /// necessary for indentation.
89 ///
90 /// Puts the token on the current line.
91 ///
92 /// If \p DryRun is \c false, also creates and stores the required
93 /// \c Replacement.
Daniel Jasper48437ce2013-11-20 14:54:39 +000094 void addTokenOnCurrentLine(LineState &State, bool DryRun,
95 unsigned ExtraSpaces);
Alexander Kornienko1f803962013-10-01 14:41:18 +000096
97 /// \brief Appends the next token to \p State and updates information
98 /// necessary for indentation.
99 ///
100 /// Adds a line break and necessary indentation.
101 ///
102 /// If \p DryRun is \c false, also creates and stores the required
103 /// \c Replacement.
104 unsigned addTokenOnNewLine(LineState &State, bool DryRun);
105
Alexander Kornienko917f9e02013-09-10 12:29:48 +0000106 /// \brief Adds a multiline token to the \p State.
Alexander Kornienkod7b837e2013-08-29 17:32:57 +0000107 ///
108 /// \returns Extra penalty for the first line of the literal: last line is
109 /// handled in \c addNextStateToQueue, and the penalty for other lines doesn't
110 /// matter, as we don't change them.
Alexander Kornienko917f9e02013-09-10 12:29:48 +0000111 unsigned addMultilineToken(const FormatToken &Current, LineState &State);
Alexander Kornienkod7b837e2013-08-29 17:32:57 +0000112
Daniel Jasperf438cb72013-08-23 11:57:34 +0000113 /// \brief Returns \c true if the next token starts a multiline string
114 /// literal.
115 ///
116 /// This includes implicitly concatenated strings, strings that will be broken
117 /// by clang-format and string literals with escaped newlines.
Daniel Jasperc39b56f2013-12-16 07:23:08 +0000118 bool nextIsMultilineString(const LineState &State);
Daniel Jasperf438cb72013-08-23 11:57:34 +0000119
Daniel Jasperde0328a2013-08-16 11:20:30 +0000120 FormatStyle Style;
121 SourceManager &SourceMgr;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000122 WhitespaceManager &Whitespaces;
123 encoding::Encoding Encoding;
124 bool BinPackInconclusiveFunctions;
125};
126
127struct ParenState {
Alexander Kornienkoe2e03872013-10-14 00:46:35 +0000128 ParenState(unsigned Indent, unsigned IndentLevel, unsigned LastSpace,
129 bool AvoidBinPacking, bool NoLineBreak)
130 : Indent(Indent), IndentLevel(IndentLevel), LastSpace(LastSpace),
131 FirstLessLess(0), BreakBeforeClosingBrace(false), QuestionColumn(0),
Daniel Jasperde0328a2013-08-16 11:20:30 +0000132 AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
133 NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
134 StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000135 CallContinuation(0), VariablePos(0), ContainsLineBreak(false),
Daniel Jasperb88b25f2013-12-23 07:29:06 +0000136 ContainsUnwrappedBuilder(0), AlignColons(true),
137 ObjCSelectorNameFound(false) {}
Daniel Jasperde0328a2013-08-16 11:20:30 +0000138
139 /// \brief The position to which a specific parenthesis level needs to be
140 /// indented.
141 unsigned Indent;
142
Alexander Kornienkoe2e03872013-10-14 00:46:35 +0000143 /// \brief The number of indentation levels of the block.
144 unsigned IndentLevel;
145
Daniel Jasperde0328a2013-08-16 11:20:30 +0000146 /// \brief The position of the last space on each level.
147 ///
148 /// Used e.g. to break like:
149 /// functionCall(Parameter, otherCall(
150 /// OtherParameter));
151 unsigned LastSpace;
152
153 /// \brief The position the first "<<" operator encountered on each level.
154 ///
155 /// Used to align "<<" operators. 0 if no such operator has been encountered
156 /// on a level.
157 unsigned FirstLessLess;
158
159 /// \brief Whether a newline needs to be inserted before the block's closing
160 /// brace.
161 ///
162 /// We only want to insert a newline before the closing brace if there also
163 /// was a newline after the beginning left brace.
164 bool BreakBeforeClosingBrace;
165
166 /// \brief The column of a \c ? in a conditional expression;
167 unsigned QuestionColumn;
168
169 /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
170 /// lines, in this context.
171 bool AvoidBinPacking;
172
173 /// \brief Break after the next comma (or all the commas in this context if
174 /// \c AvoidBinPacking is \c true).
175 bool BreakBeforeParameter;
176
177 /// \brief Line breaking in this context would break a formatting rule.
178 bool NoLineBreak;
179
180 /// \brief The position of the colon in an ObjC method declaration/call.
181 unsigned ColonPos;
182
183 /// \brief The start of the most recent function in a builder-type call.
184 unsigned StartOfFunctionCall;
185
186 /// \brief Contains the start of array subscript expressions, so that they
187 /// can be aligned.
188 unsigned StartOfArraySubscripts;
189
190 /// \brief If a nested name specifier was broken over multiple lines, this
191 /// contains the start column of the second line. Otherwise 0.
192 unsigned NestedNameSpecifierContinuation;
193
194 /// \brief If a call expression was broken over multiple lines, this
195 /// contains the start column of the second line. Otherwise 0.
196 unsigned CallContinuation;
197
198 /// \brief The column of the first variable name in a variable declaration.
199 ///
200 /// Used to align further variables if necessary.
201 unsigned VariablePos;
202
203 /// \brief \c true if this \c ParenState already contains a line-break.
204 ///
205 /// The first line break in a certain \c ParenState causes extra penalty so
206 /// that clang-format prefers similar breaks, i.e. breaks in the same
207 /// parenthesis.
208 bool ContainsLineBreak;
209
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000210 /// \brief \c true if this \c ParenState contains multiple segments of a
211 /// builder-type call on one line.
212 bool ContainsUnwrappedBuilder;
213
Daniel Jasperb88b25f2013-12-23 07:29:06 +0000214 /// \brief \c true if the colons of the curren ObjC method expression should
215 /// be aligned.
216 ///
217 /// Not considered for memoization as it will always have the same value at
218 /// the same token.
219 bool AlignColons;
220
221 /// \brief \c true if at least one selector name was found in the current
222 /// ObjC method expression.
223 ///
224 /// Not considered for memoization as it will always have the same value at
225 /// the same token.
226 bool ObjCSelectorNameFound;
227
Daniel Jasperde0328a2013-08-16 11:20:30 +0000228 bool operator<(const ParenState &Other) const {
229 if (Indent != Other.Indent)
230 return Indent < Other.Indent;
231 if (LastSpace != Other.LastSpace)
232 return LastSpace < Other.LastSpace;
233 if (FirstLessLess != Other.FirstLessLess)
234 return FirstLessLess < Other.FirstLessLess;
235 if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
236 return BreakBeforeClosingBrace;
237 if (QuestionColumn != Other.QuestionColumn)
238 return QuestionColumn < Other.QuestionColumn;
239 if (AvoidBinPacking != Other.AvoidBinPacking)
240 return AvoidBinPacking;
241 if (BreakBeforeParameter != Other.BreakBeforeParameter)
242 return BreakBeforeParameter;
243 if (NoLineBreak != Other.NoLineBreak)
244 return NoLineBreak;
245 if (ColonPos != Other.ColonPos)
246 return ColonPos < Other.ColonPos;
247 if (StartOfFunctionCall != Other.StartOfFunctionCall)
248 return StartOfFunctionCall < Other.StartOfFunctionCall;
249 if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
250 return StartOfArraySubscripts < Other.StartOfArraySubscripts;
251 if (CallContinuation != Other.CallContinuation)
252 return CallContinuation < Other.CallContinuation;
253 if (VariablePos != Other.VariablePos)
254 return VariablePos < Other.VariablePos;
255 if (ContainsLineBreak != Other.ContainsLineBreak)
256 return ContainsLineBreak < Other.ContainsLineBreak;
Daniel Jasper4c6e0052013-08-27 14:24:43 +0000257 if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
258 return ContainsUnwrappedBuilder < Other.ContainsUnwrappedBuilder;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000259 return false;
260 }
261};
262
263/// \brief The current state when indenting a unwrapped line.
264///
265/// As the indenting tries different combinations this is copied by value.
266struct LineState {
267 /// \brief The number of used columns in the current line.
268 unsigned Column;
269
270 /// \brief The token that needs to be next formatted.
Manuel Klimek71814b42013-10-11 21:25:45 +0000271 FormatToken *NextToken;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000272
273 /// \brief \c true if this line contains a continued for-loop section.
274 bool LineContainsContinuedForLoopSection;
275
276 /// \brief The level of nesting inside (), [], <> and {}.
277 unsigned ParenLevel;
278
279 /// \brief The \c ParenLevel at the start of this line.
280 unsigned StartOfLineLevel;
281
282 /// \brief The lowest \c ParenLevel on the current line.
283 unsigned LowestLevelOnLine;
284
285 /// \brief The start column of the string literal, if we're in a string
286 /// literal sequence, 0 otherwise.
287 unsigned StartOfStringLiteral;
288
289 /// \brief A stack keeping track of properties applying to parenthesis
290 /// levels.
291 std::vector<ParenState> Stack;
292
293 /// \brief Ignore the stack of \c ParenStates for state comparison.
294 ///
295 /// In long and deeply nested unwrapped lines, the current algorithm can
296 /// be insufficient for finding the best formatting with a reasonable amount
297 /// of time and memory. Setting this flag will effectively lead to the
298 /// algorithm not analyzing some combinations. However, these combinations
299 /// rarely contain the optimal solution: In short, accepting a higher
300 /// penalty early would need to lead to different values in the \c
301 /// ParenState stack (in an otherwise identical state) and these different
302 /// values would need to lead to a significant amount of avoided penalty
303 /// later.
304 ///
305 /// FIXME: Come up with a better algorithm instead.
306 bool IgnoreStackForComparison;
307
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +0000308 /// \brief The indent of the first token.
309 unsigned FirstIndent;
310
311 /// \brief The line that is being formatted.
312 ///
313 /// Does not need to be considered for memoization because it doesn't change.
314 const AnnotatedLine *Line;
315
Daniel Jasperde0328a2013-08-16 11:20:30 +0000316 /// \brief Comparison operator to be able to used \c LineState in \c map.
317 bool operator<(const LineState &Other) const {
318 if (NextToken != Other.NextToken)
319 return NextToken < Other.NextToken;
320 if (Column != Other.Column)
321 return Column < Other.Column;
322 if (LineContainsContinuedForLoopSection !=
323 Other.LineContainsContinuedForLoopSection)
324 return LineContainsContinuedForLoopSection;
325 if (ParenLevel != Other.ParenLevel)
326 return ParenLevel < Other.ParenLevel;
327 if (StartOfLineLevel != Other.StartOfLineLevel)
328 return StartOfLineLevel < Other.StartOfLineLevel;
329 if (LowestLevelOnLine != Other.LowestLevelOnLine)
330 return LowestLevelOnLine < Other.LowestLevelOnLine;
331 if (StartOfStringLiteral != Other.StartOfStringLiteral)
332 return StartOfStringLiteral < Other.StartOfStringLiteral;
333 if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
334 return false;
335 return Stack < Other.Stack;
336 }
337};
338
339} // end namespace format
340} // end namespace clang
341
342#endif // LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H