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)) {
715 if (
Tok->FirstAfterPPLine)
727 Current.
isNoneOf(tok::r_brace, tok::comment)) {
731 if (Current.
is(tok::lessless) &&
734 Previous.TokenText ==
"\'\\n\'")))) {
741 if (State.NoContinuation)
749 unsigned ExtraSpaces) {
751 assert(State.NextToken->Previous);
754 assert(!State.Stack.empty());
755 State.NoContinuation =
false;
757 if (Current.
is(TT_ImplicitStringLiteral) &&
758 (!
Previous.Tok.getIdentifierInfo() ||
759 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
760 tok::pp_not_keyword)) {
766 State.Column = EndColumn;
768 unsigned StartColumn =
770 assert(EndColumn >= StartColumn);
771 State.Column += EndColumn - StartColumn;
773 moveStateToNextToken(State, DryRun,
false);
777 unsigned Penalty = 0;
779 Penalty = addTokenOnNewLine(State, DryRun);
781 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
783 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
786void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
787 unsigned ExtraSpaces) {
789 assert(State.NextToken->Previous);
791 auto &CurrentState = State.Stack.back();
798 auto DisallowLineBreaks = [&] {
799 if (!Style.isCpp() ||
800 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
808 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
811 const auto *Prev = Current.getPreviousNonComment();
812 if (!Prev || Prev->isNot(tok::l_paren))
815 if (Prev->BlockParameterCount == 0)
819 if (Prev->BlockParameterCount > 1)
826 const auto *Comma = Prev->
Role->lastComma();
830 const auto *
Next = Comma->getNextNonComment();
831 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
834 if (DisallowLineBreaks())
835 State.NoLineBreak =
true;
837 if (Current.
is(tok::equal) &&
838 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
839 CurrentState.VariablePos == 0 &&
841 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
842 CurrentState.VariablePos = State.Column;
845 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
846 CurrentState.VariablePos -=
Tok->ColumnWidth;
847 if (
Tok->SpacesRequiredBefore != 0)
851 if (
Previous.PartOfMultiVariableDeclStmt)
852 CurrentState.LastSpace = CurrentState.VariablePos;
858 int PPColumnCorrection = 0;
862 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
869 if (Style.UseTab != FormatStyle::UT_Never)
870 PPColumnCorrection = -1;
871 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
877 const bool ContinuePPDirective =
879 Whitespaces.replaceWhitespace(Current, 0, Spaces,
880 State.
Column + Spaces + PPColumnCorrection,
881 false, ContinuePPDirective);
886 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
887 Current.
is(TT_InheritanceColon)) {
888 CurrentState.NoLineBreak =
true;
890 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
892 CurrentState.NoLineBreak =
true;
895 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
897 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
898 CurrentState.Indent.Total);
901 CurrentState.AlignColons =
false;
905 CurrentState.ColonPos = FirstColonPos;
913 auto IsStartOfBracedList = [&]() {
915 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
917 if (IsStartOfBracedList())
918 return Style.BreakAfterOpenBracketBracedList;
919 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
923 if (
Tok.Previous->isIf())
924 return Style.BreakAfterOpenBracketIf;
925 if (
Tok.Previous->isLoop(Style))
926 return Style.BreakAfterOpenBracketLoop;
927 if (
Tok.Previous->is(tok::kw_switch))
928 return Style.BreakAfterOpenBracketSwitch;
929 if (Style.BreakAfterOpenBracketFunction) {
930 return !
Tok.Previous->is(TT_CastRParen) &&
931 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
936 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
937 Tok.Previous->is(tok::identifier);
939 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
940 if (!Style.isJavaScript())
942 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
943 if (Prev->is(TT_TemplateString) && Prev->opensScope())
945 if (Prev->opensScope() && !NestBlocks)
947 if (Prev->is(TT_TemplateString) && Prev->closesScope())
953 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
954 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
956 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
963 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
965 if (
Tok.is(TT_UnaryOperator) ||
966 (Style.isJavaScript() &&
967 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
970 const auto *
Previous = TokAfterLParen.Previous;
974 Previous->Previous->is(tok::kw_switch))) {
977 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
978 TT_LambdaDefinitionLParen) &&
982 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
985 return !
Next ||
Next->isMemberAccess() ||
986 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
989 State.
Column > getNewLineColumn(State).Total &&
1000 !StartsSimpleOneArgList(Current)) {
1001 CurrentState.NoLineBreak =
true;
1005 CurrentState.NoLineBreak =
true;
1011 if (Style.AlignAfterOpenBracket &&
1012 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1013 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1014 TT_TableGenDAGArgOpener,
1015 TT_TableGenDAGArgOpenerToBreak) &&
1017 (Current.
isNot(TT_LineComment) ||
1019 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||
1021 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,
1023 Previous.is(TT_VerilogMultiLineListLParen)) &&
1024 !IsInTemplateString(Current,
false)) {
1025 CurrentState.Indent = State.
Column + Spaces;
1026 CurrentState.IsAligned =
true;
1029 CurrentState.NoLineBreak =
true;
1031 CurrentState.NoLineBreak =
true;
1034 State.
Column > getNewLineColumn(State).Total) {
1035 CurrentState.ContainsUnwrappedBuilder =
true;
1038 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1039 CurrentState.NoLineBreak =
true;
1040 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1049 CurrentState.NoLineBreak =
true;
1056 const FormatToken *P = Current.getPreviousNonComment();
1057 if (Current.
isNot(tok::comment) && P &&
1058 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1059 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1060 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1064 bool BreakBeforeOperator =
1065 P->MustBreakBefore || P->is(tok::lessless) ||
1066 (P->is(TT_BinaryOperator) &&
1067 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1068 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1072 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1073 P->isNot(TT_ConditionalExpr);
1074 if ((!BreakBeforeOperator &&
1076 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1077 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1078 CurrentState.NoLineBreakInOperand =
true;
1083 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1088 CurrentState.LastSpace = State.
Column;
1089 CurrentState.NestedBlockIndent = State.
Column;
1090 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1092 Previous.isNot(TT_OverloadedOperator)) ||
1094 CurrentState.LastSpace = State.
Column;
1095 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1097 Style.BreakConstructorInitializers ==
1098 FormatStyle::BCIS_AfterColon) {
1099 CurrentState.Indent = State.
Column;
1100 CurrentState.LastSpace = State.
Column;
1101 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1102 CurrentState.LastSpace = State.
Column;
1103 }
else if (
Previous.is(TT_BinaryOperator) &&
1110 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1111 CurrentState.LastSpace = State.
Column;
1112 }
else if (
Previous.is(TT_InheritanceColon)) {
1113 CurrentState.Indent = State.
Column;
1114 CurrentState.LastSpace = State.
Column;
1115 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1116 CurrentState.ColonPos = State.
Column;
1117 }
else if (
Previous.opensScope()) {
1125 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1126 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1127 CurrentState.LastSpace = State.
Column;
1133unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1136 assert(State.NextToken->Previous);
1138 auto &CurrentState = State.Stack.back();
1142 unsigned Penalty = 0;
1144 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1146 if (!NextNonComment)
1147 NextNonComment = &Current;
1150 if (!CurrentState.ContainsLineBreak)
1152 CurrentState.ContainsLineBreak =
true;
1154 Penalty += State.NextToken->SplitPenalty;
1159 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1160 (State.Column <= Style.ColumnLimit / 3 ||
1161 CurrentState.BreakBeforeParameter)) {
1162 Penalty += Style.PenaltyBreakFirstLessLess;
1165 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1166 State.Column = TotalColumn;
1180 if (State.Column > State.FirstIndent) {
1182 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1195 if (Current.isNot(TT_LambdaArrow) &&
1196 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1197 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1198 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1199 CurrentState.NestedBlockIndent = State.Column;
1202 if (NextNonComment->isMemberAccess()) {
1203 if (CurrentState.CallContinuation == 0)
1204 CurrentState.CallContinuation = State.Column;
1205 }
else if (NextNonComment->is(TT_SelectorName)) {
1206 if (!CurrentState.ObjCSelectorNameFound) {
1207 if (NextNonComment->LongestObjCSelectorName == 0) {
1208 CurrentState.AlignColons =
false;
1210 CurrentState.ColonPos =
1212 ? std::max(CurrentState.Indent.Total,
1213 State.FirstIndent + Style.ContinuationIndentWidth)
1214 : CurrentState.
Indent.Total) +
1218 }
else if (CurrentState.AlignColons &&
1219 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1220 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1222 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1223 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1233 if (State.Stack.size() > 1) {
1234 State.Stack[State.Stack.size() - 2].LastSpace =
1235 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1236 Style.ContinuationIndentWidth;
1240 if ((PreviousNonComment &&
1241 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1242 !CurrentState.AvoidBinPacking) ||
1244 CurrentState.BreakBeforeParameter =
false;
1246 if (PreviousNonComment &&
1247 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1248 PreviousNonComment->ClosesRequiresClause) &&
1249 Current.NestingLevel == 0) {
1250 CurrentState.BreakBeforeParameter =
false;
1252 if (NextNonComment->is(tok::question) ||
1253 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1254 CurrentState.BreakBeforeParameter =
true;
1256 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1257 CurrentState.BreakBeforeParameter =
false;
1261 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1264 !Current.MatchingParen->Children.empty()) {
1272 const bool ContinuePPDirective = State.Line->InPPDirective &&
1274 Current.isNot(TT_LineComment);
1275 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1276 CurrentState.IsAligned, ContinuePPDirective,
1277 IndentedFromColumn);
1280 if (!Current.isTrailingComment())
1281 CurrentState.LastSpace = State.Column;
1282 if (Current.is(tok::lessless)) {
1286 CurrentState.LastSpace += 3;
1289 State.StartOfLineLevel = Current.NestingLevel;
1290 State.LowestLevelOnLine = Current.NestingLevel;
1294 bool NestedBlockSpecialCase =
1295 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1296 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1297 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1298 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1300 NestedBlockSpecialCase =
1301 NestedBlockSpecialCase ||
1302 (Current.MatchingParen &&
1303 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1304 if (!NestedBlockSpecialCase) {
1305 auto ParentLevelIt = std::next(State.Stack.rbegin());
1306 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1307 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1322 auto FindCurrentLevel = [&](
const auto &It) {
1323 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1324 return PState.Tok != nullptr;
1327 auto MaybeIncrement = [&](
const auto &It) {
1328 return It != State.Stack.rend() ? std::next(It) : It;
1330 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1331 auto LevelContainingLambdaIt =
1332 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1333 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1335 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1336 I->BreakBeforeParameter =
true;
1339 if (PreviousNonComment &&
1340 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1341 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1342 !PreviousNonComment->ClosesRequiresClause) ||
1343 Current.NestingLevel != 0) &&
1344 PreviousNonComment->isNoneOf(
1345 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1346 TT_LeadingJavaAnnotation) &&
1347 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1350 (!Style.BraceWrapping.BeforeLambdaBody ||
1351 Current.isNot(TT_LambdaLBrace))) {
1352 CurrentState.BreakBeforeParameter =
true;
1357 if (PreviousNonComment &&
1358 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1360 CurrentState.BreakBeforeClosingBrace =
true;
1363 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1364 if (
auto Previous = PreviousNonComment->Previous) {
1366 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1367 }
else if (
Previous->isLoop(Style)) {
1368 CurrentState.BreakBeforeClosingParen =
1369 Style.BreakBeforeCloseBracketLoop;
1370 }
else if (
Previous->is(tok::kw_switch)) {
1371 CurrentState.BreakBeforeClosingParen =
1372 Style.BreakBeforeCloseBracketSwitch;
1374 CurrentState.BreakBeforeClosingParen =
1375 Style.BreakBeforeCloseBracketFunction;
1380 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1381 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1383 if (CurrentState.AvoidBinPacking) {
1388 bool PreviousIsBreakingCtorInitializerColon =
1389 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1390 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1391 bool AllowAllConstructorInitializersOnNextLine =
1392 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1393 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1394 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1395 !PreviousIsBreakingCtorInitializerColon) ||
1396 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1397 State.Line->MustBeDeclaration) ||
1398 (!Style.AllowAllArgumentsOnNextLine &&
1399 !State.Line->MustBeDeclaration) ||
1400 (!AllowAllConstructorInitializersOnNextLine &&
1401 PreviousIsBreakingCtorInitializerColon) ||
1403 CurrentState.BreakBeforeParameter =
true;
1409 if (PreviousIsBreakingCtorInitializerColon &&
1410 AllowAllConstructorInitializersOnNextLine) {
1411 CurrentState.BreakBeforeParameter =
false;
1416 CurrentState.BreakBeforeParameter =
true;
1422ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1423 if (!State.NextToken || !State.NextToken->Previous)
1427 const auto &CurrentState = State.Stack.back();
1429 if (CurrentState.IsCSharpGenericTypeConstraint &&
1430 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1431 return CurrentState.ColonPos + 2;
1436 const auto ContinuationIndent =
1437 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1438 CurrentState.Indent) +
1439 Style.ContinuationIndentWidth;
1440 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1442 if (!NextNonComment)
1443 NextNonComment = &Current;
1446 if (Style.isJava() &&
1447 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1448 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1449 CurrentState.Indent + Style.ContinuationIndentWidth);
1454 if (Style.isVerilog() && PreviousNonComment &&
1455 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1456 return State.FirstIndent;
1459 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1460 State.Line->First->is(tok::kw_enum)) {
1461 return IndentationAndAlignment(Style.IndentWidth *
1462 State.Line->First->IndentLevel) +
1466 if (Style.BraceWrapping.BeforeLambdaBody &&
1467 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1468 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1469 ? CurrentState.Indent
1470 : State.FirstIndent;
1471 return From + Style.IndentWidth;
1474 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1475 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1476 if (Current.NestingLevel == 0 ||
1477 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1478 State.NextToken->is(TT_LambdaLBrace))) {
1479 return State.FirstIndent;
1481 return CurrentState.Indent;
1483 if (Current.is(TT_LambdaArrow) &&
1484 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1485 tok::kw_consteval, tok::kw_static,
1486 TT_AttributeRSquare)) {
1487 return ContinuationIndent;
1489 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1490 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1491 State.Stack.size() > 1) {
1492 if (Current.closesBlockOrBlockTypeList(Style))
1493 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1494 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1495 return State.Stack[State.Stack.size() - 2].LastSpace;
1496 return State.FirstIndent;
1513 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1515 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1516 return State.Stack[State.Stack.size() - 2].LastSpace;
1520 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1521 State.Stack.size() > 1) {
1522 return State.Stack[State.Stack.size() - 2].LastSpace;
1524 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1525 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1526 State.Stack.size() > 1) {
1527 return State.Stack[State.Stack.size() - 2].LastSpace;
1529 if ((Style.BreakBeforeCloseBracketFunction ||
1530 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1531 Style.BreakBeforeCloseBracketSwitch) &&
1532 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1533 return State.Stack[State.Stack.size() - 2].LastSpace;
1535 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1536 State.Stack.size() > 1) {
1537 return State.Stack[State.Stack.size() - 2].LastSpace;
1539 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1540 return State.Stack[State.Stack.size() - 2].LastSpace;
1548 if (Current.is(tok::identifier) && Current.Next &&
1549 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1550 (Current.Next->is(TT_DictLiteral) ||
1551 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1552 return CurrentState.Indent;
1554 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1555 State.StartOfStringLiteral != 0) {
1556 return State.StartOfStringLiteral - 1;
1558 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1559 return State.StartOfStringLiteral;
1560 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1561 return CurrentState.FirstLessLess;
1562 if (NextNonComment->isMemberAccess()) {
1563 if (CurrentState.CallContinuation == 0)
1564 return ContinuationIndent;
1565 return CurrentState.CallContinuation;
1567 if (CurrentState.QuestionColumn != 0 &&
1568 ((NextNonComment->is(tok::colon) &&
1569 NextNonComment->is(TT_ConditionalExpr)) ||
1570 Previous.is(TT_ConditionalExpr))) {
1571 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1572 !NextNonComment->Next->FakeLParens.empty() &&
1574 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1576 !CurrentState.IsWrappedConditional) {
1581 unsigned Indent = CurrentState.Indent.Total;
1582 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1583 Indent -= Style.ContinuationIndentWidth;
1584 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1588 return CurrentState.QuestionColumn;
1590 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1591 return CurrentState.VariablePos;
1592 if (Current.is(TT_RequiresClause)) {
1593 if (Style.IndentRequiresClause)
1594 return CurrentState.Indent + Style.IndentWidth;
1595 switch (Style.RequiresClausePosition) {
1596 case FormatStyle::RCPS_OwnLine:
1597 case FormatStyle::RCPS_WithFollowing:
1598 case FormatStyle::RCPS_OwnLineWithBrace:
1599 return CurrentState.Indent;
1604 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1605 TT_InheritanceComma)) {
1606 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1608 if ((PreviousNonComment &&
1609 (PreviousNonComment->ClosesTemplateDeclaration ||
1610 PreviousNonComment->ClosesRequiresClause ||
1611 (PreviousNonComment->is(TT_AttributeMacro) &&
1612 Current.isNot(tok::l_paren) &&
1613 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1614 TT_PointerOrReference)) ||
1615 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1616 TT_FunctionAnnotationRParen,
1618 TT_LeadingJavaAnnotation))) ||
1619 (!Style.IndentWrappedFunctionNames &&
1620 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1621 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1622 CurrentState.Indent);
1624 if (NextNonComment->is(TT_SelectorName)) {
1625 if (!CurrentState.ObjCSelectorNameFound) {
1626 auto MinIndent = CurrentState.Indent;
1629 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1630 Style.ContinuationIndentWidth);
1641 return MinIndent.addPadding(
1642 std::max(NextNonComment->LongestObjCSelectorName,
1643 NextNonComment->ColumnWidth) -
1644 NextNonComment->ColumnWidth);
1646 if (!CurrentState.AlignColons)
1647 return CurrentState.Indent;
1648 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1649 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1650 return CurrentState.Indent;
1652 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1653 return CurrentState.ColonPos;
1654 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1655 if (CurrentState.StartOfArraySubscripts != 0) {
1656 return CurrentState.StartOfArraySubscripts;
1657 }
else if (Style.isCSharp()) {
1659 return CurrentState.Indent;
1661 return ContinuationIndent;
1666 if (State.Line->InPragmaDirective) {
1667 FormatToken *PragmaType = State.Line->First->Next->Next;
1668 if (PragmaType && PragmaType->TokenText ==
"omp")
1669 return CurrentState.Indent + Style.ContinuationIndentWidth;
1674 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1675 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1676 return CurrentState.Indent;
1679 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1680 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1681 return ContinuationIndent;
1683 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1684 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1685 return ContinuationIndent;
1687 if (NextNonComment->is(TT_CtorInitializerComma))
1688 return CurrentState.Indent;
1689 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1690 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1691 return CurrentState.Indent;
1693 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1694 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1695 return CurrentState.Indent;
1698 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1699 !Current.isBinaryOperator() &&
1700 Current.isNoneOf(tok::colon, tok::comment)) {
1701 return ContinuationIndent;
1703 if (Current.is(TT_ProtoExtensionLSquare))
1704 return CurrentState.Indent;
1705 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1706 return CurrentState.Indent - Current.Tok.getLength() -
1707 Current.SpacesRequiredBefore;
1709 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1710 CurrentState.UnindentOperator) {
1711 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1712 NextNonComment->SpacesRequiredBefore;
1714 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1715 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1718 return CurrentState.Indent + Style.ContinuationIndentWidth;
1720 return CurrentState.Indent;
1725 const FormatStyle &Style) {
1732 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1735unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1736 bool DryRun,
bool Newline) {
1737 assert(State.Stack.size());
1739 auto &CurrentState = State.Stack.back();
1741 if (Current.is(TT_CSharpGenericTypeConstraint))
1742 CurrentState.IsCSharpGenericTypeConstraint =
true;
1743 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1744 CurrentState.NoLineBreakInOperand =
false;
1745 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1746 CurrentState.AvoidBinPacking =
true;
1747 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1748 if (CurrentState.FirstLessLess == 0)
1749 CurrentState.FirstLessLess = State.Column;
1751 CurrentState.LastOperatorWrapped = Newline;
1753 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1754 CurrentState.LastOperatorWrapped = Newline;
1755 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1756 Current.Previous->isNot(TT_ConditionalExpr)) {
1757 CurrentState.LastOperatorWrapped = Newline;
1759 if (Current.is(TT_ArraySubscriptLSquare) &&
1760 CurrentState.StartOfArraySubscripts == 0) {
1761 CurrentState.StartOfArraySubscripts = State.Column;
1765 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1767 if (
Tok.MustBreakBefore)
1771 return Next &&
Next->MustBreakBefore;
1773 if (IsWrappedConditional(Current))
1774 CurrentState.IsWrappedConditional =
true;
1775 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1776 CurrentState.QuestionColumn = State.Column;
1777 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1782 CurrentState.QuestionColumn = State.Column;
1784 if (!Current.opensScope() && !Current.closesScope() &&
1785 Current.isNot(TT_PointerOrReference)) {
1786 State.LowestLevelOnLine =
1787 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1789 if (Current.isMemberAccess())
1790 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1791 if (Current.is(TT_SelectorName))
1792 CurrentState.ObjCSelectorNameFound =
true;
1793 if (Current.is(TT_CtorInitializerColon) &&
1794 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1800 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1801 FormatStyle::BCIS_BeforeComma
1804 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1805 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1806 CurrentState.AvoidBinPacking =
true;
1807 CurrentState.BreakBeforeParameter =
1808 Style.ColumnLimit > 0 &&
1809 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1810 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1812 CurrentState.BreakBeforeParameter =
false;
1815 if (Current.is(TT_CtorInitializerColon) &&
1816 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1817 CurrentState.Indent =
1818 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1819 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1820 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1821 CurrentState.AvoidBinPacking =
true;
1823 CurrentState.BreakBeforeParameter =
false;
1825 if (Current.is(TT_InheritanceColon)) {
1826 CurrentState.Indent =
1827 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1829 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1830 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1831 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1832 CurrentState.LastSpace = State.Column;
1833 if (Current.is(TT_RequiresExpression) &&
1834 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1835 CurrentState.NestedBlockIndent = State.Column;
1847 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1849 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1850 !CurrentState.HasMultipleNestedBlocks) {
1851 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1852 for (ParenState &PState : llvm::drop_end(State.Stack))
1853 PState.NoLineBreak =
true;
1854 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1856 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1857 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1858 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1859 TT_CtorInitializerColon)))) {
1860 CurrentState.NestedBlockInlined =
1864 moveStatePastFakeLParens(State, Newline);
1865 moveStatePastScopeCloser(State);
1868 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1869 !State.Stack.back().NoLineBreakInOperand;
1870 moveStatePastScopeOpener(State, Newline);
1871 moveStatePastFakeRParens(State);
1873 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1874 State.StartOfStringLiteral = State.Column + 1;
1875 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1876 State.StartOfStringLiteral = State.Column + 1;
1877 }
else if (Current.is(TT_TableGenMultiLineString) &&
1878 State.StartOfStringLiteral == 0) {
1879 State.StartOfStringLiteral = State.Column + 1;
1880 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1881 State.StartOfStringLiteral = State.Column;
1882 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1883 !Current.isStringLiteral()) {
1884 State.StartOfStringLiteral = 0;
1887 State.Column += Current.ColumnWidth;
1888 State.NextToken = State.NextToken->Next;
1893 if (Style.isVerilog() && State.NextToken &&
1894 State.NextToken->MustBreakBefore &&
1895 Keywords.isVerilogEndOfLabel(Current)) {
1896 State.FirstIndent += Style.IndentWidth;
1897 CurrentState.Indent = State.FirstIndent;
1901 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1904 Current.Role->formatFromToken(State,
this, DryRun);
1911 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1916void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1919 if (Current.FakeLParens.empty())
1927 bool SkipFirstExtraIndent =
1930 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1932 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1934 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1935 const auto &CurrentState = State.Stack.back();
1936 ParenState NewParenState = CurrentState;
1937 NewParenState.Tok =
nullptr;
1938 NewParenState.ContainsLineBreak =
false;
1939 NewParenState.LastOperatorWrapped =
true;
1940 NewParenState.IsChainedConditional =
false;
1941 NewParenState.IsWrappedConditional =
false;
1942 NewParenState.UnindentOperator =
false;
1943 NewParenState.NoLineBreak =
1944 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1948 NewParenState.AvoidBinPacking =
false;
1953 if (!Current.isTrailingComment() &&
1954 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1957 (!Style.isJava() && PrecedenceLevel > 0)) &&
1958 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1959 Current.NestingLevel == 0) &&
1960 (!Style.isTableGen() ||
1962 TT_TableGenDAGArgListCommaToBreak)))) {
1963 NewParenState.Indent =
1964 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1965 IndentationAndAlignment(CurrentState.LastSpace)});
1972 State.Stack.size() > 1) {
1973 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1974 Style.ContinuationIndentWidth;
1984 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1985 NewParenState.UnindentOperator =
true;
1987 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1988 NewParenState.IsAligned =
true;
1998 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2000 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2001 NewParenState.StartOfFunctionCall = State.Column;
2011 &PrecedenceLevel == &Current.FakeLParens.back() &&
2012 !CurrentState.IsWrappedConditional) {
2013 NewParenState.IsChainedConditional =
true;
2014 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2017 !Current.isTrailingComment())) {
2018 NewParenState.Indent += Style.ContinuationIndentWidth;
2021 NewParenState.BreakBeforeParameter =
false;
2022 State.Stack.push_back(NewParenState);
2023 SkipFirstExtraIndent =
false;
2027void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2028 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2029 unsigned VariablePos = State.Stack.back().VariablePos;
2030 if (State.Stack.size() == 1) {
2034 State.Stack.pop_back();
2035 State.Stack.back().VariablePos = VariablePos;
2038 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2041 State.Stack.back().LastSpace -= Style.IndentWidth;
2045void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2048 if (!Current.opensScope())
2051 const auto &CurrentState = State.Stack.back();
2054 if (Current.isOneOf(tok::less, tok::l_paren) &&
2055 CurrentState.IsCSharpGenericTypeConstraint) {
2059 if (Current.MatchingParen && Current.is(
BK_Block)) {
2060 moveStateToNewBlock(State, Newline);
2067 const auto *Prev =
Tok->getPreviousNonComment();
2070 return Prev->is(tok::comma);
2071 }(Current.MatchingParen);
2073 IndentationAndAlignment NewIndent = 0;
2074 unsigned LastSpace = CurrentState.LastSpace;
2075 bool AvoidBinPacking;
2076 bool BreakBeforeParameter =
false;
2077 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2078 CurrentState.NestedBlockIndent);
2079 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2081 if (Current.opensBlockOrBlockTypeList(Style)) {
2082 NewIndent = Style.IndentWidth +
2083 std::min(State.Column, CurrentState.NestedBlockIndent);
2084 }
else if (Current.is(tok::l_brace)) {
2085 const auto Width = Style.BracedInitializerIndentWidth;
2086 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2087 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2089 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2091 const FormatToken *NextNonComment = Current.getNextNonComment();
2092 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2093 Style.isProto() || !Style.BinPackArguments ||
2094 (NextNonComment && NextNonComment->isOneOf(
2095 TT_DesignatedInitializerPeriod,
2096 TT_DesignatedInitializerLSquare));
2097 BreakBeforeParameter = EndsInComma;
2098 if (Current.ParameterCount > 1)
2099 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2101 NewIndent = IndentationAndAlignment(std::max(
2102 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2103 Style.ContinuationIndentWidth;
2105 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2106 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2112 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2113 NewIndent = State.Column +
Next->TokenText.size() + 2;
2120 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2121 NewIndent = std::max(NewIndent, CurrentState.Indent);
2122 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2128 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2129 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2130 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2132 bool BinPackDeclaration =
2134 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2137 bool GenericSelection =
2138 Current.getPreviousNonComment() &&
2139 Current.getPreviousNonComment()->is(tok::kw__Generic);
2142 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2143 (Style.isJavaScript() && EndsInComma) ||
2144 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2145 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2146 (Style.ExperimentalAutoDetectBinPacking &&
2150 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2151 Style.ObjCBreakBeforeNestedBlockParam) {
2152 if (Style.ColumnLimit) {
2157 BreakBeforeParameter =
true;
2163 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2164 if (
Tok->MustBreakBefore ||
2165 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2166 BreakBeforeParameter =
true;
2173 if (Style.isJavaScript() && EndsInComma)
2174 BreakBeforeParameter =
true;
2180 Current.Children.empty() &&
2181 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2182 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2183 (Current.is(TT_TemplateOpener) &&
2184 CurrentState.ContainsUnwrappedBuilder));
2185 State.Stack.push_back(
2186 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2187 auto &NewState = State.Stack.back();
2188 NewState.NestedBlockIndent = NestedBlockIndent;
2189 NewState.BreakBeforeParameter = BreakBeforeParameter;
2190 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2192 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2193 Current.is(tok::l_paren)) {
2197 if (next->is(TT_LambdaLSquare)) {
2198 NewState.HasMultipleNestedBlocks =
true;
2205 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2207 Current.Previous->is(tok::at);
2210void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2212 if (!Current.closesScope())
2217 if (State.Stack.size() > 1 &&
2218 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2219 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2220 State.NextToken->is(TT_TemplateCloser) ||
2221 State.NextToken->is(TT_TableGenListCloser) ||
2222 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2223 State.Stack.pop_back();
2226 auto &CurrentState = State.Stack.back();
2238 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2239 Current.MatchingParen->Previous) {
2240 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2241 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2242 CurrentScopeOpener.MatchingParen) {
2243 int NecessarySpaceInLine =
2245 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2246 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2247 Style.ColumnLimit) {
2248 CurrentState.BreakBeforeParameter =
false;
2253 if (Current.is(tok::r_square)) {
2255 const FormatToken *NextNonComment = Current.getNextNonComment();
2256 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2257 CurrentState.StartOfArraySubscripts = 0;
2261void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2262 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2263 State.NextToken->is(TT_LambdaLBrace) &&
2264 !State.Line->MightBeFunctionDecl) {
2265 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2266 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2268 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2270 unsigned NewIndent =
2271 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2272 ? Style.ObjCBlockIndentWidth
2273 : Style.IndentWidth);
2280 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2281 State.NextToken->is(TT_LambdaLBrace);
2283 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2284 State.Stack.back().LastSpace,
2285 true, NoLineBreak));
2286 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2287 State.Stack.back().BreakBeforeParameter =
true;
2293 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2294 if (LastNewlinePos == StringRef::npos) {
2295 return StartColumn +
2303unsigned ContinuationIndenter::reformatRawStringLiteral(
2305 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2306 unsigned StartColumn = State.Column - Current.ColumnWidth;
2308 StringRef NewDelimiter =
2310 if (NewDelimiter.empty())
2311 NewDelimiter = OldDelimiter;
2314 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2315 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2318 std::string RawText = std::string(
2319 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2320 if (NewDelimiter != OldDelimiter) {
2323 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2324 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2325 NewDelimiter = OldDelimiter;
2328 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2329 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2332 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2343 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2365 unsigned CurrentIndent =
2366 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2367 ? State.Stack.back().NestedBlockIndent
2368 : State.Stack.back().Indent.Total;
2369 unsigned NextStartColumn = ContentStartsOnNewline
2370 ? CurrentIndent + Style.IndentWidth
2381 unsigned LastStartColumn =
2382 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2385 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2386 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2391 return addMultilineToken(Current, State);
2393 if (NewDelimiter != OldDelimiter) {
2396 SourceLocation PrefixDelimiterStart =
2397 Current.Tok.getLocation().getLocWithOffset(2);
2398 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2399 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2402 <<
"Failed to update the prefix delimiter of a raw string: "
2403 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2407 SourceLocation SuffixDelimiterStart =
2408 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2409 1 - OldDelimiter.size());
2410 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2411 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2414 <<
"Failed to update the suffix delimiter of a raw string: "
2415 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2418 SourceLocation OriginLoc =
2419 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2420 for (
const tooling::Replacement &Fix : Fixes.first) {
2421 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2422 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2423 Fix.getLength(), Fix.getReplacementText()));
2425 llvm::errs() <<
"Failed to reformat raw string: "
2426 << llvm::toString(std::move(Err)) <<
"\n";
2431 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2432 State.Column = RawLastLineEndColumn + NewSuffixSize;
2436 unsigned PrefixExcessCharacters =
2437 StartColumn + NewPrefixSize > Style.ColumnLimit
2438 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2441 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2444 for (ParenState &
Paren : State.Stack)
2445 Paren.BreakBeforeParameter =
true;
2447 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2450unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2453 for (ParenState &
Paren : State.Stack)
2454 Paren.BreakBeforeParameter =
true;
2456 unsigned ColumnsUsed = State.Column;
2459 State.Column = Current.LastLineColumnWidth;
2462 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2466unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2468 bool AllowBreak,
bool Newline) {
2469 unsigned Penalty = 0;
2472 auto RawStringStyle = getRawStringStyle(Current, State);
2473 if (RawStringStyle && !Current.Finalized) {
2474 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2476 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2479 Penalty = addMultilineToken(Current, State);
2482 LineState OriginalState = State;
2486 bool Strict =
false;
2489 bool Exceeded =
false;
2490 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2491 Current, State, AllowBreak,
true, Strict);
2495 LineState StrictState = OriginalState;
2496 unsigned StrictPenalty =
2497 breakProtrudingToken(Current, StrictState, AllowBreak,
2500 Strict = StrictPenalty <= Penalty;
2502 Penalty = StrictPenalty;
2503 State = StrictState;
2509 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2514 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2515 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2524 auto Tok = Current.getPreviousNonComment();
2525 if (!
Tok ||
Tok->isNot(tok::l_paren))
2527 Tok =
Tok->getPreviousNonComment();
2530 if (
Tok->is(TT_TemplateCloser)) {
2531 Tok =
Tok->MatchingParen;
2533 Tok =
Tok->getPreviousNonComment();
2535 if (!
Tok ||
Tok->isNot(tok::identifier))
2537 return Tok->TokenText;
2540std::optional<FormatStyle>
2541ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2542 const LineState &State) {
2543 if (!Current.isStringLiteral())
2544 return std::nullopt;
2547 return std::nullopt;
2549 if (!RawStringStyle && Delimiter->empty()) {
2553 if (!RawStringStyle)
2554 return std::nullopt;
2556 return RawStringStyle;
2559std::unique_ptr<BreakableToken>
2560ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2562 unsigned StartColumn = State.Column - Current.ColumnWidth;
2563 if (Current.isStringLiteral()) {
2566 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2580 if (Current.IsUnterminatedLiteral)
2584 if (State.Stack.back().IsInsideObjCArrayLiteral)
2591 if (Style.isVerilog() && Current.Previous &&
2592 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2595 StringRef
Text = Current.TokenText;
2605 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2608 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2609 Text.ends_with(
"'")) {
2611 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2612 Text.ends_with(
"\"")) {
2614 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2619 return std::make_unique<BreakableStringLiteralUsingOperators>(
2620 Current, QuoteStyle,
2631 if ((
Text.ends_with(Postfix =
"\"") &&
2632 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2633 Text.starts_with(Prefix =
"u\"") ||
2634 Text.starts_with(Prefix =
"U\"") ||
2635 Text.starts_with(Prefix =
"u8\"") ||
2636 Text.starts_with(Prefix =
"L\""))) ||
2637 (
Text.starts_with(Prefix =
"_T(\"") &&
2638 Text.ends_with(Postfix =
"\")"))) {
2639 return std::make_unique<BreakableStringLiteral>(
2641 State.Line->InPPDirective, Encoding, Style);
2643 }
else if (Current.is(TT_BlockComment)) {
2644 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2651 return std::make_unique<BreakableBlockComment>(
2652 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2653 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2654 }
else if (Current.is(TT_LineComment) &&
2655 (!Current.Previous ||
2656 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2657 bool RegularComments = [&]() {
2658 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2660 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2665 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2666 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2670 return std::make_unique<BreakableLineCommentSection>(
2671 Current, StartColumn,
false, Encoding, Style);
2676std::pair<unsigned, bool>
2677ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2679 bool DryRun,
bool Strict) {
2680 std::unique_ptr<const BreakableToken> Token =
2681 createBreakableToken(Current, State, AllowBreak);
2684 assert(Token->getLineCount() > 0);
2686 if (Current.is(TT_LineComment)) {
2688 ColumnLimit = Style.ColumnLimit;
2690 if (ColumnLimit == 0) {
2693 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2695 if (Current.UnbreakableTailLength >= ColumnLimit)
2699 unsigned StartColumn = State.Column - Current.ColumnWidth;
2700 unsigned NewBreakPenalty = Current.isStringLiteral()
2701 ? Style.PenaltyBreakString
2702 : Style.PenaltyBreakComment;
2705 bool Exceeded =
false;
2707 bool BreakInserted = Token->introducesBreakBeforeToken();
2710 bool NewBreakBefore =
false;
2714 bool Reflow =
false;
2717 unsigned TailOffset = 0;
2719 unsigned ContentStartColumn =
2720 Token->getContentStartColumn(0,
false);
2722 unsigned RemainingTokenColumns =
2723 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2726 Token->adaptStartOfLine(0, Whitespaces);
2728 unsigned ContentIndent = 0;
2729 unsigned Penalty = 0;
2730 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2731 << StartColumn <<
".\n");
2732 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2733 LineIndex != EndIndex; ++LineIndex) {
2734 LLVM_DEBUG(llvm::dbgs()
2735 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2736 NewBreakBefore =
false;
2740 bool TryReflow = Reflow;
2742 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2743 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2744 << (ContentStartColumn + RemainingTokenColumns)
2745 <<
", space: " << ColumnLimit
2746 <<
", reflown prefix: " << ContentStartColumn
2747 <<
", offset in line: " << TailOffset <<
"\n");
2753 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2754 ContentStartColumn, CommentPragmasRegex);
2755 if (
Split.first == StringRef::npos) {
2758 if (LineIndex < EndIndex - 1) {
2761 Penalty += Style.PenaltyExcessCharacter *
2762 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2764 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2767 assert(
Split.first != 0);
2769 if (Token->supportsReflow()) {
2789 unsigned ToSplitColumns = Token->getRangeLength(
2790 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2791 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2794 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2795 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2798 unsigned ToNextSplitColumns = 0;
2799 if (NextSplit.first == StringRef::npos) {
2800 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2801 ContentStartColumn);
2803 ToNextSplitColumns = Token->getRangeLength(
2804 LineIndex, TailOffset,
2805 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2809 ToNextSplitColumns =
2810 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2811 LLVM_DEBUG(llvm::dbgs()
2812 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2813 LLVM_DEBUG(llvm::dbgs()
2814 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2817 bool ContinueOnLine =
2818 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2819 unsigned ExcessCharactersPenalty = 0;
2820 if (!ContinueOnLine && !Strict) {
2823 ExcessCharactersPenalty =
2824 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2825 Style.PenaltyExcessCharacter;
2826 LLVM_DEBUG(llvm::dbgs()
2827 <<
" Penalty excess: " << ExcessCharactersPenalty
2828 <<
"\n break : " << NewBreakPenalty <<
"\n");
2829 if (ExcessCharactersPenalty < NewBreakPenalty) {
2831 ContinueOnLine =
true;
2834 if (ContinueOnLine) {
2835 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2840 Token->compressWhitespace(LineIndex, TailOffset, Split,
2844 ContentStartColumn += ToSplitColumns + 1;
2845 Penalty += ExcessCharactersPenalty;
2847 RemainingTokenColumns = Token->getRemainingLength(
2848 LineIndex, TailOffset, ContentStartColumn);
2852 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2857 ContentIndent = Token->getContentIndent(LineIndex);
2858 LLVM_DEBUG(llvm::dbgs()
2859 <<
" ContentIndent: " << ContentIndent <<
"\n");
2860 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2863 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2864 LineIndex, TailOffset +
Split.first +
Split.second,
2865 ContentStartColumn);
2866 if (NewRemainingTokenColumns == 0) {
2869 ContentStartColumn =
2870 Token->getContentStartColumn(LineIndex,
true);
2871 NewRemainingTokenColumns = Token->getRemainingLength(
2872 LineIndex, TailOffset +
Split.first +
Split.second,
2873 ContentStartColumn);
2879 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2884 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2885 <<
", " <<
Split.second <<
"\n");
2887 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2891 Penalty += NewBreakPenalty;
2893 RemainingTokenColumns = NewRemainingTokenColumns;
2894 BreakInserted =
true;
2895 NewBreakBefore =
true;
2899 if (LineIndex + 1 != EndIndex) {
2900 unsigned NextLineIndex = LineIndex + 1;
2901 if (NewBreakBefore) {
2920 ContentStartColumn += RemainingTokenColumns + 1;
2925 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2926 LLVM_DEBUG(llvm::dbgs()
2927 <<
" Size of reflown text: " << ContentStartColumn
2928 <<
"\n Potential reflow split: ");
2929 if (SplitBeforeNext.first != StringRef::npos) {
2930 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2931 << SplitBeforeNext.second <<
"\n");
2932 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2935 RemainingTokenColumns = Token->getRemainingLength(
2936 NextLineIndex, TailOffset, ContentStartColumn);
2938 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2939 LLVM_DEBUG(llvm::dbgs()
2940 <<
" Over limit after reflow, need: "
2941 << (ContentStartColumn + RemainingTokenColumns)
2942 <<
", space: " << ColumnLimit
2943 <<
", reflown prefix: " << ContentStartColumn
2944 <<
", offset in line: " << TailOffset <<
"\n");
2950 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2951 ContentStartColumn, CommentPragmasRegex);
2952 if (
Split.first == StringRef::npos) {
2953 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2959 unsigned ToSplitColumns = Token->getRangeLength(
2960 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2961 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2962 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2963 << (ContentStartColumn + ToSplitColumns)
2964 <<
", space: " << ColumnLimit);
2965 unsigned ExcessCharactersPenalty =
2966 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2967 Style.PenaltyExcessCharacter;
2968 if (NewBreakPenalty < ExcessCharactersPenalty)
2974 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2982 ContentStartColumn =
2983 Token->getContentStartColumn(NextLineIndex,
false);
2984 RemainingTokenColumns = Token->getRemainingLength(
2985 NextLineIndex, TailOffset, ContentStartColumn);
2988 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3003 if (NewBreakBefore) {
3004 assert(Penalty >= NewBreakPenalty);
3005 Penalty -= NewBreakPenalty;
3008 Token->reflow(NextLineIndex, Whitespaces);
3014 Token->getSplitAfterLastLine(TailOffset);
3015 if (SplitAfterLastLine.first != StringRef::npos) {
3016 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3020 Penalty += Style.PenaltyExcessCharacter *
3021 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3024 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3027 ContentStartColumn =
3028 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3029 RemainingTokenColumns = Token->getRemainingLength(
3030 Token->getLineCount() - 1,
3031 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3032 ContentStartColumn);
3035 State.Column = ContentStartColumn + RemainingTokenColumns -
3036 Current.UnbreakableTailLength;
3038 if (BreakInserted) {
3040 Token->updateAfterBroken(Whitespaces);
3045 if (Current.isNot(TT_LineComment))
3046 for (ParenState &
Paren : State.Stack)
3047 Paren.BreakBeforeParameter =
true;
3049 if (Current.is(TT_BlockComment))
3050 State.NoContinuation =
true;
3052 State.Stack.back().LastSpace = StartColumn;
3055 Token->updateNextToken(State);
3057 return {Penalty, Exceeded};
3062 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3065bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3067 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3072 if (Current.
TokenText.starts_with(
"R\""))
3076 if (Current.getNextNonComment() &&
3077 Current.getNextNonComment()->isStringLiteral()) {
3080 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3082 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...