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.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
518 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter))) ||
519 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
521 (!Style.BreakBeforeTernaryOperators &&
522 Previous.is(TT_ConditionalExpr))) &&
523 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
524 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
527 if (CurrentState.IsChainedConditional &&
528 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
529 Current.
is(tok::colon)) ||
530 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
535 (
Previous.is(TT_ArrayInitializerLSquare) &&
538 Style.ColumnLimit > 0 &&
544 const FormatToken &BreakConstructorInitializersToken =
545 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
548 if (Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterComma &&
549 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
550 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
552 CurrentState.BreakBeforeParameter) &&
553 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
558 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
559 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
562 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
563 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
564 (Style.ObjCBreakBeforeNestedBlockParam ||
565 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
569 unsigned NewLineColumn = getNewLineColumn(State).Total;
570 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
572 (State.Column > NewLineColumn ||
578 (CurrentState.CallContinuation != 0 ||
579 CurrentState.BreakBeforeParameter) &&
585 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
586 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
592 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
597 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
600 if (Style.AlwaysBreakBeforeMultilineStrings &&
601 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
603 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
604 Keywords.kw_dollar) &&
605 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
606 nextIsMultilineString(State)) {
614 const auto PreviousPrecedence =
Previous.getPrecedence();
616 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
617 const bool LHSIsBinaryExpr =
630 const bool IsComparison =
635 Previous.Previous->isNot(TT_BinaryOperator);
641 CurrentState.BreakBeforeParameter) {
646 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
647 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
651 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
656 if (
Previous.ClosesTemplateDeclaration) {
657 if (Current.
is(tok::kw_concept)) {
658 switch (Style.BreakBeforeConceptDeclarations) {
659 case FormatStyle::BBCDS_Allowed:
661 case FormatStyle::BBCDS_Always:
663 case FormatStyle::BBCDS_Never:
667 if (Current.
is(TT_RequiresClause)) {
668 switch (Style.RequiresClausePosition) {
669 case FormatStyle::RCPS_SingleLine:
670 case FormatStyle::RCPS_WithPreceding:
676 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
677 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
680 if (
Previous.is(TT_FunctionAnnotationRParen) &&
684 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
685 Current.
isNot(TT_LeadingJavaAnnotation)) {
690 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
694 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
696 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
700 if (Current.
is(TT_FunctionDeclarationName) &&
701 !State.Line->ReturnTypeWrapped &&
703 (!Style.isCSharp() ||
704 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
707 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
708 CurrentState.BreakBeforeParameter) {
710 if (
Tok->is(TT_LineComment))
712 if (
Tok->is(TT_TemplateCloser)) {
717 if (
Tok->FirstAfterPPLine)
729 Current.
isNoneOf(tok::r_brace, tok::comment)) {
733 if (Current.
is(tok::lessless) &&
736 Previous.TokenText ==
"\'\\n\'")))) {
743 if (State.NoContinuation)
751 unsigned ExtraSpaces) {
753 assert(State.NextToken->Previous);
756 assert(!State.Stack.empty());
757 State.NoContinuation =
false;
759 if (Current.
is(TT_ImplicitStringLiteral) &&
760 (!
Previous.Tok.getIdentifierInfo() ||
761 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
762 tok::pp_not_keyword)) {
768 State.Column = EndColumn;
770 unsigned StartColumn =
772 assert(EndColumn >= StartColumn);
773 State.Column += EndColumn - StartColumn;
775 moveStateToNextToken(State, DryRun,
false);
779 unsigned Penalty = 0;
781 Penalty = addTokenOnNewLine(State, DryRun);
783 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
785 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
788void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
789 unsigned ExtraSpaces) {
791 assert(State.NextToken->Previous);
793 auto &CurrentState = State.Stack.back();
800 auto DisallowLineBreaks = [&] {
801 if (!Style.isCpp() ||
802 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
810 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
813 const auto *Prev = Current.getPreviousNonComment();
814 if (!Prev || Prev->isNot(tok::l_paren))
817 if (Prev->BlockParameterCount == 0)
821 if (Prev->BlockParameterCount > 1)
828 const auto *Comma = Prev->
Role->lastComma();
832 const auto *
Next = Comma->getNextNonComment();
833 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
836 if (DisallowLineBreaks())
837 State.NoLineBreak =
true;
839 if (Current.
is(tok::equal) &&
840 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
841 CurrentState.VariablePos == 0 &&
843 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
844 CurrentState.VariablePos = State.Column;
847 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
848 CurrentState.VariablePos -=
Tok->ColumnWidth;
849 if (
Tok->SpacesRequiredBefore != 0)
853 if (
Previous.PartOfMultiVariableDeclStmt)
854 CurrentState.LastSpace = CurrentState.VariablePos;
860 int PPColumnCorrection = 0;
864 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
871 if (Style.UseTab != FormatStyle::UT_Never)
872 PPColumnCorrection = -1;
873 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
879 const bool ContinuePPDirective =
881 Whitespaces.replaceWhitespace(Current, 0, Spaces,
882 State.
Column + Spaces + PPColumnCorrection,
883 nullptr, ContinuePPDirective);
888 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
889 Current.
is(TT_InheritanceColon)) {
890 CurrentState.NoLineBreak =
true;
892 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
894 CurrentState.NoLineBreak =
true;
897 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
899 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
900 CurrentState.Indent.Total);
903 CurrentState.AlignColons =
false;
907 CurrentState.ColonPos = FirstColonPos;
915 auto IsStartOfBracedList = [&]() {
917 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
919 if (IsStartOfBracedList())
920 return Style.BreakAfterOpenBracketBracedList;
921 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
925 if (
Tok.Previous->isIf())
926 return Style.BreakAfterOpenBracketIf;
927 if (
Tok.Previous->isLoop(Style))
928 return Style.BreakAfterOpenBracketLoop;
929 if (
Tok.Previous->is(tok::kw_switch))
930 return Style.BreakAfterOpenBracketSwitch;
931 if (Style.BreakAfterOpenBracketFunction) {
932 return !
Tok.Previous->is(TT_CastRParen) &&
933 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
938 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
939 Tok.Previous->is(tok::identifier);
941 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
942 if (!Style.isJavaScript())
944 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
945 if (Prev->is(TT_TemplateString) && Prev->opensScope())
947 if (Prev->opensScope() && !NestBlocks)
949 if (Prev->is(TT_TemplateString) && Prev->closesScope())
955 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
956 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
958 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
965 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
967 if (
Tok.is(TT_UnaryOperator) ||
968 (Style.isJavaScript() &&
969 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
972 const auto *
Previous = TokAfterLParen.Previous;
976 Previous->Previous->is(tok::kw_switch))) {
979 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
980 TT_LambdaDefinitionLParen) &&
984 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
987 return !
Next ||
Next->isMemberAccess() ||
988 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
991 State.
Column > getNewLineColumn(State).Total &&
1002 !StartsSimpleOneArgList(Current)) {
1003 CurrentState.NoLineBreak =
true;
1007 CurrentState.NoLineBreak =
true;
1013 if (Style.AlignAfterOpenBracket &&
1014 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1015 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1016 TT_TableGenDAGArgOpener,
1017 TT_TableGenDAGArgOpenerToBreak) &&
1019 (Current.
isNot(TT_LineComment) ||
1021 Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall) ||
1022 Previous.is(TT_VerilogMultiLineListLParen)) &&
1023 !IsInTemplateString(Current,
false)) {
1024 CurrentState.Indent = State.
Column + Spaces;
1025 CurrentState.AlignedTo = &
Previous;
1028 CurrentState.NoLineBreak =
true;
1030 CurrentState.NoLineBreak =
true;
1033 State.
Column > getNewLineColumn(State).Total) {
1034 CurrentState.ContainsUnwrappedBuilder =
true;
1037 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1038 CurrentState.NoLineBreak =
true;
1039 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1048 CurrentState.NoLineBreak =
true;
1055 const FormatToken *P = Current.getPreviousNonComment();
1056 if (Current.
isNot(tok::comment) && P &&
1057 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1058 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1059 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1063 bool BreakBeforeOperator =
1064 P->MustBreakBefore || P->is(tok::lessless) ||
1065 (P->is(TT_BinaryOperator) &&
1066 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1067 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1071 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1072 P->isNot(TT_ConditionalExpr);
1073 if ((!BreakBeforeOperator &&
1075 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1076 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1077 CurrentState.NoLineBreakInOperand =
true;
1082 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1087 CurrentState.LastSpace = State.
Column;
1088 CurrentState.NestedBlockIndent = State.
Column;
1089 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1091 Previous.isNot(TT_OverloadedOperator)) ||
1093 CurrentState.LastSpace = State.
Column;
1094 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1096 Style.BreakConstructorInitializers ==
1097 FormatStyle::BCIS_AfterColon) {
1098 CurrentState.Indent = State.
Column;
1099 CurrentState.LastSpace = State.
Column;
1100 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1101 CurrentState.LastSpace = State.
Column;
1102 }
else if (
Previous.is(TT_BinaryOperator) &&
1109 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1110 CurrentState.LastSpace = State.
Column;
1111 }
else if (
Previous.is(TT_InheritanceColon)) {
1112 CurrentState.Indent = State.
Column;
1113 CurrentState.LastSpace = State.
Column;
1114 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1115 CurrentState.ColonPos = State.
Column;
1116 }
else if (
Previous.opensScope()) {
1124 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1125 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1126 CurrentState.LastSpace = State.
Column;
1132unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1135 assert(State.NextToken->Previous);
1137 auto &CurrentState = State.Stack.back();
1141 unsigned Penalty = 0;
1143 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1145 if (!NextNonComment)
1146 NextNonComment = &Current;
1149 if (!CurrentState.ContainsLineBreak)
1151 CurrentState.ContainsLineBreak =
true;
1153 Penalty += State.NextToken->SplitPenalty;
1158 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1159 (State.Column <= Style.ColumnLimit / 3 ||
1160 CurrentState.BreakBeforeParameter)) {
1161 Penalty += Style.PenaltyBreakFirstLessLess;
1164 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1165 State.Column = TotalColumn;
1179 if (State.Column > State.FirstIndent) {
1181 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1194 if (Current.isNot(TT_LambdaArrow) &&
1195 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1196 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1197 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1198 CurrentState.NestedBlockIndent = State.Column;
1201 if (NextNonComment->isMemberAccess()) {
1202 if (CurrentState.CallContinuation == 0)
1203 CurrentState.CallContinuation = State.Column;
1204 }
else if (NextNonComment->is(TT_SelectorName)) {
1205 if (!CurrentState.ObjCSelectorNameFound) {
1206 if (NextNonComment->LongestObjCSelectorName == 0) {
1207 CurrentState.AlignColons =
false;
1209 CurrentState.ColonPos =
1211 ? std::max(CurrentState.Indent.Total,
1212 State.FirstIndent + Style.ContinuationIndentWidth)
1213 : CurrentState.
Indent.Total) +
1217 }
else if (CurrentState.AlignColons &&
1218 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1219 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1221 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1222 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1232 if (State.Stack.size() > 1) {
1233 State.Stack[State.Stack.size() - 2].LastSpace =
1234 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1235 Style.ContinuationIndentWidth;
1239 switch (Style.BreakInheritanceList) {
1240 case FormatStyle::BILS_BeforeColon:
1241 case FormatStyle::BILS_AfterComma:
1242 if (Current.is(TT_InheritanceColon) ||
Previous.is(TT_InheritanceComma)) {
1243 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1244 tok::kw_class, tok::kw_struct, tok::kw_union);
1247 case FormatStyle::BILS_BeforeComma:
1248 if (Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma)) {
1249 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1250 tok::kw_class, tok::kw_struct, tok::kw_union);
1253 case FormatStyle::BILS_AfterColon:
1254 if (
Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma))
1255 CurrentState.AlignedTo = &
Previous;
1259 if ((PreviousNonComment &&
1260 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1261 !CurrentState.AvoidBinPacking) ||
1263 CurrentState.BreakBeforeParameter =
false;
1265 if (PreviousNonComment &&
1266 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1267 PreviousNonComment->ClosesRequiresClause) &&
1268 Current.NestingLevel == 0) {
1269 CurrentState.BreakBeforeParameter =
false;
1271 if (NextNonComment->is(tok::question) ||
1272 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1273 CurrentState.BreakBeforeParameter =
true;
1275 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1276 CurrentState.BreakBeforeParameter =
false;
1277 CurrentState.AlignedTo = &Current;
1279 if (Style.AlignOperands != FormatStyle::OAS_DontAlign &&
1280 Current.is(TT_ConditionalExpr)) {
1281 switch (Style.AlignOperands) {
1282 case FormatStyle::OAS_Align:
1283 CurrentState.AlignedTo = Current.is(tok::question)
1284 ? Current.getPrevious(tok::equal)
1285 : Current.getPrevious(tok::question);
1287 case FormatStyle::OAS_AlignAfterOperator:
1288 if (Current.is(tok::colon))
1289 CurrentState.AlignedTo = Current.getPrevious(tok::question);
1291 case FormatStyle::OAS_DontAlign:
1298 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1301 !Current.MatchingParen->Children.empty()) {
1309 const bool ContinuePPDirective = State.Line->InPPDirective &&
1311 Current.isNot(TT_LineComment);
1312 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1313 CurrentState.AlignedTo, ContinuePPDirective,
1314 IndentedFromColumn);
1317 if (!Current.isTrailingComment())
1318 CurrentState.LastSpace = State.Column;
1319 if (Current.is(tok::lessless)) {
1323 CurrentState.LastSpace += 3;
1326 State.StartOfLineLevel = Current.NestingLevel;
1327 State.LowestLevelOnLine = Current.NestingLevel;
1331 bool NestedBlockSpecialCase =
1332 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1333 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1334 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1335 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1337 NestedBlockSpecialCase =
1338 NestedBlockSpecialCase ||
1339 (Current.MatchingParen &&
1340 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1341 if (!NestedBlockSpecialCase) {
1342 auto ParentLevelIt = std::next(State.Stack.rbegin());
1343 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1344 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1359 auto FindCurrentLevel = [&](
const auto &It) {
1360 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1361 return PState.Tok != nullptr;
1364 auto MaybeIncrement = [&](
const auto &It) {
1365 return It != State.Stack.rend() ? std::next(It) : It;
1367 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1368 auto LevelContainingLambdaIt =
1369 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1370 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1372 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1373 I->BreakBeforeParameter =
true;
1376 if (PreviousNonComment &&
1377 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1378 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1379 !PreviousNonComment->ClosesRequiresClause) ||
1380 Current.NestingLevel != 0) &&
1381 PreviousNonComment->isNoneOf(
1382 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1383 TT_LeadingJavaAnnotation) &&
1384 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1387 (!Style.BraceWrapping.BeforeLambdaBody ||
1388 Current.isNot(TT_LambdaLBrace))) {
1389 CurrentState.BreakBeforeParameter =
true;
1394 if (PreviousNonComment &&
1395 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1397 CurrentState.BreakBeforeClosingBrace =
true;
1400 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1401 if (
auto Previous = PreviousNonComment->Previous) {
1403 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1404 }
else if (
Previous->isLoop(Style)) {
1405 CurrentState.BreakBeforeClosingParen =
1406 Style.BreakBeforeCloseBracketLoop;
1407 }
else if (
Previous->is(tok::kw_switch)) {
1408 CurrentState.BreakBeforeClosingParen =
1409 Style.BreakBeforeCloseBracketSwitch;
1411 CurrentState.BreakBeforeClosingParen =
1412 Style.BreakBeforeCloseBracketFunction;
1417 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1418 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1420 if (CurrentState.AvoidBinPacking) {
1425 bool PreviousIsBreakingCtorInitializerColon =
1426 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1427 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1428 bool AllowAllConstructorInitializersOnNextLine =
1429 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1430 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1431 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1432 !PreviousIsBreakingCtorInitializerColon) ||
1433 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1434 State.Line->MustBeDeclaration) ||
1435 (!Style.AllowAllArgumentsOnNextLine &&
1436 !State.Line->MustBeDeclaration) ||
1437 (!AllowAllConstructorInitializersOnNextLine &&
1438 PreviousIsBreakingCtorInitializerColon) ||
1440 CurrentState.BreakBeforeParameter =
true;
1446 if (PreviousIsBreakingCtorInitializerColon &&
1447 AllowAllConstructorInitializersOnNextLine) {
1448 CurrentState.BreakBeforeParameter =
false;
1453 CurrentState.BreakBeforeParameter =
true;
1459ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1460 if (!State.NextToken || !State.NextToken->Previous)
1464 const auto &CurrentState = State.Stack.back();
1466 if (CurrentState.IsCSharpGenericTypeConstraint &&
1467 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1468 return CurrentState.ColonPos + 2;
1473 const auto ContinuationIndent =
1474 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1475 CurrentState.Indent) +
1476 Style.ContinuationIndentWidth;
1477 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1479 if (!NextNonComment)
1480 NextNonComment = &Current;
1483 if (Style.isJava() &&
1484 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1485 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1486 CurrentState.Indent + Style.ContinuationIndentWidth);
1491 if (Style.isVerilog() && PreviousNonComment &&
1492 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1493 return State.FirstIndent;
1496 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1497 State.Line->First->is(tok::kw_enum)) {
1498 return IndentationAndAlignment(Style.IndentWidth *
1499 State.Line->First->IndentLevel) +
1503 if (Style.BraceWrapping.BeforeLambdaBody &&
1504 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1505 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1506 ? CurrentState.Indent
1507 : State.FirstIndent;
1508 return From + Style.IndentWidth;
1511 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1512 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1513 if (Current.NestingLevel == 0 ||
1514 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1515 State.NextToken->is(TT_LambdaLBrace))) {
1516 return State.FirstIndent;
1518 return CurrentState.Indent;
1520 if (Current.is(TT_LambdaArrow) &&
1521 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1522 tok::kw_consteval, tok::kw_static,
1523 TT_AttributeRSquare)) {
1524 return ContinuationIndent;
1526 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1527 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1528 State.Stack.size() > 1) {
1529 if (Current.closesBlockOrBlockTypeList(Style))
1530 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1531 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit)) {
1541 if ((State.Stack.size() == 2 &&
1542 Current.MatchingParen->getPreviousNonComment() &&
1543 Current.MatchingParen->getPreviousNonComment()->is(
1545 (State.Stack.size() == 3 &&
1547 return State.FirstIndent;
1549 return State.Stack[State.Stack.size() - 2].LastSpace;
1551 return State.FirstIndent;
1568 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1570 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1571 return State.Stack[State.Stack.size() - 2].LastSpace;
1575 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1576 State.Stack.size() > 1) {
1577 return State.Stack[State.Stack.size() - 2].LastSpace;
1579 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1580 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1581 State.Stack.size() > 1) {
1582 return State.Stack[State.Stack.size() - 2].LastSpace;
1584 if ((Style.BreakBeforeCloseBracketFunction ||
1585 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1586 Style.BreakBeforeCloseBracketSwitch) &&
1587 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1588 return State.Stack[State.Stack.size() - 2].LastSpace;
1590 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1591 State.Stack.size() > 1) {
1592 return State.Stack[State.Stack.size() - 2].LastSpace;
1594 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1595 return State.Stack[State.Stack.size() - 2].LastSpace;
1603 if (Current.is(tok::identifier) && Current.Next &&
1604 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1605 (Current.Next->is(TT_DictLiteral) ||
1606 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1607 return CurrentState.Indent;
1609 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1610 State.StartOfStringLiteral != 0) {
1611 return State.StartOfStringLiteral - 1;
1613 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1614 return State.StartOfStringLiteral;
1615 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1616 return CurrentState.FirstLessLess;
1617 if (NextNonComment->isMemberAccess()) {
1618 if (CurrentState.CallContinuation == 0)
1619 return ContinuationIndent;
1620 return CurrentState.CallContinuation;
1622 if (CurrentState.QuestionColumn != 0 &&
1623 ((NextNonComment->is(tok::colon) &&
1624 NextNonComment->is(TT_ConditionalExpr)) ||
1625 Previous.is(TT_ConditionalExpr))) {
1626 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1627 !NextNonComment->Next->FakeLParens.empty() &&
1629 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1631 !CurrentState.IsWrappedConditional) {
1636 unsigned Indent = CurrentState.Indent.Total;
1637 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1638 Indent -= Style.ContinuationIndentWidth;
1639 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1643 return CurrentState.QuestionColumn;
1645 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1646 return CurrentState.VariablePos;
1647 if (Current.is(TT_RequiresClause)) {
1648 if (Style.IndentRequiresClause)
1649 return CurrentState.Indent + Style.IndentWidth;
1650 switch (Style.RequiresClausePosition) {
1651 case FormatStyle::RCPS_OwnLine:
1652 case FormatStyle::RCPS_WithFollowing:
1653 case FormatStyle::RCPS_OwnLineWithBrace:
1654 return CurrentState.Indent;
1659 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1660 TT_InheritanceComma)) {
1661 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1663 if ((PreviousNonComment &&
1664 (PreviousNonComment->ClosesTemplateDeclaration ||
1665 PreviousNonComment->ClosesRequiresClause ||
1666 (PreviousNonComment->is(TT_AttributeMacro) &&
1667 Current.isNot(tok::l_paren) &&
1668 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1669 TT_PointerOrReference)) ||
1670 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1671 TT_FunctionAnnotationRParen,
1673 TT_LeadingJavaAnnotation))) ||
1674 (!Style.IndentWrappedFunctionNames &&
1675 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)) ||
1676 (State.Line->ReturnTypeWrapped && PreviousNonComment &&
1678 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1679 CurrentState.Indent);
1681 if (NextNonComment->is(TT_SelectorName)) {
1682 if (!CurrentState.ObjCSelectorNameFound) {
1683 auto MinIndent = CurrentState.Indent;
1686 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1687 Style.ContinuationIndentWidth);
1698 return MinIndent.addPadding(
1699 std::max(NextNonComment->LongestObjCSelectorName,
1700 NextNonComment->ColumnWidth) -
1701 NextNonComment->ColumnWidth);
1703 if (!CurrentState.AlignColons)
1704 return CurrentState.Indent;
1705 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1706 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1707 return CurrentState.Indent;
1709 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1710 return CurrentState.ColonPos;
1711 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1712 if (CurrentState.StartOfArraySubscripts != 0) {
1713 return CurrentState.StartOfArraySubscripts;
1714 }
else if (Style.isCSharp()) {
1716 return CurrentState.Indent;
1718 return ContinuationIndent;
1723 if (State.Line->InPragmaDirective) {
1724 FormatToken *PragmaType = State.Line->First->Next->Next;
1725 if (PragmaType && PragmaType->TokenText ==
"omp")
1726 return CurrentState.Indent + Style.ContinuationIndentWidth;
1731 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1732 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1733 return CurrentState.Indent;
1736 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1737 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1738 return ContinuationIndent;
1740 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1741 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1742 return ContinuationIndent;
1744 if (NextNonComment->is(TT_CtorInitializerComma))
1745 return CurrentState.Indent;
1746 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1747 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1748 return CurrentState.Indent;
1750 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1751 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1752 return CurrentState.Indent;
1755 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1756 !Current.isBinaryOperator() &&
1757 Current.isNoneOf(tok::colon, tok::comment)) {
1758 return ContinuationIndent;
1760 if (Current.is(TT_ProtoExtensionLSquare))
1761 return CurrentState.Indent;
1762 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1763 return CurrentState.Indent - Current.Tok.getLength() -
1764 Current.SpacesRequiredBefore;
1766 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1767 CurrentState.UnindentOperator) {
1768 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1769 NextNonComment->SpacesRequiredBefore;
1771 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1772 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1775 return CurrentState.Indent + Style.ContinuationIndentWidth;
1777 return CurrentState.Indent;
1782 const FormatStyle &Style) {
1789 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1792unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1793 bool DryRun,
bool Newline) {
1794 assert(State.Stack.size());
1796 auto &CurrentState = State.Stack.back();
1798 if (Current.is(TT_CSharpGenericTypeConstraint))
1799 CurrentState.IsCSharpGenericTypeConstraint =
true;
1800 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1801 CurrentState.NoLineBreakInOperand =
false;
1802 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1803 CurrentState.AvoidBinPacking =
true;
1804 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1805 if (CurrentState.FirstLessLess == 0)
1806 CurrentState.FirstLessLess = State.Column;
1808 CurrentState.LastOperatorWrapped = Newline;
1810 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1811 CurrentState.LastOperatorWrapped = Newline;
1812 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1813 Current.Previous->isNot(TT_ConditionalExpr)) {
1814 CurrentState.LastOperatorWrapped = Newline;
1816 if (Current.is(TT_ArraySubscriptLSquare) &&
1817 CurrentState.StartOfArraySubscripts == 0) {
1818 CurrentState.StartOfArraySubscripts = State.Column;
1822 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1824 if (
Tok.MustBreakBefore)
1828 return Next &&
Next->MustBreakBefore;
1830 if (IsWrappedConditional(Current))
1831 CurrentState.IsWrappedConditional =
true;
1832 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1833 CurrentState.QuestionColumn = State.Column;
1834 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1839 CurrentState.QuestionColumn = State.Column;
1841 if (!Current.opensScope() && !Current.closesScope() &&
1842 Current.isNot(TT_PointerOrReference)) {
1843 State.LowestLevelOnLine =
1844 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1846 if (Current.isMemberAccess())
1847 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1848 if (Current.is(TT_SelectorName))
1849 CurrentState.ObjCSelectorNameFound =
true;
1850 if (Current.is(TT_CtorInitializerColon) &&
1851 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1857 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1858 FormatStyle::BCIS_BeforeComma
1861 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1862 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1863 CurrentState.AvoidBinPacking =
true;
1864 CurrentState.BreakBeforeParameter =
1865 Style.ColumnLimit > 0 &&
1866 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1867 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1869 CurrentState.BreakBeforeParameter =
false;
1872 if (Current.is(TT_CtorInitializerColon) &&
1873 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1874 CurrentState.Indent =
1875 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1876 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1877 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1878 CurrentState.AvoidBinPacking =
true;
1880 CurrentState.BreakBeforeParameter =
false;
1882 if (Current.is(TT_InheritanceColon)) {
1883 CurrentState.Indent =
1884 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1886 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1887 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1888 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1889 CurrentState.LastSpace = State.Column;
1890 if (Current.is(TT_RequiresExpression) &&
1891 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1892 CurrentState.NestedBlockIndent = State.Column;
1904 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1906 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1907 !CurrentState.HasMultipleNestedBlocks) {
1908 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1909 for (ParenState &PState : llvm::drop_end(State.Stack))
1910 PState.NoLineBreak =
true;
1911 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1913 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1914 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1915 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1916 TT_CtorInitializerColon)))) {
1917 CurrentState.NestedBlockInlined =
1921 moveStatePastFakeLParens(State, Newline);
1922 moveStatePastScopeCloser(State);
1925 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1926 !State.Stack.back().NoLineBreakInOperand;
1927 moveStatePastScopeOpener(State, Newline);
1928 moveStatePastFakeRParens(State);
1930 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1931 State.StartOfStringLiteral = State.Column + 1;
1932 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1933 State.StartOfStringLiteral = State.Column + 1;
1934 }
else if (Current.is(TT_TableGenMultiLineString) &&
1935 State.StartOfStringLiteral == 0) {
1936 State.StartOfStringLiteral = State.Column + 1;
1937 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1938 State.StartOfStringLiteral = State.Column;
1939 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1940 !Current.isStringLiteral()) {
1941 State.StartOfStringLiteral = 0;
1944 State.Column += Current.ColumnWidth;
1945 State.NextToken = State.NextToken->Next;
1950 if (Style.isVerilog() && State.NextToken &&
1951 State.NextToken->MustBreakBefore &&
1952 Keywords.isVerilogEndOfLabel(Current)) {
1953 State.FirstIndent += Style.IndentWidth;
1954 CurrentState.Indent = State.FirstIndent;
1958 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1961 Current.Role->formatFromToken(State,
this, DryRun);
1968 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1973void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1976 if (Current.FakeLParens.empty())
1984 bool SkipFirstExtraIndent =
1987 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1989 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1991 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1992 const auto &CurrentState = State.Stack.back();
1993 ParenState NewParenState = CurrentState;
1994 NewParenState.Tok =
nullptr;
1995 NewParenState.ContainsLineBreak =
false;
1996 NewParenState.LastOperatorWrapped =
true;
1997 NewParenState.IsChainedConditional =
false;
1998 NewParenState.IsWrappedConditional =
false;
1999 NewParenState.UnindentOperator =
false;
2000 NewParenState.NoLineBreak =
2001 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
2002 NewParenState.Precedence = PrecedenceLevel;
2006 NewParenState.AvoidBinPacking =
false;
2011 if (!Current.isTrailingComment() &&
2012 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
2015 (!Style.isJava() && PrecedenceLevel > 0)) &&
2016 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
2017 Current.NestingLevel == 0) &&
2018 (!Style.isTableGen() ||
2020 TT_TableGenDAGArgListCommaToBreak)))) {
2021 NewParenState.Indent =
2022 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
2023 IndentationAndAlignment(CurrentState.LastSpace)});
2030 State.Stack.size() > 1) {
2031 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
2032 Style.ContinuationIndentWidth;
2042 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
2043 NewParenState.UnindentOperator =
true;
2045 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
2046 NewParenState.AlignedTo =
Previous;
2056 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2058 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2059 NewParenState.StartOfFunctionCall = State.Column;
2069 &PrecedenceLevel == &Current.FakeLParens.back() &&
2070 !CurrentState.IsWrappedConditional) {
2071 NewParenState.IsChainedConditional =
true;
2072 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2075 !Current.isTrailingComment())) {
2076 NewParenState.Indent += Style.ContinuationIndentWidth;
2079 NewParenState.BreakBeforeParameter =
false;
2080 State.Stack.push_back(NewParenState);
2081 SkipFirstExtraIndent =
false;
2085void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2086 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2087 unsigned VariablePos = State.Stack.back().VariablePos;
2088 if (State.Stack.size() == 1) {
2092 State.Stack.pop_back();
2093 State.Stack.back().VariablePos = VariablePos;
2096 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2099 State.Stack.back().LastSpace -= Style.IndentWidth;
2103void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2106 if (!Current.opensScope())
2109 const auto &CurrentState = State.Stack.back();
2112 if (Current.isOneOf(tok::less, tok::l_paren) &&
2113 CurrentState.IsCSharpGenericTypeConstraint) {
2117 if (Current.MatchingParen && Current.is(
BK_Block)) {
2118 moveStateToNewBlock(State, Newline);
2125 const auto *Prev =
Tok->getPreviousNonComment();
2128 return Prev->is(tok::comma);
2129 }(Current.MatchingParen);
2131 IndentationAndAlignment NewIndent = 0;
2132 unsigned LastSpace = CurrentState.LastSpace;
2133 bool AvoidBinPacking;
2134 bool BreakBeforeParameter =
false;
2135 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2136 CurrentState.NestedBlockIndent);
2137 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2139 if (Current.opensBlockOrBlockTypeList(Style)) {
2140 NewIndent = Style.IndentWidth +
2141 std::min(State.Column, CurrentState.NestedBlockIndent);
2142 }
else if (Current.is(tok::l_brace)) {
2143 const auto Width = Style.BracedInitializerIndentWidth;
2144 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2145 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2147 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2149 const FormatToken *NextNonComment = Current.getNextNonComment();
2151 EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() ||
2152 Style.PackArguments.BinPack == FormatStyle::BPAS_OnePerLine ||
2154 NextNonComment->isOneOf(TT_DesignatedInitializerPeriod,
2155 TT_DesignatedInitializerLSquare));
2156 BreakBeforeParameter = EndsInComma;
2157 if (Current.ParameterCount > 1)
2158 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2160 NewIndent = IndentationAndAlignment(std::max(
2161 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2162 Style.ContinuationIndentWidth;
2164 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2165 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2171 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2172 NewIndent = State.Column +
Next->TokenText.size() + 2;
2179 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2180 NewIndent = std::max(NewIndent, CurrentState.Indent);
2181 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2187 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2188 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
2189 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter)) ||
2190 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2192 bool BinPackDeclaration =
2194 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
2195 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter)) ||
2198 bool GenericSelection =
2199 Current.getPreviousNonComment() &&
2200 Current.getPreviousNonComment()->is(tok::kw__Generic);
2203 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2204 (Style.isJavaScript() && EndsInComma) ||
2205 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2206 (!State.Line->MustBeDeclaration &&
2207 Style.PackArguments.BinPack == FormatStyle::BPAS_OnePerLine) ||
2208 (Style.ExperimentalAutoDetectBinPacking &&
2212 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2213 Style.ObjCBreakBeforeNestedBlockParam) {
2214 if (Style.ColumnLimit) {
2219 BreakBeforeParameter =
true;
2225 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2226 if (
Tok->MustBreakBefore ||
2227 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2228 BreakBeforeParameter =
true;
2235 if (Style.isJavaScript() && EndsInComma)
2236 BreakBeforeParameter =
true;
2242 Current.Children.empty() &&
2243 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2244 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2245 (Current.is(TT_TemplateOpener) &&
2246 CurrentState.ContainsUnwrappedBuilder));
2247 State.Stack.push_back(
2248 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2249 auto &NewState = State.Stack.back();
2250 NewState.NestedBlockIndent = NestedBlockIndent;
2251 NewState.BreakBeforeParameter = BreakBeforeParameter;
2252 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2254 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2255 Current.is(tok::l_paren)) {
2259 if (next->is(TT_LambdaLSquare)) {
2260 NewState.HasMultipleNestedBlocks =
true;
2267 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2269 Current.Previous->is(tok::at);
2272void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2274 if (!Current.closesScope())
2279 if (State.Stack.size() > 1 &&
2280 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2281 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2282 State.NextToken->is(TT_TemplateCloser) ||
2283 State.NextToken->is(TT_TableGenListCloser) ||
2284 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2285 State.Stack.pop_back();
2288 auto &CurrentState = State.Stack.back();
2300 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2301 Current.MatchingParen->Previous) {
2302 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2303 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2304 CurrentScopeOpener.MatchingParen) {
2305 int NecessarySpaceInLine =
2307 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2308 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2309 Style.ColumnLimit) {
2310 CurrentState.BreakBeforeParameter =
false;
2315 if (Current.is(tok::r_square)) {
2317 const FormatToken *NextNonComment = Current.getNextNonComment();
2318 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2319 CurrentState.StartOfArraySubscripts = 0;
2323void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2324 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2325 State.NextToken->is(TT_LambdaLBrace) &&
2326 !State.Line->MightBeFunctionDecl) {
2327 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2328 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2330 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2332 unsigned NewIndent =
2333 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2334 ? Style.ObjCBlockIndentWidth
2335 : Style.IndentWidth);
2342 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2343 State.NextToken->is(TT_LambdaLBrace);
2345 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2346 State.Stack.back().LastSpace,
2347 true, NoLineBreak));
2348 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2349 State.Stack.back().BreakBeforeParameter =
true;
2355 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2356 if (LastNewlinePos == StringRef::npos) {
2357 return StartColumn +
2365unsigned ContinuationIndenter::reformatRawStringLiteral(
2367 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2368 unsigned StartColumn = State.Column - Current.ColumnWidth;
2370 StringRef NewDelimiter =
2372 if (NewDelimiter.empty())
2373 NewDelimiter = OldDelimiter;
2376 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2377 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2380 std::string RawText = std::string(
2381 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2382 if (NewDelimiter != OldDelimiter) {
2385 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2386 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2387 NewDelimiter = OldDelimiter;
2390 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2391 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2394 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2405 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2427 unsigned CurrentIndent =
2428 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2429 ? State.Stack.back().NestedBlockIndent
2430 : State.Stack.back().Indent.Total;
2431 unsigned NextStartColumn = ContentStartsOnNewline
2432 ? CurrentIndent + Style.IndentWidth
2443 unsigned LastStartColumn =
2444 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2447 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2448 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2453 return addMultilineToken(Current, State);
2455 if (NewDelimiter != OldDelimiter) {
2458 SourceLocation PrefixDelimiterStart =
2459 Current.Tok.getLocation().getLocWithOffset(2);
2460 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2461 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2464 <<
"Failed to update the prefix delimiter of a raw string: "
2465 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2469 SourceLocation SuffixDelimiterStart =
2470 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2471 1 - OldDelimiter.size());
2472 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2473 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2476 <<
"Failed to update the suffix delimiter of a raw string: "
2477 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2480 SourceLocation OriginLoc =
2481 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2482 for (
const tooling::Replacement &Fix : Fixes.first) {
2483 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2484 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2485 Fix.getLength(), Fix.getReplacementText()));
2487 llvm::errs() <<
"Failed to reformat raw string: "
2488 << llvm::toString(std::move(Err)) <<
"\n";
2493 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2494 State.Column = RawLastLineEndColumn + NewSuffixSize;
2498 unsigned PrefixExcessCharacters =
2499 StartColumn + NewPrefixSize > Style.ColumnLimit
2500 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2503 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2506 for (ParenState &
Paren : State.Stack)
2507 Paren.BreakBeforeParameter =
true;
2509 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2512unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2515 for (ParenState &
Paren : State.Stack)
2516 Paren.BreakBeforeParameter =
true;
2518 unsigned ColumnsUsed = State.Column;
2521 State.Column = Current.LastLineColumnWidth;
2524 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2528unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2530 bool AllowBreak,
bool Newline) {
2531 unsigned Penalty = 0;
2534 auto RawStringStyle = getRawStringStyle(Current, State);
2535 if (RawStringStyle && !Current.Finalized) {
2536 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2538 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2541 Penalty = addMultilineToken(Current, State);
2544 LineState OriginalState = State;
2548 bool Strict =
false;
2551 bool Exceeded =
false;
2552 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2553 Current, State, AllowBreak,
true, Strict);
2557 LineState StrictState = OriginalState;
2558 unsigned StrictPenalty =
2559 breakProtrudingToken(Current, StrictState, AllowBreak,
2562 Strict = StrictPenalty <= Penalty;
2564 Penalty = StrictPenalty;
2565 State = std::move(StrictState);
2571 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2576 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2577 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2586 auto Tok = Current.getPreviousNonComment();
2587 if (!
Tok ||
Tok->isNot(tok::l_paren))
2589 Tok =
Tok->getPreviousNonComment();
2592 if (
Tok->is(TT_TemplateCloser)) {
2593 Tok =
Tok->MatchingParen;
2595 Tok =
Tok->getPreviousNonComment();
2597 if (!
Tok ||
Tok->isNot(tok::identifier))
2599 return Tok->TokenText;
2602std::optional<FormatStyle>
2603ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2604 const LineState &State) {
2605 if (!Current.isStringLiteral())
2606 return std::nullopt;
2609 return std::nullopt;
2611 if (!RawStringStyle && Delimiter->empty()) {
2615 if (!RawStringStyle)
2616 return std::nullopt;
2618 return RawStringStyle;
2621std::unique_ptr<BreakableToken>
2622ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2624 unsigned StartColumn = State.Column - Current.ColumnWidth;
2625 if (Current.isStringLiteral()) {
2628 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2642 if (Current.IsUnterminatedLiteral)
2646 if (State.Stack.back().IsInsideObjCArrayLiteral)
2653 if (Style.isVerilog() && Current.Previous &&
2654 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2657 StringRef
Text = Current.TokenText;
2667 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2670 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2671 Text.ends_with(
"'")) {
2673 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2674 Text.ends_with(
"\"")) {
2676 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2681 return std::make_unique<BreakableStringLiteralUsingOperators>(
2682 Current, QuoteStyle,
2693 if ((
Text.ends_with(Postfix =
"\"") &&
2694 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2695 Text.starts_with(Prefix =
"u\"") ||
2696 Text.starts_with(Prefix =
"U\"") ||
2697 Text.starts_with(Prefix =
"u8\"") ||
2698 Text.starts_with(Prefix =
"L\""))) ||
2699 (
Text.starts_with(Prefix =
"_T(\"") &&
2700 Text.ends_with(Postfix =
"\")"))) {
2701 return std::make_unique<BreakableStringLiteral>(
2703 State.Line->InPPDirective, Encoding, Style);
2705 }
else if (Current.is(TT_BlockComment)) {
2706 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2713 return std::make_unique<BreakableBlockComment>(
2714 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2715 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2716 }
else if (Current.is(TT_LineComment) &&
2717 (!Current.Previous ||
2718 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2719 bool RegularComments = [&]() {
2720 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2722 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2727 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2728 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2732 return std::make_unique<BreakableLineCommentSection>(
2733 Current, StartColumn,
false, Encoding, Style);
2738std::pair<unsigned, bool>
2739ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2741 bool DryRun,
bool Strict) {
2742 std::unique_ptr<const BreakableToken> Token =
2743 createBreakableToken(Current, State, AllowBreak);
2746 assert(Token->getLineCount() > 0);
2748 if (Current.is(TT_LineComment)) {
2750 ColumnLimit = Style.ColumnLimit;
2752 if (ColumnLimit == 0) {
2755 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2757 if (Current.UnbreakableTailLength >= ColumnLimit)
2761 unsigned StartColumn = State.Column - Current.ColumnWidth;
2762 unsigned NewBreakPenalty = Current.isStringLiteral()
2763 ? Style.PenaltyBreakString
2764 : Style.PenaltyBreakComment;
2767 bool Exceeded =
false;
2769 bool BreakInserted = Token->introducesBreakBeforeToken();
2772 bool NewBreakBefore =
false;
2776 bool Reflow =
false;
2779 unsigned TailOffset = 0;
2781 unsigned ContentStartColumn =
2782 Token->getContentStartColumn(0,
false);
2784 unsigned RemainingTokenColumns =
2785 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2788 Token->adaptStartOfLine(0, Whitespaces);
2790 unsigned ContentIndent = 0;
2791 unsigned Penalty = 0;
2792 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2793 << StartColumn <<
".\n");
2794 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2795 LineIndex != EndIndex; ++LineIndex) {
2796 LLVM_DEBUG(llvm::dbgs()
2797 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2798 NewBreakBefore =
false;
2802 bool TryReflow = Reflow;
2804 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2805 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2806 << (ContentStartColumn + RemainingTokenColumns)
2807 <<
", space: " << ColumnLimit
2808 <<
", reflown prefix: " << ContentStartColumn
2809 <<
", offset in line: " << TailOffset <<
"\n");
2815 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2816 ContentStartColumn, CommentPragmasRegex);
2817 if (
Split.first == StringRef::npos) {
2820 if (LineIndex < EndIndex - 1) {
2823 Penalty += Style.PenaltyExcessCharacter *
2824 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2826 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2829 assert(
Split.first != 0);
2831 if (Token->supportsReflow()) {
2851 unsigned ToSplitColumns = Token->getRangeLength(
2852 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2853 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2856 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2857 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2860 unsigned ToNextSplitColumns = 0;
2861 if (NextSplit.first == StringRef::npos) {
2862 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2863 ContentStartColumn);
2865 ToNextSplitColumns = Token->getRangeLength(
2866 LineIndex, TailOffset,
2867 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2871 ToNextSplitColumns =
2872 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2873 LLVM_DEBUG(llvm::dbgs()
2874 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2875 LLVM_DEBUG(llvm::dbgs()
2876 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2879 bool ContinueOnLine =
2880 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2881 unsigned ExcessCharactersPenalty = 0;
2882 if (!ContinueOnLine && !Strict) {
2885 ExcessCharactersPenalty =
2886 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2887 Style.PenaltyExcessCharacter;
2888 LLVM_DEBUG(llvm::dbgs()
2889 <<
" Penalty excess: " << ExcessCharactersPenalty
2890 <<
"\n break : " << NewBreakPenalty <<
"\n");
2891 if (ExcessCharactersPenalty < NewBreakPenalty) {
2893 ContinueOnLine =
true;
2896 if (ContinueOnLine) {
2897 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2902 Token->compressWhitespace(LineIndex, TailOffset, Split,
2906 ContentStartColumn += ToSplitColumns + 1;
2907 Penalty += ExcessCharactersPenalty;
2909 RemainingTokenColumns = Token->getRemainingLength(
2910 LineIndex, TailOffset, ContentStartColumn);
2914 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2919 ContentIndent = Token->getContentIndent(LineIndex);
2920 LLVM_DEBUG(llvm::dbgs()
2921 <<
" ContentIndent: " << ContentIndent <<
"\n");
2922 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2925 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2926 LineIndex, TailOffset +
Split.first +
Split.second,
2927 ContentStartColumn);
2928 if (NewRemainingTokenColumns == 0) {
2931 ContentStartColumn =
2932 Token->getContentStartColumn(LineIndex,
true);
2933 NewRemainingTokenColumns = Token->getRemainingLength(
2934 LineIndex, TailOffset +
Split.first +
Split.second,
2935 ContentStartColumn);
2941 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2946 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2947 <<
", " <<
Split.second <<
"\n");
2949 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2953 Penalty += NewBreakPenalty;
2955 RemainingTokenColumns = NewRemainingTokenColumns;
2956 BreakInserted =
true;
2957 NewBreakBefore =
true;
2961 if (LineIndex + 1 != EndIndex) {
2962 unsigned NextLineIndex = LineIndex + 1;
2963 if (NewBreakBefore) {
2982 ContentStartColumn += RemainingTokenColumns + 1;
2987 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2988 LLVM_DEBUG(llvm::dbgs()
2989 <<
" Size of reflown text: " << ContentStartColumn
2990 <<
"\n Potential reflow split: ");
2991 if (SplitBeforeNext.first != StringRef::npos) {
2992 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2993 << SplitBeforeNext.second <<
"\n");
2994 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2997 RemainingTokenColumns = Token->getRemainingLength(
2998 NextLineIndex, TailOffset, ContentStartColumn);
3000 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
3001 LLVM_DEBUG(llvm::dbgs()
3002 <<
" Over limit after reflow, need: "
3003 << (ContentStartColumn + RemainingTokenColumns)
3004 <<
", space: " << ColumnLimit
3005 <<
", reflown prefix: " << ContentStartColumn
3006 <<
", offset in line: " << TailOffset <<
"\n");
3012 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
3013 ContentStartColumn, CommentPragmasRegex);
3014 if (
Split.first == StringRef::npos) {
3015 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
3021 unsigned ToSplitColumns = Token->getRangeLength(
3022 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
3023 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
3024 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
3025 << (ContentStartColumn + ToSplitColumns)
3026 <<
", space: " << ColumnLimit);
3027 unsigned ExcessCharactersPenalty =
3028 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
3029 Style.PenaltyExcessCharacter;
3030 if (NewBreakPenalty < ExcessCharactersPenalty)
3036 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3044 ContentStartColumn =
3045 Token->getContentStartColumn(NextLineIndex,
false);
3046 RemainingTokenColumns = Token->getRemainingLength(
3047 NextLineIndex, TailOffset, ContentStartColumn);
3050 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3065 if (NewBreakBefore) {
3066 assert(Penalty >= NewBreakPenalty);
3067 Penalty -= NewBreakPenalty;
3070 Token->reflow(NextLineIndex, Whitespaces);
3076 Token->getSplitAfterLastLine(TailOffset);
3077 if (SplitAfterLastLine.first != StringRef::npos) {
3078 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3082 Penalty += Style.PenaltyExcessCharacter *
3083 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3086 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3089 ContentStartColumn =
3090 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3091 RemainingTokenColumns = Token->getRemainingLength(
3092 Token->getLineCount() - 1,
3093 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3094 ContentStartColumn);
3097 State.Column = ContentStartColumn + RemainingTokenColumns -
3098 Current.UnbreakableTailLength;
3100 if (BreakInserted) {
3102 Token->updateAfterBroken(Whitespaces);
3107 if (Current.isNot(TT_LineComment))
3108 for (ParenState &
Paren : State.Stack)
3109 Paren.BreakBeforeParameter =
true;
3111 if (Current.is(TT_BlockComment))
3112 State.NoContinuation =
true;
3114 State.Stack.back().LastSpace = StartColumn;
3117 Token->updateNextToken(State);
3119 return {Penalty, Exceeded};
3124 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3127bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3129 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3134 if (Current.
TokenText.starts_with(
"R\""))
3138 if (Current.getNextNonComment() &&
3139 Current.getNextNonComment()->isStringLiteral()) {
3142 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3144 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...
bool isReturnTypePrefixSpecifier(const FormatToken &Tok)
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...