clang: lib/Format/ContinuationIndenter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
25#include
26
27#define DEBUG_TYPE "format-indenter"
28
30namespace format {
31
32
33
38
39
40
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
45}
46
47
48
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 if (.MatchingParen)
90 return 0;
92
93 int MatchingStackIndex = Stack.size() - 1;
94
95
96
97
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] : nullptr;
102 };
103 for (; End->Next; End = End->Next) {
105 break;
106 if (!End->Next->closesScope())
107 continue;
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
113 break;
114 }
115 }
117}
118
120 if (.NextOperator)
121 return 0;
122 return Tok.NextOperator->TotalLength - Tok.TotalLength;
123}
124
125
126
128 return Tok.isMemberAccess() && Tok.Previous && Tok.Previous->closesScope();
129}
130
131
133
134 bool HasTwoOperands = Token.OperatorIndex == 0 && .NextOperator;
135 return Token.is(TT_BinaryOperator) && !HasTwoOperands &&
138}
139
140
146
147
149 const FormatStyle &Style) {
150 return Style.BreakBinaryOperations != FormatStyle::BBO_Never &&
152 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None
155}
156
158 const FormatStyle &Style) {
159 if (LessTok.isNot(tok::less))
160 return false;
161 return Style.isTextProto() ||
162 (Style.Language == FormatStyle::LK_Proto &&
165}
166
167
168
169
171 if (TokenText.size() < 5
173 return std::nullopt;
174 }
175
176
177
178
179 size_t LParenPos = TokenText.substr(0, 19).find_first_of('(');
180 if (LParenPos == StringRef::npos)
181 return std::nullopt;
182 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);
183
184
185 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
187 return std::nullopt;
188 if (.substr(RParenPos + 1).starts_with(Delimiter))
189 return std::nullopt;
190 return Delimiter;
191}
192
193
194
195static StringRef
197 FormatStyle::LanguageKind Language) {
198 for (const auto &Format : Style.RawStringFormats)
199 if (Format.Language == Language)
200 return StringRef(Format.CanonicalDelimiter);
201 return "";
202}
203
205 const FormatStyle &CodeStyle) {
206 for (const auto &RawStringFormat : CodeStyle.RawStringFormats) {
207 std::optional LanguageStyle =
209 if (!LanguageStyle) {
210 FormatStyle PredefinedStyle;
215 }
216 LanguageStyle = PredefinedStyle;
217 }
218 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;
223 }
224}
225
226std::optional
230 return std::nullopt;
231 return It->second;
232}
233
234std::optional
236 StringRef EnclosingFunction) const {
239 return std::nullopt;
240 return It->second;
241}
242
247
252
257
259 *this = *this + Spaces;
260 return *this;
261}
262
266
269
281
287 bool BinPackInconclusiveFunctions)
288 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
289 Whitespaces(Whitespaces), Encoding(Encoding),
290 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
291 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
292
294 unsigned FirstStartColumn,
296 bool DryRun) {
299 if (FirstStartColumn && Line->First->NewlinesBefore == 0)
300 State.Column = FirstStartColumn;
301 else
302 State.Column = FirstIndent;
303
304
305
306 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
309 State.Column = 0;
310 }
311 State.Line = Line;
312 State.NextToken = Line->First;
313 State.Stack.push_back(ParenState(nullptr, FirstIndent, FirstIndent,
314 false,
315 false));
316 State.NoContinuation = false;
317 State.StartOfStringLiteral = 0;
318 State.NoLineBreak = false;
319 State.StartOfLineLevel = 0;
320 State.LowestLevelOnLine = 0;
321 State.IgnoreStackForComparison = false;
322
323 if (Style.isTextProto()) {
324
325
326 auto &CurrentState = State.Stack.back();
327 CurrentState.AvoidBinPacking = true;
328 CurrentState.BreakBeforeParameter = true;
329 CurrentState.AlignColons = false;
330 }
331
332
333 moveStateToNextToken(State, DryRun, false);
334 return State;
335}
336
338 const FormatToken &Current = *State.NextToken;
340 const auto &CurrentState = State.Stack.back();
342 if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
343 Current.closesBlockOrBlockTypeList(Style))) {
344 return false;
345 }
346
347
351 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
352 return false;
353 }
354
355
356
357
358
360 State.LowestLevelOnLine < State.StartOfLineLevel &&
361 State.LowestLevelOnLine < Current.NestingLevel) {
362 return false;
363 }
364 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
365 return false;
366
367
368
369 if (Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
370 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
371 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
372 return Style.isCpp() &&
373 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
374 }
375
376
377
378 if (Current.is(TT_FunctionDeclarationName)) {
379 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&
380 State.Column < 6) {
381 return false;
382 }
383
384 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
385 assert(State.Column >= State.FirstIndent);
386 if (State.Column - State.FirstIndent < 6)
387 return false;
388 }
389 }
390
391
392
394 Current.isBlockIndentedInitRBrace(Style)) {
395 return CurrentState.BreakBeforeClosingBrace;
396 }
397
398
399
400 if ((Style.BreakBeforeCloseBracketFunction ||
401 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
402 Style.BreakBeforeCloseBracketSwitch) &&
403 Current.is(tok::r_paren)) {
404 return CurrentState.BreakBeforeClosingParen;
405 }
406
407 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser))
408 return CurrentState.BreakBeforeClosingAngle;
409
410
411
412 if (Current.isNoneOf(TT_BinaryOperator, tok::comma) &&
413
414
415
416 (!Style.BraceWrapping.BeforeLambdaBody ||
417 Current.isNot(TT_LambdaLBrace)) &&
418 CurrentState.NoLineBreakInOperand) {
419 return false;
420 }
421
422 if (Previous.is(tok::l_square) && Previous.is(TT_ObjCMethodExpr))
423 return false;
424
425 if (Current.is(TT_ConditionalExpr) && Previous.is(tok::r_paren) &&
426 Previous.MatchingParen && Previous.MatchingParen->Previous &&
427 Previous.MatchingParen->Previous->MatchingParen &&
428 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
429
430 assert(Previous.MatchingParen->Previous->is(tok::r_brace));
431 return true;
432 }
433
434 return !State.NoLineBreak && !CurrentState.NoLineBreak;
435}
436
438 const FormatToken &Current = *State.NextToken;
440 const auto &CurrentState = State.Stack.back();
441 if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore &&
442 Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) {
445 }
447 (Current.is(TT_InlineASMColon) &&
448 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
449 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
450 Style.ColumnLimit > 0)))) {
451 return true;
452 }
453 if (CurrentState.BreakBeforeClosingBrace &&
454 (Current.closesBlockOrBlockTypeList(Style) ||
456 Current.isBlockIndentedInitRBrace(Style)))) {
457 return true;
458 }
459 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
460 return true;
461 if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser))
462 return true;
463 if (Style.Language == FormatStyle::LK_ObjC &&
464 Style.ObjCBreakBeforeNestedBlockParam &&
466 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
467 return true;
468 }
469
470
471 if (CurrentState.IsCSharpGenericTypeConstraint &&
472 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
473 return false;
474 }
476 (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
477 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
478
479
480
481
482 (Previous.NestingLevel == 1 ||
483 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||
484 (Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) &&
485 Previous.isNot(tok::question)) ||
486 (!Style.BreakBeforeTernaryOperators &&
487 Previous.is(TT_ConditionalExpr))) &&
488 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
489 Current.isNoneOf(tok::r_paren, tok::r_brace)) {
490 return true;
491 }
492 if (CurrentState.IsChainedConditional &&
493 ((Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) &&
494 Current.is(tok::colon)) ||
495 (!Style.BreakBeforeTernaryOperators && Previous.is(TT_ConditionalExpr) &&
497 return true;
498 }
499 if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) ||
500 (Previous.is(TT_ArrayInitializerLSquare) &&
501 Previous.ParameterCount > 1) ||
503 Style.ColumnLimit > 0 &&
506 return true;
507 }
508
509 const FormatToken &BreakConstructorInitializersToken =
510 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
512 : Current;
513 if (BreakConstructorInitializersToken.is(TT_CtorInitializerColon) &&
514 (State.Column + State.Line->Last->TotalLength - Previous.TotalLength >
516 CurrentState.BreakBeforeParameter) &&
517 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
519 return true;
520 }
521
522 if (Current.is(TT_ObjCMethodExpr) && Previous.isNot(TT_SelectorName) &&
523 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
524 return true;
525 }
526 if (Current.is(TT_SelectorName) && Previous.isNot(tok::at) &&
527 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
528 (Style.ObjCBreakBeforeNestedBlockParam ||
529 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
530 return true;
531 }
532
533 unsigned NewLineColumn = getNewLineColumn(State).Total;
534 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
536 (State.Column > NewLineColumn ||
537 Current.NestingLevel < State.StartOfLineLevel)) {
538 return true;
539 }
540
542 (CurrentState.CallContinuation != 0 ||
543 CurrentState.BreakBeforeParameter) &&
544
545
546
547
548
549 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
550 !(Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
551 return true;
552 }
553
554
555
556 if (Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
558 return true;
559 }
560
561 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
562 return false;
563
564 if (Style.AlwaysBreakBeforeMultilineStrings &&
565 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
567 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
568 Keywords.kw_dollar) &&
569 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
570 nextIsMultilineString(State)) {
571 return true;
572 }
573
574
575
576
578 const auto PreviousPrecedence = Previous.getPrecedence();
580 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
581 const bool LHSIsBinaryExpr =
582 Previous.Previous && Previous.Previous->EndsBinaryExpression;
583 if (LHSIsBinaryExpr)
584 return true;
585
586
587
588
589
590
591
592
593
594 const bool IsComparison =
599 Previous.Previous->isNot(TT_BinaryOperator);
600 if (!IsComparison)
601 return true;
602 }
603 } else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&
605 CurrentState.BreakBeforeParameter) {
606 return true;
607 }
608
609
610 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
611 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
612 return true;
613 }
614
615 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
616
617
618
619
620 if (Previous.ClosesTemplateDeclaration) {
621 if (Current.is(tok::kw_concept)) {
622 switch (Style.BreakBeforeConceptDeclarations) {
623 case FormatStyle::BBCDS_Allowed:
624 break;
625 case FormatStyle::BBCDS_Always:
626 return true;
627 case FormatStyle::BBCDS_Never:
628 return false;
629 }
630 }
631 if (Current.is(TT_RequiresClause)) {
632 switch (Style.RequiresClausePosition) {
633 case FormatStyle::RCPS_SingleLine:
634 case FormatStyle::RCPS_WithPreceding:
635 return false;
636 default:
637 return true;
638 }
639 }
640 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
641 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
643 }
644 if (Previous.is(TT_FunctionAnnotationRParen) &&
646 return true;
647 }
648 if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
649 Current.isNot(TT_LeadingJavaAnnotation)) {
650 return true;
651 }
652 }
653
654 if (Style.isJavaScript() && Previous.is(tok::r_paren) &&
655 Previous.is(TT_JavaAnnotation)) {
656
657
658 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {"get", "set",
659 "function"};
660 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))
661 return true;
662 }
663
664 if (Current.is(TT_FunctionDeclarationName) &&
665 !State.Line->ReturnTypeWrapped &&
666
667 (!Style.isCSharp() ||
668 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
669
670
671 !Style.isJavaScript() && Previous.isNot(tok::kw_template) &&
672 CurrentState.BreakBeforeParameter) {
674 if (Tok->is(TT_LineComment))
675 return false;
676 if (Tok->is(TT_TemplateCloser)) {
678 assert(Tok);
679 }
680 if (Tok->FirstAfterPPLine)
681 return false;
682 }
683
684 return true;
685 }
686
687
688
689
692 Current.isNoneOf(tok::r_brace, tok::comment)) {
693 return true;
694 }
695
696 if (Current.is(tok::lessless) &&
697 ((Previous.is(tok::identifier) && Previous.TokenText == "endl") ||
698 (Previous.Tok.isLiteral() && (Previous.TokenText.ends_with("\\n\"") ||
699 Previous.TokenText == "\'\\n\'")))) {
700 return true;
701 }
702
704 return true;
705
706 if (State.NoContinuation)
707 return true;
708
709 return false;
710}
711
713 bool DryRun,
714 unsigned ExtraSpaces) {
715 const FormatToken &Current = *State.NextToken;
716 assert(State.NextToken->Previous);
718
719 assert(!State.Stack.empty());
720 State.NoContinuation = false;
721
722 if (Current.is(TT_ImplicitStringLiteral) &&
723 (.Tok.getIdentifierInfo() ||
724 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
725 tok::pp_not_keyword)) {
726 unsigned EndColumn =
729
730
731 State.Column = EndColumn;
732 } else {
733 unsigned StartColumn =
735 assert(EndColumn >= StartColumn);
736 State.Column += EndColumn - StartColumn;
737 }
738 moveStateToNextToken(State, DryRun, false);
739 return 0;
740 }
741
742 unsigned Penalty = 0;
743 if (Newline)
744 Penalty = addTokenOnNewLine(State, DryRun);
745 else
746 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
747
748 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
749}
750
751void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
752 unsigned ExtraSpaces) {
754 assert(State.NextToken->Previous);
756 auto &CurrentState = State.Stack.back();
757
758
759
760
761
762
763 auto DisallowLineBreaks = [&] {
764 if (!Style.isCpp() ||
765 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
766 return false;
767 }
768
769
771 return false;
772
773 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
774 return false;
775
776 const auto *Prev = Current.getPreviousNonComment();
777 if (!Prev || Prev->isNot(tok::l_paren))
778 return false;
779
780 if (Prev->BlockParameterCount == 0)
781 return false;
782
783
784 if (Prev->BlockParameterCount > 1)
785 return true;
786
787
788 if (!Prev->Role)
789 return false;
790
791 const auto *Comma = Prev->Role->lastComma();
792 if (!Comma)
793 return false;
794
795 const auto *Next = Comma->getNextNonComment();
796 return Next && Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
797 };
798
799 if (DisallowLineBreaks())
800 State.NoLineBreak = true;
801
802 if (Current.is(tok::equal) &&
803 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
804 CurrentState.VariablePos == 0 &&
806 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
807 CurrentState.VariablePos = State.Column;
808
810 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {
811 CurrentState.VariablePos -= Tok->ColumnWidth;
812 if (Tok->SpacesRequiredBefore != 0)
813 break;
815 }
816 if (Previous.PartOfMultiVariableDeclStmt)
817 CurrentState.LastSpace = CurrentState.VariablePos;
818 }
819
821
822
823 int PPColumnCorrection = 0;
827 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
829
830
831
832
833
834 if (Style.UseTab != FormatStyle::UT_Never)
835 PPColumnCorrection = -1;
836 } else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
838 }
839 }
840
841 if (!DryRun) {
842 const bool ContinuePPDirective =
844 Whitespaces.replaceWhitespace(Current, 0, Spaces,
845 State.Column + Spaces + PPColumnCorrection,
846 false, ContinuePPDirective);
847 }
848
849
850
851 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
852 Current.is(TT_InheritanceColon)) {
853 CurrentState.NoLineBreak = true;
854 }
855 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
856 Previous.is(TT_InheritanceColon)) {
857 CurrentState.NoLineBreak = true;
858 }
859
860 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
861 unsigned MinIndent =
862 std::max(State.FirstIndent + Style.ContinuationIndentWidth,
863 CurrentState.Indent.Total);
864 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
866 CurrentState.AlignColons = false;
869 else
870 CurrentState.ColonPos = FirstColonPos;
871 }
872
873
874
875
876
877 auto IsOpeningBracket = [&](const FormatToken &Tok) {
878 auto IsStartOfBracedList = [&]() {
879 return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) &&
880 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
881 };
882 if (IsStartOfBracedList())
883 return Style.BreakAfterOpenBracketBracedList;
884 if (Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
885 return false;
886 if (.Previous)
887 return true;
888 if (Tok.Previous->isIf())
889 return Style.BreakAfterOpenBracketIf;
890 if (Tok.Previous->isLoop(Style))
891 return Style.BreakAfterOpenBracketLoop;
892 if (Tok.Previous->is(tok::kw_switch))
893 return Style.BreakAfterOpenBracketSwitch;
894 if (Style.BreakAfterOpenBracketFunction) {
895 return .Previous->is(TT_CastRParen) &&
896 !(Style.isJavaScript() && Tok.is(Keywords.kw_await));
897 }
898 return false;
899 };
900 auto IsFunctionCallParen = [](const FormatToken &Tok) {
901 return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&
902 Tok.Previous->is(tok::identifier);
903 };
904 auto IsInTemplateString = [this](const FormatToken &Tok, bool NestBlocks) {
905 if (!Style.isJavaScript())
906 return false;
907 for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {
908 if (Prev->is(TT_TemplateString) && Prev->opensScope())
909 return true;
910 if (Prev->opensScope() && !NestBlocks)
911 return false;
912 if (Prev->is(TT_TemplateString) && Prev->closesScope())
913 return false;
914 }
915 return false;
916 };
917
918 auto StartsSimpleOneArgList = [&](const FormatToken &TokAfterLParen) {
919 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
920 const auto &Tok =
921 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
923 return false;
924
925
926
927
928 if (Tok.is(tok::kw_new) || Tok.startsSequence(tok::coloncolon, tok::kw_new))
929 return true;
930 if (Tok.is(TT_UnaryOperator) ||
931 (Style.isJavaScript() &&
932 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
933 return true;
934 }
935 const auto *Previous = TokAfterLParen.Previous;
936 assert(Previous);
938 (Previous->Previous->isIf() || Previous->Previous->isLoop(Style) ||
939 Previous->Previous->is(tok::kw_switch))) {
940 return false;
941 }
942 if (Previous->isNoneOf(TT_FunctionDeclarationLParen,
943 TT_LambdaDefinitionLParen) &&
944 !IsFunctionCallParen(*Previous)) {
945 return true;
946 }
947 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok, true))
948 return true;
949 const auto *Next = Tok.Next;
950 return || Next->isMemberAccess() ||
951 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
952 };
953 if (IsOpeningBracket(Previous) &&
954 State.Column > getNewLineColumn(State).Total &&
955
956
957
958
959
960
961
962
963
964
965 !StartsSimpleOneArgList(Current)) {
966 CurrentState.NoLineBreak = true;
967 }
968
970 CurrentState.NoLineBreak = true;
971
972
973
974
975
976 if (Style.AlignAfterOpenBracket &&
977 !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&
978 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
979 TT_TableGenDAGArgOpener,
980 TT_TableGenDAGArgOpenerToBreak) &&
982 (Current.isNot(TT_LineComment) ||
984 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||
986 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,
988 Previous.is(TT_VerilogMultiLineListLParen)) &&
989 !IsInTemplateString(Current, false)) {
990 CurrentState.Indent = State.Column + Spaces;
991 CurrentState.IsAligned = true;
992 }
994 CurrentState.NoLineBreak = true;
996 CurrentState.NoLineBreak = true;
997
999 State.Column > getNewLineColumn(State).Total) {
1000 CurrentState.ContainsUnwrappedBuilder = true;
1001 }
1002
1003 if (Current.is(TT_LambdaArrow) && Style.isJava())
1004 CurrentState.NoLineBreak = true;
1005 if (Current.isMemberAccess() && Previous.is(tok::r_paren) &&
1007 (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) {
1008
1009
1010
1011
1012
1013
1014 CurrentState.NoLineBreak = true;
1015 }
1016
1017
1018
1019
1020
1021 const FormatToken *P = Current.getPreviousNonComment();
1022 if (Current.isNot(tok::comment) && P &&
1023 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1024 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1025 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1029 bool BreakBeforeOperator =
1030 P->MustBreakBefore || P->is(tok::lessless) ||
1031 (P->is(TT_BinaryOperator) &&
1032 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1033 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1034
1035
1036
1037 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1038 P->isNot(TT_ConditionalExpr);
1039 if ((!BreakBeforeOperator &&
1040 !(HasTwoOperands &&
1041 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1042 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1043 CurrentState.NoLineBreakInOperand = true;
1044 }
1045 }
1046
1047 State.Column += Spaces;
1048 if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) &&
1050 (Previous.Previous->is(tok::kw_for) || Previous.Previous->isIf())) {
1051
1052
1053 CurrentState.LastSpace = State.Column;
1054 CurrentState.NestedBlockIndent = State.Column;
1055 } else if (Current.isNoneOf(tok::comment, tok::caret) &&
1056 ((Previous.is(tok::comma) &&
1057 Previous.isNot(TT_OverloadedOperator)) ||
1058 (Previous.is(tok::colon) && Previous.is(TT_ObjCMethodExpr)))) {
1059 CurrentState.LastSpace = State.Column;
1060 } else if (Previous.is(TT_CtorInitializerColon) &&
1061 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
1062 Style.BreakConstructorInitializers ==
1063 FormatStyle::BCIS_AfterColon) {
1064 CurrentState.Indent = State.Column;
1065 CurrentState.LastSpace = State.Column;
1066 } else if (Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1067 CurrentState.LastSpace = State.Column;
1068 } else if (Previous.is(TT_BinaryOperator) &&
1070 (Previous.isNot(tok::lessless) || Previous.OperatorIndex != 0 ||
1073
1074
1075 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1076 CurrentState.LastSpace = State.Column;
1077 } else if (Previous.is(TT_InheritanceColon)) {
1078 CurrentState.Indent = State.Column;
1079 CurrentState.LastSpace = State.Column;
1080 } else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {
1081 CurrentState.ColonPos = State.Column;
1082 } else if (Previous.opensScope()) {
1083
1084
1085
1086
1087
1088 if (Previous.MatchingParen) {
1090 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&
1091 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {
1092 CurrentState.LastSpace = State.Column;
1093 }
1094 }
1095 }
1096}
1097
1098unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
1099 bool DryRun) {
1100 FormatToken &Current = *State.NextToken;
1101 assert(State.NextToken->Previous);
1103 auto &CurrentState = State.Stack.back();
1104
1105
1106
1107 unsigned Penalty = 0;
1108
1109 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1111 if (!NextNonComment)
1112 NextNonComment = &Current;
1113
1114
1115 if (!CurrentState.ContainsLineBreak)
1116 Penalty += 15;
1117 CurrentState.ContainsLineBreak = true;
1118
1119 Penalty += State.NextToken->SplitPenalty;
1120
1121
1122
1123
1124 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1125 (State.Column <= Style.ColumnLimit / 3 ||
1126 CurrentState.BreakBeforeParameter)) {
1127 Penalty += Style.PenaltyBreakFirstLessLess;
1128 }
1129
1130 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1131 State.Column = TotalColumn;
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 if (State.Column > State.FirstIndent) {
1146 Penalty +=
1147 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160 if (Current.isNot(TT_LambdaArrow) &&
1161 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1162 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1163 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1164 CurrentState.NestedBlockIndent = State.Column;
1165 }
1166
1167 if (NextNonComment->isMemberAccess()) {
1168 if (CurrentState.CallContinuation == 0)
1169 CurrentState.CallContinuation = State.Column;
1170 } else if (NextNonComment->is(TT_SelectorName)) {
1171 if (!CurrentState.ObjCSelectorNameFound) {
1172 if (NextNonComment->LongestObjCSelectorName == 0) {
1173 CurrentState.AlignColons = false;
1174 } else {
1175 CurrentState.ColonPos =
1177 ? std::max(CurrentState.Indent.Total,
1178 State.FirstIndent + Style.ContinuationIndentWidth)
1179 : CurrentState.Indent.Total) +
1182 }
1183 } else if (CurrentState.AlignColons &&
1184 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1185 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1186 }
1187 } else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1188 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 if (State.Stack.size() > 1) {
1199 State.Stack[State.Stack.size() - 2].LastSpace =
1200 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1201 Style.ContinuationIndentWidth;
1202 }
1203 }
1204
1205 if ((PreviousNonComment &&
1206 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1207 !CurrentState.AvoidBinPacking) ||
1208 Previous.is(TT_BinaryOperator)) {
1209 CurrentState.BreakBeforeParameter = false;
1210 }
1211 if (PreviousNonComment &&
1212 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1213 PreviousNonComment->ClosesRequiresClause) &&
1214 Current.NestingLevel == 0) {
1215 CurrentState.BreakBeforeParameter = false;
1216 }
1217 if (NextNonComment->is(tok::question) ||
1218 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1219 CurrentState.BreakBeforeParameter = true;
1220 }
1221 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1222 CurrentState.BreakBeforeParameter = false;
1223
1224 if (!DryRun) {
1226 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1227
1228
1229 !Current.MatchingParen->Children.empty()) {
1230
1231
1232
1234 }
1237 const bool ContinuePPDirective = State.Line->InPPDirective &&
1239 Current.isNot(TT_LineComment);
1240 Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
1241 CurrentState.IsAligned, ContinuePPDirective,
1242 IndentedFromColumn);
1243 }
1244
1245 if (!Current.isTrailingComment())
1246 CurrentState.LastSpace = State.Column;
1247 if (Current.is(tok::lessless)) {
1248
1249
1250
1251 CurrentState.LastSpace += 3;
1252 }
1253
1254 State.StartOfLineLevel = Current.NestingLevel;
1255 State.LowestLevelOnLine = Current.NestingLevel;
1256
1257
1258
1259 bool NestedBlockSpecialCase =
1260 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1261 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1262 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1263 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1264
1265 NestedBlockSpecialCase =
1266 NestedBlockSpecialCase ||
1267 (Current.MatchingParen &&
1268 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1269 if (!NestedBlockSpecialCase) {
1270 auto ParentLevelIt = std::next(State.Stack.rbegin());
1271 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1272 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287 auto FindCurrentLevel = [&](const auto &It) {
1288 return std::find_if(It, State.Stack.rend(), [](const auto &PState) {
1289 return PState.Tok != nullptr;
1290 });
1291 };
1292 auto MaybeIncrement = [&](const auto &It) {
1293 return It != State.Stack.rend() ? std::next(It) : It;
1294 };
1295 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1296 auto LevelContainingLambdaIt =
1297 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1298 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1299 }
1300 for (auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1301 I->BreakBeforeParameter = true;
1302 }
1303
1304 if (PreviousNonComment &&
1305 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1306 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1307 !PreviousNonComment->ClosesRequiresClause) ||
1308 Current.NestingLevel != 0) &&
1309 PreviousNonComment->isNoneOf(
1310 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1311 TT_LeadingJavaAnnotation) &&
1312 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1313
1314
1315 (!Style.BraceWrapping.BeforeLambdaBody ||
1316 Current.isNot(TT_LambdaLBrace))) {
1317 CurrentState.BreakBeforeParameter = true;
1318 }
1319
1320
1321
1322 if (PreviousNonComment &&
1323 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1325 CurrentState.BreakBeforeClosingBrace = true;
1326 }
1327
1328 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1329 if (auto Previous = PreviousNonComment->Previous) {
1331 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1332 } else if (Previous->isLoop(Style)) {
1333 CurrentState.BreakBeforeClosingParen =
1334 Style.BreakBeforeCloseBracketLoop;
1335 } else if (Previous->is(tok::kw_switch)) {
1336 CurrentState.BreakBeforeClosingParen =
1337 Style.BreakBeforeCloseBracketSwitch;
1338 } else {
1339 CurrentState.BreakBeforeClosingParen =
1340 Style.BreakBeforeCloseBracketFunction;
1341 }
1342 }
1343 }
1344
1345 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1346 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1347
1348 if (CurrentState.AvoidBinPacking) {
1349
1350
1351
1352
1353 bool PreviousIsBreakingCtorInitializerColon =
1354 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1355 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1356 bool AllowAllConstructorInitializersOnNextLine =
1357 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1358 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1359 if ((Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1360 !PreviousIsBreakingCtorInitializerColon) ||
1361 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1362 State.Line->MustBeDeclaration) ||
1363 (!Style.AllowAllArgumentsOnNextLine &&
1364 !State.Line->MustBeDeclaration) ||
1365 (!AllowAllConstructorInitializersOnNextLine &&
1366 PreviousIsBreakingCtorInitializerColon) ||
1367 Previous.is(TT_DictLiteral)) {
1368 CurrentState.BreakBeforeParameter = true;
1369 }
1370
1371
1372
1373
1374 if (PreviousIsBreakingCtorInitializerColon &&
1375 AllowAllConstructorInitializersOnNextLine) {
1376 CurrentState.BreakBeforeParameter = false;
1377 }
1378 }
1379
1381 CurrentState.BreakBeforeParameter = true;
1382
1383 return Penalty;
1384}
1385
1387ContinuationIndenter::getNewLineColumn(const LineState &State) {
1388 if (!State.NextToken || !State.NextToken->Previous)
1389 return 0;
1390
1391 FormatToken &Current = *State.NextToken;
1392 const auto &CurrentState = State.Stack.back();
1393
1394 if (CurrentState.IsCSharpGenericTypeConstraint &&
1395 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1396 return CurrentState.ColonPos + 2;
1397 }
1398
1400
1401 const auto ContinuationIndent =
1402 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1403 CurrentState.Indent) +
1404 Style.ContinuationIndentWidth;
1405 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1407 if (!NextNonComment)
1408 NextNonComment = &Current;
1409
1410
1411 if (Style.isJava() &&
1412 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1413 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1414 CurrentState.Indent + Style.ContinuationIndentWidth);
1415 }
1416
1417
1418
1419 if (Style.isVerilog() && PreviousNonComment &&
1420 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1421 return State.FirstIndent;
1422 }
1423
1424 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1425 State.Line->First->is(tok::kw_enum)) {
1426 return IndentationAndAlignment(Style.IndentWidth *
1427 State.Line->First->IndentLevel) +
1428 Style.IndentWidth;
1429 }
1430
1431 if (Style.BraceWrapping.BeforeLambdaBody &&
1432 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1433 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1434 ? CurrentState.Indent
1435 : State.FirstIndent;
1436 return From + Style.IndentWidth;
1437 }
1438
1439 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
1440 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1441 if (Current.NestingLevel == 0 ||
1442 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1443 State.NextToken->is(TT_LambdaLBrace))) {
1444 return State.FirstIndent;
1445 }
1446 return CurrentState.Indent;
1447 }
1448 if (Current.is(TT_LambdaArrow) &&
1449 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1450 tok::kw_consteval, tok::kw_static,
1451 TT_AttributeRSquare)) {
1452 return ContinuationIndent;
1453 }
1454 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1455 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1456 State.Stack.size() > 1) {
1457 if (Current.closesBlockOrBlockTypeList(Style))
1458 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1459 if (Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit))
1460 return State.Stack[State.Stack.size() - 2].LastSpace;
1461 return State.FirstIndent;
1462 }
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1479 (!Current.Next ||
1480 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1481 return State.Stack[State.Stack.size() - 2].LastSpace;
1482 }
1483
1484
1485 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1486 State.Stack.size() > 1) {
1487 return State.Stack[State.Stack.size() - 2].LastSpace;
1488 }
1489 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1490 Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit) &&
1491 State.Stack.size() > 1) {
1492 return State.Stack[State.Stack.size() - 2].LastSpace;
1493 }
1494 if ((Style.BreakBeforeCloseBracketFunction ||
1495 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1496 Style.BreakBeforeCloseBracketSwitch) &&
1497 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1498 return State.Stack[State.Stack.size() - 2].LastSpace;
1499 }
1500 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1501 State.Stack.size() > 1) {
1502 return State.Stack[State.Stack.size() - 2].LastSpace;
1503 }
1504 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1505 return State.Stack[State.Stack.size() - 2].LastSpace;
1506
1507
1508
1509
1510
1511
1512
1513 if (Current.is(tok::identifier) && Current.Next &&
1514 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1515 (Current.Next->is(TT_DictLiteral) ||
1516 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1517 return CurrentState.Indent;
1518 }
1519 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1520 State.StartOfStringLiteral != 0) {
1521 return State.StartOfStringLiteral - 1;
1522 }
1523 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1524 return State.StartOfStringLiteral;
1525 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1526 return CurrentState.FirstLessLess;
1527 if (NextNonComment->isMemberAccess()) {
1528 if (CurrentState.CallContinuation == 0)
1529 return ContinuationIndent;
1530 return CurrentState.CallContinuation;
1531 }
1532 if (CurrentState.QuestionColumn != 0 &&
1533 ((NextNonComment->is(tok::colon) &&
1534 NextNonComment->is(TT_ConditionalExpr)) ||
1535 Previous.is(TT_ConditionalExpr))) {
1536 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1537 !NextNonComment->Next->FakeLParens.empty() &&
1538 NextNonComment->Next->FakeLParens.back() == prec::Conditional) ||
1539 (Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1541 !CurrentState.IsWrappedConditional) {
1542
1543
1544
1545
1546 unsigned Indent = CurrentState.Indent.Total;
1547 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1548 Indent -= Style.ContinuationIndentWidth;
1549 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1552 }
1553 return CurrentState.QuestionColumn;
1554 }
1555 if (Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1556 return CurrentState.VariablePos;
1557 if (Current.is(TT_RequiresClause)) {
1558 if (Style.IndentRequiresClause)
1559 return CurrentState.Indent + Style.IndentWidth;
1560 switch (Style.RequiresClausePosition) {
1561 case FormatStyle::RCPS_OwnLine:
1562 case FormatStyle::RCPS_WithFollowing:
1563 case FormatStyle::RCPS_OwnLineWithBrace:
1564 return CurrentState.Indent;
1565 default:
1566 break;
1567 }
1568 }
1569 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1570 TT_InheritanceComma)) {
1571 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1572 }
1573 if ((PreviousNonComment &&
1574 (PreviousNonComment->ClosesTemplateDeclaration ||
1575 PreviousNonComment->ClosesRequiresClause ||
1576 (PreviousNonComment->is(TT_AttributeMacro) &&
1577 Current.isNot(tok::l_paren) &&
1578 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1579 TT_PointerOrReference)) ||
1580 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1581 TT_FunctionAnnotationRParen,
1582 TT_JavaAnnotation,
1583 TT_LeadingJavaAnnotation))) ||
1584 (!Style.IndentWrappedFunctionNames &&
1585 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1586 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1587 CurrentState.Indent);
1588 }
1589 if (NextNonComment->is(TT_SelectorName)) {
1590 if (!CurrentState.ObjCSelectorNameFound) {
1591 auto MinIndent = CurrentState.Indent;
1593 MinIndent =
1594 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1595 Style.ContinuationIndentWidth);
1596 }
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606 return MinIndent.addPadding(
1607 std::max(NextNonComment->LongestObjCSelectorName,
1608 NextNonComment->ColumnWidth) -
1609 NextNonComment->ColumnWidth);
1610 }
1611 if (!CurrentState.AlignColons)
1612 return CurrentState.Indent;
1613 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1614 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1615 return CurrentState.Indent;
1616 }
1617 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1618 return CurrentState.ColonPos;
1619 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1620 if (CurrentState.StartOfArraySubscripts != 0) {
1621 return CurrentState.StartOfArraySubscripts;
1622 } else if (Style.isCSharp()) {
1623
1624 return CurrentState.Indent;
1625 }
1626 return ContinuationIndent;
1627 }
1628
1629
1630
1631 if (State.Line->InPragmaDirective) {
1632 FormatToken *PragmaType = State.Line->First->Next->Next;
1633 if (PragmaType && PragmaType->TokenText == "omp")
1634 return CurrentState.Indent + Style.ContinuationIndentWidth;
1635 }
1636
1637
1638
1639 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1640 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1641 return CurrentState.Indent;
1642 }
1643
1644 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1645 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1646 return ContinuationIndent;
1647 }
1648 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1649 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1650 return ContinuationIndent;
1651 }
1652 if (NextNonComment->is(TT_CtorInitializerComma))
1653 return CurrentState.Indent;
1654 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1655 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1656 return CurrentState.Indent;
1657 }
1658 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1659 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1660 return CurrentState.Indent;
1661 }
1662 if (Previous.is(tok::r_paren) &&
1663 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1664 !Current.isBinaryOperator() &&
1665 Current.isNoneOf(tok::colon, tok::comment)) {
1666 return ContinuationIndent;
1667 }
1668 if (Current.is(TT_ProtoExtensionLSquare))
1669 return CurrentState.Indent;
1670 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1671 return CurrentState.Indent - Current.Tok.getLength() -
1672 Current.SpacesRequiredBefore;
1673 }
1674 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1675 CurrentState.UnindentOperator) {
1676 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1677 NextNonComment->SpacesRequiredBefore;
1678 }
1679 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1680 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1681
1682
1683 return CurrentState.Indent + Style.ContinuationIndentWidth;
1684 }
1685 return CurrentState.Indent;
1686}
1687
1690 const FormatStyle &Style) {
1691 if (Previous->isNot(tok::l_paren))
1692 return true;
1693 if (Previous->ParameterCount > 1)
1694 return true;
1695
1696
1697 return Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLSquare);
1698}
1699
1700unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1701 bool DryRun, bool Newline) {
1702 assert(State.Stack.size());
1703 const FormatToken &Current = *State.NextToken;
1704 auto &CurrentState = State.Stack.back();
1705
1706 if (Current.is(TT_CSharpGenericTypeConstraint))
1707 CurrentState.IsCSharpGenericTypeConstraint = true;
1708 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1709 CurrentState.NoLineBreakInOperand = false;
1710 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1711 CurrentState.AvoidBinPacking = true;
1712 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1713 if (CurrentState.FirstLessLess == 0)
1714 CurrentState.FirstLessLess = State.Column;
1715 else
1716 CurrentState.LastOperatorWrapped = Newline;
1717 }
1718 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1719 CurrentState.LastOperatorWrapped = Newline;
1720 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1721 Current.Previous->isNot(TT_ConditionalExpr)) {
1722 CurrentState.LastOperatorWrapped = Newline;
1723 }
1724 if (Current.is(TT_ArraySubscriptLSquare) &&
1725 CurrentState.StartOfArraySubscripts == 0) {
1726 CurrentState.StartOfArraySubscripts = State.Column;
1727 }
1728
1729 auto IsWrappedConditional = [](const FormatToken &Tok) {
1730 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))
1731 return false;
1732 if (Tok.MustBreakBefore)
1733 return true;
1734
1736 return Next && Next->MustBreakBefore;
1737 };
1738 if (IsWrappedConditional(Current))
1739 CurrentState.IsWrappedConditional = true;
1740 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1741 CurrentState.QuestionColumn = State.Column;
1742 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1747 CurrentState.QuestionColumn = State.Column;
1748 }
1749 if (!Current.opensScope() && !Current.closesScope() &&
1750 Current.isNot(TT_PointerOrReference)) {
1751 State.LowestLevelOnLine =
1752 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1753 }
1754 if (Current.isMemberAccess())
1755 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1756 if (Current.is(TT_SelectorName))
1757 CurrentState.ObjCSelectorNameFound = true;
1758 if (Current.is(TT_CtorInitializerColon) &&
1759 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1760
1761
1762
1763
1764
1765 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1766 FormatStyle::BCIS_BeforeComma
1767 ? 0
1768 : 2);
1769 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1770 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1771 CurrentState.AvoidBinPacking = true;
1772 CurrentState.BreakBeforeParameter =
1773 Style.ColumnLimit > 0 &&
1774 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1775 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1776 } else {
1777 CurrentState.BreakBeforeParameter = false;
1778 }
1779 }
1780 if (Current.is(TT_CtorInitializerColon) &&
1781 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1782 CurrentState.Indent =
1783 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1784 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1785 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1786 CurrentState.AvoidBinPacking = true;
1787 else
1788 CurrentState.BreakBeforeParameter = false;
1789 }
1790 if (Current.is(TT_InheritanceColon)) {
1791 CurrentState.Indent =
1792 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1793 }
1794 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1795 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1796 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1797 CurrentState.LastSpace = State.Column;
1798 if (Current.is(TT_RequiresExpression) &&
1799 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1800 CurrentState.NestedBlockIndent = State.Column;
1801 }
1802
1803
1805
1806
1807
1808
1809
1810
1811
1812 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1813 Previous && Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
1814 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1815 !CurrentState.HasMultipleNestedBlocks) {
1816 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1817 for (ParenState &PState : llvm::drop_end(State.Stack))
1818 PState.NoLineBreak = true;
1819 State.Stack[State.Stack.size() - 2].NestedBlockInlined = false;
1820 }
1821 if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1822 (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1823 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1824 TT_CtorInitializerColon)))) {
1825 CurrentState.NestedBlockInlined =
1827 }
1828
1829 moveStatePastFakeLParens(State, Newline);
1830 moveStatePastScopeCloser(State);
1831
1832
1833 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1834 !State.Stack.back().NoLineBreakInOperand;
1835 moveStatePastScopeOpener(State, Newline);
1836 moveStatePastFakeRParens(State);
1837
1838 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1839 State.StartOfStringLiteral = State.Column + 1;
1840 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1841 State.StartOfStringLiteral = State.Column + 1;
1842 } else if (Current.is(TT_TableGenMultiLineString) &&
1843 State.StartOfStringLiteral == 0) {
1844 State.StartOfStringLiteral = State.Column + 1;
1845 } else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1846 State.StartOfStringLiteral = State.Column;
1847 } else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1848 !Current.isStringLiteral()) {
1849 State.StartOfStringLiteral = 0;
1850 }
1851
1852 State.Column += Current.ColumnWidth;
1853 State.NextToken = State.NextToken->Next;
1854
1855
1856
1857
1858 if (Style.isVerilog() && State.NextToken &&
1859 State.NextToken->MustBreakBefore &&
1860 Keywords.isVerilogEndOfLabel(Current)) {
1861 State.FirstIndent += Style.IndentWidth;
1862 CurrentState.Indent = State.FirstIndent;
1863 }
1864
1865 unsigned Penalty =
1866 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1867
1868 if (Current.Role)
1869 Current.Role->formatFromToken(State, this, DryRun);
1870
1871
1872
1873
1874
1876 Penalty += Previous->Role->formatAfterToken(State, this, DryRun);
1877
1878 return Penalty;
1879}
1880
1881void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
1882 bool Newline) {
1883 const FormatToken &Current = *State.NextToken;
1884 if (Current.FakeLParens.empty())
1885 return;
1886
1888
1889
1890
1891
1892 bool SkipFirstExtraIndent =
1895 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1897 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1898 Previous->is(TT_ObjCMethodExpr));
1899 for (const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1900 const auto &CurrentState = State.Stack.back();
1901 ParenState NewParenState = CurrentState;
1902 NewParenState.Tok = nullptr;
1903 NewParenState.ContainsLineBreak = false;
1904 NewParenState.LastOperatorWrapped = true;
1905 NewParenState.IsChainedConditional = false;
1906 NewParenState.IsWrappedConditional = false;
1907 NewParenState.UnindentOperator = false;
1908 NewParenState.NoLineBreak =
1909 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1910
1911
1913 NewParenState.AvoidBinPacking = false;
1914
1915
1916
1917
1918 if (!Current.isTrailingComment() &&
1919 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1922 (!Style.isJava() && PrecedenceLevel > 0)) &&
1923 (Style.AlignAfterOpenBracket || PrecedenceLevel > prec::Comma ||
1924 Current.NestingLevel == 0) &&
1925 (!Style.isTableGen() ||
1927 TT_TableGenDAGArgListCommaToBreak)))) {
1928 NewParenState.Indent =
1929 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1930 IndentationAndAlignment(CurrentState.LastSpace)});
1931 }
1932
1933
1934
1935
1936 if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) &&
1937 State.Stack.size() > 1) {
1938 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1939 Style.ContinuationIndentWidth;
1940 }
1941
1945 Previous->is(tok::question) && Previous->is(TT_ConditionalExpr)))) &&
1946 !Newline) {
1947
1948
1949 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1950 NewParenState.UnindentOperator = true;
1951
1952 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1953 NewParenState.IsAligned = true;
1954 }
1955
1956
1957
1958
1959
1960
1961
1963 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1965 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
1966 NewParenState.StartOfFunctionCall = State.Column;
1967 }
1968
1969
1970
1971
1972
1973
1975 Previous->is(tok::colon) && Previous->is(TT_ConditionalExpr) &&
1976 &PrecedenceLevel == &Current.FakeLParens.back() &&
1977 !CurrentState.IsWrappedConditional) {
1978 NewParenState.IsChainedConditional = true;
1979 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1981 (!SkipFirstExtraIndent && PrecedenceLevel > prec::Assignment &&
1982 !Current.isTrailingComment())) {
1983 NewParenState.Indent += Style.ContinuationIndentWidth;
1984 }
1986 NewParenState.BreakBeforeParameter = false;
1987 State.Stack.push_back(NewParenState);
1988 SkipFirstExtraIndent = false;
1989 }
1990}
1991
1992void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
1993 for (unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1994 unsigned VariablePos = State.Stack.back().VariablePos;
1995 if (State.Stack.size() == 1) {
1996
1997 break;
1998 }
1999 State.Stack.pop_back();
2000 State.Stack.back().VariablePos = VariablePos;
2001 }
2002
2003 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2004
2005
2006 State.Stack.back().LastSpace -= Style.IndentWidth;
2007 }
2008}
2009
2010void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
2011 bool Newline) {
2012 const FormatToken &Current = *State.NextToken;
2013 if (!Current.opensScope())
2014 return;
2015
2016 const auto &CurrentState = State.Stack.back();
2017
2018
2019 if (Current.isOneOf(tok::less, tok::l_paren) &&
2020 CurrentState.IsCSharpGenericTypeConstraint) {
2021 return;
2022 }
2023
2024 if (Current.MatchingParen && Current.is(BK_Block)) {
2025 moveStateToNewBlock(State, Newline);
2026 return;
2027 }
2028
2029 const bool EndsInComma = [](const FormatToken *Tok) {
2030 if ()
2031 return false;
2032 const auto *Prev = Tok->getPreviousNonComment();
2033 if (!Prev)
2034 return false;
2035 return Prev->is(tok::comma);
2036 }(Current.MatchingParen);
2037
2038 IndentationAndAlignment NewIndent = 0;
2039 unsigned LastSpace = CurrentState.LastSpace;
2040 bool AvoidBinPacking;
2041 bool BreakBeforeParameter = false;
2042 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2043 CurrentState.NestedBlockIndent);
2044 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2046 if (Current.opensBlockOrBlockTypeList(Style)) {
2047 NewIndent = Style.IndentWidth +
2048 std::min(State.Column, CurrentState.NestedBlockIndent);
2049 } else if (Current.is(tok::l_brace)) {
2050 const auto Width = Style.BracedInitializerIndentWidth;
2051 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2052 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2053 } else {
2054 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2055 }
2056 const FormatToken *NextNonComment = Current.getNextNonComment();
2057 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2058 Style.isProto() || !Style.BinPackArguments ||
2059 (NextNonComment && NextNonComment->isOneOf(
2060 TT_DesignatedInitializerPeriod,
2061 TT_DesignatedInitializerLSquare));
2062 BreakBeforeParameter = EndsInComma;
2063 if (Current.ParameterCount > 1)
2064 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2065 } else {
2066 NewIndent = IndentationAndAlignment(std::max(
2067 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2068 Style.ContinuationIndentWidth;
2069
2070 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2071 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2072
2073
2074
2075
2077 if (Next && Next->is(TT_TableGenDAGArgOperatorID))
2078 NewIndent = State.Column + Next->TokenText.size() + 2;
2079 }
2080
2081
2082
2083
2084
2085 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2086 NewIndent = std::max(NewIndent, CurrentState.Indent);
2087 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2088 }
2089
2090
2091
2093 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2094 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2095 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2096
2097 bool BinPackDeclaration =
2099 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2101
2102 bool GenericSelection =
2103 Current.getPreviousNonComment() &&
2104 Current.getPreviousNonComment()->is(tok::kw__Generic);
2105
2106 AvoidBinPacking =
2107 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2108 (Style.isJavaScript() && EndsInComma) ||
2109 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2110 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2111 (Style.ExperimentalAutoDetectBinPacking &&
2113 (!BinPackInconclusiveFunctions && Current.is(PPK_Inconclusive))));
2114
2115 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2116 Style.ObjCBreakBeforeNestedBlockParam) {
2117 if (Style.ColumnLimit) {
2118
2119
2122 BreakBeforeParameter = true;
2123 }
2124 } else {
2125
2126
2128 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {
2129 if (Tok->MustBreakBefore ||
2130 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {
2131 BreakBeforeParameter = true;
2132 break;
2133 }
2134 }
2135 }
2136 }
2137
2138 if (Style.isJavaScript() && EndsInComma)
2139 BreakBeforeParameter = true;
2140 }
2141
2142
2143
2144 bool NoLineBreak =
2145 Current.Children.empty() &&
2146 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2147 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2148 (Current.is(TT_TemplateOpener) &&
2149 CurrentState.ContainsUnwrappedBuilder));
2150 State.Stack.push_back(
2151 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2152 auto &NewState = State.Stack.back();
2153 NewState.NestedBlockIndent = NestedBlockIndent;
2154 NewState.BreakBeforeParameter = BreakBeforeParameter;
2155 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2156
2157 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2158 Current.is(tok::l_paren)) {
2159
2161 while (next) {
2162 if (next->is(TT_LambdaLSquare)) {
2163 NewState.HasMultipleNestedBlocks = true;
2164 break;
2165 }
2166 next = next->Next;
2167 }
2168 }
2169
2170 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2171 Current.Previous &&
2172 Current.Previous->is(tok::at);
2173}
2174
2175void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
2176 const FormatToken &Current = *State.NextToken;
2177 if (!Current.closesScope())
2178 return;
2179
2180
2181
2182 if (State.Stack.size() > 1 &&
2183 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2184 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2185 State.NextToken->is(TT_TemplateCloser) ||
2186 State.NextToken->is(TT_TableGenListCloser) ||
2187 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2188 State.Stack.pop_back();
2189 }
2190
2191 auto &CurrentState = State.Stack.back();
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2204 Current.MatchingParen->Previous) {
2205 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2206 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2207 CurrentScopeOpener.MatchingParen) {
2208 int NecessarySpaceInLine =
2210 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2211 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2212 Style.ColumnLimit) {
2213 CurrentState.BreakBeforeParameter = false;
2214 }
2215 }
2216 }
2217
2218 if (Current.is(tok::r_square)) {
2219
2220 const FormatToken *NextNonComment = Current.getNextNonComment();
2221 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2222 CurrentState.StartOfArraySubscripts = 0;
2223 }
2224}
2225
2226void ContinuationIndenter::moveStateToNewBlock(LineState &State, bool NewLine) {
2227 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2228 State.NextToken->is(TT_LambdaLBrace) &&
2229 !State.Line->MightBeFunctionDecl) {
2230 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2231 State.Stack.back().NestedBlockIndent = State.FirstIndent + Indent;
2232 }
2233 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2234
2235 unsigned NewIndent =
2236 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2237 ? Style.ObjCBlockIndentWidth
2238 : Style.IndentWidth);
2239
2240
2241
2242
2243
2244
2245 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2246 State.NextToken->is(TT_LambdaLBrace);
2247
2248 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2249 State.Stack.back().LastSpace,
2250 true, NoLineBreak));
2251 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2252 State.Stack.back().BreakBeforeParameter = true;
2253}
2254
2258 size_t LastNewlinePos = Text.find_last_of("\n");
2259 if (LastNewlinePos == StringRef::npos) {
2260 return StartColumn +
2262 } else {
2264 0, TabWidth, Encoding);
2265 }
2266}
2267
2268unsigned ContinuationIndenter::reformatRawStringLiteral(
2269 const FormatToken &Current, LineState &State,
2270 const FormatStyle &RawStringStyle, bool DryRun, bool Newline) {
2271 unsigned StartColumn = State.Column - Current.ColumnWidth;
2273 StringRef NewDelimiter =
2275 if (NewDelimiter.empty())
2276 NewDelimiter = OldDelimiter;
2277
2278
2279 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2280 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2281
2282
2283 std::string RawText = std::string(
2284 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2285 if (NewDelimiter != OldDelimiter) {
2286
2287
2288 std::string CanonicalDelimiterSuffix = (")" + NewDelimiter + "\"").str();
2289 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
2290 NewDelimiter = OldDelimiter;
2291 }
2292
2293 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2294 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2295
2296
2297 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n';
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330 unsigned CurrentIndent =
2331 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2332 ? State.Stack.back().NestedBlockIndent
2333 : State.Stack.back().Indent.Total;
2334 unsigned NextStartColumn = ContentStartsOnNewline
2335 ? CurrentIndent + Style.IndentWidth
2336 : FirstStartColumn;
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346 unsigned LastStartColumn =
2347 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2348
2349 std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat(
2350 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2351 FirstStartColumn, NextStartColumn, LastStartColumn, "",
2352 nullptr);
2353
2355 if (!NewCode)
2356 return addMultilineToken(Current, State);
2357 if (!DryRun) {
2358 if (NewDelimiter != OldDelimiter) {
2359
2360
2361 SourceLocation PrefixDelimiterStart =
2362 Current.Tok.getLocation().getLocWithOffset(2);
2363 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2364 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2365 if (PrefixErr) {
2366 llvm::errs()
2367 << "Failed to update the prefix delimiter of a raw string: "
2368 << llvm::toString(std::move(PrefixErr)) << "\n";
2369 }
2370
2371
2372 SourceLocation SuffixDelimiterStart =
2373 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2374 1 - OldDelimiter.size());
2375 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2376 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2377 if (SuffixErr) {
2378 llvm::errs()
2379 << "Failed to update the suffix delimiter of a raw string: "
2380 << llvm::toString(std::move(SuffixErr)) << "\n";
2381 }
2382 }
2383 SourceLocation OriginLoc =
2384 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2385 for (const tooling::Replacement &Fix : Fixes.first) {
2386 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2387 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2388 Fix.getLength(), Fix.getReplacementText()));
2389 if (Err) {
2390 llvm::errs() << "Failed to reformat raw string: "
2391 << llvm::toString(std::move(Err)) << "\n";
2392 }
2393 }
2394 }
2396 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2397 State.Column = RawLastLineEndColumn + NewSuffixSize;
2398
2399
2400
2401 unsigned PrefixExcessCharacters =
2402 StartColumn + NewPrefixSize > Style.ColumnLimit
2403 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2404 : 0;
2406 ContentStartsOnNewline || (NewCode->find('\n') != std:🧵:npos);
2408
2409 for (ParenState &Paren : State.Stack)
2410 Paren.BreakBeforeParameter = true;
2411 }
2412 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2413}
2414
2415unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,
2417
2418 for (ParenState &Paren : State.Stack)
2419 Paren.BreakBeforeParameter = true;
2420
2421 unsigned ColumnsUsed = State.Column;
2422
2423
2424 State.Column = Current.LastLineColumnWidth;
2425
2427 return Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit(State));
2428 return 0;
2429}
2430
2431unsigned ContinuationIndenter::handleEndOfLine(const FormatToken &Current,
2433 bool AllowBreak, bool Newline) {
2434 unsigned Penalty = 0;
2435
2436
2437 auto RawStringStyle = getRawStringStyle(Current, State);
2438 if (RawStringStyle && !Current.Finalized) {
2439 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2440 Newline);
2441 } else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2442
2443
2444 Penalty = addMultilineToken(Current, State);
2446
2447 LineState OriginalState = State;
2448
2449
2450
2451 bool Strict = false;
2452
2453
2454 bool Exceeded = false;
2455 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2456 Current, State, AllowBreak, true, Strict);
2457 if (Exceeded) {
2458
2459
2460 LineState StrictState = OriginalState;
2461 unsigned StrictPenalty =
2462 breakProtrudingToken(Current, StrictState, AllowBreak,
2463 true, true)
2464 .first;
2465 Strict = StrictPenalty <= Penalty;
2466 if (Strict) {
2467 Penalty = StrictPenalty;
2468 State = StrictState;
2469 }
2470 }
2471 if (!DryRun) {
2472
2473
2474 breakProtrudingToken(Current, OriginalState, AllowBreak, false,
2475 Strict);
2476 }
2477 }
2479 unsigned ExcessCharacters = State.Column - getColumnLimit(State);
2480 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2481 }
2482 return Penalty;
2483}
2484
2485
2486
2488
2489 auto Tok = Current.getPreviousNonComment();
2490 if ( || Tok->isNot(tok::l_paren))
2491 return "";
2492 Tok = Tok->getPreviousNonComment();
2493 if ()
2494 return "";
2495 if (Tok->is(TT_TemplateCloser)) {
2496 Tok = Tok->MatchingParen;
2497 if (Tok)
2498 Tok = Tok->getPreviousNonComment();
2499 }
2500 if ( || Tok->isNot(tok::identifier))
2501 return "";
2502 return Tok->TokenText;
2503}
2504
2505std::optional
2506ContinuationIndenter::getRawStringStyle(const FormatToken &Current,
2507 const LineState &State) {
2508 if (!Current.isStringLiteral())
2509 return std::nullopt;
2511 if (!Delimiter)
2512 return std::nullopt;
2513 auto RawStringStyle = RawStringFormats.getDelimiterStyle(*Delimiter);
2514 if (!RawStringStyle && Delimiter->empty()) {
2515 RawStringStyle = RawStringFormats.getEnclosingFunctionStyle(
2517 }
2518 if (!RawStringStyle)
2519 return std::nullopt;
2520 RawStringStyle->ColumnLimit = getColumnLimit(State);
2521 return RawStringStyle;
2522}
2523
2524std::unique_ptr
2525ContinuationIndenter::createBreakableToken(const FormatToken &Current,
2526 LineState &State, bool AllowBreak) {
2527 unsigned StartColumn = State.Column - Current.ColumnWidth;
2528 if (Current.isStringLiteral()) {
2529
2530
2531 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2532 !AllowBreak) {
2533 return nullptr;
2534 }
2535
2536
2537
2538
2539
2540
2542 return nullptr;
2543
2544
2545 if (Current.IsUnterminatedLiteral)
2546 return nullptr;
2547
2548
2549 if (State.Stack.back().IsInsideObjCArrayLiteral)
2550 return nullptr;
2551
2552
2553
2554
2555
2556 if (Style.isVerilog() && Current.Previous &&
2557 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2558 return nullptr;
2559 }
2560 StringRef Text = Current.TokenText;
2561
2562
2563
2564
2565
2567 ? 0
2569
2570 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2571 Style.isCSharp()) {
2573 if (Style.isJavaScript() && Text.starts_with("'") &&
2574 Text.ends_with("'")) {
2576 } else if (Style.isCSharp() && Text.starts_with("@\"") &&
2577 Text.ends_with("\"")) {
2579 } else if (Text.starts_with("\"") && Text.ends_with("\"")) {
2581 } else {
2582 return nullptr;
2583 }
2584 return std::make_unique(
2585 Current, QuoteStyle,
2588 }
2589
2590 StringRef Prefix;
2591 StringRef Postfix;
2592
2593
2594
2595
2596 if ((Text.ends_with(Postfix = "\"") &&
2597 (Text.starts_with(Prefix = "@\"") || Text.starts_with(Prefix = "\"") ||
2598 Text.starts_with(Prefix = "u\"") ||
2599 Text.starts_with(Prefix = "U\"") ||
2600 Text.starts_with(Prefix = "u8\"") ||
2601 Text.starts_with(Prefix = "L\""))) ||
2602 (Text.starts_with(Prefix = "_T(\"") &&
2603 Text.ends_with(Postfix = "\")"))) {
2604 return std::make_unique(
2606 State.Line->InPPDirective, Encoding, Style);
2607 }
2608 } else if (Current.is(TT_BlockComment)) {
2609 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2610
2611
2612
2614 return nullptr;
2615 }
2616 return std::make_unique(
2617 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2618 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2619 } else if (Current.is(TT_LineComment) &&
2620 (!Current.Previous ||
2621 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2622 bool RegularComments = [&]() {
2623 for (const FormatToken *T = &Current; T && T->is(TT_LineComment);
2625 if (!(T->TokenText.starts_with("//") || T->TokenText.starts_with("#")))
2626 return false;
2627 }
2628 return true;
2629 }();
2630 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2631 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2633 return nullptr;
2634 }
2635 return std::make_unique(
2636 Current, StartColumn, false, Encoding, Style);
2637 }
2638 return nullptr;
2639}
2640
2641std::pair<unsigned, bool>
2642ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
2643 LineState &State, bool AllowBreak,
2644 bool DryRun, bool Strict) {
2645 std::unique_ptr Token =
2646 createBreakableToken(Current, State, AllowBreak);
2647 if (!Token)
2648 return {0, false};
2649 assert(Token->getLineCount() > 0);
2651 if (Current.is(TT_LineComment)) {
2652
2653 ColumnLimit = Style.ColumnLimit;
2654 }
2655 if (ColumnLimit == 0) {
2656
2657
2658 ColumnLimit = std::numeric_limits<decltype(ColumnLimit)>::max();
2659 }
2660 if (Current.UnbreakableTailLength >= ColumnLimit)
2661 return {0, false};
2662
2663
2664 unsigned StartColumn = State.Column - Current.ColumnWidth;
2665 unsigned NewBreakPenalty = Current.isStringLiteral()
2666 ? Style.PenaltyBreakString
2667 : Style.PenaltyBreakComment;
2668
2669
2670 bool Exceeded = false;
2671
2672 bool BreakInserted = Token->introducesBreakBeforeToken();
2673
2674
2675 bool NewBreakBefore = false;
2676
2677
2678
2679 bool Reflow = false;
2680
2681
2682 unsigned TailOffset = 0;
2683
2684 unsigned ContentStartColumn =
2685 Token->getContentStartColumn(0, false);
2686
2687 unsigned RemainingTokenColumns =
2688 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2689
2690 if (!DryRun)
2691 Token->adaptStartOfLine(0, Whitespaces);
2692
2693 unsigned ContentIndent = 0;
2694 unsigned Penalty = 0;
2695 LLVM_DEBUG(llvm::dbgs() << "Breaking protruding token at column "
2696 << StartColumn << ".\n");
2697 for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2698 LineIndex != EndIndex; ++LineIndex) {
2699 LLVM_DEBUG(llvm::dbgs()
2700 << " Line: " << LineIndex << " (Reflow: " << Reflow << ")\n");
2701 NewBreakBefore = false;
2702
2703
2704
2705 bool TryReflow = Reflow;
2706
2707 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2708 LLVM_DEBUG(llvm::dbgs() << " Over limit, need: "
2709 << (ContentStartColumn + RemainingTokenColumns)
2710 << ", space: " << ColumnLimit
2711 << ", reflown prefix: " << ContentStartColumn
2712 << ", offset in line: " << TailOffset << "\n");
2713
2714
2715
2716
2718 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2719 ContentStartColumn, CommentPragmasRegex);
2720 if (Split.first == StringRef::npos) {
2721
2722
2723 if (LineIndex < EndIndex - 1) {
2724
2725
2726 Penalty += Style.PenaltyExcessCharacter *
2727 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2728 }
2729 LLVM_DEBUG(llvm::dbgs() << " No break opportunity.\n");
2730 break;
2731 }
2732 assert(Split.first != 0);
2733
2734 if (Token->supportsReflow()) {
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754 unsigned ToSplitColumns = Token->getRangeLength(
2755 LineIndex, TailOffset, Split.first, ContentStartColumn);
2756 LLVM_DEBUG(llvm::dbgs() << " ToSplit: " << ToSplitColumns << "\n");
2757
2759 LineIndex, TailOffset + Split.first + Split.second, ColumnLimit,
2760 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2761
2762
2763 unsigned ToNextSplitColumns = 0;
2764 if (NextSplit.first == StringRef::npos) {
2765 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2766 ContentStartColumn);
2767 } else {
2768 ToNextSplitColumns = Token->getRangeLength(
2769 LineIndex, TailOffset,
2770 Split.first + Split.second + NextSplit.first, ContentStartColumn);
2771 }
2772
2773
2774 ToNextSplitColumns =
2775 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2776 LLVM_DEBUG(llvm::dbgs()
2777 << " ContentStartColumn: " << ContentStartColumn << "\n");
2778 LLVM_DEBUG(llvm::dbgs()
2779 << " ToNextSplit: " << ToNextSplitColumns << "\n");
2780
2781
2782 bool ContinueOnLine =
2783 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2784 unsigned ExcessCharactersPenalty = 0;
2785 if (!ContinueOnLine && !Strict) {
2786
2787
2788 ExcessCharactersPenalty =
2789 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2790 Style.PenaltyExcessCharacter;
2791 LLVM_DEBUG(llvm::dbgs()
2792 << " Penalty excess: " << ExcessCharactersPenalty
2793 << "\n break : " << NewBreakPenalty << "\n");
2794 if (ExcessCharactersPenalty < NewBreakPenalty) {
2795 Exceeded = true;
2796 ContinueOnLine = true;
2797 }
2798 }
2799 if (ContinueOnLine) {
2800 LLVM_DEBUG(llvm::dbgs() << " Continuing on line...\n");
2801
2802
2803 TryReflow = true;
2804 if (!DryRun) {
2805 Token->compressWhitespace(LineIndex, TailOffset, Split,
2806 Whitespaces);
2807 }
2808
2809 ContentStartColumn += ToSplitColumns + 1;
2810 Penalty += ExcessCharactersPenalty;
2811 TailOffset += Split.first + Split.second;
2812 RemainingTokenColumns = Token->getRemainingLength(
2813 LineIndex, TailOffset, ContentStartColumn);
2814 continue;
2815 }
2816 }
2817 LLVM_DEBUG(llvm::dbgs() << " Breaking...\n");
2818
2819
2820
2821 if (!Reflow)
2822 ContentIndent = Token->getContentIndent(LineIndex);
2823 LLVM_DEBUG(llvm::dbgs()
2824 << " ContentIndent: " << ContentIndent << "\n");
2825 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2826 LineIndex, true);
2827
2828 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2829 LineIndex, TailOffset + Split.first + Split.second,
2830 ContentStartColumn);
2831 if (NewRemainingTokenColumns == 0) {
2832
2833 ContentIndent = 0;
2834 ContentStartColumn =
2835 Token->getContentStartColumn(LineIndex, true);
2836 NewRemainingTokenColumns = Token->getRemainingLength(
2837 LineIndex, TailOffset + Split.first + Split.second,
2838 ContentStartColumn);
2839 }
2840
2841
2842
2843
2844 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2845
2846 break;
2847 }
2848
2849 LLVM_DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first
2850 << ", " << Split.second << "\n");
2851 if (!DryRun) {
2852 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2853 Whitespaces);
2854 }
2855
2856 Penalty += NewBreakPenalty;
2857 TailOffset += Split.first + Split.second;
2858 RemainingTokenColumns = NewRemainingTokenColumns;
2859 BreakInserted = true;
2860 NewBreakBefore = true;
2861 }
2862
2863
2864 if (LineIndex + 1 != EndIndex) {
2865 unsigned NextLineIndex = LineIndex + 1;
2866 if (NewBreakBefore) {
2867
2868
2869 TryReflow = true;
2870 }
2871 if (TryReflow) {
2872
2873
2874
2875
2876
2877
2878 Reflow = false;
2879
2880
2881
2882
2883
2884
2885 ContentStartColumn += RemainingTokenColumns + 1;
2886
2887
2888
2890 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2891 LLVM_DEBUG(llvm::dbgs()
2892 << " Size of reflown text: " << ContentStartColumn
2893 << "\n Potential reflow split: ");
2894 if (SplitBeforeNext.first != StringRef::npos) {
2895 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first << ", "
2896 << SplitBeforeNext.second << "\n");
2897 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2898
2899
2900 RemainingTokenColumns = Token->getRemainingLength(
2901 NextLineIndex, TailOffset, ContentStartColumn);
2902 Reflow = true;
2903 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2904 LLVM_DEBUG(llvm::dbgs()
2905 << " Over limit after reflow, need: "
2906 << (ContentStartColumn + RemainingTokenColumns)
2907 << ", space: " << ColumnLimit
2908 << ", reflown prefix: " << ContentStartColumn
2909 << ", offset in line: " << TailOffset << "\n");
2910
2911
2912
2913
2915 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2916 ContentStartColumn, CommentPragmasRegex);
2917 if (Split.first == StringRef::npos) {
2918 LLVM_DEBUG(llvm::dbgs() << " Did not find later break\n");
2919 Reflow = false;
2920 } else {
2921
2922
2923
2924 unsigned ToSplitColumns = Token->getRangeLength(
2925 NextLineIndex, TailOffset, Split.first, ContentStartColumn);
2926 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2927 LLVM_DEBUG(llvm::dbgs() << " Next split protrudes, need: "
2928 << (ContentStartColumn + ToSplitColumns)
2929 << ", space: " << ColumnLimit);
2930 unsigned ExcessCharactersPenalty =
2931 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2932 Style.PenaltyExcessCharacter;
2933 if (NewBreakPenalty < ExcessCharactersPenalty)
2934 Reflow = false;
2935 }
2936 }
2937 }
2938 } else {
2939 LLVM_DEBUG(llvm::dbgs() << "not found.\n");
2940 }
2941 }
2942 if (!Reflow) {
2943
2944
2945
2946 TailOffset = 0;
2947 ContentStartColumn =
2948 Token->getContentStartColumn(NextLineIndex, false);
2949 RemainingTokenColumns = Token->getRemainingLength(
2950 NextLineIndex, TailOffset, ContentStartColumn);
2951
2952 if (!DryRun)
2953 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2954 } else {
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968 if (NewBreakBefore) {
2969 assert(Penalty >= NewBreakPenalty);
2970 Penalty -= NewBreakPenalty;
2971 }
2972 if (!DryRun)
2973 Token->reflow(NextLineIndex, Whitespaces);
2974 }
2975 }
2976 }
2977
2979 Token->getSplitAfterLastLine(TailOffset);
2980 if (SplitAfterLastLine.first != StringRef::npos) {
2981 LLVM_DEBUG(llvm::dbgs() << "Replacing whitespace after last line.\n");
2982
2983
2984
2985 Penalty += Style.PenaltyExcessCharacter *
2986 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2987
2988 if (!DryRun) {
2989 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2990 Whitespaces);
2991 }
2992 ContentStartColumn =
2993 Token->getContentStartColumn(Token->getLineCount() - 1, true);
2994 RemainingTokenColumns = Token->getRemainingLength(
2995 Token->getLineCount() - 1,
2996 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2997 ContentStartColumn);
2998 }
2999
3000 State.Column = ContentStartColumn + RemainingTokenColumns -
3001 Current.UnbreakableTailLength;
3002
3003 if (BreakInserted) {
3004 if (!DryRun)
3005 Token->updateAfterBroken(Whitespaces);
3006
3007
3008
3009
3010 if (Current.isNot(TT_LineComment))
3011 for (ParenState &Paren : State.Stack)
3012 Paren.BreakBeforeParameter = true;
3013
3014 if (Current.is(TT_BlockComment))
3015 State.NoContinuation = true;
3016
3017 State.Stack.back().LastSpace = StartColumn;
3018 }
3019
3020 Token->updateNextToken(State);
3021
3022 return {Penalty, Exceeded};
3023}
3024
3026
3027 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3028}
3029
3030bool ContinuationIndenter::nextIsMultilineString(const LineState &State) {
3031 const FormatToken &Current = *State.NextToken;
3032 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))
3033 return false;
3034
3035
3036
3037 if (Current.TokenText.starts_with("R\""))
3038 return false;
3040 return true;
3041 if (Current.getNextNonComment() &&
3042 Current.getNextNonComment()->isStringLiteral()) {
3043 return true;
3044 }
3045 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3047 Style.ColumnLimit) {
3048 return true;
3049 }
3050 return false;
3051}
3052
3053}
3054}
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
This file declares Format APIs to be used internally by the formatting library implementation.
This file contains the declaration of the FormatToken, a wrapper around Token with additional informa...
unsigned UnbreakableTailLength
The length of following tokens until the next natural split point, or the next token that can be brok...
unsigned ColumnWidth
The width of the non-whitespace parts of the token (or its first line for multi-line tokens) in colum...
int Newlines
The number of newlines immediately before the Token after formatting.
StringRef TokenText
The raw text of the token.
unsigned IsMultiline
Whether the token text contains newlines (escaped or not).
unsigned LongestObjCSelectorName
If this is the first ObjC selector name in an ObjC method definition or call, this contains the lengt...
FormatToken * Previous
The previous token in the unwrapped line.
FormatToken * Next
The next token in the unwrapped line.
Various functions to configurably format source code.
Defines and computes precedence levels for binary/ternary operators.
static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
WhitespaceManager class manages whitespace around tokens and their replacements.
__DEVICE__ int max(int __a, int __b)
This class handles loading and caching of source files into memory.
SourceLocation getEnd() const
SourceLocation getBegin() const
Token - This structure provides full information about a lexed token.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
std::pair< StringRef::size_type, unsigned > Split
Contains starting character index and length of split.
bool canBreak(const LineState &State)
Returns true, if a line break after State is allowed.
Definition ContinuationIndenter.cpp:337
unsigned addTokenToState(LineState &State, bool Newline, bool DryRun, unsigned ExtraSpaces=0)
Appends the next token to State and updates information necessary for indentation.
Definition ContinuationIndenter.cpp:712
unsigned getColumnLimit(const LineState &State) const
Get the column limit for this line.
Definition ContinuationIndenter.cpp:3025
LineState getInitialState(unsigned FirstIndent, unsigned FirstStartColumn, const AnnotatedLine *Line, bool DryRun)
Get the initial state, i.e.
Definition ContinuationIndenter.cpp:293
ContinuationIndenter(const FormatStyle &Style, const AdditionalKeywords &Keywords, const SourceManager &SourceMgr, WhitespaceManager &Whitespaces, encoding::Encoding Encoding, bool BinPackInconclusiveFunctions)
Constructs a ContinuationIndenter to format Line starting in column FirstIndent.
Definition ContinuationIndenter.cpp:282
bool mustBreak(const LineState &State)
Returns true, if a line break after State is mandatory.
Definition ContinuationIndenter.cpp:437
Manages the whitespaces around tokens and their replacements.
unsigned columnWidthWithTabs(StringRef Text, unsigned StartColumn, unsigned TabWidth, Encoding Encoding)
Returns the number of columns required to display the Text, starting from the StartColumn on a termin...
std::pair< tooling::Replacements, unsigned > reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, FormattingAttemptStatus *Status)
Reformats the given Ranges in the code fragment Code.
static bool mustBreakBinaryOperation(const FormatToken &Current, const FormatStyle &Style)
Definition ContinuationIndenter.cpp:148
static unsigned getLastLineEndColumn(StringRef Text, unsigned StartColumn, unsigned TabWidth, encoding::Encoding Encoding)
Definition ContinuationIndenter.cpp:2255
static bool shouldUnindentNextOperator(const FormatToken &Tok)
Definition ContinuationIndenter.cpp:41
bool switchesFormatting(const FormatToken &Token)
Checks if Token switches formatting, like /* clang-format off */.
static bool hasNestedBlockInlined(const FormatToken *Previous, const FormatToken &Current, const FormatStyle &Style)
Definition ContinuationIndenter.cpp:1688
static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok)
Definition ContinuationIndenter.cpp:127
static unsigned getLengthToNextOperator(const FormatToken &Tok)
Definition ContinuationIndenter.cpp:119
static bool isAlignableBinaryOperator(const FormatToken &Token)
Definition ContinuationIndenter.cpp:132
static unsigned getLengthToMatchingParen(const FormatToken &Tok, ArrayRef< ParenState > Stack)
Definition ContinuationIndenter.cpp:49
static bool shouldIndentWrappedSelectorName(const FormatStyle &Style, LineType LineType)
Definition ContinuationIndenter.cpp:34
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)
static std::optional< StringRef > getRawStringDelimiter(StringRef TokenText)
Definition ContinuationIndenter.cpp:170
static StringRef getCanonicalRawStringDelimiter(const FormatStyle &Style, FormatStyle::LanguageKind Language)
Definition ContinuationIndenter.cpp:196
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language)
static bool startsNextOperand(const FormatToken &Current)
Definition ContinuationIndenter.cpp:141
static bool opensProtoMessageField(const FormatToken &LessTok, const FormatStyle &Style)
Definition ContinuationIndenter.cpp:157
static StringRef getEnclosingFunctionName(const FormatToken &Current)
Definition ContinuationIndenter.cpp:2487
@ LT_PreprocessorDirective
bool startsNextParameter(const FormatToken &Current, const FormatStyle &Style)
The JSON file list parser is used to communicate input to InstallAPI.
unsigned TabWidth
The number of columns used for tab stops.
std::vector< RawStringFormat > RawStringFormats
Defines hints for detecting supported languages code blocks in raw strings.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Language
The language for the input, used to select and validate the language standard and possible actions.
const FunctionProtoType * T
BinPackStyle ObjCBinPackProtocolList
Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...
unsigned MaxEmptyLinesToKeep
The maximum number of consecutive empty lines to keep.
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...
See documentation of RawStringFormats.
std::vector< std::string > Delimiters
A list of raw string delimiters that match this language.
std::vector< std::string > EnclosingFunctions
A list of enclosing function names that match this language.
std::string BasedOnStyle
The style name on which this raw string format is based on. If not specified, the raw string format i...
LanguageKind Language
The language of this raw string.
A wrapper around a Token storing information about the whitespace characters preceding it.
unsigned NestingLevel
The nesting level of this token, i.e.
bool MacroParent
When macro expansion introduces nodes with children, those are marked as MacroParent.
unsigned StartsBinaryExpression
true if this token starts a binary expression, i.e.
unsigned OriginalColumn
The original 0-based column of this token, including expanded tabs.
unsigned CanBreakBefore
true if it is allowed to break before this token.
StringRef TokenText
The raw text of the token.
unsigned LongestObjCSelectorName
If this is the first ObjC selector name in an ObjC method definition or call, this contains the lengt...
unsigned LastNewlineOffset
The offset just past the last ' ' in this token's leading whitespace (relative to WhiteSpaceStart).
bool isNoneOf(Ts... Ks) const
FormatToken * Next
The next token in the unwrapped line.
unsigned IsMultiline
Whether the token text contains newlines (escaped or not).
unsigned NewlinesBefore
The number of newlines immediately before the Token.
unsigned SpacesRequiredBefore
The number of spaces that should be inserted before this token.
std::shared_ptr< TokenRole > Role
A token can have a special role that can carry extra information about the token's formatting.
unsigned MustBreakBefore
Whether there must be a line break before this token.
unsigned ColumnWidth
The width of the non-whitespace parts of the token (or its first line for multi-line tokens) in colum...
unsigned ObjCSelectorNameParts
If this is the first ObjC selector name in an ObjC method definition or call, this contains the numbe...
unsigned UnbreakableTailLength
The length of following tokens until the next natural split point, or the next token that can be brok...
bool is(tok::TokenKind Kind) const
unsigned TotalLength
The total length of the unwrapped line up to and including this token.
bool isOneOf(A K1, B K2) const
SourceRange WhitespaceRange
The range of the whitespace immediately preceding the Token.
FormatToken * MatchingParen
If this is a bracket, this points to the matching one.
FormatToken * Previous
The previous token in the unwrapped line.
Represents the spaces at the start of a line, keeping track of what the spaces are for.
IndentationAndAlignment operator+(unsigned Spaces) const
Adding indentation is more common than padding. So the operator does that.
Definition ContinuationIndenter.cpp:249
IndentationAndAlignment(unsigned Total, unsigned IndentedFrom)
Definition ContinuationIndenter.cpp:263
IndentationAndAlignment addPadding(unsigned Spaces) const
Add spaces for right-justifying the token.
Definition ContinuationIndenter.cpp:244
IndentationAndAlignment operator-(unsigned Spaces) const
Definition ContinuationIndenter.cpp:254
IndentationAndAlignment & operator+=(unsigned Spaces)
Definition ContinuationIndenter.cpp:258
bool operator<(const IndentationAndAlignment &Other) const
Definition ContinuationIndenter.cpp:270
unsigned IndentedFrom
The column that the position of the start of the line is calculated from.
The current state when indenting a unwrapped line.
const AnnotatedLine * Line
The line that is being formatted.
unsigned Column
The number of used columns in the current line.
SmallVector< ParenState > Stack
A stack keeping track of properties applying to parenthesis levels.
unsigned FirstIndent
The indent of the first token.
llvm::StringMap< FormatStyle > EnclosingFunctionStyle
std::optional< FormatStyle > getDelimiterStyle(StringRef Delimiter) const
Definition ContinuationIndenter.cpp:227
std::optional< FormatStyle > getEnclosingFunctionStyle(StringRef EnclosingFunction) const
Definition ContinuationIndenter.cpp:235
RawStringFormatStyleManager(const FormatStyle &CodeStyle)
Definition ContinuationIndenter.cpp:204
llvm::StringMap< FormatStyle > DelimiterStyle