Lines Matching +full:last +full:- +full:level
1 //===--- UnwrappedLineFormatter.cpp - Format C++ code ---------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
16 #define DEBUG_TYPE "format-formatter"
24 const FormatToken *Next = Line.First->getNextNonComment();
25 const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr;
26 return Line.startsWith(tok::kw_extern) && Next && Next->isStringLiteral() &&
27 NextNext && NextNext->is(tok::l_brace);
35 /// Tracks the indent level of \c AnnotatedLines across levels.
38 /// getIndent() will return the indent for the last line \c nextLine was called
42 /// subsequent lines on the same level to be indented at the same level as the
61 // Update the indent level cache size so that we can rely on it
63 if (Line.Level >= IndentForLevel.size())
64 IndentForLevel.resize(Line.Level + 1, -1);
73 (Line.Level - Line.PPLevel) * Style.IndentWidth
74 : Line.Level * PPIndentWidth;
81 assert(Line.Level <= IndentForLevel.size());
82 IndentForLevel.resize(Line.Level + 1);
84 Indent = getIndent(Line.Level);
89 Indent = Line.Level * Style.IndentWidth + Style.ContinuationIndentWidth;
92 /// Update the level indent to adapt to the given \p Line.
95 /// level to the same indent.
100 assert(Line.Level < IndentForLevel.size());
101 if (Line.First->is(tok::comment) && IndentForLevel[Line.Level] != -1)
103 unsigned LevelIndent = Line.First->OriginalColumn;
104 if (static_cast<int>(LevelIndent) - Offset >= 0)
105 LevelIndent -= Offset;
106 IndentForLevel[Line.Level] = LevelIndent;
110 /// Get the offset of the line relatively to the level.
113 /// characters to the left from their level.
128 Next && Next->is(tok::colon)) {
132 if (Next && Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
133 Next->Next && Next->Next->is(tok::colon)) {
144 // the upper indent level.
145 return Style.IndentAccessModifiers ? -Style.IndentWidth
152 /// Get the indent of \p Level from \p IndentForLevel.
154 /// \p IndentForLevel must contain the indent for the level \c l
156 /// that level is unknown.
157 unsigned getIndent(unsigned Level) const {
158 assert(Level < IndentForLevel.size());
159 if (IndentForLevel[Level] != -1)
160 return IndentForLevel[Level];
161 if (Level == 0)
163 return getIndent(Level - 1) + Style.IndentWidth;
170 /// The indent in characters for each level. It remembers the indent of
172 /// is used to align formatted lines to the indent of previous non-formatted
173 /// lines. Think about the --lines parameter of clang-format.
176 /// Offset of the current line relative to the indent level.
189 if (!Line->startsWith(tok::r_brace))
191 size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex;
195 return AnnotatedLines[StartLineIndex]->First->getNamespaceToken();
199 const FormatToken *NamespaceToken = Line->First->getNamespaceToken();
200 return NamespaceToken ? NamespaceToken->TokenText : StringRef();
208 return NamespaceToken ? NamespaceToken->TokenText : StringRef();
230 if (Next[i + 1]->First->NewlinesBefore > 0)
248 // Can't join the last line with anything.
253 if (TheLine->Last->is(TT_LineComment))
256 if (NextLine.Type == LT_Invalid || NextLine.First->MustBreakBefore)
258 if (TheLine->InPPDirective &&
259 (!NextLine.InPPDirective || NextLine.First->HasUnescapedNewline)) {
267 Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent;
270 Limit = TheLine->Last->TotalLength > Limit
272 : Limit - TheLine->Last->TotalLength;
274 if (TheLine->Last->is(TT_FunctionLBrace) &&
275 TheLine->First == TheLine->Last &&
277 NextLine.First->is(tok::r_brace)) {
281 const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1] : nullptr;
283 if (PreviousLine && TheLine->Last->is(tok::l_brace) &&
284 TheLine->First == TheLine->Last) {
285 bool EmptyBlock = NextLine.First->is(tok::r_brace);
287 const FormatToken *Tok = PreviousLine->First;
288 if (Tok && Tok->is(tok::comment))
289 Tok = Tok->getNextNonComment();
291 if (Tok && Tok->getNamespaceToken()) {
297 if (Tok && Tok->is(tok::kw_typedef))
298 Tok = Tok->getNextNonComment();
299 if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
306 if (Tok && Tok->is(tok::kw_template) &&
317 NextLine.First->is(tok::r_brace)) {
323 // Just checking TheLine->Level != 0 is not enough, because it
325 if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
328 if (TheLine->Level != 0) {
333 // Find the last line with lower level.
335 for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
337 if (!(*J)->InPPDirective && !(*J)->isComment() &&
338 (*J)->Level < TheLine->Level) {
348 const auto *LastNonComment = Line->getLastNonComment();
350 // non-PPDirective and non-comment line that has a smaller level.
361 const auto *FirstNonComment = TheLine->getFirstNonComment();
365 // instead of TheLine->First.
368 if (const auto *NSToken = TheLine->First->getNamespaceToken()) {
370 assert(TheLine->MatchingClosingBlockLineIndex > 0);
371 for (auto ClosingLineIndex = TheLine->MatchingClosingBlockLineIndex - 1;
372 I + J != E && NSToken->TokenText == getNamespaceTokenText(I[J]) &&
373 ClosingLineIndex == I[J]->MatchingClosingBlockLineIndex &&
374 I[J]->Last->TotalLength < Limit;
375 ++J, --ClosingLineIndex) {
376 Limit -= I[J]->Last->TotalLength;
378 // Reduce indent level for bodies of namespaces which were compacted,
381 const int OutdentBy = I[J]->Level - TheLine->Level;
385 if (!(*CompactedLine)->InPPDirective) {
386 const int Level = (*CompactedLine)->Level;
387 (*CompactedLine)->Level = std::max(Level - OutdentBy, 0);
391 return J - 1;
396 unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1;
398 nsToken->TokenText ==
400 openingLine == I[i + 1]->MatchingOpeningBlockLineIndex;
401 i++, --openingLine) {
403 I[i + 1]->First->SpacesRequiredBefore =
404 I[i]->Last->isNot(tok::r_brace);
406 // Indent like the outer-most namespace.
413 const auto *LastNonComment = TheLine->getLastNonComment();
416 // instead of TheLine->Last.
419 if (LastNonComment->is(TT_FunctionLBrace) &&
420 TheLine->First != LastNonComment) {
424 if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last &&
425 FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for,
432 if (NextLine.First->is(tok::l_brace)) {
433 if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
436 (TheLine->First->is(tok::r_brace) && TheLine->First->Next &&
437 TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) &&
442 // multi-line control statement.
443 return (Style.ColumnLimit == 0 || TheLine->Level * Style.IndentWidth +
444 TheLine->Last->TotalLength <=
449 if (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
456 if (TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) &&
465 TheLine->Last->TotalLength <= Style.ColumnLimit)
470 if (PreviousLine && TheLine->First->is(tok::l_brace)) {
471 switch (PreviousLine->First->Tok.getKind()) {
474 if (PreviousLine->First->Next) {
476 PreviousLine->First->Next->Tok.getObjCKeywordID();
497 TheLine->Last->is(tok::l_brace) && PreviousLine->Last) {
498 const FormatToken *Previous = PreviousLine->Last;
500 if (Previous->is(tok::comment))
501 Previous = Previous->getPreviousNonComment();
503 if (Previous->is(tok::greater) && !PreviousLine->InPPDirective)
505 if (Previous->is(tok::identifier)) {
507 Previous->getPreviousNonComment();
509 PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)) {
517 if (TheLine->First->is(TT_SwitchExpressionLabel)) {
523 if (TheLine->Last->is(tok::l_brace)) {
526 if (TheLine->Last->is(TT_EnumLBrace)) {
528 } else if (TheLine->Last->is(TT_RequiresExpressionLBrace)) {
530 } else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace)) {
535 (NextLine.First->is(tok::r_brace) &&
537 } else if (TheLine->InPPDirective ||
538 !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
543 (NextLine.First->is(tok::r_brace) &&
550 if (NextLine.First->is(TT_FunctionLBrace) &&
552 if (NextLine.Last->is(TT_LineComment))
558 Limit -= 2;
563 NextLine.First == NextLine.Last && I + 2 != E &&
564 I[2]->First->is(tok::r_brace))) {
573 auto IsElseLine = [&TheLine]() -> bool {
574 const FormatToken *First = TheLine->First;
575 if (First->is(tok::kw_else))
578 return First->is(tok::r_brace) && First->Next &&
579 First->Next->is(tok::kw_else);
581 if (TheLine->First->is(tok::kw_if) ||
588 if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do,
594 if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {
599 if (TheLine->InPPDirective &&
600 (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
612 if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)
614 if (1 + I[1]->Last->TotalLength > Limit)
626 I[1]->First->is(tok::l_brace) &&
630 if (I[1]->InPPDirective != (*I)->InPPDirective ||
631 (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline)) {
636 if (Line.First->isNot(tok::kw_do) && Line.First->isNot(tok::kw_else) &&
637 Line.Last->isNot(tok::kw_else) && Line.Last->isNot(tok::r_paren)) {
641 if (Line.First->is(tok::kw_do) && Line.Last->isNot(tok::kw_do))
643 if (1 + I[1]->Last->TotalLength > Limit)
646 if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while,
654 I[2]->First->is(tok::kw_else)) {
666 I[1]->First->isOneOf(tok::kw_case, tok::kw_default)) {
669 if (I[0]->Last->is(tok::l_brace) || I[1]->First->is(tok::l_brace))
674 bool InPPDirective = I[0]->InPPDirective;
675 bool InMacroBody = I[0]->InMacroBody;
676 const unsigned Level = I[0]->Level;
681 if (Line->InPPDirective != InPPDirective)
683 if (Line->InMacroBody != InMacroBody)
685 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
687 if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
692 if (Line->First->is(tok::comment)) {
693 if (Level != Line->Level)
698 if (Line->InPPDirective != InPPDirective)
700 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
702 if (Line->First->isNot(tok::comment) || Level != Line->Level)
707 if (Line->Last->is(tok::comment))
709 Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
721 if (I[1]->Type == LT_PreprocessorDirective)
730 Line.First->isOneOf(tok::at, tok::minus, tok::plus)) {
736 if (Line.First->is(tok::kw_case) ||
737 (Line.First->Next && Line.First->Next->is(tok::kw_else))) {
741 if (Line.First->is(tok::kw_default)) {
742 const FormatToken *Tok = Line.First->getNextNonComment();
743 if (Tok && Tok->is(tok::colon))
748 return Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
755 I[1]->First->isNot(tok::r_brace));
758 Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch,
766 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
768 I[1]->First->isNot(tok::r_brace)) {
772 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
775 I + 2 != E && I[2]->First->isNot(tok::r_brace)) {
779 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for,
782 I[1]->First->isNot(tok::r_brace)) {
786 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for,
790 I + 2 != E && I[2]->First->isNot(tok::r_brace)) {
798 if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch,
806 Line.First->is(TT_BlockLBrace)) {
810 if (IsSplitBlock && Line.First == Line.Last &&
812 (I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) {
815 FormatToken *Tok = I[1]->First;
817 if (Tok->isNot(tok::r_brace) || Tok->MustBreakBefore)
819 const FormatToken *Next = Tok->getNextNonComment();
820 return !Next || Next->is(tok::semi);
825 Tok->SpacesRequiredBefore =
826 (Style.SpaceInEmptyBlock || Line.Last->is(tok::comment)) ? 1 : 0;
827 Tok->CanBreakBefore = true;
832 if (isRecordLBrace(*Line.Last))
836 if (I + 2 == E || I[2]->Type == LT_Invalid)
843 // Second, check that the next line does not contain any braces - if it
845 if (I[1]->Last->is(TT_LineComment))
848 if (Tok->is(tok::l_brace) && Tok->isNot(BK_BracedInit))
850 Tok = Tok->Next;
853 // Last, check that the third line starts with a closing brace.
854 Tok = I[2]->First;
855 if (Tok->isNot(tok::r_brace))
859 if (Tok->Next && Tok->Next->is(tok::kw_else))
862 // Don't merge a trailing multi-line control statement block like:
865 // { <-- current Line
868 if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace) &&
876 } else if (I[1]->First->is(tok::l_brace)) {
877 if (I[1]->Last->is(TT_LineComment))
883 Limit -= 2;
886 (I[1]->First == I[1]->Last && I + 2 != E &&
887 I[2]->First->is(tok::r_brace))) {
905 if (I[0]->InPPDirective && I + 1 != E &&
906 !I[1]->First->HasUnescapedNewline && I[1]->First->isNot(tok::eof)) {
907 return Limit < 2 ? 0 : Limit - 2;
914 if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)
916 return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;
920 assert(Line->First);
922 // last token of the previous line.
923 for (const FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next)
924 if (Tok->MustBreakBefore)
930 assert(!A.Last->Next);
931 assert(!B.First->Previous);
934 A.Last->Next = B.First;
935 B.First->Previous = A.Last;
936 B.First->CanBreakBefore = true;
937 unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;
938 for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {
939 Tok->TotalLength += LengthA;
940 A.Last = Tok;
953 if (Tok->is(tok::hash) && !Tok->Previous && Tok->Next &&
954 Tok->Next->isOneOf(tok::pp_if, tok::pp_ifdef, tok::pp_ifndef,
957 Tok = Tok->Next;
959 for (; Tok; Tok = Tok->Next) {
960 if (Tok->MacroCtx && Tok->MacroCtx->Role == MR_ExpandedArg) {
965 Tok->MacroCtx->Role = MR_UnexpandedArg;
968 // the macro call. For example, given M(x) -> 2 * x, and the macro call
972 Tok->SpacesRequiredBefore = 0;
973 if (!Tok->MustBreakBeforeFinalized)
974 Tok->MustBreakBefore = 0;
976 Tok->Finalized = true;
985 llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|"
988 llvm::dbgs() << State.NextToken->TokenText << "\n";
1031 const FormatToken *LBrace = State.NextToken->getPreviousNonComment();
1032 bool HasLBrace = LBrace && LBrace->is(tok::l_brace) && LBrace->is(BK_Block);
1033 FormatToken &Previous = *State.NextToken->Previous;
1034 if (Previous.Children.size() == 0 || (!HasLBrace && !LBrace->MacroParent)) {
1044 P.Indent - Previous.Children[0]->Level * Style.IndentWidth;
1046 BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent,
1051 if (Previous.Children[0]->First->MustBreakBefore)
1064 if (Child->Last->isTrailingComment())
1070 Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit) {
1075 Whitespaces->replaceWhitespace(
1076 *Child->First, /*Newlines=*/0, /*Spaces=*/1,
1078 State.Line->InPPDirective);
1083 markFinalized(Child->First);
1085 State.Column += 1 + Child->Last->TotalLength;
1111 LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn,
1115 Indenter->mustBreak(State) ||
1116 (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
1119 Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
1138 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
1141 Indenter->addTokenToState(
1142 State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun);
1162 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
1166 if (State.Line->Type == LT_ObjCMethodDecl)
1187 /// An edge in the solution space from \c Previous->State to \c State,
1238 if (!Node->State.NextToken) {
1240 << "\n---\nPenalty for line: " << Penalty << "\n");
1248 Node->State.IgnoreStackForComparison = true;
1250 if (!Seen.insert(&Node->State).second) {
1255 FormatDecision LastFormat = Node->State.NextToken->getDecision();
1275 LLVM_DEBUG(llvm::dbgs() << "---\n");
1286 if (NewLine && !Indenter->canBreak(PreviousNode->State))
1288 if (!NewLine && Indenter->mustBreak(PreviousNode->State))
1292 StateNode(PreviousNode->State, NewLine, PreviousNode);
1293 if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))
1296 Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
1298 Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));
1307 while (Best->Previous) {
1309 Best = Best->Previous;
1313 formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty);
1314 Penalty += Indenter->addTokenToState(State, Node->NewLine, false);
1317 printLineState(Node->Previous->State);
1318 if (Node->NewLine) {
1320 << Node->Previous->State.NextToken->Tok.getName()
1338 // Try to look up already computed penalty in DryRun-mode.
1343 return CacheIt->second;
1347 LevelIndentTracker IndentTracker(Style, Keywords, Lines[0]->Level,
1353 // The minimum level of consecutive lines that have been formatted.
1361 assert(Line->First);
1370 PreviousLine && PreviousLine->startsWith(tok::r_brace);
1372 TheLine.Level > RangeMinLevel ||
1373 (TheLine.Level == RangeMinLevel && !PreviousRBrace &&
1377 Indent != TheLine.First->OriginalColumn;
1382 Status->FormatComplete = false;
1383 Status->Line =
1384 SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation());
1389 bool LastLine = TheLine.First->is(tok::eof);
1398 (TheLine.Last->TotalLength + Indent <= ColumnLimit ||
1416 RangeMinLevel = std::min(RangeMinLevel, TheLine.Level);
1421 for (const FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next)
1422 if (!Tok->Children.empty())
1423 format(Tok->Children, DryRun);
1426 // Adapt following lines on the current indent level to the same level
1429 TheLine.First->NewlinesBefore > 0 || TheLine.First->IsFirst;
1434 StartsNewLine && ((PreviousLine && PreviousLine->Affected) ||
1439 TheLine.First->OriginalColumn,
1440 TheLine.First->OriginalColumn);
1442 Whitespaces->addUntouchableToken(*TheLine.First,
1447 for (FormatToken *Tok = TheLine.First->Next; Tok; Tok = Tok->Next)
1448 Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
1471 (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)) &&
1477 if (!PreviousLine && Line.Level > 0)
1488 PreviousLine->Last->is(tok::l_brace) &&
1489 !PreviousLine->startsWithNamespace() &&
1490 !(PrevPrevLine && PrevPrevLine->startsWithNamespace() &&
1491 PreviousLine->startsWith(tok::l_brace)) &&
1507 if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && Newlines <= 1)
1509 if (PreviousLine->First->isAccessSpecifier())
1514 if (PreviousLine->Last->is(tok::comment))
1515 previousToken = PreviousLine->Last->getPreviousNonComment();
1517 previousToken = PreviousLine->Last;
1518 if ((!previousToken || previousToken->isNot(tok::l_brace)) &&
1527 if (PreviousLine && PreviousLine->First->isAccessSpecifier() &&
1528 (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) {
1563 Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
1586 Whitespaces->replaceWhitespace(RootToken, RootToken.Newlines, Indent, Indent,
1602 (NextLine->InPPDirective &&
1605 !NextLine->First->HasUnescapedNewline));
1606 return Style.ColumnLimit - (ContinuesPPDirective ? 2 : 0);