1 //===--- ContinuationIndenter.h - Format C++ code ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief This file implements an indenter that manages the indentation of
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
17 #define LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
20 #include "clang/Format/Format.h"
31 class WhitespaceManager;
33 class ContinuationIndenter {
35 /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in
36 /// column \p FirstIndent.
37 ContinuationIndenter(const FormatStyle &Style, SourceManager &SourceMgr,
38 WhitespaceManager &Whitespaces,
39 encoding::Encoding Encoding,
40 bool BinPackInconclusiveFunctions);
42 /// \brief Get the initial state, i.e. the state after placing \p Line's
43 /// first token at \p FirstIndent.
44 LineState getInitialState(unsigned FirstIndent, const AnnotatedLine *Line,
47 // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a
49 /// \brief Returns \c true, if a line break after \p State is allowed.
50 bool canBreak(const LineState &State);
52 /// \brief Returns \c true, if a line break after \p State is mandatory.
53 bool mustBreak(const LineState &State);
55 /// \brief Appends the next token to \p State and updates information
56 /// necessary for indentation.
58 /// Puts the token on the current line if \p Newline is \c false and adds a
59 /// line break and necessary indentation otherwise.
61 /// If \p DryRun is \c false, also creates and stores the required
63 unsigned addTokenToState(LineState &State, bool Newline, bool DryRun,
64 unsigned ExtraSpaces = 0);
66 /// \brief Get the column limit for this line. This is the style's column
67 /// limit, potentially reduced for preprocessor definitions.
68 unsigned getColumnLimit(const LineState &State) const;
71 /// \brief Mark the next token as consumed in \p State and modify its stacks
73 unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
75 /// \brief If the current token sticks out over the end of the line, break
78 /// \returns An extra penalty if a token was broken, otherwise 0.
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,
87 /// \brief Appends the next token to \p State and updates information
88 /// necessary for indentation.
90 /// Puts the token on the current line.
92 /// If \p DryRun is \c false, also creates and stores the required
94 void addTokenOnCurrentLine(LineState &State, bool DryRun,
95 unsigned ExtraSpaces);
97 /// \brief Appends the next token to \p State and updates information
98 /// necessary for indentation.
100 /// Adds a line break and necessary indentation.
102 /// If \p DryRun is \c false, also creates and stores the required
104 unsigned addTokenOnNewLine(LineState &State, bool DryRun);
106 /// \brief Adds a multiline token to the \p State.
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.
111 unsigned addMultilineToken(const FormatToken &Current, LineState &State);
113 /// \brief Returns \c true if the next token starts a multiline string
116 /// This includes implicitly concatenated strings, strings that will be broken
117 /// by clang-format and string literals with escaped newlines.
118 bool NextIsMultilineString(const LineState &State);
121 SourceManager &SourceMgr;
122 WhitespaceManager &Whitespaces;
123 encoding::Encoding Encoding;
124 bool BinPackInconclusiveFunctions;
128 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),
132 AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
133 NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
134 StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
135 CallContinuation(0), VariablePos(0), ContainsLineBreak(false),
136 ContainsUnwrappedBuilder(0) {}
138 /// \brief The position to which a specific parenthesis level needs to be
142 /// \brief The number of indentation levels of the block.
143 unsigned IndentLevel;
145 /// \brief The position of the last space on each level.
147 /// Used e.g. to break like:
148 /// functionCall(Parameter, otherCall(
149 /// OtherParameter));
152 /// \brief The position the first "<<" operator encountered on each level.
154 /// Used to align "<<" operators. 0 if no such operator has been encountered
156 unsigned FirstLessLess;
158 /// \brief Whether a newline needs to be inserted before the block's closing
161 /// We only want to insert a newline before the closing brace if there also
162 /// was a newline after the beginning left brace.
163 bool BreakBeforeClosingBrace;
165 /// \brief The column of a \c ? in a conditional expression;
166 unsigned QuestionColumn;
168 /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
169 /// lines, in this context.
170 bool AvoidBinPacking;
172 /// \brief Break after the next comma (or all the commas in this context if
173 /// \c AvoidBinPacking is \c true).
174 bool BreakBeforeParameter;
176 /// \brief Line breaking in this context would break a formatting rule.
179 /// \brief The position of the colon in an ObjC method declaration/call.
182 /// \brief The start of the most recent function in a builder-type call.
183 unsigned StartOfFunctionCall;
185 /// \brief Contains the start of array subscript expressions, so that they
187 unsigned StartOfArraySubscripts;
189 /// \brief If a nested name specifier was broken over multiple lines, this
190 /// contains the start column of the second line. Otherwise 0.
191 unsigned NestedNameSpecifierContinuation;
193 /// \brief If a call expression was broken over multiple lines, this
194 /// contains the start column of the second line. Otherwise 0.
195 unsigned CallContinuation;
197 /// \brief The column of the first variable name in a variable declaration.
199 /// Used to align further variables if necessary.
200 unsigned VariablePos;
202 /// \brief \c true if this \c ParenState already contains a line-break.
204 /// The first line break in a certain \c ParenState causes extra penalty so
205 /// that clang-format prefers similar breaks, i.e. breaks in the same
207 bool ContainsLineBreak;
209 /// \brief \c true if this \c ParenState contains multiple segments of a
210 /// builder-type call on one line.
211 bool ContainsUnwrappedBuilder;
213 bool operator<(const ParenState &Other) const {
214 if (Indent != Other.Indent)
215 return Indent < Other.Indent;
216 if (LastSpace != Other.LastSpace)
217 return LastSpace < Other.LastSpace;
218 if (FirstLessLess != Other.FirstLessLess)
219 return FirstLessLess < Other.FirstLessLess;
220 if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
221 return BreakBeforeClosingBrace;
222 if (QuestionColumn != Other.QuestionColumn)
223 return QuestionColumn < Other.QuestionColumn;
224 if (AvoidBinPacking != Other.AvoidBinPacking)
225 return AvoidBinPacking;
226 if (BreakBeforeParameter != Other.BreakBeforeParameter)
227 return BreakBeforeParameter;
228 if (NoLineBreak != Other.NoLineBreak)
230 if (ColonPos != Other.ColonPos)
231 return ColonPos < Other.ColonPos;
232 if (StartOfFunctionCall != Other.StartOfFunctionCall)
233 return StartOfFunctionCall < Other.StartOfFunctionCall;
234 if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
235 return StartOfArraySubscripts < Other.StartOfArraySubscripts;
236 if (CallContinuation != Other.CallContinuation)
237 return CallContinuation < Other.CallContinuation;
238 if (VariablePos != Other.VariablePos)
239 return VariablePos < Other.VariablePos;
240 if (ContainsLineBreak != Other.ContainsLineBreak)
241 return ContainsLineBreak < Other.ContainsLineBreak;
242 if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
243 return ContainsUnwrappedBuilder < Other.ContainsUnwrappedBuilder;
248 /// \brief The current state when indenting a unwrapped line.
250 /// As the indenting tries different combinations this is copied by value.
252 /// \brief The number of used columns in the current line.
255 /// \brief The token that needs to be next formatted.
256 FormatToken *NextToken;
258 /// \brief \c true if this line contains a continued for-loop section.
259 bool LineContainsContinuedForLoopSection;
261 /// \brief The level of nesting inside (), [], <> and {}.
264 /// \brief The \c ParenLevel at the start of this line.
265 unsigned StartOfLineLevel;
267 /// \brief The lowest \c ParenLevel on the current line.
268 unsigned LowestLevelOnLine;
270 /// \brief The start column of the string literal, if we're in a string
271 /// literal sequence, 0 otherwise.
272 unsigned StartOfStringLiteral;
274 /// \brief A stack keeping track of properties applying to parenthesis
276 std::vector<ParenState> Stack;
278 /// \brief Ignore the stack of \c ParenStates for state comparison.
280 /// In long and deeply nested unwrapped lines, the current algorithm can
281 /// be insufficient for finding the best formatting with a reasonable amount
282 /// of time and memory. Setting this flag will effectively lead to the
283 /// algorithm not analyzing some combinations. However, these combinations
284 /// rarely contain the optimal solution: In short, accepting a higher
285 /// penalty early would need to lead to different values in the \c
286 /// ParenState stack (in an otherwise identical state) and these different
287 /// values would need to lead to a significant amount of avoided penalty
290 /// FIXME: Come up with a better algorithm instead.
291 bool IgnoreStackForComparison;
293 /// \brief The indent of the first token.
294 unsigned FirstIndent;
296 /// \brief The line that is being formatted.
298 /// Does not need to be considered for memoization because it doesn't change.
299 const AnnotatedLine *Line;
301 /// \brief Comparison operator to be able to used \c LineState in \c map.
302 bool operator<(const LineState &Other) const {
303 if (NextToken != Other.NextToken)
304 return NextToken < Other.NextToken;
305 if (Column != Other.Column)
306 return Column < Other.Column;
307 if (LineContainsContinuedForLoopSection !=
308 Other.LineContainsContinuedForLoopSection)
309 return LineContainsContinuedForLoopSection;
310 if (ParenLevel != Other.ParenLevel)
311 return ParenLevel < Other.ParenLevel;
312 if (StartOfLineLevel != Other.StartOfLineLevel)
313 return StartOfLineLevel < Other.StartOfLineLevel;
314 if (LowestLevelOnLine != Other.LowestLevelOnLine)
315 return LowestLevelOnLine < Other.LowestLevelOnLine;
316 if (StartOfStringLiteral != Other.StartOfStringLiteral)
317 return StartOfStringLiteral < Other.StartOfStringLiteral;
318 if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
320 return Stack < Other.Stack;
324 } // end namespace format
325 } // end namespace clang
327 #endif // LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H