23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "format-indenter"
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
89 if (!
Tok.MatchingParen)
93 int MatchingStackIndex = Stack.size() - 1;
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].
Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
103 for (; End->
Next; End = End->
Next) {
106 if (!End->
Next->closesScope())
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
120 if (!
Tok.NextOperator)
122 return Tok.NextOperator->TotalLength -
Tok.TotalLength;
128 return Tok.isMemberAccess() &&
Tok.Previous &&
Tok.Previous->closesScope();
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
151 while (
Last->NextOperator)
153 return Last->OperatorIndex + 2;
158 const FormatStyle &Style) {
164 bool BreakBefore = Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
179 const auto OperatorBreakStyle =
180 Style.BreakBinaryOperations.getStyleForOperator(OpToken->
Tok.
getKind());
181 if (OperatorBreakStyle == FormatStyle::BBO_Never)
185 const unsigned MinChain =
186 Style.BreakBinaryOperations.getMinChainLengthForOperator(
192 const FormatStyle &Style) {
193 if (LessTok.
isNot(tok::less))
195 return Style.isTextProto() ||
196 (Style.Language == FormatStyle::LK_Proto &&
213 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
214 if (LParenPos == StringRef::npos)
216 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
219 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
222 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
231 FormatStyle::LanguageKind
Language) {
232 for (
const auto &Format : Style.RawStringFormats)
234 return StringRef(Format.CanonicalDelimiter);
239 const FormatStyle &CodeStyle) {
241 std::optional<FormatStyle> LanguageStyle =
243 if (!LanguageStyle) {
244 FormatStyle PredefinedStyle;
250 LanguageStyle = PredefinedStyle;
252 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;
260std::optional<FormatStyle>
268std::optional<FormatStyle>
270 StringRef EnclosingFunction)
const {
293 *
this = *
this + Spaces;
321 bool BinPackInconclusiveFunctions)
322 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
323 Whitespaces(Whitespaces), Encoding(Encoding),
324 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
325 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
328 unsigned FirstStartColumn,
333 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
334 State.Column = FirstStartColumn;
336 State.Column = FirstIndent;
340 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
346 State.NextToken =
Line->First;
347 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
350 State.NoContinuation =
false;
351 State.StartOfStringLiteral = 0;
352 State.NoLineBreak =
false;
353 State.StartOfLineLevel = 0;
354 State.LowestLevelOnLine = 0;
355 State.IgnoreStackForComparison =
false;
357 if (Style.isTextProto()) {
360 auto &CurrentState = State.Stack.back();
361 CurrentState.AvoidBinPacking =
true;
362 CurrentState.BreakBeforeParameter =
true;
363 CurrentState.AlignColons =
false;
367 moveStateToNextToken(State, DryRun,
false);
374 const auto &CurrentState = State.Stack.back();
376 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
377 Current.closesBlockOrBlockTypeList(Style))) {
385 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
394 State.LowestLevelOnLine < State.StartOfLineLevel &&
398 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
403 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
404 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
405 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
406 return Style.isCpp() &&
407 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
412 if (Current.
is(TT_FunctionDeclarationName)) {
413 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&
418 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
419 assert(State.Column >= State.FirstIndent);
420 if (State.Column - State.FirstIndent < 6)
428 Current.isBlockIndentedInitRBrace(Style)) {
429 return CurrentState.BreakBeforeClosingBrace;
434 if ((Style.BreakBeforeCloseBracketFunction ||
435 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
436 Style.BreakBeforeCloseBracketSwitch) &&
437 Current.
is(tok::r_paren)) {
438 return CurrentState.BreakBeforeClosingParen;
441 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
442 return CurrentState.BreakBeforeClosingAngle;
446 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
450 (!Style.BraceWrapping.BeforeLambdaBody ||
451 Current.
isNot(TT_LambdaLBrace)) &&
452 CurrentState.NoLineBreakInOperand) {
459 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
461 Previous.MatchingParen->Previous->MatchingParen &&
462 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
464 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
468 return !State.NoLineBreak && !CurrentState.NoLineBreak;
474 const auto &CurrentState = State.Stack.back();
475 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
476 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
481 (Current.
is(TT_InlineASMColon) &&
482 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
483 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
484 Style.ColumnLimit > 0)))) {
487 if (CurrentState.BreakBeforeClosingBrace &&
488 (Current.closesBlockOrBlockTypeList(Style) ||
490 Current.isBlockIndentedInitRBrace(Style)))) {
493 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
495 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
497 if (Style.Language == FormatStyle::LK_ObjC &&
498 Style.ObjCBreakBeforeNestedBlockParam &&
500 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
505 if (CurrentState.IsCSharpGenericTypeConstraint &&
506 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
510 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
511 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
517 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||
518 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
520 (!Style.BreakBeforeTernaryOperators &&
521 Previous.is(TT_ConditionalExpr))) &&
522 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
523 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
526 if (CurrentState.IsChainedConditional &&
527 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
528 Current.
is(tok::colon)) ||
529 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
534 (
Previous.is(TT_ArrayInitializerLSquare) &&
537 Style.ColumnLimit > 0 &&
543 const FormatToken &BreakConstructorInitializersToken =
544 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
547 if (Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterComma &&
548 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
549 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
551 CurrentState.BreakBeforeParameter) &&
552 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
557 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
558 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
561 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
562 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
563 (Style.ObjCBreakBeforeNestedBlockParam ||
564 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
568 unsigned NewLineColumn = getNewLineColumn(State).Total;
569 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
571 (State.Column > NewLineColumn ||
577 (CurrentState.CallContinuation != 0 ||
578 CurrentState.BreakBeforeParameter) &&
584 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
585 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
591 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
596 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
599 if (Style.AlwaysBreakBeforeMultilineStrings &&
600 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
602 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
603 Keywords.kw_dollar) &&
604 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
605 nextIsMultilineString(State)) {
613 const auto PreviousPrecedence =
Previous.getPrecedence();
615 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
616 const bool LHSIsBinaryExpr =
629 const bool IsComparison =
634 Previous.Previous->isNot(TT_BinaryOperator);
640 CurrentState.BreakBeforeParameter) {
645 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
646 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
650 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
655 if (
Previous.ClosesTemplateDeclaration) {
656 if (Current.
is(tok::kw_concept)) {
657 switch (Style.BreakBeforeConceptDeclarations) {
658 case FormatStyle::BBCDS_Allowed:
660 case FormatStyle::BBCDS_Always:
662 case FormatStyle::BBCDS_Never:
666 if (Current.
is(TT_RequiresClause)) {
667 switch (Style.RequiresClausePosition) {
668 case FormatStyle::RCPS_SingleLine:
669 case FormatStyle::RCPS_WithPreceding:
675 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
676 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
679 if (
Previous.is(TT_FunctionAnnotationRParen) &&
683 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
684 Current.
isNot(TT_LeadingJavaAnnotation)) {
689 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
693 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
695 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
699 if (Current.
is(TT_FunctionDeclarationName) &&
700 !State.Line->ReturnTypeWrapped &&
702 (!Style.isCSharp() ||
703 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
706 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
707 CurrentState.BreakBeforeParameter) {
709 if (
Tok->is(TT_LineComment))
711 if (
Tok->is(TT_TemplateCloser)) {
716 if (
Tok->FirstAfterPPLine)
728 Current.
isNoneOf(tok::r_brace, tok::comment)) {
732 if (Current.
is(tok::lessless) &&
735 Previous.TokenText ==
"\'\\n\'")))) {
742 if (State.NoContinuation)
750 unsigned ExtraSpaces) {
752 assert(State.NextToken->Previous);
755 assert(!State.Stack.empty());
756 State.NoContinuation =
false;
758 if (Current.
is(TT_ImplicitStringLiteral) &&
759 (!
Previous.Tok.getIdentifierInfo() ||
760 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
761 tok::pp_not_keyword)) {
767 State.Column = EndColumn;
769 unsigned StartColumn =
771 assert(EndColumn >= StartColumn);
772 State.Column += EndColumn - StartColumn;
774 moveStateToNextToken(State, DryRun,
false);
778 unsigned Penalty = 0;
780 Penalty = addTokenOnNewLine(State, DryRun);
782 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
784 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
787void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
788 unsigned ExtraSpaces) {
790 assert(State.NextToken->Previous);
792 auto &CurrentState = State.Stack.back();
799 auto DisallowLineBreaks = [&] {
800 if (!Style.isCpp() ||
801 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
809 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
812 const auto *Prev = Current.getPreviousNonComment();
813 if (!Prev || Prev->isNot(tok::l_paren))
816 if (Prev->BlockParameterCount == 0)
820 if (Prev->BlockParameterCount > 1)
827 const auto *Comma = Prev->
Role->lastComma();
831 const auto *
Next = Comma->getNextNonComment();
832 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
835 if (DisallowLineBreaks())
836 State.NoLineBreak =
true;
838 if (Current.
is(tok::equal) &&
839 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
840 CurrentState.VariablePos == 0 &&
842 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
843 CurrentState.VariablePos = State.Column;
846 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
847 CurrentState.VariablePos -=
Tok->ColumnWidth;
848 if (
Tok->SpacesRequiredBefore != 0)
852 if (
Previous.PartOfMultiVariableDeclStmt)
853 CurrentState.LastSpace = CurrentState.VariablePos;
859 int PPColumnCorrection = 0;
863 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
870 if (Style.UseTab != FormatStyle::UT_Never)
871 PPColumnCorrection = -1;
872 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
878 const bool ContinuePPDirective =
880 Whitespaces.replaceWhitespace(Current, 0, Spaces,
881 State.
Column + Spaces + PPColumnCorrection,
882 false, ContinuePPDirective);
887 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
888 Current.
is(TT_InheritanceColon)) {
889 CurrentState.NoLineBreak =
true;
891 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
893 CurrentState.NoLineBreak =
true;
896 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
898 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
899 CurrentState.Indent.Total);
902 CurrentState.AlignColons =
false;
906 CurrentState.ColonPos = FirstColonPos;
914 auto IsStartOfBracedList = [&]() {
916 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
918 if (IsStartOfBracedList())
919 return Style.BreakAfterOpenBracketBracedList;
920 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
924 if (
Tok.Previous->isIf())
925 return Style.BreakAfterOpenBracketIf;
926 if (
Tok.Previous->isLoop(Style))
927 return Style.BreakAfterOpenBracketLoop;
928 if (
Tok.Previous->is(tok::kw_switch))
929 return Style.BreakAfterOpenBracketSwitch;
930 if (Style.BreakAfterOpenBracketFunction) {
931 return !
Tok.Previous->is(TT_CastRParen) &&
932 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
937 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
938 Tok.Previous->is(tok::identifier);
940 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
941 if (!Style.isJavaScript())
943 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
944 if (Prev->is(TT_TemplateString) && Prev->opensScope())
946 if (Prev->opensScope() && !NestBlocks)
948 if (Prev->is(TT_TemplateString) && Prev->closesScope())
954 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
955 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
957 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
964 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
966 if (
Tok.is(TT_UnaryOperator) ||
967 (Style.isJavaScript() &&
968 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
971 const auto *
Previous = TokAfterLParen.Previous;
975 Previous->Previous->is(tok::kw_switch))) {
978 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
979 TT_LambdaDefinitionLParen) &&
983 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
986 return !
Next ||
Next->isMemberAccess() ||
987 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
990 State.
Column > getNewLineColumn(State).Total &&
1001 !StartsSimpleOneArgList(Current)) {
1002 CurrentState.NoLineBreak =
true;
1006 CurrentState.NoLineBreak =
true;
1012 if (Style.AlignAfterOpenBracket &&
1013 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1014 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1015 TT_TableGenDAGArgOpener,
1016 TT_TableGenDAGArgOpenerToBreak) &&
1018 (Current.
isNot(TT_LineComment) ||
1020 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||
1022 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,
1024 Previous.is(TT_VerilogMultiLineListLParen)) &&
1025 !IsInTemplateString(Current,
false)) {
1026 CurrentState.Indent = State.
Column + Spaces;
1027 CurrentState.IsAligned =
true;
1030 CurrentState.NoLineBreak =
true;
1032 CurrentState.NoLineBreak =
true;
1035 State.
Column > getNewLineColumn(State).Total) {
1036 CurrentState.ContainsUnwrappedBuilder =
true;
1039 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1040 CurrentState.NoLineBreak =
true;
1041 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1050 CurrentState.NoLineBreak =
true;
1057 const FormatToken *P = Current.getPreviousNonComment();
1058 if (Current.
isNot(tok::comment) && P &&
1059 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1060 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1061 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1065 bool BreakBeforeOperator =
1066 P->MustBreakBefore || P->is(tok::lessless) ||
1067 (P->is(TT_BinaryOperator) &&
1068 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1069 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1073 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1074 P->isNot(TT_ConditionalExpr);
1075 if ((!BreakBeforeOperator &&
1077 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1078 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1079 CurrentState.NoLineBreakInOperand =
true;
1084 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1089 CurrentState.LastSpace = State.
Column;
1090 CurrentState.NestedBlockIndent = State.
Column;
1091 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1093 Previous.isNot(TT_OverloadedOperator)) ||
1095 CurrentState.LastSpace = State.
Column;
1096 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1098 Style.BreakConstructorInitializers ==
1099 FormatStyle::BCIS_AfterColon) {
1100 CurrentState.Indent = State.
Column;
1101 CurrentState.LastSpace = State.
Column;
1102 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1103 CurrentState.LastSpace = State.
Column;
1104 }
else if (
Previous.is(TT_BinaryOperator) &&
1111 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1112 CurrentState.LastSpace = State.
Column;
1113 }
else if (
Previous.is(TT_InheritanceColon)) {
1114 CurrentState.Indent = State.
Column;
1115 CurrentState.LastSpace = State.
Column;
1116 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1117 CurrentState.ColonPos = State.
Column;
1118 }
else if (
Previous.opensScope()) {
1126 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1127 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1128 CurrentState.LastSpace = State.
Column;
1134unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1137 assert(State.NextToken->Previous);
1139 auto &CurrentState = State.Stack.back();
1143 unsigned Penalty = 0;
1145 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1147 if (!NextNonComment)
1148 NextNonComment = &Current;
1151 if (!CurrentState.ContainsLineBreak)
1153 CurrentState.ContainsLineBreak =
true;
1155 Penalty += State.NextToken->SplitPenalty;
1160 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1161 (State.Column <= Style.ColumnLimit / 3 ||
1162 CurrentState.BreakBeforeParameter)) {
1163 Penalty += Style.PenaltyBreakFirstLessLess;
1166 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1167 State.Column = TotalColumn;
1181 if (State.Column > State.FirstIndent) {
1183 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1196 if (Current.isNot(TT_LambdaArrow) &&
1197 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1198 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1199 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1200 CurrentState.NestedBlockIndent = State.Column;
1203 if (NextNonComment->isMemberAccess()) {
1204 if (CurrentState.CallContinuation == 0)
1205 CurrentState.CallContinuation = State.Column;
1206 }
else if (NextNonComment->is(TT_SelectorName)) {
1207 if (!CurrentState.ObjCSelectorNameFound) {
1208 if (NextNonComment->LongestObjCSelectorName == 0) {
1209 CurrentState.AlignColons =
false;
1211 CurrentState.ColonPos =
1213 ? std::max(CurrentState.Indent.Total,
1214 State.FirstIndent + Style.ContinuationIndentWidth)
1215 : CurrentState.
Indent.Total) +
1219 }
else if (CurrentState.AlignColons &&
1220 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1221 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1223 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1224 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1234 if (State.Stack.size() > 1) {
1235 State.Stack[State.Stack.size() - 2].LastSpace =
1236 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1237 Style.ContinuationIndentWidth;
1241 switch (Style.BreakInheritanceList) {
1242 case FormatStyle::BILS_BeforeColon:
1243 case FormatStyle::BILS_AfterComma:
1244 CurrentState.IsAligned = CurrentState.IsAligned ||
1245 Current.is(TT_InheritanceColon) ||
1248 case FormatStyle::BILS_BeforeComma:
1249 CurrentState.IsAligned =
1250 CurrentState.IsAligned ||
1251 Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma);
1253 case FormatStyle::BILS_AfterColon:
1254 CurrentState.IsAligned =
1255 CurrentState.IsAligned ||
1256 Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma);
1260 if ((PreviousNonComment &&
1261 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1262 !CurrentState.AvoidBinPacking) ||
1264 CurrentState.BreakBeforeParameter =
false;
1266 if (PreviousNonComment &&
1267 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1268 PreviousNonComment->ClosesRequiresClause) &&
1269 Current.NestingLevel == 0) {
1270 CurrentState.BreakBeforeParameter =
false;
1272 if (NextNonComment->is(tok::question) ||
1273 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1274 CurrentState.BreakBeforeParameter =
true;
1276 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1277 CurrentState.BreakBeforeParameter =
false;
1278 CurrentState.IsAligned =
true;
1283 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1286 !Current.MatchingParen->Children.empty()) {
1294 const bool ContinuePPDirective = State.Line->InPPDirective &&
1296 Current.isNot(TT_LineComment);
1297 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1298 CurrentState.IsAligned, ContinuePPDirective,
1299 IndentedFromColumn);
1302 if (!Current.isTrailingComment())
1303 CurrentState.LastSpace = State.Column;
1304 if (Current.is(tok::lessless)) {
1308 CurrentState.LastSpace += 3;
1311 State.StartOfLineLevel = Current.NestingLevel;
1312 State.LowestLevelOnLine = Current.NestingLevel;
1316 bool NestedBlockSpecialCase =
1317 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1318 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1319 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1320 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1322 NestedBlockSpecialCase =
1323 NestedBlockSpecialCase ||
1324 (Current.MatchingParen &&
1325 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1326 if (!NestedBlockSpecialCase) {
1327 auto ParentLevelIt = std::next(State.Stack.rbegin());
1328 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1329 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1344 auto FindCurrentLevel = [&](
const auto &It) {
1345 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1346 return PState.Tok != nullptr;
1349 auto MaybeIncrement = [&](
const auto &It) {
1350 return It != State.Stack.rend() ? std::next(It) : It;
1352 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1353 auto LevelContainingLambdaIt =
1354 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1355 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1357 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1358 I->BreakBeforeParameter =
true;
1361 if (PreviousNonComment &&
1362 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1363 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1364 !PreviousNonComment->ClosesRequiresClause) ||
1365 Current.NestingLevel != 0) &&
1366 PreviousNonComment->isNoneOf(
1367 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1368 TT_LeadingJavaAnnotation) &&
1369 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1372 (!Style.BraceWrapping.BeforeLambdaBody ||
1373 Current.isNot(TT_LambdaLBrace))) {
1374 CurrentState.BreakBeforeParameter =
true;
1379 if (PreviousNonComment &&
1380 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1382 CurrentState.BreakBeforeClosingBrace =
true;
1385 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1386 if (
auto Previous = PreviousNonComment->Previous) {
1388 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1389 }
else if (
Previous->isLoop(Style)) {
1390 CurrentState.BreakBeforeClosingParen =
1391 Style.BreakBeforeCloseBracketLoop;
1392 }
else if (
Previous->is(tok::kw_switch)) {
1393 CurrentState.BreakBeforeClosingParen =
1394 Style.BreakBeforeCloseBracketSwitch;
1396 CurrentState.BreakBeforeClosingParen =
1397 Style.BreakBeforeCloseBracketFunction;
1402 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1403 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1405 if (CurrentState.AvoidBinPacking) {
1410 bool PreviousIsBreakingCtorInitializerColon =
1411 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1412 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1413 bool AllowAllConstructorInitializersOnNextLine =
1414 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1415 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1416 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1417 !PreviousIsBreakingCtorInitializerColon) ||
1418 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1419 State.Line->MustBeDeclaration) ||
1420 (!Style.AllowAllArgumentsOnNextLine &&
1421 !State.Line->MustBeDeclaration) ||
1422 (!AllowAllConstructorInitializersOnNextLine &&
1423 PreviousIsBreakingCtorInitializerColon) ||
1425 CurrentState.BreakBeforeParameter =
true;
1431 if (PreviousIsBreakingCtorInitializerColon &&
1432 AllowAllConstructorInitializersOnNextLine) {
1433 CurrentState.BreakBeforeParameter =
false;
1438 CurrentState.BreakBeforeParameter =
true;
1444ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1445 if (!State.NextToken || !State.NextToken->Previous)
1449 const auto &CurrentState = State.Stack.back();
1451 if (CurrentState.IsCSharpGenericTypeConstraint &&
1452 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1453 return CurrentState.ColonPos + 2;
1458 const auto ContinuationIndent =
1459 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1460 CurrentState.Indent) +
1461 Style.ContinuationIndentWidth;
1462 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1464 if (!NextNonComment)
1465 NextNonComment = &Current;
1468 if (Style.isJava() &&
1469 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1470 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1471 CurrentState.Indent + Style.ContinuationIndentWidth);
1476 if (Style.isVerilog() && PreviousNonComment &&
1477 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1478 return State.FirstIndent;
1481 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1482 State.Line->First->is(tok::kw_enum)) {
1483 return IndentationAndAlignment(Style.IndentWidth *
1484 State.Line->First->IndentLevel) +
1488 if (Style.BraceWrapping.BeforeLambdaBody &&
1489 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1490 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1491 ? CurrentState.Indent
1492 : State.FirstIndent;
1493 return From + Style.IndentWidth;
1496 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1497 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1498 if (Current.NestingLevel == 0 ||
1499 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1500 State.NextToken->is(TT_LambdaLBrace))) {
1501 return State.FirstIndent;
1503 return CurrentState.Indent;
1505 if (Current.is(TT_LambdaArrow) &&
1506 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1507 tok::kw_consteval, tok::kw_static,
1508 TT_AttributeRSquare)) {
1509 return ContinuationIndent;
1511 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1512 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1513 State.Stack.size() > 1) {
1514 if (Current.closesBlockOrBlockTypeList(Style))
1515 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1516 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1517 return State.Stack[State.Stack.size() - 2].LastSpace;
1518 return State.FirstIndent;
1535 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1537 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1538 return State.Stack[State.Stack.size() - 2].LastSpace;
1542 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1543 State.Stack.size() > 1) {
1544 return State.Stack[State.Stack.size() - 2].LastSpace;
1546 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1547 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1548 State.Stack.size() > 1) {
1549 return State.Stack[State.Stack.size() - 2].LastSpace;
1551 if ((Style.BreakBeforeCloseBracketFunction ||
1552 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1553 Style.BreakBeforeCloseBracketSwitch) &&
1554 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1555 return State.Stack[State.Stack.size() - 2].LastSpace;
1557 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1558 State.Stack.size() > 1) {
1559 return State.Stack[State.Stack.size() - 2].LastSpace;
1561 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1562 return State.Stack[State.Stack.size() - 2].LastSpace;
1570 if (Current.is(tok::identifier) && Current.Next &&
1571 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1572 (Current.Next->is(TT_DictLiteral) ||
1573 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1574 return CurrentState.Indent;
1576 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1577 State.StartOfStringLiteral != 0) {
1578 return State.StartOfStringLiteral - 1;
1580 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1581 return State.StartOfStringLiteral;
1582 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1583 return CurrentState.FirstLessLess;
1584 if (NextNonComment->isMemberAccess()) {
1585 if (CurrentState.CallContinuation == 0)
1586 return ContinuationIndent;
1587 return CurrentState.CallContinuation;
1589 if (CurrentState.QuestionColumn != 0 &&
1590 ((NextNonComment->is(tok::colon) &&
1591 NextNonComment->is(TT_ConditionalExpr)) ||
1592 Previous.is(TT_ConditionalExpr))) {
1593 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1594 !NextNonComment->Next->FakeLParens.empty() &&
1596 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1598 !CurrentState.IsWrappedConditional) {
1603 unsigned Indent = CurrentState.Indent.Total;
1604 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1605 Indent -= Style.ContinuationIndentWidth;
1606 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1610 return CurrentState.QuestionColumn;
1612 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1613 return CurrentState.VariablePos;
1614 if (Current.is(TT_RequiresClause)) {
1615 if (Style.IndentRequiresClause)
1616 return CurrentState.Indent + Style.IndentWidth;
1617 switch (Style.RequiresClausePosition) {
1618 case FormatStyle::RCPS_OwnLine:
1619 case FormatStyle::RCPS_WithFollowing:
1620 case FormatStyle::RCPS_OwnLineWithBrace:
1621 return CurrentState.Indent;
1626 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1627 TT_InheritanceComma)) {
1628 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1630 if ((PreviousNonComment &&
1631 (PreviousNonComment->ClosesTemplateDeclaration ||
1632 PreviousNonComment->ClosesRequiresClause ||
1633 (PreviousNonComment->is(TT_AttributeMacro) &&
1634 Current.isNot(tok::l_paren) &&
1635 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1636 TT_PointerOrReference)) ||
1637 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1638 TT_FunctionAnnotationRParen,
1640 TT_LeadingJavaAnnotation))) ||
1641 (!Style.IndentWrappedFunctionNames &&
1642 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1643 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1644 CurrentState.Indent);
1646 if (NextNonComment->is(TT_SelectorName)) {
1647 if (!CurrentState.ObjCSelectorNameFound) {
1648 auto MinIndent = CurrentState.Indent;
1651 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1652 Style.ContinuationIndentWidth);
1663 return MinIndent.addPadding(
1664 std::max(NextNonComment->LongestObjCSelectorName,
1665 NextNonComment->ColumnWidth) -
1666 NextNonComment->ColumnWidth);
1668 if (!CurrentState.AlignColons)
1669 return CurrentState.Indent;
1670 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1671 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1672 return CurrentState.Indent;
1674 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1675 return CurrentState.ColonPos;
1676 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1677 if (CurrentState.StartOfArraySubscripts != 0) {
1678 return CurrentState.StartOfArraySubscripts;
1679 }
else if (Style.isCSharp()) {
1681 return CurrentState.Indent;
1683 return ContinuationIndent;
1688 if (State.Line->InPragmaDirective) {
1689 FormatToken *PragmaType = State.Line->First->Next->Next;
1690 if (PragmaType && PragmaType->TokenText ==
"omp")
1691 return CurrentState.Indent + Style.ContinuationIndentWidth;
1696 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1697 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1698 return CurrentState.Indent;
1701 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1702 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1703 return ContinuationIndent;
1705 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1706 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1707 return ContinuationIndent;
1709 if (NextNonComment->is(TT_CtorInitializerComma))
1710 return CurrentState.Indent;
1711 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1712 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1713 return CurrentState.Indent;
1715 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1716 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1717 return CurrentState.Indent;
1720 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1721 !Current.isBinaryOperator() &&
1722 Current.isNoneOf(tok::colon, tok::comment)) {
1723 return ContinuationIndent;
1725 if (Current.is(TT_ProtoExtensionLSquare))
1726 return CurrentState.Indent;
1727 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1728 return CurrentState.Indent - Current.Tok.getLength() -
1729 Current.SpacesRequiredBefore;
1731 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1732 CurrentState.UnindentOperator) {
1733 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1734 NextNonComment->SpacesRequiredBefore;
1736 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1737 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1740 return CurrentState.Indent + Style.ContinuationIndentWidth;
1742 return CurrentState.Indent;
1747 const FormatStyle &Style) {
1754 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1757unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1758 bool DryRun,
bool Newline) {
1759 assert(State.Stack.size());
1761 auto &CurrentState = State.Stack.back();
1763 if (Current.is(TT_CSharpGenericTypeConstraint))
1764 CurrentState.IsCSharpGenericTypeConstraint =
true;
1765 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1766 CurrentState.NoLineBreakInOperand =
false;
1767 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1768 CurrentState.AvoidBinPacking =
true;
1769 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1770 if (CurrentState.FirstLessLess == 0)
1771 CurrentState.FirstLessLess = State.Column;
1773 CurrentState.LastOperatorWrapped = Newline;
1775 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1776 CurrentState.LastOperatorWrapped = Newline;
1777 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1778 Current.Previous->isNot(TT_ConditionalExpr)) {
1779 CurrentState.LastOperatorWrapped = Newline;
1781 if (Current.is(TT_ArraySubscriptLSquare) &&
1782 CurrentState.StartOfArraySubscripts == 0) {
1783 CurrentState.StartOfArraySubscripts = State.Column;
1787 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1789 if (
Tok.MustBreakBefore)
1793 return Next &&
Next->MustBreakBefore;
1795 if (IsWrappedConditional(Current))
1796 CurrentState.IsWrappedConditional =
true;
1797 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1798 CurrentState.QuestionColumn = State.Column;
1799 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1804 CurrentState.QuestionColumn = State.Column;
1806 if (!Current.opensScope() && !Current.closesScope() &&
1807 Current.isNot(TT_PointerOrReference)) {
1808 State.LowestLevelOnLine =
1809 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1811 if (Current.isMemberAccess())
1812 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1813 if (Current.is(TT_SelectorName))
1814 CurrentState.ObjCSelectorNameFound =
true;
1815 if (Current.is(TT_CtorInitializerColon) &&
1816 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1822 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1823 FormatStyle::BCIS_BeforeComma
1826 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1827 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1828 CurrentState.AvoidBinPacking =
true;
1829 CurrentState.BreakBeforeParameter =
1830 Style.ColumnLimit > 0 &&
1831 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1832 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1834 CurrentState.BreakBeforeParameter =
false;
1837 if (Current.is(TT_CtorInitializerColon) &&
1838 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1839 CurrentState.Indent =
1840 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1841 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1842 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1843 CurrentState.AvoidBinPacking =
true;
1845 CurrentState.BreakBeforeParameter =
false;
1847 if (Current.is(TT_InheritanceColon)) {
1848 CurrentState.Indent =
1849 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1851 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1852 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1853 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1854 CurrentState.LastSpace = State.Column;
1855 if (Current.is(TT_RequiresExpression) &&
1856 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1857 CurrentState.NestedBlockIndent = State.Column;
1869 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1871 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1872 !CurrentState.HasMultipleNestedBlocks) {
1873 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1874 for (ParenState &PState : llvm::drop_end(State.Stack))
1875 PState.NoLineBreak =
true;
1876 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1878 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1879 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1880 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1881 TT_CtorInitializerColon)))) {
1882 CurrentState.NestedBlockInlined =
1886 moveStatePastFakeLParens(State, Newline);
1887 moveStatePastScopeCloser(State);
1890 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1891 !State.Stack.back().NoLineBreakInOperand;
1892 moveStatePastScopeOpener(State, Newline);
1893 moveStatePastFakeRParens(State);
1895 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1896 State.StartOfStringLiteral = State.Column + 1;
1897 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1898 State.StartOfStringLiteral = State.Column + 1;
1899 }
else if (Current.is(TT_TableGenMultiLineString) &&
1900 State.StartOfStringLiteral == 0) {
1901 State.StartOfStringLiteral = State.Column + 1;
1902 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1903 State.StartOfStringLiteral = State.Column;
1904 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1905 !Current.isStringLiteral()) {
1906 State.StartOfStringLiteral = 0;
1909 State.Column += Current.ColumnWidth;
1910 State.NextToken = State.NextToken->Next;
1915 if (Style.isVerilog() && State.NextToken &&
1916 State.NextToken->MustBreakBefore &&
1917 Keywords.isVerilogEndOfLabel(Current)) {
1918 State.FirstIndent += Style.IndentWidth;
1919 CurrentState.Indent = State.FirstIndent;
1923 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1926 Current.Role->formatFromToken(State,
this, DryRun);
1933 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1938void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1941 if (Current.FakeLParens.empty())
1949 bool SkipFirstExtraIndent =
1952 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1954 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1956 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1957 const auto &CurrentState = State.Stack.back();
1958 ParenState NewParenState = CurrentState;
1959 NewParenState.Tok =
nullptr;
1960 NewParenState.ContainsLineBreak =
false;
1961 NewParenState.LastOperatorWrapped =
true;
1962 NewParenState.IsChainedConditional =
false;
1963 NewParenState.IsWrappedConditional =
false;
1964 NewParenState.UnindentOperator =
false;
1965 NewParenState.NoLineBreak =
1966 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1970 NewParenState.AvoidBinPacking =
false;
1975 if (!Current.isTrailingComment() &&
1976 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1979 (!Style.isJava() && PrecedenceLevel > 0)) &&
1980 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1981 Current.NestingLevel == 0) &&
1982 (!Style.isTableGen() ||
1984 TT_TableGenDAGArgListCommaToBreak)))) {
1985 NewParenState.Indent =
1986 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1987 IndentationAndAlignment(CurrentState.LastSpace)});
1994 State.Stack.size() > 1) {
1995 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1996 Style.ContinuationIndentWidth;
2006 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
2007 NewParenState.UnindentOperator =
true;
2009 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
2010 NewParenState.IsAligned =
true;
2020 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2022 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2023 NewParenState.StartOfFunctionCall = State.Column;
2033 &PrecedenceLevel == &Current.FakeLParens.back() &&
2034 !CurrentState.IsWrappedConditional) {
2035 NewParenState.IsChainedConditional =
true;
2036 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2039 !Current.isTrailingComment())) {
2040 NewParenState.Indent += Style.ContinuationIndentWidth;
2043 NewParenState.BreakBeforeParameter =
false;
2044 State.Stack.push_back(NewParenState);
2045 SkipFirstExtraIndent =
false;
2049void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2050 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2051 unsigned VariablePos = State.Stack.back().VariablePos;
2052 if (State.Stack.size() == 1) {
2056 State.Stack.pop_back();
2057 State.Stack.back().VariablePos = VariablePos;
2060 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2063 State.Stack.back().LastSpace -= Style.IndentWidth;
2067void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2070 if (!Current.opensScope())
2073 const auto &CurrentState = State.Stack.back();
2076 if (Current.isOneOf(tok::less, tok::l_paren) &&
2077 CurrentState.IsCSharpGenericTypeConstraint) {
2081 if (Current.MatchingParen && Current.is(
BK_Block)) {
2082 moveStateToNewBlock(State, Newline);
2089 const auto *Prev =
Tok->getPreviousNonComment();
2092 return Prev->is(tok::comma);
2093 }(Current.MatchingParen);
2095 IndentationAndAlignment NewIndent = 0;
2096 unsigned LastSpace = CurrentState.LastSpace;
2097 bool AvoidBinPacking;
2098 bool BreakBeforeParameter =
false;
2099 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2100 CurrentState.NestedBlockIndent);
2101 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2103 if (Current.opensBlockOrBlockTypeList(Style)) {
2104 NewIndent = Style.IndentWidth +
2105 std::min(State.Column, CurrentState.NestedBlockIndent);
2106 }
else if (Current.is(tok::l_brace)) {
2107 const auto Width = Style.BracedInitializerIndentWidth;
2108 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2109 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2111 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2113 const FormatToken *NextNonComment = Current.getNextNonComment();
2114 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2115 Style.isProto() || !Style.BinPackArguments ||
2116 (NextNonComment && NextNonComment->isOneOf(
2117 TT_DesignatedInitializerPeriod,
2118 TT_DesignatedInitializerLSquare));
2119 BreakBeforeParameter = EndsInComma;
2120 if (Current.ParameterCount > 1)
2121 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2123 NewIndent = IndentationAndAlignment(std::max(
2124 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2125 Style.ContinuationIndentWidth;
2127 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2128 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2134 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2135 NewIndent = State.Column +
Next->TokenText.size() + 2;
2142 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2143 NewIndent = std::max(NewIndent, CurrentState.Indent);
2144 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2150 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2151 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2152 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2154 bool BinPackDeclaration =
2156 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2159 bool GenericSelection =
2160 Current.getPreviousNonComment() &&
2161 Current.getPreviousNonComment()->is(tok::kw__Generic);
2164 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2165 (Style.isJavaScript() && EndsInComma) ||
2166 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2167 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2168 (Style.ExperimentalAutoDetectBinPacking &&
2172 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2173 Style.ObjCBreakBeforeNestedBlockParam) {
2174 if (Style.ColumnLimit) {
2179 BreakBeforeParameter =
true;
2185 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2186 if (
Tok->MustBreakBefore ||
2187 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2188 BreakBeforeParameter =
true;
2195 if (Style.isJavaScript() && EndsInComma)
2196 BreakBeforeParameter =
true;
2202 Current.Children.empty() &&
2203 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2204 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2205 (Current.is(TT_TemplateOpener) &&
2206 CurrentState.ContainsUnwrappedBuilder));
2207 State.Stack.push_back(
2208 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2209 auto &NewState = State.Stack.back();
2210 NewState.NestedBlockIndent = NestedBlockIndent;
2211 NewState.BreakBeforeParameter = BreakBeforeParameter;
2212 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2214 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2215 Current.is(tok::l_paren)) {
2219 if (next->is(TT_LambdaLSquare)) {
2220 NewState.HasMultipleNestedBlocks =
true;
2227 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2229 Current.Previous->is(tok::at);
2232void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2234 if (!Current.closesScope())
2239 if (State.Stack.size() > 1 &&
2240 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2241 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2242 State.NextToken->is(TT_TemplateCloser) ||
2243 State.NextToken->is(TT_TableGenListCloser) ||
2244 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2245 State.Stack.pop_back();
2248 auto &CurrentState = State.Stack.back();
2260 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2261 Current.MatchingParen->Previous) {
2262 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2263 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2264 CurrentScopeOpener.MatchingParen) {
2265 int NecessarySpaceInLine =
2267 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2268 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2269 Style.ColumnLimit) {
2270 CurrentState.BreakBeforeParameter =
false;
2275 if (Current.is(tok::r_square)) {
2277 const FormatToken *NextNonComment = Current.getNextNonComment();
2278 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2279 CurrentState.StartOfArraySubscripts = 0;
2283void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2284 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2285 State.NextToken->is(TT_LambdaLBrace) &&
2286 !State.Line->MightBeFunctionDecl) {
2287 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2288 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2290 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2292 unsigned NewIndent =
2293 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2294 ? Style.ObjCBlockIndentWidth
2295 : Style.IndentWidth);
2302 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2303 State.NextToken->is(TT_LambdaLBrace);
2305 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2306 State.Stack.back().LastSpace,
2307 true, NoLineBreak));
2308 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2309 State.Stack.back().BreakBeforeParameter =
true;
2315 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2316 if (LastNewlinePos == StringRef::npos) {
2317 return StartColumn +
2325unsigned ContinuationIndenter::reformatRawStringLiteral(
2327 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2328 unsigned StartColumn = State.Column - Current.ColumnWidth;
2330 StringRef NewDelimiter =
2332 if (NewDelimiter.empty())
2333 NewDelimiter = OldDelimiter;
2336 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2337 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2340 std::string RawText = std::string(
2341 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2342 if (NewDelimiter != OldDelimiter) {
2345 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2346 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2347 NewDelimiter = OldDelimiter;
2350 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2351 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2354 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2365 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2387 unsigned CurrentIndent =
2388 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2389 ? State.Stack.back().NestedBlockIndent
2390 : State.Stack.back().Indent.Total;
2391 unsigned NextStartColumn = ContentStartsOnNewline
2392 ? CurrentIndent + Style.IndentWidth
2403 unsigned LastStartColumn =
2404 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2407 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2408 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2413 return addMultilineToken(Current, State);
2415 if (NewDelimiter != OldDelimiter) {
2418 SourceLocation PrefixDelimiterStart =
2419 Current.Tok.getLocation().getLocWithOffset(2);
2420 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2421 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2424 <<
"Failed to update the prefix delimiter of a raw string: "
2425 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2429 SourceLocation SuffixDelimiterStart =
2430 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2431 1 - OldDelimiter.size());
2432 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2433 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2436 <<
"Failed to update the suffix delimiter of a raw string: "
2437 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2440 SourceLocation OriginLoc =
2441 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2442 for (
const tooling::Replacement &Fix : Fixes.first) {
2443 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2444 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2445 Fix.getLength(), Fix.getReplacementText()));
2447 llvm::errs() <<
"Failed to reformat raw string: "
2448 << llvm::toString(std::move(Err)) <<
"\n";
2453 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2454 State.Column = RawLastLineEndColumn + NewSuffixSize;
2458 unsigned PrefixExcessCharacters =
2459 StartColumn + NewPrefixSize > Style.ColumnLimit
2460 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2463 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2466 for (ParenState &
Paren : State.Stack)
2467 Paren.BreakBeforeParameter =
true;
2469 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2472unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2475 for (ParenState &
Paren : State.Stack)
2476 Paren.BreakBeforeParameter =
true;
2478 unsigned ColumnsUsed = State.Column;
2481 State.Column = Current.LastLineColumnWidth;
2484 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2488unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2490 bool AllowBreak,
bool Newline) {
2491 unsigned Penalty = 0;
2494 auto RawStringStyle = getRawStringStyle(Current, State);
2495 if (RawStringStyle && !Current.Finalized) {
2496 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2498 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2501 Penalty = addMultilineToken(Current, State);
2504 LineState OriginalState = State;
2508 bool Strict =
false;
2511 bool Exceeded =
false;
2512 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2513 Current, State, AllowBreak,
true, Strict);
2517 LineState StrictState = OriginalState;
2518 unsigned StrictPenalty =
2519 breakProtrudingToken(Current, StrictState, AllowBreak,
2522 Strict = StrictPenalty <= Penalty;
2524 Penalty = StrictPenalty;
2525 State = std::move(StrictState);
2531 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2536 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2537 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2546 auto Tok = Current.getPreviousNonComment();
2547 if (!
Tok ||
Tok->isNot(tok::l_paren))
2549 Tok =
Tok->getPreviousNonComment();
2552 if (
Tok->is(TT_TemplateCloser)) {
2553 Tok =
Tok->MatchingParen;
2555 Tok =
Tok->getPreviousNonComment();
2557 if (!
Tok ||
Tok->isNot(tok::identifier))
2559 return Tok->TokenText;
2562std::optional<FormatStyle>
2563ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2564 const LineState &State) {
2565 if (!Current.isStringLiteral())
2566 return std::nullopt;
2569 return std::nullopt;
2571 if (!RawStringStyle && Delimiter->empty()) {
2575 if (!RawStringStyle)
2576 return std::nullopt;
2578 return RawStringStyle;
2581std::unique_ptr<BreakableToken>
2582ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2584 unsigned StartColumn = State.Column - Current.ColumnWidth;
2585 if (Current.isStringLiteral()) {
2588 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2602 if (Current.IsUnterminatedLiteral)
2606 if (State.Stack.back().IsInsideObjCArrayLiteral)
2613 if (Style.isVerilog() && Current.Previous &&
2614 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2617 StringRef
Text = Current.TokenText;
2627 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2630 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2631 Text.ends_with(
"'")) {
2633 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2634 Text.ends_with(
"\"")) {
2636 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2641 return std::make_unique<BreakableStringLiteralUsingOperators>(
2642 Current, QuoteStyle,
2653 if ((
Text.ends_with(Postfix =
"\"") &&
2654 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2655 Text.starts_with(Prefix =
"u\"") ||
2656 Text.starts_with(Prefix =
"U\"") ||
2657 Text.starts_with(Prefix =
"u8\"") ||
2658 Text.starts_with(Prefix =
"L\""))) ||
2659 (
Text.starts_with(Prefix =
"_T(\"") &&
2660 Text.ends_with(Postfix =
"\")"))) {
2661 return std::make_unique<BreakableStringLiteral>(
2663 State.Line->InPPDirective, Encoding, Style);
2665 }
else if (Current.is(TT_BlockComment)) {
2666 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2673 return std::make_unique<BreakableBlockComment>(
2674 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2675 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2676 }
else if (Current.is(TT_LineComment) &&
2677 (!Current.Previous ||
2678 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2679 bool RegularComments = [&]() {
2680 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2682 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2687 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2688 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2692 return std::make_unique<BreakableLineCommentSection>(
2693 Current, StartColumn,
false, Encoding, Style);
2698std::pair<unsigned, bool>
2699ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2701 bool DryRun,
bool Strict) {
2702 std::unique_ptr<const BreakableToken> Token =
2703 createBreakableToken(Current, State, AllowBreak);
2706 assert(Token->getLineCount() > 0);
2708 if (Current.is(TT_LineComment)) {
2710 ColumnLimit = Style.ColumnLimit;
2712 if (ColumnLimit == 0) {
2715 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2717 if (Current.UnbreakableTailLength >= ColumnLimit)
2721 unsigned StartColumn = State.Column - Current.ColumnWidth;
2722 unsigned NewBreakPenalty = Current.isStringLiteral()
2723 ? Style.PenaltyBreakString
2724 : Style.PenaltyBreakComment;
2727 bool Exceeded =
false;
2729 bool BreakInserted = Token->introducesBreakBeforeToken();
2732 bool NewBreakBefore =
false;
2736 bool Reflow =
false;
2739 unsigned TailOffset = 0;
2741 unsigned ContentStartColumn =
2742 Token->getContentStartColumn(0,
false);
2744 unsigned RemainingTokenColumns =
2745 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2748 Token->adaptStartOfLine(0, Whitespaces);
2750 unsigned ContentIndent = 0;
2751 unsigned Penalty = 0;
2752 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2753 << StartColumn <<
".\n");
2754 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2755 LineIndex != EndIndex; ++LineIndex) {
2756 LLVM_DEBUG(llvm::dbgs()
2757 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2758 NewBreakBefore =
false;
2762 bool TryReflow = Reflow;
2764 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2765 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2766 << (ContentStartColumn + RemainingTokenColumns)
2767 <<
", space: " << ColumnLimit
2768 <<
", reflown prefix: " << ContentStartColumn
2769 <<
", offset in line: " << TailOffset <<
"\n");
2775 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2776 ContentStartColumn, CommentPragmasRegex);
2777 if (
Split.first == StringRef::npos) {
2780 if (LineIndex < EndIndex - 1) {
2783 Penalty += Style.PenaltyExcessCharacter *
2784 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2786 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2789 assert(
Split.first != 0);
2791 if (Token->supportsReflow()) {
2811 unsigned ToSplitColumns = Token->getRangeLength(
2812 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2813 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2816 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2817 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2820 unsigned ToNextSplitColumns = 0;
2821 if (NextSplit.first == StringRef::npos) {
2822 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2823 ContentStartColumn);
2825 ToNextSplitColumns = Token->getRangeLength(
2826 LineIndex, TailOffset,
2827 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2831 ToNextSplitColumns =
2832 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2833 LLVM_DEBUG(llvm::dbgs()
2834 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2835 LLVM_DEBUG(llvm::dbgs()
2836 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2839 bool ContinueOnLine =
2840 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2841 unsigned ExcessCharactersPenalty = 0;
2842 if (!ContinueOnLine && !Strict) {
2845 ExcessCharactersPenalty =
2846 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2847 Style.PenaltyExcessCharacter;
2848 LLVM_DEBUG(llvm::dbgs()
2849 <<
" Penalty excess: " << ExcessCharactersPenalty
2850 <<
"\n break : " << NewBreakPenalty <<
"\n");
2851 if (ExcessCharactersPenalty < NewBreakPenalty) {
2853 ContinueOnLine =
true;
2856 if (ContinueOnLine) {
2857 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2862 Token->compressWhitespace(LineIndex, TailOffset, Split,
2866 ContentStartColumn += ToSplitColumns + 1;
2867 Penalty += ExcessCharactersPenalty;
2869 RemainingTokenColumns = Token->getRemainingLength(
2870 LineIndex, TailOffset, ContentStartColumn);
2874 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2879 ContentIndent = Token->getContentIndent(LineIndex);
2880 LLVM_DEBUG(llvm::dbgs()
2881 <<
" ContentIndent: " << ContentIndent <<
"\n");
2882 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2885 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2886 LineIndex, TailOffset +
Split.first +
Split.second,
2887 ContentStartColumn);
2888 if (NewRemainingTokenColumns == 0) {
2891 ContentStartColumn =
2892 Token->getContentStartColumn(LineIndex,
true);
2893 NewRemainingTokenColumns = Token->getRemainingLength(
2894 LineIndex, TailOffset +
Split.first +
Split.second,
2895 ContentStartColumn);
2901 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2906 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2907 <<
", " <<
Split.second <<
"\n");
2909 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2913 Penalty += NewBreakPenalty;
2915 RemainingTokenColumns = NewRemainingTokenColumns;
2916 BreakInserted =
true;
2917 NewBreakBefore =
true;
2921 if (LineIndex + 1 != EndIndex) {
2922 unsigned NextLineIndex = LineIndex + 1;
2923 if (NewBreakBefore) {
2942 ContentStartColumn += RemainingTokenColumns + 1;
2947 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2948 LLVM_DEBUG(llvm::dbgs()
2949 <<
" Size of reflown text: " << ContentStartColumn
2950 <<
"\n Potential reflow split: ");
2951 if (SplitBeforeNext.first != StringRef::npos) {
2952 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2953 << SplitBeforeNext.second <<
"\n");
2954 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2957 RemainingTokenColumns = Token->getRemainingLength(
2958 NextLineIndex, TailOffset, ContentStartColumn);
2960 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2961 LLVM_DEBUG(llvm::dbgs()
2962 <<
" Over limit after reflow, need: "
2963 << (ContentStartColumn + RemainingTokenColumns)
2964 <<
", space: " << ColumnLimit
2965 <<
", reflown prefix: " << ContentStartColumn
2966 <<
", offset in line: " << TailOffset <<
"\n");
2972 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2973 ContentStartColumn, CommentPragmasRegex);
2974 if (
Split.first == StringRef::npos) {
2975 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2981 unsigned ToSplitColumns = Token->getRangeLength(
2982 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2983 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2984 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2985 << (ContentStartColumn + ToSplitColumns)
2986 <<
", space: " << ColumnLimit);
2987 unsigned ExcessCharactersPenalty =
2988 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2989 Style.PenaltyExcessCharacter;
2990 if (NewBreakPenalty < ExcessCharactersPenalty)
2996 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3004 ContentStartColumn =
3005 Token->getContentStartColumn(NextLineIndex,
false);
3006 RemainingTokenColumns = Token->getRemainingLength(
3007 NextLineIndex, TailOffset, ContentStartColumn);
3010 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3025 if (NewBreakBefore) {
3026 assert(Penalty >= NewBreakPenalty);
3027 Penalty -= NewBreakPenalty;
3030 Token->reflow(NextLineIndex, Whitespaces);
3036 Token->getSplitAfterLastLine(TailOffset);
3037 if (SplitAfterLastLine.first != StringRef::npos) {
3038 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3042 Penalty += Style.PenaltyExcessCharacter *
3043 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3046 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3049 ContentStartColumn =
3050 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3051 RemainingTokenColumns = Token->getRemainingLength(
3052 Token->getLineCount() - 1,
3053 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3054 ContentStartColumn);
3057 State.Column = ContentStartColumn + RemainingTokenColumns -
3058 Current.UnbreakableTailLength;
3060 if (BreakInserted) {
3062 Token->updateAfterBroken(Whitespaces);
3067 if (Current.isNot(TT_LineComment))
3068 for (ParenState &
Paren : State.Stack)
3069 Paren.BreakBeforeParameter =
true;
3071 if (Current.is(TT_BlockComment))
3072 State.NoContinuation =
true;
3074 State.Stack.back().LastSpace = StartColumn;
3077 Token->updateNextToken(State);
3079 return {Penalty, Exceeded};
3084 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3087bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3089 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3094 if (Current.
TokenText.starts_with(
"R\""))
3098 if (Current.getNextNonComment() &&
3099 Current.getNextNonComment()->isStringLiteral()) {
3102 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3104 Style.ColumnLimit) {
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
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)) {....
tok::TokenKind getKind() const
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.
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...