18#define DEBUG_TYPE "format-indenter"
35 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
84 int MatchingStackIndex = Stack.size() - 1;
90 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != LBrace)
92 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
94 for (; End->Next; End = End->Next) {
95 if (End->Next->CanBreakBefore)
97 if (!End->Next->closesScope())
99 if (End->Next->MatchingParen &&
100 End->Next->MatchingParen->isOneOf(
101 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
102 const ParenState *State = FindParenState(End->Next->MatchingParen);
103 if (State && State->BreakBeforeClosingBrace)
126 if (Current.
is(TT_CtorInitializerComma) &&
133 ((
Previous.isNot(TT_CtorInitializerComma) ||
136 (
Previous.isNot(TT_InheritanceComma) ||
142 if (LessTok.
isNot(tok::less))
154 if (TokenText.size() < 5
155 || !TokenText.starts_with(
"R\"") || !TokenText.ends_with(
"\"")) {
162 size_t LParenPos = TokenText.substr(0, 19).find_first_of(
'(');
163 if (LParenPos == StringRef::npos)
165 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);
168 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
169 if (TokenText[RParenPos] !=
')')
171 if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter))
183 return StringRef(Format.CanonicalDelimiter);
190 std::optional<FormatStyle> LanguageStyle =
192 if (!LanguageStyle) {
195 RawStringFormat.Language, &PredefinedStyle)) {
197 PredefinedStyle.
Language = RawStringFormat.Language;
199 LanguageStyle = PredefinedStyle;
202 for (StringRef Delimiter : RawStringFormat.Delimiters)
204 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)
209std::optional<FormatStyle>
217std::optional<FormatStyle>
219 StringRef EnclosingFunction)
const {
231 bool BinPackInconclusiveFunctions)
232 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
233 Whitespaces(Whitespaces), Encoding(Encoding),
234 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
235 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {
236 assert(
IsCpp == Style.isCpp());
240 unsigned FirstStartColumn,
244 State.FirstIndent = FirstIndent;
245 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
246 State.Column = FirstStartColumn;
248 State.Column = FirstIndent;
258 State.NextToken =
Line->First;
259 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
262 State.NoContinuation =
false;
263 State.StartOfStringLiteral = 0;
264 State.NoLineBreak =
false;
265 State.StartOfLineLevel = 0;
266 State.LowestLevelOnLine = 0;
267 State.IgnoreStackForComparison =
false;
272 auto &CurrentState = State.Stack.back();
273 CurrentState.AvoidBinPacking =
true;
274 CurrentState.BreakBeforeParameter =
true;
275 CurrentState.AlignColons =
false;
279 moveStateToNextToken(State, DryRun,
false);
286 const auto &CurrentState = State.Stack.back();
287 assert(&
Previous == Current.Previous);
288 if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
289 Current.closesBlockOrBlockTypeList(Style))) {
294 if (!Current.MustBreakBefore &&
Previous.is(tok::l_brace) &&
297 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
306 State.LowestLevelOnLine < State.StartOfLineLevel &&
307 State.LowestLevelOnLine < Current.NestingLevel) {
310 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
315 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
316 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
317 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks &&
324 if (Current.is(TT_FunctionDeclarationName)) {
331 assert(State.Column >= State.FirstIndent);
332 if (State.Column - State.FirstIndent < 6)
339 if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
344 Current.isNot(TT_LambdaLBrace)) &&
345 CurrentState.NoLineBreakInOperand) {
352 if (Current.is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
354 Previous.MatchingParen->Previous->MatchingParen &&
355 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
357 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
361 return !State.NoLineBreak && !CurrentState.NoLineBreak;
367 const auto &CurrentState = State.Stack.back();
369 Current.is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
373 if (Current.MustBreakBefore ||
374 (Current.is(TT_InlineASMColon) &&
380 if (CurrentState.BreakBeforeClosingBrace &&
381 (Current.closesBlockOrBlockTypeList(Style) ||
382 (Current.is(tok::r_brace) &&
383 Current.isBlockIndentedInitRBrace(Style)))) {
386 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
390 Current.ObjCSelectorNameParts > 1 &&
391 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
396 if (CurrentState.IsCSharpGenericTypeConstraint &&
397 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
401 (
Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
402 State.Line->First->isNot(TT_AttributeSquare) &&
IsCpp &&
411 Previous.is(TT_ConditionalExpr))) &&
412 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
413 !Current.isOneOf(tok::r_paren, tok::r_brace)) {
416 if (CurrentState.IsChainedConditional &&
418 Current.is(tok::colon)) ||
424 (
Previous.is(TT_ArrayInitializerLSquare) &&
433 const FormatToken &BreakConstructorInitializersToken =
437 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
438 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
440 CurrentState.BreakBeforeParameter) &&
441 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
448 if (Current.is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
449 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
452 if (Current.is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
453 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
455 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
459 unsigned NewLineColumn = getNewLineColumn(State);
460 if (Current.isMemberAccess() && Style.
ColumnLimit != 0 &&
462 (State.Column > NewLineColumn ||
463 Current.NestingLevel < State.StartOfLineLevel)) {
468 (CurrentState.CallContinuation != 0 ||
469 CurrentState.BreakBeforeParameter) &&
475 !(State.Column <= NewLineColumn && Style.
isJavaScript()) &&
476 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
482 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
483 Current.CanBreakBefore) {
487 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
492 Previous.is(tok::comma) || Current.NestingLevel < 2) &&
493 !
Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
495 !
Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
496 nextIsMultilineString(State)) {
503 if (
Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) {
504 const auto PreviousPrecedence =
Previous.getPrecedence();
506 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
507 const bool LHSIsBinaryExpr =
520 const bool IsComparison =
525 Previous.Previous->isNot(TT_BinaryOperator);
529 }
else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&
530 CurrentState.BreakBeforeParameter) {
535 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
536 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
540 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
545 if (
Previous.ClosesTemplateDeclaration) {
546 if (Current.is(tok::kw_concept)) {
556 if (Current.is(TT_RequiresClause)) {
567 Current.NewlinesBefore > 0);
569 if (
Previous.is(TT_FunctionAnnotationRParen) &&
573 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
574 Current.isNot(TT_LeadingJavaAnnotation)) {
583 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
585 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))
589 if (Current.is(TT_FunctionDeclarationName) &&
590 !State.Line->ReturnTypeWrapped &&
597 CurrentState.BreakBeforeParameter) {
606 !Current.isOneOf(tok::r_brace, tok::comment)) {
610 if (Current.is(tok::lessless) &&
613 Previous.TokenText ==
"\'\\n\'")))) {
620 if (State.NoContinuation)
628 unsigned ExtraSpaces) {
630 assert(State.NextToken->Previous);
633 assert(!State.Stack.empty());
634 State.NoContinuation =
false;
636 if (Current.is(TT_ImplicitStringLiteral) &&
637 (!
Previous.Tok.getIdentifierInfo() ||
638 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
639 tok::pp_not_keyword)) {
642 if (Current.LastNewlineOffset != 0) {
645 State.Column = EndColumn;
647 unsigned StartColumn =
649 assert(EndColumn >= StartColumn);
650 State.Column += EndColumn - StartColumn;
652 moveStateToNextToken(State, DryRun,
false);
656 unsigned Penalty = 0;
658 Penalty = addTokenOnNewLine(State, DryRun);
660 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
662 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
665void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
666 unsigned ExtraSpaces) {
668 assert(State.NextToken->Previous);
670 auto &CurrentState = State.Stack.back();
672 bool DisallowLineBreaksOnThisLine =
680 auto PrevNonComment = Current.getPreviousNonComment();
681 if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))
683 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
685 auto BlockParameterCount = PrevNonComment->BlockParameterCount;
686 if (BlockParameterCount == 0)
690 if (BlockParameterCount > 1)
694 if (!PrevNonComment->Role)
696 auto Comma = PrevNonComment->Role->lastComma();
699 auto Next = Comma->getNextNonComment();
701 !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
704 if (DisallowLineBreaksOnThisLine)
705 State.NoLineBreak =
true;
707 if (Current.is(tok::equal) &&
708 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
709 CurrentState.VariablePos == 0 &&
711 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
712 CurrentState.VariablePos = State.Column;
715 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {
716 CurrentState.VariablePos -= Tok->ColumnWidth;
717 if (Tok->SpacesRequiredBefore != 0)
721 if (
Previous.PartOfMultiVariableDeclStmt)
722 CurrentState.LastSpace = CurrentState.VariablePos;
725 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
728 int PPColumnCorrection = 0;
730 Previous.is(tok::hash) && State.FirstIndent > 0 &&
734 Spaces += State.FirstIndent;
741 PPColumnCorrection = -1;
746 State.Column + Spaces + PPColumnCorrection,
747 false, State.Line->InMacroBody);
753 Current.is(TT_InheritanceColon)) {
754 CurrentState.NoLineBreak =
true;
758 CurrentState.NoLineBreak =
true;
761 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
762 unsigned MinIndent = std::max(
764 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
765 if (Current.LongestObjCSelectorName == 0)
766 CurrentState.AlignColons =
false;
767 else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos)
768 CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName;
770 CurrentState.ColonPos = FirstColonPos;
777 auto IsOpeningBracket = [&](
const FormatToken &Tok) {
778 auto IsStartOfBracedList = [&]() {
779 return Tok.is(tok::l_brace) && Tok.isNot(
BK_Block) &&
782 if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
783 !IsStartOfBracedList()) {
788 if (Tok.Previous->isIf())
790 return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
795 IsOpeningBracket(
Previous) && State.Column > getNewLineColumn(State) &&
803 Current.FakeLParens.size() > 0 &&
805 CurrentState.NoLineBreak =
true;
808 CurrentState.NoLineBreak =
true;
815 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
817 Previous.isNot(TT_TableGenDAGArgOpener) &&
818 !(Current.MacroParent &&
Previous.MacroParent) &&
819 (Current.isNot(TT_LineComment) ||
821 CurrentState.Indent = State.Column + Spaces;
822 CurrentState.IsAligned =
true;
825 CurrentState.NoLineBreak =
true;
827 State.Column > getNewLineColumn(State)) {
828 CurrentState.ContainsUnwrappedBuilder =
true;
831 if (Current.is(TT_TrailingReturnArrow) &&
833 CurrentState.NoLineBreak =
true;
835 if (Current.isMemberAccess() &&
Previous.is(tok::r_paren) &&
844 CurrentState.NoLineBreak =
true;
851 const FormatToken *
P = Current.getPreviousNonComment();
852 if (Current.isNot(tok::comment) &&
P &&
853 (
P->isOneOf(TT_BinaryOperator, tok::comma) ||
854 (
P->is(TT_ConditionalExpr) &&
P->is(tok::colon))) &&
855 !
P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
859 bool BreakBeforeOperator =
860 P->MustBreakBefore ||
P->is(tok::lessless) ||
861 (
P->is(TT_BinaryOperator) &&
867 bool HasTwoOperands =
P->OperatorIndex == 0 && !
P->NextOperator &&
868 P->isNot(TT_ConditionalExpr);
869 if ((!BreakBeforeOperator &&
872 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
873 CurrentState.NoLineBreakInOperand =
true;
877 State.Column += Spaces;
878 if (Current.isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
883 CurrentState.LastSpace = State.Column;
884 CurrentState.NestedBlockIndent = State.Column;
885 }
else if (!Current.isOneOf(tok::comment, tok::caret) &&
887 Previous.isNot(TT_OverloadedOperator)) ||
889 CurrentState.LastSpace = State.Column;
890 }
else if (
Previous.is(TT_CtorInitializerColon) &&
891 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
894 CurrentState.Indent = State.Column;
895 CurrentState.LastSpace = State.Column;
896 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
897 CurrentState.LastSpace = State.Column;
898 }
else if (
Previous.is(TT_BinaryOperator) &&
902 Current.StartsBinaryExpression)) {
906 CurrentState.LastSpace = State.Column;
907 }
else if (
Previous.is(TT_InheritanceColon)) {
908 CurrentState.Indent = State.Column;
909 CurrentState.LastSpace = State.Column;
910 }
else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {
911 CurrentState.ColonPos = State.Column;
919 const FormatToken *Next =
Previous.MatchingParen->getNextNonComment();
920 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&
921 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {
922 CurrentState.LastSpace = State.Column;
928unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
930 FormatToken &Current = *State.NextToken;
931 assert(State.NextToken->Previous);
932 const FormatToken &
Previous = *State.NextToken->Previous;
933 auto &CurrentState = State.Stack.back();
937 unsigned Penalty = 0;
939 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
940 const FormatToken *NextNonComment =
Previous.getNextNonComment();
942 NextNonComment = &Current;
945 if (!CurrentState.ContainsLineBreak)
947 CurrentState.ContainsLineBreak =
true;
949 Penalty += State.NextToken->SplitPenalty;
954 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
956 CurrentState.BreakBeforeParameter)) {
960 State.Column = getNewLineColumn(State);
974 if (State.Column > State.FirstIndent) {
989 if (Current.isNot(TT_TrailingReturnArrow) &&
991 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
993 CurrentState.NestedBlockIndent = State.Column;
996 if (NextNonComment->isMemberAccess()) {
997 if (CurrentState.CallContinuation == 0)
998 CurrentState.CallContinuation = State.Column;
999 }
else if (NextNonComment->is(TT_SelectorName)) {
1000 if (!CurrentState.ObjCSelectorNameFound) {
1001 if (NextNonComment->LongestObjCSelectorName == 0) {
1002 CurrentState.AlignColons =
false;
1004 CurrentState.ColonPos =
1006 ? std::max(CurrentState.Indent,
1008 : CurrentState.Indent) +
1010 NextNonComment->ColumnWidth);
1012 }
else if (CurrentState.AlignColons &&
1013 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1014 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1016 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1017 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1027 if (State.Stack.size() > 1) {
1028 State.Stack[State.Stack.size() - 2].LastSpace =
1029 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1034 if ((PreviousNonComment &&
1035 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1036 !CurrentState.AvoidBinPacking) ||
1038 CurrentState.BreakBeforeParameter =
false;
1040 if (PreviousNonComment &&
1041 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1042 PreviousNonComment->ClosesRequiresClause) &&
1043 Current.NestingLevel == 0) {
1044 CurrentState.BreakBeforeParameter =
false;
1046 if (NextNonComment->is(tok::question) ||
1047 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1048 CurrentState.BreakBeforeParameter =
true;
1050 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1051 CurrentState.BreakBeforeParameter =
false;
1055 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1058 !Current.MatchingParen->Children.empty()) {
1062 MaxEmptyLinesToKeep = 1;
1065 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1066 bool ContinuePPDirective =
1069 CurrentState.IsAligned, ContinuePPDirective);
1072 if (!Current.isTrailingComment())
1073 CurrentState.LastSpace = State.Column;
1074 if (Current.is(tok::lessless)) {
1078 CurrentState.LastSpace += 3;
1081 State.StartOfLineLevel = Current.NestingLevel;
1082 State.LowestLevelOnLine = Current.NestingLevel;
1086 bool NestedBlockSpecialCase =
1087 (!
IsCpp && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1088 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1092 NestedBlockSpecialCase =
1093 NestedBlockSpecialCase ||
1094 (Current.MatchingParen &&
1095 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1096 if (!NestedBlockSpecialCase) {
1097 auto ParentLevelIt = std::next(State.Stack.rbegin());
1099 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1114 auto FindCurrentLevel = [&](
const auto &It) {
1115 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1116 return PState.Tok != nullptr;
1119 auto MaybeIncrement = [&](
const auto &It) {
1120 return It != State.Stack.rend() ? std::next(It) : It;
1122 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1123 auto LevelContainingLambdaIt =
1124 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1125 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1127 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1128 I->BreakBeforeParameter =
true;
1131 if (PreviousNonComment &&
1132 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1133 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1134 !PreviousNonComment->ClosesRequiresClause) ||
1135 Current.NestingLevel != 0) &&
1136 !PreviousNonComment->isOneOf(
1137 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1138 TT_LeadingJavaAnnotation) &&
1139 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1143 Current.isNot(TT_LambdaLBrace))) {
1144 CurrentState.BreakBeforeParameter =
true;
1149 if (PreviousNonComment &&
1150 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1152 CurrentState.BreakBeforeClosingBrace =
true;
1155 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1156 CurrentState.BreakBeforeClosingParen =
1160 if (CurrentState.AvoidBinPacking) {
1165 bool PreviousIsBreakingCtorInitializerColon =
1166 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1168 bool AllowAllConstructorInitializersOnNextLine =
1171 if (!(
Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1172 PreviousIsBreakingCtorInitializerColon) ||
1174 State.Line->MustBeDeclaration) ||
1176 !State.Line->MustBeDeclaration) ||
1177 (!AllowAllConstructorInitializersOnNextLine &&
1178 PreviousIsBreakingCtorInitializerColon) ||
1180 CurrentState.BreakBeforeParameter =
true;
1186 if (PreviousIsBreakingCtorInitializerColon &&
1187 AllowAllConstructorInitializersOnNextLine) {
1188 CurrentState.BreakBeforeParameter =
false;
1195unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1196 if (!State.NextToken || !State.NextToken->Previous)
1199 FormatToken &Current = *State.NextToken;
1200 const auto &CurrentState = State.Stack.back();
1202 if (CurrentState.IsCSharpGenericTypeConstraint &&
1203 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1204 return CurrentState.ColonPos + 2;
1207 const FormatToken &
Previous = *Current.Previous;
1209 unsigned ContinuationIndent =
1210 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1212 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1213 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1214 if (!NextNonComment)
1215 NextNonComment = &Current;
1220 return std::max(CurrentState.LastSpace,
1226 if (Style.
isVerilog() && PreviousNonComment &&
1228 return State.FirstIndent;
1232 State.Line->First->is(tok::kw_enum)) {
1233 return (Style.
IndentWidth * State.Line->First->IndentLevel) +
1237 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1239 if (Current.NestingLevel == 0 ||
1241 State.NextToken->is(TT_LambdaLBrace))) {
1242 return State.FirstIndent;
1244 return CurrentState.Indent;
1246 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1248 State.Stack.size() > 1) {
1249 if (Current.closesBlockOrBlockTypeList(Style))
1250 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1251 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1252 return State.Stack[State.Stack.size() - 2].LastSpace;
1253 return State.FirstIndent;
1270 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1272 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1273 return State.Stack[State.Stack.size() - 2].LastSpace;
1277 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1278 State.Stack.size() > 1) {
1279 return State.Stack[State.Stack.size() - 2].LastSpace;
1282 (Current.is(tok::r_paren) ||
1283 (Current.is(tok::r_brace) && Current.MatchingParen &&
1285 State.Stack.size() > 1) {
1286 return State.Stack[State.Stack.size() - 2].LastSpace;
1288 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1289 return State.Stack[State.Stack.size() - 2].LastSpace;
1297 if (Current.is(tok::identifier) && Current.Next &&
1298 (!Style.
isVerilog() || Current.Next->is(tok::colon)) &&
1299 (Current.Next->is(TT_DictLiteral) ||
1300 (Style.
isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1301 return CurrentState.Indent;
1303 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1304 State.StartOfStringLiteral != 0) {
1305 return State.StartOfStringLiteral - 1;
1307 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1308 return State.StartOfStringLiteral;
1309 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1310 return CurrentState.FirstLessLess;
1311 if (NextNonComment->isMemberAccess()) {
1312 if (CurrentState.CallContinuation == 0)
1313 return ContinuationIndent;
1314 return CurrentState.CallContinuation;
1316 if (CurrentState.QuestionColumn != 0 &&
1317 ((NextNonComment->is(tok::colon) &&
1318 NextNonComment->is(TT_ConditionalExpr)) ||
1319 Previous.is(TT_ConditionalExpr))) {
1320 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1321 !NextNonComment->Next->FakeLParens.empty() &&
1323 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1325 !CurrentState.IsWrappedConditional) {
1330 unsigned Indent = CurrentState.Indent;
1337 return CurrentState.QuestionColumn;
1339 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1340 return CurrentState.VariablePos;
1341 if (Current.is(TT_RequiresClause)) {
1347 return CurrentState.Indent;
1352 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1353 TT_InheritanceComma)) {
1356 if ((PreviousNonComment &&
1357 (PreviousNonComment->ClosesTemplateDeclaration ||
1358 PreviousNonComment->ClosesRequiresClause ||
1359 (PreviousNonComment->is(TT_AttributeMacro) &&
1360 Current.isNot(tok::l_paren)) ||
1361 PreviousNonComment->isOneOf(
1362 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1363 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1365 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1366 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1368 if (NextNonComment->is(TT_SelectorName)) {
1369 if (!CurrentState.ObjCSelectorNameFound) {
1370 unsigned MinIndent = CurrentState.Indent;
1372 MinIndent = std::max(MinIndent,
1385 std::max(NextNonComment->LongestObjCSelectorName,
1386 NextNonComment->ColumnWidth) -
1387 NextNonComment->ColumnWidth;
1389 if (!CurrentState.AlignColons)
1390 return CurrentState.Indent;
1391 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1392 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1393 return CurrentState.Indent;
1395 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1396 return CurrentState.ColonPos;
1397 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1398 if (CurrentState.StartOfArraySubscripts != 0) {
1399 return CurrentState.StartOfArraySubscripts;
1402 return CurrentState.Indent;
1404 return ContinuationIndent;
1409 if (State.Line->InPragmaDirective) {
1410 FormatToken *PragmaType = State.Line->First->Next->Next;
1411 if (PragmaType && PragmaType->TokenText.equals(
"omp"))
1417 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1418 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1419 return CurrentState.Indent;
1422 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1423 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1424 return ContinuationIndent;
1426 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1427 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1428 return ContinuationIndent;
1430 if (NextNonComment->is(TT_CtorInitializerComma))
1431 return CurrentState.Indent;
1432 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1434 return CurrentState.Indent;
1436 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1438 return CurrentState.Indent;
1440 if (
Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
1441 !Current.isOneOf(tok::colon, tok::comment)) {
1442 return ContinuationIndent;
1444 if (Current.is(TT_ProtoExtensionLSquare))
1445 return CurrentState.Indent;
1446 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1447 return CurrentState.Indent - Current.Tok.getLength() -
1448 Current.SpacesRequiredBefore;
1450 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1451 CurrentState.UnindentOperator) {
1452 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1453 NextNonComment->SpacesRequiredBefore;
1455 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1456 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1461 return CurrentState.Indent;
1476unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1477 bool DryRun,
bool Newline) {
1478 assert(State.Stack.size());
1479 const FormatToken &Current = *State.NextToken;
1480 auto &CurrentState = State.Stack.back();
1482 if (Current.is(TT_CSharpGenericTypeConstraint))
1483 CurrentState.IsCSharpGenericTypeConstraint =
true;
1484 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1485 CurrentState.NoLineBreakInOperand =
false;
1486 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1487 CurrentState.AvoidBinPacking =
true;
1488 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1489 if (CurrentState.FirstLessLess == 0)
1490 CurrentState.FirstLessLess = State.Column;
1492 CurrentState.LastOperatorWrapped = Newline;
1494 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1495 CurrentState.LastOperatorWrapped = Newline;
1496 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1497 Current.Previous->isNot(TT_ConditionalExpr)) {
1498 CurrentState.LastOperatorWrapped = Newline;
1500 if (Current.is(TT_ArraySubscriptLSquare) &&
1501 CurrentState.StartOfArraySubscripts == 0) {
1502 CurrentState.StartOfArraySubscripts = State.Column;
1505 auto IsWrappedConditional = [](
const FormatToken &Tok) {
1506 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))
1508 if (Tok.MustBreakBefore)
1511 const FormatToken *Next = Tok.getNextNonComment();
1512 return Next && Next->MustBreakBefore;
1514 if (IsWrappedConditional(Current))
1515 CurrentState.IsWrappedConditional =
true;
1517 CurrentState.QuestionColumn = State.Column;
1519 const FormatToken *
Previous = Current.Previous;
1523 CurrentState.QuestionColumn = State.Column;
1525 if (!Current.opensScope() && !Current.closesScope() &&
1526 Current.isNot(TT_PointerOrReference)) {
1527 State.LowestLevelOnLine =
1528 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1530 if (Current.isMemberAccess())
1531 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1532 if (Current.is(TT_SelectorName))
1533 CurrentState.ObjCSelectorNameFound =
true;
1534 if (Current.is(TT_CtorInitializerColon) &&
1545 CurrentState.NestedBlockIndent = CurrentState.Indent;
1547 CurrentState.AvoidBinPacking =
true;
1548 CurrentState.BreakBeforeParameter =
1553 CurrentState.BreakBeforeParameter =
false;
1556 if (Current.is(TT_CtorInitializerColon) &&
1558 CurrentState.Indent =
1560 CurrentState.NestedBlockIndent = CurrentState.Indent;
1562 CurrentState.AvoidBinPacking =
true;
1564 CurrentState.BreakBeforeParameter =
false;
1566 if (Current.is(TT_InheritanceColon)) {
1567 CurrentState.Indent =
1570 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1571 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1572 if (Current.isOneOf(TT_LambdaLSquare, TT_TrailingReturnArrow))
1573 CurrentState.LastSpace = State.Column;
1574 if (Current.is(TT_RequiresExpression) &&
1576 CurrentState.NestedBlockIndent = State.Column;
1580 const FormatToken *
Previous = Current.getPreviousNonComment();
1588 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1590 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1591 !CurrentState.HasMultipleNestedBlocks) {
1592 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1593 for (ParenState &PState : llvm::drop_end(State.Stack))
1594 PState.NoLineBreak =
true;
1595 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1597 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1598 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1599 !
Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) {
1600 CurrentState.NestedBlockInlined =
1604 moveStatePastFakeLParens(State, Newline);
1605 moveStatePastScopeCloser(State);
1608 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1609 !State.Stack.back().NoLineBreakInOperand;
1610 moveStatePastScopeOpener(State, Newline);
1611 moveStatePastFakeRParens(State);
1613 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1614 State.StartOfStringLiteral = State.Column + 1;
1615 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1616 State.StartOfStringLiteral = State.Column + 1;
1617 }
else if (Current.is(TT_TableGenMultiLineString) &&
1618 State.StartOfStringLiteral == 0) {
1619 State.StartOfStringLiteral = State.Column + 1;
1620 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1621 State.StartOfStringLiteral = State.Column;
1622 }
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1623 !Current.isStringLiteral()) {
1624 State.StartOfStringLiteral = 0;
1627 State.Column += Current.ColumnWidth;
1628 State.NextToken = State.NextToken->Next;
1633 if (Style.
isVerilog() && State.NextToken &&
1634 State.NextToken->MustBreakBefore &&
1637 CurrentState.Indent = State.FirstIndent;
1641 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1644 Current.Role->formatFromToken(State,
this, DryRun);
1651 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1656void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
1658 const FormatToken &Current = *State.NextToken;
1659 if (Current.FakeLParens.empty())
1662 const FormatToken *
Previous = Current.getPreviousNonComment();
1667 bool SkipFirstExtraIndent =
1670 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1674 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1675 const auto &CurrentState = State.Stack.back();
1676 ParenState NewParenState = CurrentState;
1677 NewParenState.Tok =
nullptr;
1678 NewParenState.ContainsLineBreak =
false;
1679 NewParenState.LastOperatorWrapped =
true;
1680 NewParenState.IsChainedConditional =
false;
1681 NewParenState.IsWrappedConditional =
false;
1682 NewParenState.UnindentOperator =
false;
1683 NewParenState.NoLineBreak =
1684 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1688 NewParenState.AvoidBinPacking =
false;
1693 if (!Current.isTrailingComment() &&
1699 PrecedenceLevel !=
prec::Comma || Current.NestingLevel == 0) &&
1702 NewParenState.Indent = std::max(
1703 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1710 State.Stack.size() > 1) {
1711 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1723 NewParenState.UnindentOperator =
true;
1726 NewParenState.IsAligned =
true;
1736 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1738 Current.isNot(TT_UnaryOperator) &&
1740 NewParenState.StartOfFunctionCall = State.Column;
1750 &PrecedenceLevel == &Current.FakeLParens.back() &&
1751 !CurrentState.IsWrappedConditional) {
1752 NewParenState.IsChainedConditional =
true;
1753 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1756 !Current.isTrailingComment())) {
1760 NewParenState.BreakBeforeParameter =
false;
1761 State.Stack.push_back(NewParenState);
1762 SkipFirstExtraIndent =
false;
1766void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
1767 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1768 unsigned VariablePos = State.Stack.back().VariablePos;
1769 if (State.Stack.size() == 1) {
1773 State.Stack.pop_back();
1774 State.Stack.back().VariablePos = VariablePos;
1780 State.Stack.back().LastSpace -= Style.
IndentWidth;
1784void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
1786 const FormatToken &Current = *State.NextToken;
1787 if (!Current.opensScope())
1790 const auto &CurrentState = State.Stack.back();
1793 if (Current.isOneOf(tok::less, tok::l_paren) &&
1794 CurrentState.IsCSharpGenericTypeConstraint) {
1798 if (Current.MatchingParen && Current.is(
BK_Block)) {
1799 moveStateToNewBlock(State, Newline);
1804 unsigned LastSpace = CurrentState.LastSpace;
1805 bool AvoidBinPacking;
1806 bool BreakBeforeParameter =
false;
1807 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1808 CurrentState.NestedBlockIndent);
1809 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1811 if (Current.opensBlockOrBlockTypeList(Style)) {
1813 std::min(State.Column, CurrentState.NestedBlockIndent);
1814 }
else if (Current.is(tok::l_brace)) {
1821 const FormatToken *NextNonComment = Current.getNextNonComment();
1822 bool EndsInComma = Current.MatchingParen &&
1823 Current.MatchingParen->Previous &&
1824 Current.MatchingParen->Previous->is(tok::comma);
1825 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1827 (NextNonComment && NextNonComment->isOneOf(
1828 TT_DesignatedInitializerPeriod,
1829 TT_DesignatedInitializerLSquare));
1830 BreakBeforeParameter = EndsInComma;
1831 if (Current.ParameterCount > 1)
1832 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1836 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1842 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
1843 NewIndent = std::max(NewIndent, CurrentState.Indent);
1844 LastSpace = std::max(LastSpace, CurrentState.Indent);
1848 Current.MatchingParen &&
1849 Current.MatchingParen->getPreviousNonComment() &&
1850 Current.MatchingParen->getPreviousNonComment()->is(tok::comma);
1854 bool ObjCBinPackProtocolList =
1859 bool BinPackDeclaration =
1861 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
1863 bool GenericSelection =
1864 Current.getPreviousNonComment() &&
1865 Current.getPreviousNonComment()->is(tok::kw__Generic);
1868 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
1870 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
1876 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
1883 BreakBeforeParameter =
true;
1888 for (
const FormatToken *Tok = &Current;
1889 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {
1890 if (Tok->MustBreakBefore ||
1891 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {
1892 BreakBeforeParameter =
true;
1900 BreakBeforeParameter =
true;
1906 Current.Children.empty() &&
1907 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
1908 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
1909 (Current.is(TT_TemplateOpener) &&
1910 CurrentState.ContainsUnwrappedBuilder));
1911 State.Stack.push_back(
1912 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
1913 auto &NewState = State.Stack.back();
1914 NewState.NestedBlockIndent = NestedBlockIndent;
1915 NewState.BreakBeforeParameter = BreakBeforeParameter;
1916 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
1919 Current.is(tok::l_paren)) {
1921 FormatToken
const *next = Current.Next;
1923 if (next->is(TT_LambdaLSquare)) {
1924 NewState.HasMultipleNestedBlocks =
true;
1931 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
1933 Current.Previous->is(tok::at);
1936void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
1937 const FormatToken &Current = *State.NextToken;
1938 if (!Current.closesScope())
1943 if (State.Stack.size() > 1 &&
1944 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
1945 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
1946 State.NextToken->is(TT_TemplateCloser) ||
1947 State.NextToken->is(TT_TableGenListCloser) ||
1948 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
1949 State.Stack.pop_back();
1952 auto &CurrentState = State.Stack.back();
1964 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
1965 Current.MatchingParen->Previous) {
1966 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
1967 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
1968 CurrentScopeOpener.MatchingParen) {
1969 int NecessarySpaceInLine =
1971 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
1972 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
1974 CurrentState.BreakBeforeParameter =
false;
1979 if (Current.is(tok::r_square)) {
1981 const FormatToken *NextNonComment = Current.getNextNonComment();
1982 if (NextNonComment && NextNonComment->isNot(tok::l_square))
1983 CurrentState.StartOfArraySubscripts = 0;
1987void ContinuationIndenter::moveStateToNewBlock(LineState &State,
bool NewLine) {
1989 State.NextToken->is(TT_LambdaLBrace) &&
1990 !State.Line->MightBeFunctionDecl) {
1991 State.Stack.back().NestedBlockIndent = State.FirstIndent;
1993 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
1995 unsigned NewIndent =
1996 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2006 State.NextToken->is(TT_LambdaLBrace);
2008 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2009 State.Stack.back().LastSpace,
2010 true, NoLineBreak));
2011 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2012 State.Stack.back().BreakBeforeParameter =
true;
2018 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2019 if (LastNewlinePos == StringRef::npos) {
2020 return StartColumn +
2024 0, TabWidth, Encoding);
2028unsigned ContinuationIndenter::reformatRawStringLiteral(
2029 const FormatToken &Current, LineState &State,
2030 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2031 unsigned StartColumn = State.Column - Current.ColumnWidth;
2033 StringRef NewDelimiter =
2035 if (NewDelimiter.empty())
2036 NewDelimiter = OldDelimiter;
2039 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2040 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2043 std::string RawText = std::string(
2044 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2045 if (NewDelimiter != OldDelimiter) {
2048 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2049 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
2050 NewDelimiter = OldDelimiter;
2053 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2054 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2057 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2068 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2090 unsigned CurrentIndent =
2091 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2092 ? State.Stack.back().NestedBlockIndent
2093 : State.Stack.back().Indent;
2094 unsigned NextStartColumn = ContentStartsOnNewline
2106 unsigned LastStartColumn =
2107 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2110 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2111 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2115 tooling::Replacements NoFixes;
2117 return addMultilineToken(Current, State);
2119 if (NewDelimiter != OldDelimiter) {
2122 SourceLocation PrefixDelimiterStart =
2123 Current.Tok.getLocation().getLocWithOffset(2);
2124 auto PrefixErr = Whitespaces.
addReplacement(tooling::Replacement(
2125 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2128 <<
"Failed to update the prefix delimiter of a raw string: "
2129 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2133 SourceLocation SuffixDelimiterStart =
2134 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2135 1 - OldDelimiter.size());
2136 auto SuffixErr = Whitespaces.
addReplacement(tooling::Replacement(
2137 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2140 <<
"Failed to update the suffix delimiter of a raw string: "
2141 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2144 SourceLocation OriginLoc =
2145 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2146 for (
const tooling::Replacement &Fix : Fixes.first) {
2148 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2149 Fix.getLength(), Fix.getReplacementText()));
2151 llvm::errs() <<
"Failed to reformat raw string: "
2152 << llvm::toString(std::move(Err)) <<
"\n";
2157 *NewCode, FirstStartColumn, Style.
TabWidth, Encoding);
2158 State.Column = RawLastLineEndColumn + NewSuffixSize;
2162 unsigned PrefixExcessCharacters =
2167 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2170 for (ParenState &
Paren : State.Stack)
2171 Paren.BreakBeforeParameter =
true;
2176unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2179 for (ParenState &
Paren : State.Stack)
2180 Paren.BreakBeforeParameter =
true;
2182 unsigned ColumnsUsed = State.Column;
2185 State.Column = Current.LastLineColumnWidth;
2192unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2193 LineState &State,
bool DryRun,
2194 bool AllowBreak,
bool Newline) {
2195 unsigned Penalty = 0;
2198 auto RawStringStyle = getRawStringStyle(Current, State);
2199 if (RawStringStyle && !Current.Finalized) {
2200 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2202 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2205 Penalty = addMultilineToken(Current, State);
2208 LineState OriginalState = State;
2212 bool Strict =
false;
2215 bool Exceeded =
false;
2216 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2217 Current, State, AllowBreak,
true, Strict);
2221 LineState StrictState = OriginalState;
2222 unsigned StrictPenalty =
2223 breakProtrudingToken(Current, StrictState, AllowBreak,
2226 Strict = StrictPenalty <= Penalty;
2228 Penalty = StrictPenalty;
2229 State = StrictState;
2235 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2240 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2251 if (!Tok || Tok->isNot(tok::l_paren))
2256 if (Tok->is(TT_TemplateCloser)) {
2261 if (!Tok || Tok->isNot(tok::identifier))
2266std::optional<FormatStyle>
2267ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2268 const LineState &State) {
2269 if (!Current.isStringLiteral())
2270 return std::nullopt;
2273 return std::nullopt;
2275 if (!RawStringStyle && Delimiter->empty()) {
2279 if (!RawStringStyle)
2280 return std::nullopt;
2282 return RawStringStyle;
2285std::unique_ptr<BreakableToken>
2286ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2287 LineState &State,
bool AllowBreak) {
2288 unsigned StartColumn = State.Column - Current.ColumnWidth;
2289 if (Current.isStringLiteral()) {
2306 if (Current.IsUnterminatedLiteral)
2310 if (State.Stack.back().IsInsideObjCArrayLiteral)
2317 if (Style.
isVerilog() && Current.Previous &&
2318 Current.Previous->isOneOf(tok::kw_export, Keywords.
kw_import)) {
2321 StringRef
Text = Current.TokenText;
2327 unsigned UnbreakableTailLength = (State.NextToken &&
canBreak(State))
2329 : Current.UnbreakableTailLength;
2335 Text.ends_with(
"'")) {
2337 }
else if (Style.
isCSharp() &&
Text.starts_with(
"@\"") &&
2338 Text.ends_with(
"\"")) {
2340 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2345 return std::make_unique<BreakableStringLiteralUsingOperators>(
2346 Current, QuoteStyle,
2348 UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style);
2357 if ((
Text.ends_with(Postfix =
"\"") &&
2358 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2359 Text.starts_with(Prefix =
"u\"") ||
2360 Text.starts_with(Prefix =
"U\"") ||
2361 Text.starts_with(Prefix =
"u8\"") ||
2362 Text.starts_with(Prefix =
"L\""))) ||
2363 (
Text.starts_with(Prefix =
"_T(\"") &&
2364 Text.ends_with(Postfix =
"\")"))) {
2365 return std::make_unique<BreakableStringLiteral>(
2366 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
2367 State.Line->InPPDirective, Encoding, Style);
2369 }
else if (Current.is(TT_BlockComment)) {
2377 return std::make_unique<BreakableBlockComment>(
2378 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2379 State.Line->InPPDirective, Encoding, Style, Whitespaces.
useCRLF());
2380 }
else if (Current.is(TT_LineComment) &&
2381 (!Current.Previous ||
2382 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2383 bool RegularComments = [&]() {
2384 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2386 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2392 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2396 return std::make_unique<BreakableLineCommentSection>(
2397 Current, StartColumn,
false, Encoding, Style);
2402std::pair<unsigned, bool>
2403ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2404 LineState &State,
bool AllowBreak,
2405 bool DryRun,
bool Strict) {
2406 std::unique_ptr<const BreakableToken> Token =
2407 createBreakableToken(Current, State, AllowBreak);
2410 assert(Token->getLineCount() > 0);
2412 if (Current.is(TT_LineComment)) {
2416 if (ColumnLimit == 0) {
2419 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2421 if (Current.UnbreakableTailLength >= ColumnLimit)
2425 unsigned StartColumn = State.Column - Current.ColumnWidth;
2426 unsigned NewBreakPenalty = Current.isStringLiteral()
2431 bool Exceeded =
false;
2433 bool BreakInserted = Token->introducesBreakBeforeToken();
2436 bool NewBreakBefore =
false;
2440 bool Reflow =
false;
2443 unsigned TailOffset = 0;
2445 unsigned ContentStartColumn =
2446 Token->getContentStartColumn(0,
false);
2448 unsigned RemainingTokenColumns =
2449 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2452 Token->adaptStartOfLine(0, Whitespaces);
2454 unsigned ContentIndent = 0;
2455 unsigned Penalty = 0;
2456 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2457 << StartColumn <<
".\n");
2458 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2459 LineIndex != EndIndex; ++LineIndex) {
2460 LLVM_DEBUG(llvm::dbgs()
2461 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2462 NewBreakBefore =
false;
2466 bool TryReflow = Reflow;
2468 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2469 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2470 << (ContentStartColumn + RemainingTokenColumns)
2471 <<
", space: " << ColumnLimit
2472 <<
", reflown prefix: " << ContentStartColumn
2473 <<
", offset in line: " << TailOffset <<
"\n");
2479 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2480 ContentStartColumn, CommentPragmasRegex);
2481 if (
Split.first == StringRef::npos) {
2484 if (LineIndex < EndIndex - 1) {
2488 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2490 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2493 assert(
Split.first != 0);
2495 if (Token->supportsReflow()) {
2515 unsigned ToSplitColumns = Token->getRangeLength(
2516 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2517 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2520 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2521 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2524 unsigned ToNextSplitColumns = 0;
2525 if (NextSplit.first == StringRef::npos) {
2526 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2527 ContentStartColumn);
2529 ToNextSplitColumns = Token->getRangeLength(
2530 LineIndex, TailOffset,
2531 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2535 ToNextSplitColumns =
2536 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2537 LLVM_DEBUG(llvm::dbgs()
2538 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2539 LLVM_DEBUG(llvm::dbgs()
2540 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2543 bool ContinueOnLine =
2544 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2545 unsigned ExcessCharactersPenalty = 0;
2546 if (!ContinueOnLine && !Strict) {
2549 ExcessCharactersPenalty =
2550 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2552 LLVM_DEBUG(llvm::dbgs()
2553 <<
" Penalty excess: " << ExcessCharactersPenalty
2554 <<
"\n break : " << NewBreakPenalty <<
"\n");
2555 if (ExcessCharactersPenalty < NewBreakPenalty) {
2557 ContinueOnLine =
true;
2560 if (ContinueOnLine) {
2561 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2566 Token->compressWhitespace(LineIndex, TailOffset, Split,
2570 ContentStartColumn += ToSplitColumns + 1;
2571 Penalty += ExcessCharactersPenalty;
2573 RemainingTokenColumns = Token->getRemainingLength(
2574 LineIndex, TailOffset, ContentStartColumn);
2578 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2583 ContentIndent = Token->getContentIndent(LineIndex);
2584 LLVM_DEBUG(llvm::dbgs()
2585 <<
" ContentIndent: " << ContentIndent <<
"\n");
2586 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2589 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2590 LineIndex, TailOffset +
Split.first +
Split.second,
2591 ContentStartColumn);
2592 if (NewRemainingTokenColumns == 0) {
2595 ContentStartColumn =
2596 Token->getContentStartColumn(LineIndex,
true);
2597 NewRemainingTokenColumns = Token->getRemainingLength(
2598 LineIndex, TailOffset +
Split.first +
Split.second,
2599 ContentStartColumn);
2605 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2610 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2611 <<
", " <<
Split.second <<
"\n");
2613 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2617 Penalty += NewBreakPenalty;
2619 RemainingTokenColumns = NewRemainingTokenColumns;
2620 BreakInserted =
true;
2621 NewBreakBefore =
true;
2625 if (LineIndex + 1 != EndIndex) {
2626 unsigned NextLineIndex = LineIndex + 1;
2627 if (NewBreakBefore) {
2646 ContentStartColumn += RemainingTokenColumns + 1;
2651 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2652 LLVM_DEBUG(llvm::dbgs()
2653 <<
" Size of reflown text: " << ContentStartColumn
2654 <<
"\n Potential reflow split: ");
2655 if (SplitBeforeNext.first != StringRef::npos) {
2656 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2657 << SplitBeforeNext.second <<
"\n");
2658 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2661 RemainingTokenColumns = Token->getRemainingLength(
2662 NextLineIndex, TailOffset, ContentStartColumn);
2664 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2665 LLVM_DEBUG(llvm::dbgs()
2666 <<
" Over limit after reflow, need: "
2667 << (ContentStartColumn + RemainingTokenColumns)
2668 <<
", space: " << ColumnLimit
2669 <<
", reflown prefix: " << ContentStartColumn
2670 <<
", offset in line: " << TailOffset <<
"\n");
2676 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2677 ContentStartColumn, CommentPragmasRegex);
2678 if (
Split.first == StringRef::npos) {
2679 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2685 unsigned ToSplitColumns = Token->getRangeLength(
2686 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2687 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2688 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2689 << (ContentStartColumn + ToSplitColumns)
2690 <<
", space: " << ColumnLimit);
2691 unsigned ExcessCharactersPenalty =
2692 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2694 if (NewBreakPenalty < ExcessCharactersPenalty)
2700 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2708 ContentStartColumn =
2709 Token->getContentStartColumn(NextLineIndex,
false);
2710 RemainingTokenColumns = Token->getRemainingLength(
2711 NextLineIndex, TailOffset, ContentStartColumn);
2714 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2729 if (NewBreakBefore) {
2730 assert(Penalty >= NewBreakPenalty);
2731 Penalty -= NewBreakPenalty;
2734 Token->reflow(NextLineIndex, Whitespaces);
2740 Token->getSplitAfterLastLine(TailOffset);
2741 if (SplitAfterLastLine.first != StringRef::npos) {
2742 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2747 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2750 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2753 ContentStartColumn =
2754 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2755 RemainingTokenColumns = Token->getRemainingLength(
2756 Token->getLineCount() - 1,
2757 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2758 ContentStartColumn);
2761 State.Column = ContentStartColumn + RemainingTokenColumns -
2762 Current.UnbreakableTailLength;
2764 if (BreakInserted) {
2766 Token->updateAfterBroken(Whitespaces);
2771 if (Current.isNot(TT_LineComment))
2772 for (ParenState &
Paren : State.Stack)
2773 Paren.BreakBeforeParameter =
true;
2775 if (Current.is(TT_BlockComment))
2776 State.NoContinuation =
true;
2778 State.Stack.back().LastSpace = StartColumn;
2781 Token->updateNextToken(State);
2783 return {Penalty, Exceeded};
2788 return Style.
ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2791bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2793 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))
2798 if (Current.TokenText.starts_with(
"R\""))
2800 if (Current.IsMultiline)
2802 if (Current.getNextNonComment() &&
2803 Current.getNextNonComment()->isStringLiteral()) {
2807 State.Column + Current.ColumnWidth + Current.UnbreakableTailLength >
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
unsigned LongestObjCSelectorName
__DEVICE__ int max(int __a, int __b)
This class handles loading and caching of source files into memory.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
The JSON file list parser is used to communicate input to InstallAPI.
Language
The language for the input, used to select and validate the language standard and possible actions.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))