/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- UnwrappedLineFormatter.cpp - Format C++ code ---------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "UnwrappedLineFormatter.h" |
10 | | #include "NamespaceEndCommentsFixer.h" |
11 | | #include "WhitespaceManager.h" |
12 | | #include "llvm/Support/Debug.h" |
13 | | #include <queue> |
14 | | |
15 | | #define DEBUG_TYPE "format-formatter" |
16 | | |
17 | | namespace clang { |
18 | | namespace format { |
19 | | |
20 | | namespace { |
21 | | |
22 | 5.82k | bool startsExternCBlock(const AnnotatedLine &Line) { |
23 | 5.82k | const FormatToken *Next = Line.First->getNextNonComment(); |
24 | 5.82k | const FormatToken *NextNext = Next ? Next->getNextNonComment()4.83k : nullptr987 ; |
25 | 5.82k | return Line.startsWith(tok::kw_extern) && Next46 && Next->isStringLiteral()46 && |
26 | 5.82k | NextNext46 && NextNext->is(tok::l_brace)46 ; |
27 | 5.82k | } |
28 | | |
29 | 5.21k | bool isRecordLBrace(const FormatToken &Tok) { |
30 | 5.21k | return Tok.isOneOf(TT_ClassLBrace, TT_EnumLBrace, TT_RecordLBrace, |
31 | 5.21k | TT_StructLBrace, TT_UnionLBrace); |
32 | 5.21k | } |
33 | | |
34 | | /// Tracks the indent level of \c AnnotatedLines across levels. |
35 | | /// |
36 | | /// \c nextLine must be called for each \c AnnotatedLine, after which \c |
37 | | /// getIndent() will return the indent for the last line \c nextLine was called |
38 | | /// with. |
39 | | /// If the line is not formatted (and thus the indent does not change), calling |
40 | | /// \c adjustToUnmodifiedLine after the call to \c nextLine will cause |
41 | | /// subsequent lines on the same level to be indented at the same level as the |
42 | | /// given line. |
43 | | class LevelIndentTracker { |
44 | | public: |
45 | | LevelIndentTracker(const FormatStyle &Style, |
46 | | const AdditionalKeywords &Keywords, unsigned StartLevel, |
47 | | int AdditionalIndent) |
48 | 24.9k | : Style(Style), Keywords(Keywords), AdditionalIndent(AdditionalIndent) { |
49 | 27.6k | for (unsigned i = 0; i != StartLevel; ++i2.68k ) |
50 | 2.68k | IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent); |
51 | 24.9k | } |
52 | | |
53 | | /// Returns the indent for the current line. |
54 | 162k | unsigned getIndent() const { return Indent; } |
55 | | |
56 | | /// Update the indent state given that \p Line is going to be formatted |
57 | | /// next. |
58 | 81.3k | void nextLine(const AnnotatedLine &Line) { |
59 | 81.3k | Offset = getIndentOffset(*Line.First); |
60 | | // Update the indent level cache size so that we can rely on it |
61 | | // having the right size in adjustToUnmodifiedline. |
62 | 81.3k | skipLine(Line, /*UnknownIndent=*/true); |
63 | 81.3k | if (Line.InPPDirective) { |
64 | 4.65k | unsigned IndentWidth = |
65 | 4.65k | (Style.PPIndentWidth >= 0) ? Style.PPIndentWidth27 : Style.IndentWidth4.62k ; |
66 | 4.65k | Indent = Line.Level * IndentWidth + AdditionalIndent; |
67 | 76.6k | } else { |
68 | 76.6k | Indent = getIndent(Line.Level); |
69 | 76.6k | } |
70 | 81.3k | if (static_cast<int>(Indent) + Offset >= 0) |
71 | 81.3k | Indent += Offset; |
72 | 81.3k | if (Line.First->is(TT_CSharpGenericTypeConstraint)) |
73 | 12 | Indent = Line.Level * Style.IndentWidth + Style.ContinuationIndentWidth; |
74 | 81.3k | } |
75 | | |
76 | | /// Update the indent state given that \p Line indent should be |
77 | | /// skipped. |
78 | 81.3k | void skipLine(const AnnotatedLine &Line, bool UnknownIndent = false) { |
79 | 81.3k | if (Line.Level >= IndentForLevel.size()) |
80 | 30.8k | IndentForLevel.resize(Line.Level + 1, UnknownIndent ? -130.8k : Indent4 ); |
81 | 81.3k | } |
82 | | |
83 | | /// Update the level indent to adapt to the given \p Line. |
84 | | /// |
85 | | /// When a line is not formatted, we move the subsequent lines on the same |
86 | | /// level to the same indent. |
87 | | /// Note that \c nextLine must have been called before this method. |
88 | 5.19k | void adjustToUnmodifiedLine(const AnnotatedLine &Line) { |
89 | 5.19k | unsigned LevelIndent = Line.First->OriginalColumn; |
90 | 5.19k | if (static_cast<int>(LevelIndent) - Offset >= 0) |
91 | 5.19k | LevelIndent -= Offset; |
92 | 5.19k | assert(Line.Level < IndentForLevel.size()); |
93 | 5.19k | if ((!Line.First->is(tok::comment) || IndentForLevel[Line.Level] == -111 ) && |
94 | 5.19k | !Line.InPPDirective5.19k ) { |
95 | 4.77k | IndentForLevel[Line.Level] = LevelIndent; |
96 | 4.77k | } |
97 | 5.19k | } |
98 | | |
99 | | private: |
100 | | /// Get the offset of the line relatively to the level. |
101 | | /// |
102 | | /// For example, 'public:' labels in classes are offset by 1 or 2 |
103 | | /// characters to the left from their level. |
104 | 81.3k | int getIndentOffset(const FormatToken &RootToken) { |
105 | 81.3k | if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript()80.3k || |
106 | 81.3k | Style.isCSharp()75.7k ) { |
107 | 8.21k | return 0; |
108 | 8.21k | } |
109 | | |
110 | 73.1k | auto IsAccessModifier = [this, &RootToken]() { |
111 | 73.1k | if (RootToken.isAccessSpecifier(Style.isCpp())) { |
112 | 642 | return true; |
113 | 72.4k | } else if (RootToken.isObjCAccessSpecifier()) { |
114 | 49 | return true; |
115 | 49 | } |
116 | | // Handle Qt signals. |
117 | 72.4k | else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && |
118 | 72.4k | RootToken.Next15 && RootToken.Next->is(tok::colon)15 )) { |
119 | 6 | return true; |
120 | 72.4k | } else if (RootToken.Next && |
121 | 72.4k | RootToken.Next->isOneOf(Keywords.kw_slots, |
122 | 44.6k | Keywords.kw_qslots) && |
123 | 72.4k | RootToken.Next->Next18 && RootToken.Next->Next->is(tok::colon)18 ) { |
124 | 18 | return true; |
125 | 18 | } |
126 | | // Handle malformed access specifier e.g. 'private' without trailing ':'. |
127 | 72.4k | else if (!RootToken.Next && RootToken.isAccessSpecifier(false)27.8k ) { |
128 | 15 | return true; |
129 | 15 | } |
130 | 72.3k | return false; |
131 | 73.1k | }; |
132 | | |
133 | 73.1k | if (IsAccessModifier()) { |
134 | | // The AccessModifierOffset may be overridden by IndentAccessModifiers, |
135 | | // in which case we take a negative value of the IndentWidth to simulate |
136 | | // the upper indent level. |
137 | 730 | return Style.IndentAccessModifiers ? -Style.IndentWidth15 |
138 | 730 | : Style.AccessModifierOffset715 ; |
139 | 730 | } |
140 | 72.3k | return 0; |
141 | 73.1k | } |
142 | | |
143 | | /// Get the indent of \p Level from \p IndentForLevel. |
144 | | /// |
145 | | /// \p IndentForLevel must contain the indent for the level \c l |
146 | | /// at \p IndentForLevel[l], or a value < 0 if the indent for |
147 | | /// that level is unknown. |
148 | 95.2k | unsigned getIndent(unsigned Level) const { |
149 | 95.2k | if (IndentForLevel[Level] != -1) |
150 | 10.1k | return IndentForLevel[Level]; |
151 | 85.0k | if (Level == 0) |
152 | 66.5k | return 0; |
153 | 18.5k | return getIndent(Level - 1) + Style.IndentWidth; |
154 | 85.0k | } |
155 | | |
156 | | const FormatStyle &Style; |
157 | | const AdditionalKeywords &Keywords; |
158 | | const unsigned AdditionalIndent; |
159 | | |
160 | | /// The indent in characters for each level. |
161 | | SmallVector<int> IndentForLevel; |
162 | | |
163 | | /// Offset of the current line relative to the indent level. |
164 | | /// |
165 | | /// For example, the 'public' keywords is often indented with a negative |
166 | | /// offset. |
167 | | int Offset = 0; |
168 | | |
169 | | /// The current line's indent. |
170 | | unsigned Indent = 0; |
171 | | }; |
172 | | |
173 | | const FormatToken *getMatchingNamespaceToken( |
174 | | const AnnotatedLine *Line, |
175 | 80 | const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { |
176 | 80 | if (!Line->startsWith(tok::r_brace)) |
177 | 31 | return nullptr; |
178 | 49 | size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex; |
179 | 49 | if (StartLineIndex == UnwrappedLine::kInvalidIndex) |
180 | 0 | return nullptr; |
181 | 49 | assert(StartLineIndex < AnnotatedLines.size()); |
182 | 0 | return AnnotatedLines[StartLineIndex]->First->getNamespaceToken(); |
183 | 49 | } |
184 | | |
185 | 61 | StringRef getNamespaceTokenText(const AnnotatedLine *Line) { |
186 | 61 | const FormatToken *NamespaceToken = Line->First->getNamespaceToken(); |
187 | 61 | return NamespaceToken ? NamespaceToken->TokenText31 : StringRef()30 ; |
188 | 61 | } |
189 | | |
190 | | StringRef getMatchingNamespaceTokenText( |
191 | | const AnnotatedLine *Line, |
192 | 49 | const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { |
193 | 49 | const FormatToken *NamespaceToken = |
194 | 49 | getMatchingNamespaceToken(Line, AnnotatedLines); |
195 | 49 | return NamespaceToken ? NamespaceToken->TokenText26 : StringRef()23 ; |
196 | 49 | } |
197 | | |
198 | | class LineJoiner { |
199 | | public: |
200 | | LineJoiner(const FormatStyle &Style, const AdditionalKeywords &Keywords, |
201 | | const SmallVectorImpl<AnnotatedLine *> &Lines) |
202 | | : Style(Style), Keywords(Keywords), End(Lines.end()), Next(Lines.begin()), |
203 | 25.5k | AnnotatedLines(Lines) {} |
204 | | |
205 | | /// Returns the next line, merging multiple lines into one if possible. |
206 | | const AnnotatedLine *getNextMergedLine(bool DryRun, |
207 | 106k | LevelIndentTracker &IndentTracker) { |
208 | 106k | if (Next == End) |
209 | 24.9k | return nullptr; |
210 | 81.3k | const AnnotatedLine *Current = *Next; |
211 | 81.3k | IndentTracker.nextLine(*Current); |
212 | 81.3k | unsigned MergedLines = tryFitMultipleLinesInOne(IndentTracker, Next, End); |
213 | 81.3k | if (MergedLines > 0 && Style.ColumnLimit == 05.98k ) { |
214 | | // Disallow line merging if there is a break at the start of one of the |
215 | | // input lines. |
216 | 97 | for (unsigned i = 0; i < MergedLines; ++i55 ) |
217 | 55 | if (Next[i + 1]->First->NewlinesBefore > 0) |
218 | 2 | MergedLines = 0; |
219 | 42 | } |
220 | 81.3k | if (!DryRun) |
221 | 85.6k | for (unsigned i = 0; 78.3k i < MergedLines; ++i7.33k ) |
222 | 7.33k | join(*Next[0], *Next[i + 1]); |
223 | 81.3k | Next = Next + MergedLines + 1; |
224 | 81.3k | return Current; |
225 | 106k | } |
226 | | |
227 | | private: |
228 | | /// Calculates how many lines can be merged into 1 starting at \p I. |
229 | | unsigned |
230 | | tryFitMultipleLinesInOne(LevelIndentTracker &IndentTracker, |
231 | | SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
232 | 81.3k | SmallVectorImpl<AnnotatedLine *>::const_iterator E) { |
233 | 81.3k | const unsigned Indent = IndentTracker.getIndent(); |
234 | | |
235 | | // Can't join the last line with anything. |
236 | 81.3k | if (I + 1 == E) |
237 | 24.7k | return 0; |
238 | | // We can never merge stuff if there are trailing line comments. |
239 | 56.5k | const AnnotatedLine *TheLine = *I; |
240 | 56.5k | if (TheLine->Last->is(TT_LineComment)) |
241 | 2.69k | return 0; |
242 | 53.8k | const auto &NextLine = *I[1]; |
243 | 53.8k | if (NextLine.Type == LT_Invalid || NextLine.First->MustBreakBefore53.8k ) |
244 | 1.27k | return 0; |
245 | 52.6k | if (TheLine->InPPDirective && |
246 | 52.6k | (3.45k !NextLine.InPPDirective3.45k || NextLine.First->HasUnescapedNewline1.99k )) { |
247 | 2.16k | return 0; |
248 | 2.16k | } |
249 | | |
250 | 50.4k | if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit49.2k ) |
251 | 0 | return 0; |
252 | | |
253 | 50.4k | unsigned Limit = |
254 | 50.4k | Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent49.2k ; |
255 | | // If we already exceed the column limit, we set 'Limit' to 0. The different |
256 | | // tryMerge..() functions can then decide whether to still do merging. |
257 | 50.4k | Limit = TheLine->Last->TotalLength > Limit |
258 | 50.4k | ? 06.33k |
259 | 50.4k | : Limit - TheLine->Last->TotalLength44.0k ; |
260 | | |
261 | 50.4k | if (TheLine->Last->is(TT_FunctionLBrace) && |
262 | 50.4k | TheLine->First == TheLine->Last4.84k && |
263 | 50.4k | !Style.BraceWrapping.SplitEmptyFunction455 && |
264 | 50.4k | NextLine.First->is(tok::r_brace)27 ) { |
265 | 12 | return tryMergeSimpleBlock(I, E, Limit); |
266 | 12 | } |
267 | | |
268 | 50.4k | const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1]28.5k : nullptr21.8k ; |
269 | | // Handle empty record blocks where the brace has already been wrapped. |
270 | 50.4k | if (PreviousLine && TheLine->Last->is(tok::l_brace)28.5k && |
271 | 50.4k | TheLine->First == TheLine->Last6.94k ) { |
272 | 1.55k | bool EmptyBlock = NextLine.First->is(tok::r_brace); |
273 | | |
274 | 1.55k | const FormatToken *Tok = PreviousLine->First; |
275 | 1.55k | if (Tok && Tok->is(tok::comment)) |
276 | 33 | Tok = Tok->getNextNonComment(); |
277 | | |
278 | 1.55k | if (Tok && Tok->getNamespaceToken()1.55k ) { |
279 | 80 | return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock18 |
280 | 80 | ? tryMergeSimpleBlock(I, E, Limit)15 |
281 | 80 | : 065 ; |
282 | 80 | } |
283 | | |
284 | 1.47k | if (Tok && Tok->is(tok::kw_typedef)1.47k ) |
285 | 21 | Tok = Tok->getNextNonComment(); |
286 | 1.47k | if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union, |
287 | 1.47k | tok::kw_extern, Keywords.kw_interface)) { |
288 | 174 | return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock60 |
289 | 174 | ? tryMergeSimpleBlock(I, E, Limit)30 |
290 | 174 | : 0144 ; |
291 | 174 | } |
292 | | |
293 | 1.30k | if (Tok && Tok->is(tok::kw_template)1.29k && |
294 | 1.30k | Style.BraceWrapping.SplitEmptyRecord36 && EmptyBlock30 ) { |
295 | 9 | return 0; |
296 | 9 | } |
297 | 1.30k | } |
298 | | |
299 | 50.1k | auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine, |
300 | 50.1k | TheLine]() { |
301 | 50.1k | if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All) |
302 | 42.4k | return true; |
303 | 7.66k | if (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && |
304 | 7.66k | NextLine.First->is(tok::r_brace)6.21k ) { |
305 | 1.19k | return true; |
306 | 1.19k | } |
307 | | |
308 | 6.47k | if (Style.AllowShortFunctionsOnASingleLine & |
309 | 6.47k | FormatStyle::SFS_InlineOnly) { |
310 | | // Just checking TheLine->Level != 0 is not enough, because it |
311 | | // provokes treating functions inside indented namespaces as short. |
312 | 540 | if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace)20 ) |
313 | 4 | return true; |
314 | | |
315 | 536 | if (TheLine->Level != 0) { |
316 | 167 | if (!PreviousLine) |
317 | 0 | return false; |
318 | | |
319 | | // TODO: Use IndentTracker to avoid loop? |
320 | | // Find the last line with lower level. |
321 | 167 | const AnnotatedLine *Line = nullptr; |
322 | 200 | for (auto J = I - 1; J >= AnnotatedLines.begin(); --J33 ) { |
323 | 191 | assert(*J); |
324 | 191 | if (!(*J)->InPPDirective && !(*J)->isComment()182 && |
325 | 191 | (*J)->Level < TheLine->Level170 ) { |
326 | 158 | Line = *J; |
327 | 158 | break; |
328 | 158 | } |
329 | 191 | } |
330 | | |
331 | 167 | if (!Line) |
332 | 9 | return false; |
333 | | |
334 | | // Check if the found line starts a record. |
335 | 158 | const FormatToken *LastNonComment = Line->Last; |
336 | 158 | assert(LastNonComment); |
337 | 158 | if (LastNonComment->is(tok::comment)) { |
338 | 12 | LastNonComment = LastNonComment->getPreviousNonComment(); |
339 | | // There must be another token (usually `{`), because we chose a |
340 | | // non-PPDirective and non-comment line that has a smaller level. |
341 | 12 | assert(LastNonComment); |
342 | 12 | } |
343 | 0 | return isRecordLBrace(*LastNonComment); |
344 | 167 | } |
345 | 536 | } |
346 | | |
347 | 6.29k | return false; |
348 | 6.47k | }; |
349 | | |
350 | 50.1k | bool MergeShortFunctions = ShouldMergeShortFunctions(); |
351 | | |
352 | 50.1k | const FormatToken *FirstNonComment = TheLine->First; |
353 | 50.1k | if (FirstNonComment->is(tok::comment)) { |
354 | 467 | FirstNonComment = FirstNonComment->getNextNonComment(); |
355 | 467 | if (!FirstNonComment) |
356 | 371 | return 0; |
357 | 467 | } |
358 | | // FIXME: There are probably cases where we should use FirstNonComment |
359 | | // instead of TheLine->First. |
360 | | |
361 | 49.7k | if (Style.CompactNamespaces) { |
362 | 68 | if (auto nsToken = TheLine->First->getNamespaceToken()) { |
363 | 37 | int i = 0; |
364 | 37 | unsigned closingLine = TheLine->MatchingClosingBlockLineIndex - 1; |
365 | 61 | for (; I + 1 + i != E && |
366 | 61 | nsToken->TokenText == getNamespaceTokenText(I[i + 1]) && |
367 | 61 | closingLine == I[i + 1]->MatchingClosingBlockLineIndex28 && |
368 | 61 | I[i + 1]->Last->TotalLength < Limit26 ; |
369 | 37 | i++, --closingLine24 ) { |
370 | | // No extra indent for compacted namespaces. |
371 | 24 | IndentTracker.skipLine(*I[i + 1]); |
372 | | |
373 | 24 | Limit -= I[i + 1]->Last->TotalLength; |
374 | 24 | } |
375 | 37 | return i; |
376 | 37 | } |
377 | | |
378 | 31 | if (auto nsToken = getMatchingNamespaceToken(TheLine, AnnotatedLines)) { |
379 | 23 | int i = 0; |
380 | 23 | unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1; |
381 | 49 | for (; I + 1 + i != E && |
382 | 49 | nsToken->TokenText == |
383 | 49 | getMatchingNamespaceTokenText(I[i + 1], AnnotatedLines) && |
384 | 49 | openingLine == I[i + 1]->MatchingOpeningBlockLineIndex26 ; |
385 | 26 | i++, --openingLine) { |
386 | | // No space between consecutive braces. |
387 | 26 | I[i + 1]->First->SpacesRequiredBefore = !I[i]->Last->is(tok::r_brace); |
388 | | |
389 | | // Indent like the outer-most namespace. |
390 | 26 | IndentTracker.nextLine(*I[i + 1]); |
391 | 26 | } |
392 | 23 | return i; |
393 | 23 | } |
394 | 31 | } |
395 | | |
396 | | // Try to merge a function block with left brace unwrapped. |
397 | 49.7k | if (TheLine->Last->is(TT_FunctionLBrace) && TheLine->First != TheLine->Last4.83k ) |
398 | 4.39k | return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit)4.07k : 0315 ; |
399 | | // Try to merge a control statement block with left brace unwrapped. |
400 | 45.3k | if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last8.11k && |
401 | 45.3k | FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, |
402 | 6.52k | TT_ForEachMacro)) { |
403 | 1.29k | return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never |
404 | 1.29k | ? tryMergeSimpleBlock(I, E, Limit)164 |
405 | 1.29k | : 01.12k ; |
406 | 1.29k | } |
407 | | // Try to merge a control statement block with left brace wrapped. |
408 | 44.0k | if (NextLine.First->is(tok::l_brace)) { |
409 | 1.66k | if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, |
410 | 1.66k | tok::kw_for, tok::kw_switch, tok::kw_try, |
411 | 1.66k | tok::kw_do, TT_ForEachMacro) || |
412 | 1.66k | (1.28k TheLine->First->is(tok::r_brace)1.28k && TheLine->First->Next31 && |
413 | 1.28k | TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch)31 )) && |
414 | 1.66k | Style.BraceWrapping.AfterControlStatement == |
415 | 414 | FormatStyle::BWACS_MultiLine) { |
416 | | // If possible, merge the next line's wrapped left brace with the |
417 | | // current line. Otherwise, leave it on the next line, as this is a |
418 | | // multi-line control statement. |
419 | 37 | return (Style.ColumnLimit == 0 || TheLine->Level * Style.IndentWidth + |
420 | 37 | TheLine->Last->TotalLength <= |
421 | 37 | Style.ColumnLimit) |
422 | 37 | ? 124 |
423 | 37 | : 013 ; |
424 | 37 | } |
425 | 1.62k | if (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, |
426 | 1.62k | tok::kw_for, TT_ForEachMacro)) { |
427 | 296 | return (Style.BraceWrapping.AfterControlStatement == |
428 | 296 | FormatStyle::BWACS_Always) |
429 | 296 | ? tryMergeSimpleBlock(I, E, Limit)292 |
430 | 296 | : 04 ; |
431 | 296 | } |
432 | 1.33k | if (TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) && |
433 | 1.33k | Style.BraceWrapping.AfterControlStatement == |
434 | 14 | FormatStyle::BWACS_MultiLine) { |
435 | | // This case if different from the upper BWACS_MultiLine processing |
436 | | // in that a preceding r_brace is not on the same line as else/catch |
437 | | // most likely because of BeforeElse/BeforeCatch set to true. |
438 | | // If the line length doesn't fit ColumnLimit, leave l_brace on the |
439 | | // next line to respect the BWACS_MultiLine. |
440 | 1 | return (Style.ColumnLimit == 0 || |
441 | 1 | TheLine->Last->TotalLength <= Style.ColumnLimit) |
442 | 1 | ? 1 |
443 | 1 | : 00 ; |
444 | 1 | } |
445 | 1.33k | } |
446 | 43.7k | if (PreviousLine && TheLine->First->is(tok::l_brace)25.6k ) { |
447 | 1.31k | switch (PreviousLine->First->Tok.getKind()) { |
448 | 17 | case tok::at: |
449 | | // Don't merge block with left brace wrapped after ObjC special blocks. |
450 | 17 | if (PreviousLine->First->Next) { |
451 | 17 | tok::ObjCKeywordKind kwId = |
452 | 17 | PreviousLine->First->Next->Tok.getObjCKeywordID(); |
453 | 17 | if (kwId == tok::objc_autoreleasepool || |
454 | 17 | kwId == tok::objc_synchronized13 ) { |
455 | 8 | return 0; |
456 | 8 | } |
457 | 17 | } |
458 | 9 | break; |
459 | | |
460 | 40 | case tok::kw_case: |
461 | 50 | case tok::kw_default: |
462 | | // Don't merge block with left brace wrapped after case labels. |
463 | 50 | return 0; |
464 | | |
465 | 1.24k | default: |
466 | 1.24k | break; |
467 | 1.31k | } |
468 | 1.31k | } |
469 | | |
470 | | // Don't merge an empty template class or struct if SplitEmptyRecords |
471 | | // is defined. |
472 | 43.6k | if (PreviousLine && Style.BraceWrapping.SplitEmptyRecord25.6k && |
473 | 43.6k | TheLine->Last->is(tok::l_brace)25.1k && PreviousLine->Last4.28k ) { |
474 | 4.28k | const FormatToken *Previous = PreviousLine->Last; |
475 | 4.28k | if (Previous) { |
476 | 4.28k | if (Previous->is(tok::comment)) |
477 | 313 | Previous = Previous->getPreviousNonComment(); |
478 | 4.28k | if (Previous) { |
479 | 4.20k | if (Previous->is(tok::greater) && !PreviousLine->InPPDirective21 ) |
480 | 14 | return 0; |
481 | 4.18k | if (Previous->is(tok::identifier)) { |
482 | 333 | const FormatToken *PreviousPrevious = |
483 | 333 | Previous->getPreviousNonComment(); |
484 | 333 | if (PreviousPrevious && |
485 | 333 | PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)330 ) { |
486 | 40 | return 0; |
487 | 40 | } |
488 | 333 | } |
489 | 4.18k | } |
490 | 4.28k | } |
491 | 4.28k | } |
492 | | |
493 | 43.5k | if (TheLine->Last->is(tok::l_brace)) { |
494 | 6.71k | bool ShouldMerge = false; |
495 | | // Try to merge records. |
496 | 6.71k | if (TheLine->Last->is(TT_EnumLBrace)) { |
497 | 78 | ShouldMerge = Style.AllowShortEnumsOnASingleLine; |
498 | 6.63k | } else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace)) { |
499 | | // NOTE: We use AfterClass (whereas AfterStruct exists) for both classes |
500 | | // and structs, but it seems that wrapping is still handled correctly |
501 | | // elsewhere. |
502 | 2.50k | ShouldMerge = !Style.BraceWrapping.AfterClass || |
503 | 2.50k | (16 NextLine.First->is(tok::r_brace)16 && |
504 | 16 | !Style.BraceWrapping.SplitEmptyRecord5 ); |
505 | 4.13k | } else { |
506 | | // Try to merge a block with left brace unwrapped that wasn't yet |
507 | | // covered. |
508 | 4.13k | assert(TheLine->InPPDirective || |
509 | 4.13k | !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum, |
510 | 4.13k | tok::kw_struct)); |
511 | 4.13k | ShouldMerge = !Style.BraceWrapping.AfterFunction || |
512 | 4.13k | (848 NextLine.First->is(tok::r_brace)848 && |
513 | 848 | !Style.BraceWrapping.SplitEmptyFunction129 ); |
514 | 4.13k | } |
515 | 6.71k | return ShouldMerge ? tryMergeSimpleBlock(I, E, Limit)5.79k : 0917 ; |
516 | 6.71k | } |
517 | | |
518 | | // Try to merge a function block with left brace wrapped. |
519 | 36.8k | if (NextLine.First->is(TT_FunctionLBrace) && |
520 | 36.8k | Style.BraceWrapping.AfterFunction560 ) { |
521 | 558 | if (NextLine.Last->is(TT_LineComment)) |
522 | 6 | return 0; |
523 | | |
524 | | // Check for Limit <= 2 to account for the " {". |
525 | 552 | if (Limit <= 2 || (484 Style.ColumnLimit == 0484 && containsMustBreak(TheLine)97 )) |
526 | 87 | return 0; |
527 | 465 | Limit -= 2; |
528 | | |
529 | 465 | unsigned MergedLines = 0; |
530 | 465 | if (MergeShortFunctions || |
531 | 465 | (242 Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty242 && |
532 | 242 | NextLine.First == NextLine.Last96 && I + 2 != E96 && |
533 | 244 | I[2]->First->is(tok::r_brace)96 )) { |
534 | 244 | MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); |
535 | | // If we managed to merge the block, count the function header, which is |
536 | | // on a separate line. |
537 | 244 | if (MergedLines > 0) |
538 | 150 | ++MergedLines; |
539 | 244 | } |
540 | 465 | return MergedLines; |
541 | 552 | } |
542 | 36.3k | auto IsElseLine = [&TheLine]() -> bool { |
543 | 35.4k | const FormatToken *First = TheLine->First; |
544 | 35.4k | if (First->is(tok::kw_else)) |
545 | 344 | return true; |
546 | | |
547 | 35.0k | return First->is(tok::r_brace) && First->Next6.78k && |
548 | 35.0k | First->Next->is(tok::kw_else)2.05k ; |
549 | 35.4k | }; |
550 | 36.3k | if (TheLine->First->is(tok::kw_if) || |
551 | 36.3k | (35.4k IsElseLine()35.4k && (Style.AllowShortIfStatementsOnASingleLine == |
552 | 1.05k | FormatStyle::SIS_AllIfsAndElse))) { |
553 | 1.05k | return Style.AllowShortIfStatementsOnASingleLine |
554 | 1.05k | ? tryMergeSimpleControlStatement(I, E, Limit)539 |
555 | 1.05k | : 0517 ; |
556 | 1.05k | } |
557 | 35.2k | if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do, |
558 | 35.2k | TT_ForEachMacro)) { |
559 | 448 | return Style.AllowShortLoopsOnASingleLine |
560 | 448 | ? tryMergeSimpleControlStatement(I, E, Limit)91 |
561 | 448 | : 0357 ; |
562 | 448 | } |
563 | 34.8k | if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) { |
564 | 376 | return Style.AllowShortCaseLabelsOnASingleLine |
565 | 376 | ? tryMergeShortCaseLabels(I, E, Limit)87 |
566 | 376 | : 0289 ; |
567 | 376 | } |
568 | 34.4k | if (TheLine->InPPDirective && |
569 | 34.4k | (1.18k TheLine->First->HasUnescapedNewline1.18k || TheLine->First->IsFirst698 )) { |
570 | 964 | return tryMergeSimplePPDirective(I, E, Limit); |
571 | 964 | } |
572 | 33.4k | return 0; |
573 | 34.4k | } |
574 | | |
575 | | unsigned |
576 | | tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
577 | | SmallVectorImpl<AnnotatedLine *>::const_iterator E, |
578 | 964 | unsigned Limit) { |
579 | 964 | if (Limit == 0) |
580 | 3 | return 0; |
581 | 961 | if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline416 ) |
582 | 175 | return 0; |
583 | 786 | if (1 + I[1]->Last->TotalLength > Limit) |
584 | 70 | return 0; |
585 | 716 | return 1; |
586 | 786 | } |
587 | | |
588 | | unsigned tryMergeSimpleControlStatement( |
589 | | SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
590 | 630 | SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) { |
591 | 630 | if (Limit == 0) |
592 | 10 | return 0; |
593 | 620 | if (Style.BraceWrapping.AfterControlStatement == |
594 | 620 | FormatStyle::BWACS_Always && |
595 | 620 | I[1]->First->is(tok::l_brace)12 && |
596 | 620 | Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never0 ) { |
597 | 0 | return 0; |
598 | 0 | } |
599 | 620 | if (I[1]->InPPDirective != (*I)->InPPDirective || |
600 | 620 | (617 I[1]->InPPDirective617 && I[1]->First->HasUnescapedNewline21 )) { |
601 | 3 | return 0; |
602 | 3 | } |
603 | 617 | Limit = limitConsideringMacros(I + 1, E, Limit); |
604 | 617 | AnnotatedLine &Line = **I; |
605 | 617 | if (!Line.First->is(tok::kw_do) && !Line.First->is(tok::kw_else)608 && |
606 | 617 | !Line.Last->is(tok::kw_else)518 && Line.Last->isNot(tok::r_paren)491 ) { |
607 | 34 | return 0; |
608 | 34 | } |
609 | | // Only merge `do while` if `do` is the only statement on the line. |
610 | 583 | if (Line.First->is(tok::kw_do) && !Line.Last->is(tok::kw_do)9 ) |
611 | 3 | return 0; |
612 | 580 | if (1 + I[1]->Last->TotalLength > Limit) |
613 | 15 | return 0; |
614 | | // Don't merge with loops, ifs, a single semicolon or a line comment. |
615 | 565 | if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while, |
616 | 565 | TT_ForEachMacro, TT_LineComment)) { |
617 | 78 | return 0; |
618 | 78 | } |
619 | | // Only inline simple if's (no nested if or else), unless specified |
620 | 487 | if (Style.AllowShortIfStatementsOnASingleLine == |
621 | 487 | FormatStyle::SIS_WithoutElse) { |
622 | 154 | if (I + 2 != E && Line.startsWith(tok::kw_if)142 && |
623 | 154 | I[2]->First->is(tok::kw_else)138 ) { |
624 | 62 | return 0; |
625 | 62 | } |
626 | 154 | } |
627 | 425 | return 1; |
628 | 487 | } |
629 | | |
630 | | unsigned |
631 | | tryMergeShortCaseLabels(SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
632 | | SmallVectorImpl<AnnotatedLine *>::const_iterator E, |
633 | 87 | unsigned Limit) { |
634 | 87 | if (Limit == 0 || I + 1 == E || |
635 | 87 | I[1]->First->isOneOf(tok::kw_case, tok::kw_default)) { |
636 | 12 | return 0; |
637 | 12 | } |
638 | 75 | if (I[0]->Last->is(tok::l_brace) || I[1]->First->is(tok::l_brace)) |
639 | 2 | return 0; |
640 | 73 | unsigned NumStmts = 0; |
641 | 73 | unsigned Length = 0; |
642 | 73 | bool EndsWithComment = false; |
643 | 73 | bool InPPDirective = I[0]->InPPDirective; |
644 | 73 | const unsigned Level = I[0]->Level; |
645 | 155 | for (; NumStmts < 3; ++NumStmts82 ) { |
646 | 155 | if (I + 1 + NumStmts == E) |
647 | 0 | break; |
648 | 155 | const AnnotatedLine *Line = I[1 + NumStmts]; |
649 | 155 | if (Line->InPPDirective != InPPDirective) |
650 | 4 | break; |
651 | 151 | if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace)) |
652 | 43 | break; |
653 | 108 | if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch, |
654 | 108 | tok::kw_while) || |
655 | 108 | EndsWithComment105 ) { |
656 | 11 | return 0; |
657 | 11 | } |
658 | 97 | if (Line->First->is(tok::comment)) { |
659 | 15 | if (Level != Line->Level) |
660 | 7 | return 0; |
661 | 8 | SmallVectorImpl<AnnotatedLine *>::const_iterator J = I + 2 + NumStmts; |
662 | 8 | for (; J != E; ++J0 ) { |
663 | 8 | Line = *J; |
664 | 8 | if (Line->InPPDirective != InPPDirective) |
665 | 1 | break; |
666 | 7 | if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace)) |
667 | 7 | break; |
668 | 0 | if (Line->First->isNot(tok::comment) || Level != Line->Level) |
669 | 0 | return 0; |
670 | 0 | } |
671 | 8 | break; |
672 | 8 | } |
673 | 82 | if (Line->Last->is(tok::comment)) |
674 | 21 | EndsWithComment = true; |
675 | 82 | Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space. |
676 | 82 | } |
677 | 55 | if (NumStmts == 0 || NumStmts == 3 || Length > Limit) |
678 | 7 | return 0; |
679 | 48 | return NumStmts; |
680 | 55 | } |
681 | | |
682 | | unsigned |
683 | | tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
684 | | SmallVectorImpl<AnnotatedLine *>::const_iterator E, |
685 | 10.7k | unsigned Limit) { |
686 | | // Don't merge with a preprocessor directive. |
687 | 10.7k | if (I[1]->Type == LT_PreprocessorDirective) |
688 | 86 | return 0; |
689 | | |
690 | 10.6k | AnnotatedLine &Line = **I; |
691 | | |
692 | | // Don't merge ObjC @ keywords and methods. |
693 | | // FIXME: If an option to allow short exception handling clauses on a single |
694 | | // line is added, change this to not return for @try and friends. |
695 | 10.6k | if (Style.Language != FormatStyle::LK_Java && |
696 | 10.6k | Line.First->isOneOf(tok::at, tok::minus, tok::plus)10.4k ) { |
697 | 153 | return 0; |
698 | 153 | } |
699 | | |
700 | | // Check that the current line allows merging. This depends on whether we |
701 | | // are in a control flow statements as well as several style flags. |
702 | 10.4k | if (Line.First->is(tok::kw_case) || |
703 | 10.4k | (10.4k Line.First->Next10.4k && Line.First->Next->is(tok::kw_else)9.28k )) { |
704 | 388 | return 0; |
705 | 388 | } |
706 | | // default: in switch statement |
707 | 10.0k | if (Line.First->is(tok::kw_default)) { |
708 | 28 | const FormatToken *Tok = Line.First->getNextNonComment(); |
709 | 28 | if (Tok && Tok->is(tok::colon)) |
710 | 26 | return 0; |
711 | 28 | } |
712 | 10.0k | if (Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_do, |
713 | 10.0k | tok::kw_try, tok::kw___try, tok::kw_catch, |
714 | 10.0k | tok::kw___finally, tok::kw_for, TT_ForEachMacro, |
715 | 10.0k | tok::r_brace, Keywords.kw___except)) { |
716 | 881 | if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) |
717 | 567 | return 0; |
718 | 314 | if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Empty && |
719 | 314 | !I[1]->First->is(tok::r_brace)46 ) { |
720 | 24 | return 0; |
721 | 24 | } |
722 | | // Don't merge when we can't except the case when |
723 | | // the control statement block is empty |
724 | 290 | if (!Style.AllowShortIfStatementsOnASingleLine && |
725 | 290 | Line.First->isOneOf(tok::kw_if, tok::kw_else)103 && |
726 | 290 | !Style.BraceWrapping.AfterControlStatement48 && |
727 | 290 | !I[1]->First->is(tok::r_brace)30 ) { |
728 | 12 | return 0; |
729 | 12 | } |
730 | 278 | if (!Style.AllowShortIfStatementsOnASingleLine && |
731 | 278 | Line.First->isOneOf(tok::kw_if, tok::kw_else)91 && |
732 | 278 | Style.BraceWrapping.AfterControlStatement == |
733 | 36 | FormatStyle::BWACS_Always && |
734 | 278 | I + 2 != E18 && !I[2]->First->is(tok::r_brace)18 ) { |
735 | 12 | return 0; |
736 | 12 | } |
737 | 266 | if (!Style.AllowShortLoopsOnASingleLine && |
738 | 266 | Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for, |
739 | 65 | TT_ForEachMacro) && |
740 | 266 | !Style.BraceWrapping.AfterControlStatement44 && |
741 | 266 | !I[1]->First->is(tok::r_brace)26 ) { |
742 | 15 | return 0; |
743 | 15 | } |
744 | 251 | if (!Style.AllowShortLoopsOnASingleLine && |
745 | 251 | Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for, |
746 | 50 | TT_ForEachMacro) && |
747 | 251 | Style.BraceWrapping.AfterControlStatement == |
748 | 29 | FormatStyle::BWACS_Always && |
749 | 251 | I + 2 != E18 && !I[2]->First->is(tok::r_brace)18 ) { |
750 | 9 | return 0; |
751 | 9 | } |
752 | | // FIXME: Consider an option to allow short exception handling clauses on |
753 | | // a single line. |
754 | | // FIXME: This isn't covered by tests. |
755 | | // FIXME: For catch, __except, __finally the first token on the line |
756 | | // is '}', so this isn't correct here. |
757 | 242 | if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch, |
758 | 242 | Keywords.kw___except, tok::kw___finally)) { |
759 | 0 | return 0; |
760 | 0 | } |
761 | 242 | } |
762 | | |
763 | 9.43k | if (Line.Last->is(tok::l_brace)) { |
764 | 9.33k | FormatToken *Tok = I[1]->First; |
765 | 9.33k | auto ShouldMerge = [Tok]() { |
766 | 9.33k | if (Tok->isNot(tok::r_brace) || Tok->MustBreakBefore3.12k ) |
767 | 6.20k | return false; |
768 | 3.12k | const FormatToken *Next = Tok->getNextNonComment(); |
769 | 3.12k | return !Next || Next->is(tok::semi)852 ; |
770 | 9.33k | }; |
771 | | |
772 | 9.33k | if (ShouldMerge()) { |
773 | | // We merge empty blocks even if the line exceeds the column limit. |
774 | 2.96k | Tok->SpacesRequiredBefore = Style.SpaceInEmptyBlock ? 116 : 02.94k ; |
775 | 2.96k | Tok->CanBreakBefore = true; |
776 | 2.96k | return 1; |
777 | 6.36k | } else if (Limit != 0 && !Line.startsWithNamespace()6.26k && |
778 | 6.36k | !startsExternCBlock(Line)5.09k ) { |
779 | | // We don't merge short records. |
780 | 5.06k | if (isRecordLBrace(*Line.Last)) |
781 | 1.76k | return 0; |
782 | | |
783 | | // Check that we still have three lines and they fit into the limit. |
784 | 3.29k | if (I + 2 == E || I[2]->Type == LT_Invalid3.26k ) |
785 | 31 | return 0; |
786 | 3.26k | Limit = limitConsideringMacros(I + 2, E, Limit); |
787 | | |
788 | 3.26k | if (!nextTwoLinesFitInto(I, Limit)) |
789 | 576 | return 0; |
790 | | |
791 | | // Second, check that the next line does not contain any braces - if it |
792 | | // does, readability declines when putting it into a single line. |
793 | 2.68k | if (I[1]->Last->is(TT_LineComment)) |
794 | 84 | return 0; |
795 | 15.1k | do 2.60k { |
796 | 15.1k | if (Tok->is(tok::l_brace) && Tok->isNot(BK_BracedInit)209 ) |
797 | 170 | return 0; |
798 | 14.9k | Tok = Tok->Next; |
799 | 14.9k | } while (Tok); |
800 | | |
801 | | // Last, check that the third line starts with a closing brace. |
802 | 2.43k | Tok = I[2]->First; |
803 | 2.43k | if (Tok->isNot(tok::r_brace)) |
804 | 650 | return 0; |
805 | | |
806 | | // Don't merge "if (a) { .. } else {". |
807 | 1.78k | if (Tok->Next && Tok->Next->is(tok::kw_else)511 ) |
808 | 13 | return 0; |
809 | | |
810 | | // Don't merge a trailing multi-line control statement block like: |
811 | | // } else if (foo && |
812 | | // bar) |
813 | | // { <-- current Line |
814 | | // baz(); |
815 | | // } |
816 | 1.77k | if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace)585 && |
817 | 1.77k | Style.BraceWrapping.AfterControlStatement == |
818 | 501 | FormatStyle::BWACS_MultiLine) { |
819 | 11 | return 0; |
820 | 11 | } |
821 | | |
822 | 1.76k | return 2; |
823 | 1.77k | } |
824 | 9.33k | } else if (100 I[1]->First->is(tok::l_brace)100 ) { |
825 | 100 | if (I[1]->Last->is(TT_LineComment)) |
826 | 6 | return 0; |
827 | | |
828 | | // Check for Limit <= 2 to account for the " {". |
829 | 94 | if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(*I)0 )) |
830 | 0 | return 0; |
831 | 94 | Limit -= 2; |
832 | 94 | unsigned MergedLines = 0; |
833 | 94 | if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never || |
834 | 94 | (0 I[1]->First == I[1]->Last0 && I + 2 != E0 && |
835 | 94 | I[2]->First->is(tok::r_brace)0 )) { |
836 | 94 | MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); |
837 | | // If we managed to merge the block, count the statement header, which |
838 | | // is on a separate line. |
839 | 94 | if (MergedLines > 0) |
840 | 69 | ++MergedLines; |
841 | 94 | } |
842 | 94 | return MergedLines; |
843 | 94 | } |
844 | 1.30k | return 0; |
845 | 9.43k | } |
846 | | |
847 | | /// Returns the modified column limit for \p I if it is inside a macro and |
848 | | /// needs a trailing '\'. |
849 | | unsigned |
850 | | limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
851 | | SmallVectorImpl<AnnotatedLine *>::const_iterator E, |
852 | 3.88k | unsigned Limit) { |
853 | 3.88k | if (I[0]->InPPDirective && I + 1 != E81 && |
854 | 3.88k | !I[1]->First->HasUnescapedNewline81 && !I[1]->First->is(tok::eof)63 ) { |
855 | 34 | return Limit < 2 ? 00 : Limit - 2; |
856 | 34 | } |
857 | 3.84k | return Limit; |
858 | 3.88k | } |
859 | | |
860 | | bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I, |
861 | 3.26k | unsigned Limit) { |
862 | 3.26k | if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore) |
863 | 39 | return false; |
864 | 3.22k | return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit; |
865 | 3.26k | } |
866 | | |
867 | 97 | bool containsMustBreak(const AnnotatedLine *Line) { |
868 | 522 | for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next425 ) |
869 | 444 | if (Tok->MustBreakBefore) |
870 | 19 | return true; |
871 | 78 | return false; |
872 | 97 | } |
873 | | |
874 | 7.33k | void join(AnnotatedLine &A, const AnnotatedLine &B) { |
875 | 7.33k | assert(!A.Last->Next); |
876 | 0 | assert(!B.First->Previous); |
877 | 7.33k | if (B.Affected) |
878 | 6.41k | A.Affected = true; |
879 | 7.33k | A.Last->Next = B.First; |
880 | 7.33k | B.First->Previous = A.Last; |
881 | 7.33k | B.First->CanBreakBefore = true; |
882 | 7.33k | unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore; |
883 | 26.4k | for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next19.0k ) { |
884 | 19.0k | Tok->TotalLength += LengthA; |
885 | 19.0k | A.Last = Tok; |
886 | 19.0k | } |
887 | 7.33k | } |
888 | | |
889 | | const FormatStyle &Style; |
890 | | const AdditionalKeywords &Keywords; |
891 | | const SmallVectorImpl<AnnotatedLine *>::const_iterator End; |
892 | | |
893 | | SmallVectorImpl<AnnotatedLine *>::const_iterator Next; |
894 | | const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines; |
895 | | }; |
896 | | |
897 | 80.7k | static void markFinalized(FormatToken *Tok) { |
898 | 470k | for (; Tok; Tok = Tok->Next389k ) { |
899 | 389k | Tok->Finalized = true; |
900 | 389k | for (AnnotatedLine *Child : Tok->Children) |
901 | 2.43k | markFinalized(Child->First); |
902 | 389k | } |
903 | 80.7k | } |
904 | | |
905 | | #ifndef NDEBUG |
906 | 0 | static void printLineState(const LineState &State) { |
907 | 0 | llvm::dbgs() << "State: "; |
908 | 0 | for (const ParenState &P : State.Stack) { |
909 | 0 | llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|" |
910 | 0 | << P.LastSpace << "|" << P.NestedBlockIndent << " "; |
911 | 0 | } |
912 | 0 | llvm::dbgs() << State.NextToken->TokenText << "\n"; |
913 | 0 | } |
914 | | #endif |
915 | | |
916 | | /// Base class for classes that format one \c AnnotatedLine. |
917 | | class LineFormatter { |
918 | | public: |
919 | | LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, |
920 | | const FormatStyle &Style, |
921 | | UnwrappedLineFormatter *BlockFormatter) |
922 | | : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), |
923 | 75.8k | BlockFormatter(BlockFormatter) {} |
924 | 75.8k | virtual ~LineFormatter() {} |
925 | | |
926 | | /// Formats an \c AnnotatedLine and returns the penalty. |
927 | | /// |
928 | | /// If \p DryRun is \c false, directly applies the changes. |
929 | | virtual unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, |
930 | | unsigned FirstStartColumn, bool DryRun) = 0; |
931 | | |
932 | | protected: |
933 | | /// If the \p State's next token is an r_brace closing a nested block, |
934 | | /// format the nested block before it. |
935 | | /// |
936 | | /// Returns \c true if all children could be placed successfully and adapts |
937 | | /// \p Penalty as well as \p State. If \p DryRun is false, also directly |
938 | | /// creates changes using \c Whitespaces. |
939 | | /// |
940 | | /// The crucial idea here is that children always get formatted upon |
941 | | /// encountering the closing brace right after the nested block. Now, if we |
942 | | /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is |
943 | | /// \c false), the entire block has to be kept on the same line (which is only |
944 | | /// possible if it fits on the line, only contains a single statement, etc. |
945 | | /// |
946 | | /// If \p NewLine is true, we format the nested block on separate lines, i.e. |
947 | | /// break after the "{", format all lines with correct indentation and the put |
948 | | /// the closing "}" on yet another new line. |
949 | | /// |
950 | | /// This enables us to keep the simple structure of the |
951 | | /// \c UnwrappedLineFormatter, where we only have two options for each token: |
952 | | /// break or don't break. |
953 | | bool formatChildren(LineState &State, bool NewLine, bool DryRun, |
954 | 1.12M | unsigned &Penalty) { |
955 | 1.12M | const FormatToken *LBrace = State.NextToken->getPreviousNonComment(); |
956 | 1.12M | FormatToken &Previous = *State.NextToken->Previous; |
957 | 1.12M | if (!LBrace || LBrace->isNot(tok::l_brace)1.12M || LBrace->isNot(BK_Block)31.0k || |
958 | 1.12M | Previous.Children.size() == 011.9k ) { |
959 | | // The previous token does not open a block. Nothing to do. We don't |
960 | | // assert so that we can simply call this function for all tokens. |
961 | 1.11M | return true; |
962 | 1.11M | } |
963 | | |
964 | 4.72k | if (NewLine) { |
965 | 3.00k | const ParenState &P = State.Stack.back(); |
966 | | |
967 | 3.00k | int AdditionalIndent = |
968 | 3.00k | P.Indent - Previous.Children[0]->Level * Style.IndentWidth; |
969 | | |
970 | 3.00k | if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope && |
971 | 3.00k | P.NestedBlockIndent == P.LastSpace76 ) { |
972 | 19 | if (State.NextToken->MatchingParen && |
973 | 19 | State.NextToken->MatchingParen->is(TT_LambdaLBrace)) { |
974 | 19 | State.Stack.pop_back(); |
975 | 19 | } |
976 | 19 | if (LBrace->is(TT_LambdaLBrace)) |
977 | 19 | AdditionalIndent = 0; |
978 | 19 | } |
979 | | |
980 | 3.00k | Penalty += |
981 | 3.00k | BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent, |
982 | 3.00k | /*FixBadIndentation=*/true); |
983 | 3.00k | return true; |
984 | 3.00k | } |
985 | | |
986 | 1.72k | if (Previous.Children[0]->First->MustBreakBefore) |
987 | 1 | return false; |
988 | | |
989 | | // Cannot merge into one line if this line ends on a comment. |
990 | 1.72k | if (Previous.is(tok::comment)) |
991 | 0 | return false; |
992 | | |
993 | | // Cannot merge multiple statements into a single line. |
994 | 1.72k | if (Previous.Children.size() > 1) |
995 | 692 | return false; |
996 | | |
997 | 1.03k | const AnnotatedLine *Child = Previous.Children[0]; |
998 | | // We can't put the closing "}" on a line with a trailing comment. |
999 | 1.03k | if (Child->Last->isTrailingComment()) |
1000 | 0 | return false; |
1001 | | |
1002 | | // If the child line exceeds the column limit, we wouldn't want to merge it. |
1003 | | // We add +2 for the trailing " }". |
1004 | 1.03k | if (Style.ColumnLimit > 0 && |
1005 | 1.03k | Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit1.03k ) { |
1006 | 127 | return false; |
1007 | 127 | } |
1008 | | |
1009 | 907 | if (!DryRun) { |
1010 | 608 | Whitespaces->replaceWhitespace( |
1011 | 608 | *Child->First, /*Newlines=*/0, /*Spaces=*/1, |
1012 | 608 | /*StartOfTokenColumn=*/State.Column, /*IsAligned=*/false, |
1013 | 608 | State.Line->InPPDirective); |
1014 | 608 | } |
1015 | 907 | Penalty += |
1016 | 907 | formatLine(*Child, State.Column + 1, /*FirstStartColumn=*/0, DryRun); |
1017 | | |
1018 | 907 | State.Column += 1 + Child->Last->TotalLength; |
1019 | 907 | return true; |
1020 | 1.03k | } |
1021 | | |
1022 | | ContinuationIndenter *Indenter; |
1023 | | |
1024 | | private: |
1025 | | WhitespaceManager *Whitespaces; |
1026 | | const FormatStyle &Style; |
1027 | | UnwrappedLineFormatter *BlockFormatter; |
1028 | | }; |
1029 | | |
1030 | | /// Formatter that keeps the existing line breaks. |
1031 | | class NoColumnLimitLineFormatter : public LineFormatter { |
1032 | | public: |
1033 | | NoColumnLimitLineFormatter(ContinuationIndenter *Indenter, |
1034 | | WhitespaceManager *Whitespaces, |
1035 | | const FormatStyle &Style, |
1036 | | UnwrappedLineFormatter *BlockFormatter) |
1037 | 1.78k | : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} |
1038 | | |
1039 | | /// Formats the line, simply keeping all of the input's line breaking |
1040 | | /// decisions. |
1041 | | unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, |
1042 | 1.78k | unsigned FirstStartColumn, bool DryRun) override { |
1043 | 1.78k | assert(!DryRun); |
1044 | 0 | LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn, |
1045 | 1.78k | &Line, /*DryRun=*/false); |
1046 | 6.16k | while (State.NextToken) { |
1047 | 4.38k | bool Newline = |
1048 | 4.38k | Indenter->mustBreak(State) || |
1049 | 4.38k | (4.02k Indenter->canBreak(State)4.02k && State.NextToken->NewlinesBefore > 01.11k ); |
1050 | 4.38k | unsigned Penalty = 0; |
1051 | 4.38k | formatChildren(State, Newline, /*DryRun=*/false, Penalty); |
1052 | 4.38k | Indenter->addTokenToState(State, Newline, /*DryRun=*/false); |
1053 | 4.38k | } |
1054 | 1.78k | return 0; |
1055 | 1.78k | } |
1056 | | }; |
1057 | | |
1058 | | /// Formatter that puts all tokens into a single line without breaks. |
1059 | | class NoLineBreakFormatter : public LineFormatter { |
1060 | | public: |
1061 | | NoLineBreakFormatter(ContinuationIndenter *Indenter, |
1062 | | WhitespaceManager *Whitespaces, const FormatStyle &Style, |
1063 | | UnwrappedLineFormatter *BlockFormatter) |
1064 | 67.1k | : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} |
1065 | | |
1066 | | /// Puts all tokens into a single line. |
1067 | | unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, |
1068 | 67.6k | unsigned FirstStartColumn, bool DryRun) override { |
1069 | 67.6k | unsigned Penalty = 0; |
1070 | 67.6k | LineState State = |
1071 | 67.6k | Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun); |
1072 | 259k | while (State.NextToken) { |
1073 | 192k | formatChildren(State, /*NewLine=*/false, DryRun, Penalty); |
1074 | 192k | Indenter->addTokenToState( |
1075 | 192k | State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun); |
1076 | 192k | } |
1077 | 67.6k | return Penalty; |
1078 | 67.6k | } |
1079 | | }; |
1080 | | |
1081 | | /// Finds the best way to break lines. |
1082 | | class OptimizingLineFormatter : public LineFormatter { |
1083 | | public: |
1084 | | OptimizingLineFormatter(ContinuationIndenter *Indenter, |
1085 | | WhitespaceManager *Whitespaces, |
1086 | | const FormatStyle &Style, |
1087 | | UnwrappedLineFormatter *BlockFormatter) |
1088 | 6.87k | : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} |
1089 | | |
1090 | | /// Formats the line by finding the best line breaks with line lengths |
1091 | | /// below the column limit. |
1092 | | unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, |
1093 | 7.36k | unsigned FirstStartColumn, bool DryRun) override { |
1094 | 7.36k | LineState State = |
1095 | 7.36k | Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun); |
1096 | | |
1097 | | // If the ObjC method declaration does not fit on a line, we should format |
1098 | | // it with one arg per line. |
1099 | 7.36k | if (State.Line->Type == LT_ObjCMethodDecl) |
1100 | 42 | State.Stack.back().BreakBeforeParameter = true; |
1101 | | |
1102 | | // Find best solution in solution space. |
1103 | 7.36k | return analyzeSolutionSpace(State, DryRun); |
1104 | 7.36k | } |
1105 | | |
1106 | | private: |
1107 | | struct CompareLineStatePointers { |
1108 | 14.9M | bool operator()(LineState *obj1, LineState *obj2) const { |
1109 | 14.9M | return *obj1 < *obj2; |
1110 | 14.9M | } |
1111 | | }; |
1112 | | |
1113 | | /// A pair of <penalty, count> that is used to prioritize the BFS on. |
1114 | | /// |
1115 | | /// In case of equal penalties, we want to prefer states that were inserted |
1116 | | /// first. During state generation we make sure that we insert states first |
1117 | | /// that break the line as late as possible. |
1118 | | typedef std::pair<unsigned, unsigned> OrderedPenalty; |
1119 | | |
1120 | | /// An edge in the solution space from \c Previous->State to \c State, |
1121 | | /// inserting a newline dependent on the \c NewLine. |
1122 | | struct StateNode { |
1123 | | StateNode(const LineState &State, bool NewLine, StateNode *Previous) |
1124 | 841k | : State(State), NewLine(NewLine), Previous(Previous) {} |
1125 | | LineState State; |
1126 | | bool NewLine; |
1127 | | StateNode *Previous; |
1128 | | }; |
1129 | | |
1130 | | /// An item in the prioritized BFS search queue. The \c StateNode's |
1131 | | /// \c State has the given \c OrderedPenalty. |
1132 | | typedef std::pair<OrderedPenalty, StateNode *> QueueItem; |
1133 | | |
1134 | | /// The BFS queue type. |
1135 | | typedef std::priority_queue<QueueItem, SmallVector<QueueItem>, |
1136 | | std::greater<QueueItem>> |
1137 | | QueueType; |
1138 | | |
1139 | | /// Analyze the entire solution space starting from \p InitialState. |
1140 | | /// |
1141 | | /// This implements a variant of Dijkstra's algorithm on the graph that spans |
1142 | | /// the solution space (\c LineStates are the nodes). The algorithm tries to |
1143 | | /// find the shortest path (the one with lowest penalty) from \p InitialState |
1144 | | /// to a state where all tokens are placed. Returns the penalty. |
1145 | | /// |
1146 | | /// If \p DryRun is \c false, directly applies the changes. |
1147 | 7.36k | unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun) { |
1148 | 7.36k | std::set<LineState *, CompareLineStatePointers> Seen; |
1149 | | |
1150 | | // Increasing count of \c StateNode items we have created. This is used to |
1151 | | // create a deterministic order independent of the container. |
1152 | 7.36k | unsigned Count = 0; |
1153 | 7.36k | QueueType Queue; |
1154 | | |
1155 | | // Insert start element into queue. |
1156 | 7.36k | StateNode *RootNode = |
1157 | 7.36k | new (Allocator.Allocate()) StateNode(InitialState, false, nullptr); |
1158 | 7.36k | Queue.push(QueueItem(OrderedPenalty(0, Count), RootNode)); |
1159 | 7.36k | ++Count; |
1160 | | |
1161 | 7.36k | unsigned Penalty = 0; |
1162 | | |
1163 | | // While not empty, take first element and follow edges. |
1164 | 763k | while (!Queue.empty()) { |
1165 | | // Quit if we still haven't found a solution by now. |
1166 | 763k | if (Count > 25000000) |
1167 | 0 | return 0; |
1168 | | |
1169 | 763k | Penalty = Queue.top().first.first; |
1170 | 763k | StateNode *Node = Queue.top().second; |
1171 | 763k | if (!Node->State.NextToken) { |
1172 | 7.36k | LLVM_DEBUG(llvm::dbgs() |
1173 | 7.36k | << "\n---\nPenalty for line: " << Penalty << "\n"); |
1174 | 7.36k | break; |
1175 | 7.36k | } |
1176 | 755k | Queue.pop(); |
1177 | | |
1178 | | // Cut off the analysis of certain solutions if the analysis gets too |
1179 | | // complex. See description of IgnoreStackForComparison. |
1180 | 755k | if (Count > 50000) |
1181 | 134k | Node->State.IgnoreStackForComparison = true; |
1182 | | |
1183 | 755k | if (!Seen.insert(&Node->State).second) { |
1184 | | // State already examined with lower penalty. |
1185 | 139k | continue; |
1186 | 139k | } |
1187 | | |
1188 | 616k | FormatDecision LastFormat = Node->State.NextToken->getDecision(); |
1189 | 616k | if (LastFormat == FD_Unformatted || LastFormat == FD_Continue594 ) |
1190 | 616k | addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue); |
1191 | 616k | if (LastFormat == FD_Unformatted || LastFormat == FD_Break594 ) |
1192 | 615k | addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue); |
1193 | 616k | } |
1194 | | |
1195 | 7.36k | if (Queue.empty()) { |
1196 | | // We were unable to find a solution, do nothing. |
1197 | | // FIXME: Add diagnostic? |
1198 | 0 | LLVM_DEBUG(llvm::dbgs() << "Could not find a solution.\n"); |
1199 | 0 | return 0; |
1200 | 0 | } |
1201 | | |
1202 | | // Reconstruct the solution. |
1203 | 7.36k | if (!DryRun) |
1204 | 6.89k | reconstructPath(InitialState, Queue.top().second); |
1205 | | |
1206 | 7.36k | LLVM_DEBUG(llvm::dbgs() |
1207 | 7.36k | << "Total number of analyzed states: " << Count << "\n"); |
1208 | 7.36k | LLVM_DEBUG(llvm::dbgs() << "---\n"); |
1209 | | |
1210 | 7.36k | return Penalty; |
1211 | 7.36k | } |
1212 | | |
1213 | | /// Add the following state to the analysis queue \c Queue. |
1214 | | /// |
1215 | | /// Assume the current state is \p PreviousNode and has been reached with a |
1216 | | /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true. |
1217 | | void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode, |
1218 | 1.23M | bool NewLine, unsigned *Count, QueueType *Queue) { |
1219 | 1.23M | if (NewLine && !Indenter->canBreak(PreviousNode->State)615k ) |
1220 | 357k | return; |
1221 | 874k | if (!NewLine && Indenter->mustBreak(PreviousNode->State)616k ) |
1222 | 39.9k | return; |
1223 | | |
1224 | 834k | StateNode *Node = new (Allocator.Allocate()) |
1225 | 834k | StateNode(PreviousNode->State, NewLine, PreviousNode); |
1226 | 834k | if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty)) |
1227 | 820 | return; |
1228 | | |
1229 | 833k | Penalty += Indenter->addTokenToState(Node->State, NewLine, true); |
1230 | | |
1231 | 833k | Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node)); |
1232 | 833k | ++(*Count); |
1233 | 833k | } |
1234 | | |
1235 | | /// Applies the best formatting by reconstructing the path in the |
1236 | | /// solution space that leads to \c Best. |
1237 | 6.89k | void reconstructPath(LineState &State, StateNode *Best) { |
1238 | 6.89k | llvm::SmallVector<StateNode *> Path; |
1239 | | // We do not need a break before the initial token. |
1240 | 98.6k | while (Best->Previous) { |
1241 | 91.7k | Path.push_back(Best); |
1242 | 91.7k | Best = Best->Previous; |
1243 | 91.7k | } |
1244 | 91.7k | for (const auto &Node : llvm::reverse(Path)) { |
1245 | 91.7k | unsigned Penalty = 0; |
1246 | 91.7k | formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty); |
1247 | 91.7k | Penalty += Indenter->addTokenToState(State, Node->NewLine, false); |
1248 | | |
1249 | 91.7k | LLVM_DEBUG({ |
1250 | 91.7k | printLineState(Node->Previous->State); |
1251 | 91.7k | if (Node->NewLine) { |
1252 | 91.7k | llvm::dbgs() << "Penalty for placing " |
1253 | 91.7k | << Node->Previous->State.NextToken->Tok.getName() |
1254 | 91.7k | << " on a new line: " << Penalty << "\n"; |
1255 | 91.7k | } |
1256 | 91.7k | }); |
1257 | 91.7k | } |
1258 | 6.89k | } |
1259 | | |
1260 | | llvm::SpecificBumpPtrAllocator<StateNode> Allocator; |
1261 | | }; |
1262 | | |
1263 | | } // anonymous namespace |
1264 | | |
1265 | | unsigned UnwrappedLineFormatter::format( |
1266 | | const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun, |
1267 | | int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn, |
1268 | 25.5k | unsigned NextStartColumn, unsigned LastStartColumn) { |
1269 | 25.5k | LineJoiner Joiner(Style, Keywords, Lines); |
1270 | | |
1271 | | // Try to look up already computed penalty in DryRun-mode. |
1272 | 25.5k | std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey( |
1273 | 25.5k | &Lines, AdditionalIndent); |
1274 | 25.5k | auto CacheIt = PenaltyCache.find(CacheKey); |
1275 | 25.5k | if (DryRun && CacheIt != PenaltyCache.end()2.20k ) |
1276 | 623 | return CacheIt->second; |
1277 | | |
1278 | 24.9k | assert(!Lines.empty()); |
1279 | 0 | unsigned Penalty = 0; |
1280 | 24.9k | LevelIndentTracker IndentTracker(Style, Keywords, Lines[0]->Level, |
1281 | 24.9k | AdditionalIndent); |
1282 | 24.9k | const AnnotatedLine *PrevPrevLine = nullptr; |
1283 | 24.9k | const AnnotatedLine *PreviousLine = nullptr; |
1284 | 24.9k | const AnnotatedLine *NextLine = nullptr; |
1285 | | |
1286 | | // The minimum level of consecutive lines that have been formatted. |
1287 | 24.9k | unsigned RangeMinLevel = UINT_MAX; |
1288 | | |
1289 | 24.9k | bool FirstLine = true; |
1290 | 24.9k | for (const AnnotatedLine *Line = |
1291 | 24.9k | Joiner.getNextMergedLine(DryRun, IndentTracker); |
1292 | 106k | Line; PrevPrevLine = PreviousLine, PreviousLine = Line, Line = NextLine, |
1293 | 81.3k | FirstLine = false) { |
1294 | 81.3k | assert(Line->First); |
1295 | 0 | const AnnotatedLine &TheLine = *Line; |
1296 | 81.3k | unsigned Indent = IndentTracker.getIndent(); |
1297 | | |
1298 | | // We continue formatting unchanged lines to adjust their indent, e.g. if a |
1299 | | // scope was added. However, we need to carefully stop doing this when we |
1300 | | // exit the scope of affected lines to prevent indenting a the entire |
1301 | | // remaining file if it currently missing a closing brace. |
1302 | 81.3k | bool PreviousRBrace = |
1303 | 81.3k | PreviousLine && PreviousLine->startsWith(tok::r_brace)56.3k ; |
1304 | 81.3k | bool ContinueFormatting = |
1305 | 81.3k | TheLine.Level > RangeMinLevel || |
1306 | 81.3k | (69.2k TheLine.Level == RangeMinLevel69.2k && !PreviousRBrace39.1k && |
1307 | 69.2k | !TheLine.startsWith(tok::r_brace)32.9k ); |
1308 | | |
1309 | 81.3k | bool FixIndentation = (FixBadIndentation || ContinueFormatting76.7k ) && |
1310 | 81.3k | Indent != TheLine.First->OriginalColumn42.1k ; |
1311 | 81.3k | bool ShouldFormat = TheLine.Affected || FixIndentation5.83k ; |
1312 | | // We cannot format this line; if the reason is that the line had a |
1313 | | // parsing error, remember that. |
1314 | 81.3k | if (ShouldFormat && TheLine.Type == LT_Invalid75.8k && Status26 ) { |
1315 | 20 | Status->FormatComplete = false; |
1316 | 20 | Status->Line = |
1317 | 20 | SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation()); |
1318 | 20 | } |
1319 | | |
1320 | 81.3k | if (ShouldFormat && TheLine.Type != LT_Invalid75.8k ) { |
1321 | 75.8k | if (!DryRun) { |
1322 | 72.8k | bool LastLine = TheLine.First->is(tok::eof); |
1323 | 72.8k | formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, Indent, |
1324 | 72.8k | LastLine ? LastStartColumn22.1k : NextStartColumn + Indent50.6k ); |
1325 | 72.8k | } |
1326 | | |
1327 | 75.8k | NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker); |
1328 | 75.8k | unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine); |
1329 | 75.8k | bool FitsIntoOneLine = |
1330 | 75.8k | TheLine.Last->TotalLength + Indent <= ColumnLimit || |
1331 | 75.8k | (8.42k TheLine.Type == LT_ImportStatement8.42k && |
1332 | 8.42k | (63 !Style.isJavaScript()63 || !Style.JavaScriptWrapImports26 )) || |
1333 | 75.8k | (8.37k Style.isCSharp()8.37k && |
1334 | 8.37k | TheLine.InPPDirective94 ); // don't split #regions in C# |
1335 | 75.8k | if (Style.ColumnLimit == 0) { |
1336 | 1.78k | NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this) |
1337 | 1.78k | .formatLine(TheLine, NextStartColumn + Indent, |
1338 | 1.78k | FirstLine ? FirstStartColumn334 : 01.44k , DryRun); |
1339 | 74.0k | } else if (FitsIntoOneLine) { |
1340 | 67.1k | Penalty += NoLineBreakFormatter(Indenter, Whitespaces, Style, this) |
1341 | 67.1k | .formatLine(TheLine, NextStartColumn + Indent, |
1342 | 67.1k | FirstLine ? FirstStartColumn18.6k : 048.5k , DryRun); |
1343 | 67.1k | } else { |
1344 | 6.87k | Penalty += OptimizingLineFormatter(Indenter, Whitespaces, Style, this) |
1345 | 6.87k | .formatLine(TheLine, NextStartColumn + Indent, |
1346 | 6.87k | FirstLine ? FirstStartColumn5.40k : 01.47k , DryRun); |
1347 | 6.87k | } |
1348 | 75.8k | RangeMinLevel = std::min(RangeMinLevel, TheLine.Level); |
1349 | 75.8k | } else { |
1350 | | // If no token in the current line is affected, we still need to format |
1351 | | // affected children. |
1352 | 5.45k | if (TheLine.ChildrenAffected) { |
1353 | 93 | for (const FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next82 ) |
1354 | 82 | if (!Tok->Children.empty()) |
1355 | 12 | format(Tok->Children, DryRun); |
1356 | 11 | } |
1357 | | |
1358 | | // Adapt following lines on the current indent level to the same level |
1359 | | // unless the current \c AnnotatedLine is not at the beginning of a line. |
1360 | 5.45k | bool StartsNewLine = |
1361 | 5.45k | TheLine.First->NewlinesBefore > 0 || TheLine.First->IsFirst565 ; |
1362 | 5.45k | if (StartsNewLine) |
1363 | 5.19k | IndentTracker.adjustToUnmodifiedLine(TheLine); |
1364 | 5.45k | if (!DryRun) { |
1365 | 5.44k | bool ReformatLeadingWhitespace = |
1366 | 5.44k | StartsNewLine && (5.19k (5.19k PreviousLine5.19k && PreviousLine->Affected4.65k ) || |
1367 | 5.19k | TheLine.LeadingEmptyLinesAffected4.76k ); |
1368 | | // Format the first token. |
1369 | 5.44k | if (ReformatLeadingWhitespace) { |
1370 | 447 | formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, |
1371 | 447 | TheLine.First->OriginalColumn, |
1372 | 447 | TheLine.First->OriginalColumn); |
1373 | 4.99k | } else { |
1374 | 4.99k | Whitespaces->addUntouchableToken(*TheLine.First, |
1375 | 4.99k | TheLine.InPPDirective); |
1376 | 4.99k | } |
1377 | | |
1378 | | // Notify the WhitespaceManager about the unchanged whitespace. |
1379 | 24.5k | for (FormatToken *Tok = TheLine.First->Next; Tok; Tok = Tok->Next19.1k ) |
1380 | 19.1k | Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective); |
1381 | 5.44k | } |
1382 | 5.45k | NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker); |
1383 | 5.45k | RangeMinLevel = UINT_MAX; |
1384 | 5.45k | } |
1385 | 81.3k | if (!DryRun) |
1386 | 78.3k | markFinalized(TheLine.First); |
1387 | 81.3k | } |
1388 | 24.9k | PenaltyCache[CacheKey] = Penalty; |
1389 | 24.9k | return Penalty; |
1390 | 25.5k | } |
1391 | | |
1392 | | void UnwrappedLineFormatter::formatFirstToken( |
1393 | | const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, |
1394 | | const AnnotatedLine *PrevPrevLine, |
1395 | | const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent, |
1396 | 73.3k | unsigned NewlineIndent) { |
1397 | 73.3k | FormatToken &RootToken = *Line.First; |
1398 | 73.3k | if (RootToken.is(tok::eof)) { |
1399 | 22.2k | unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u); |
1400 | 22.2k | unsigned TokenIndent = Newlines ? NewlineIndent1.72k : 020.4k ; |
1401 | 22.2k | Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent, |
1402 | 22.2k | TokenIndent); |
1403 | 22.2k | return; |
1404 | 22.2k | } |
1405 | 51.0k | unsigned Newlines = |
1406 | 51.0k | std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); |
1407 | | // Remove empty lines before "}" where applicable. |
1408 | 51.0k | if (RootToken.is(tok::r_brace) && |
1409 | 51.0k | (7.29k !RootToken.Next7.29k || |
1410 | 7.29k | (2.59k RootToken.Next->is(tok::semi)2.59k && !RootToken.Next->Next1.09k )) && |
1411 | | // Do not remove empty lines before namespace closing "}". |
1412 | 51.0k | !getNamespaceToken(&Line, Lines)5.79k ) { |
1413 | 5.59k | Newlines = std::min(Newlines, 1u); |
1414 | 5.59k | } |
1415 | | // Remove empty lines at the start of nested blocks (lambdas/arrow functions) |
1416 | 51.0k | if (PreviousLine == nullptr && Line.Level > 022.8k ) |
1417 | 786 | Newlines = std::min(Newlines, 1u); |
1418 | 51.0k | if (Newlines == 0 && !RootToken.IsFirst33.8k ) |
1419 | 12.1k | Newlines = 1; |
1420 | 51.0k | if (RootToken.IsFirst && !RootToken.HasUnescapedNewline22.0k ) |
1421 | 21.7k | Newlines = 0; |
1422 | | |
1423 | | // Remove empty lines after "{". |
1424 | 51.0k | if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine6.37k && |
1425 | 51.0k | PreviousLine->Last->is(tok::l_brace)2.56k && |
1426 | 51.0k | !PreviousLine->startsWithNamespace()750 && |
1427 | 51.0k | !(743 PrevPrevLine743 && PrevPrevLine->startsWithNamespace()269 && |
1428 | 743 | PreviousLine->startsWith(tok::l_brace)9 ) && |
1429 | 51.0k | !startsExternCBlock(*PreviousLine)734 ) { |
1430 | 727 | Newlines = 1; |
1431 | 727 | } |
1432 | | |
1433 | | // Insert or remove empty line before access specifiers. |
1434 | 51.0k | if (PreviousLine && RootToken.isAccessSpecifier()28.2k ) { |
1435 | 523 | switch (Style.EmptyLineBeforeAccessModifier) { |
1436 | 64 | case FormatStyle::ELBAMS_Never: |
1437 | 64 | if (Newlines > 1) |
1438 | 13 | Newlines = 1; |
1439 | 64 | break; |
1440 | 38 | case FormatStyle::ELBAMS_Leave: |
1441 | 38 | Newlines = std::max(RootToken.NewlinesBefore, 1u); |
1442 | 38 | break; |
1443 | 369 | case FormatStyle::ELBAMS_LogicalBlock: |
1444 | 369 | if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && Newlines <= 1101 ) |
1445 | 49 | Newlines = 2; |
1446 | 369 | if (PreviousLine->First->isAccessSpecifier()) |
1447 | 44 | Newlines = 1; // Previous is an access modifier remove all new lines. |
1448 | 369 | break; |
1449 | 52 | case FormatStyle::ELBAMS_Always: { |
1450 | 52 | const FormatToken *previousToken; |
1451 | 52 | if (PreviousLine->Last->is(tok::comment)) |
1452 | 6 | previousToken = PreviousLine->Last->getPreviousNonComment(); |
1453 | 46 | else |
1454 | 46 | previousToken = PreviousLine->Last; |
1455 | 52 | if ((!previousToken || !previousToken->is(tok::l_brace)49 ) && Newlines <= 135 ) |
1456 | 24 | Newlines = 2; |
1457 | 52 | } break; |
1458 | 523 | } |
1459 | 523 | } |
1460 | | |
1461 | | // Insert or remove empty line after access specifiers. |
1462 | 51.0k | if (PreviousLine && PreviousLine->First->isAccessSpecifier()28.2k && |
1463 | 51.0k | (525 !PreviousLine->InPPDirective525 || !RootToken.HasUnescapedNewline5 )) { |
1464 | | // EmptyLineBeforeAccessModifier is handling the case when two access |
1465 | | // modifiers follow each other. |
1466 | 525 | if (!RootToken.isAccessSpecifier()) { |
1467 | 456 | switch (Style.EmptyLineAfterAccessModifier) { |
1468 | 376 | case FormatStyle::ELAAMS_Never: |
1469 | 376 | Newlines = 1; |
1470 | 376 | break; |
1471 | 34 | case FormatStyle::ELAAMS_Leave: |
1472 | 34 | Newlines = std::max(Newlines, 1u); |
1473 | 34 | break; |
1474 | 46 | case FormatStyle::ELAAMS_Always: |
1475 | 46 | if (RootToken.is(tok::r_brace)) // Do not add at end of class. |
1476 | 10 | Newlines = 1u; |
1477 | 36 | else |
1478 | 36 | Newlines = std::max(Newlines, 2u); |
1479 | 46 | break; |
1480 | 456 | } |
1481 | 456 | } |
1482 | 525 | } |
1483 | | |
1484 | 51.0k | if (Newlines) |
1485 | 29.3k | Indent = NewlineIndent; |
1486 | | |
1487 | | // Preprocessor directives get indented before the hash only if specified. In |
1488 | | // Javascript import statements are indented like normal statements. |
1489 | 51.0k | if (!Style.isJavaScript() && |
1490 | 51.0k | Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash48.5k && |
1491 | 51.0k | (48.3k Line.Type == LT_PreprocessorDirective48.3k || |
1492 | 48.3k | Line.Type == LT_ImportStatement45.7k )) { |
1493 | 3.66k | Indent = 0; |
1494 | 3.66k | } |
1495 | | |
1496 | 51.0k | Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent, |
1497 | 51.0k | /*IsAligned=*/false, |
1498 | 51.0k | Line.InPPDirective && |
1499 | 51.0k | !RootToken.HasUnescapedNewline4.22k ); |
1500 | 51.0k | } |
1501 | | |
1502 | | unsigned |
1503 | | UnwrappedLineFormatter::getColumnLimit(bool InPPDirective, |
1504 | 75.8k | const AnnotatedLine *NextLine) const { |
1505 | | // In preprocessor directives reserve two chars for trailing " \" if the |
1506 | | // next line continues the preprocessor directive. |
1507 | 75.8k | bool ContinuesPPDirective = |
1508 | 75.8k | InPPDirective && |
1509 | | // If there is no next line, this is likely a child line and the parent |
1510 | | // continues the preprocessor directive. |
1511 | 75.8k | (4.23k !NextLine4.23k || |
1512 | 4.23k | (4.21k NextLine->InPPDirective4.21k && |
1513 | | // If there is an unescaped newline between this line and the next, the |
1514 | | // next line starts a new preprocessor directive. |
1515 | 4.21k | !NextLine->First->HasUnescapedNewline2.08k )); |
1516 | 75.8k | return Style.ColumnLimit - (ContinuesPPDirective ? 2573 : 075.2k ); |
1517 | 75.8k | } |
1518 | | |
1519 | | } // namespace format |
1520 | | } // namespace clang |