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))
1532 return State.Stack[State.Stack.size() - 2].LastSpace;
1533 return State.FirstIndent;
1550 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1552 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1553 return State.Stack[State.Stack.size() - 2].LastSpace;
1557 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1558 State.Stack.size() > 1) {
1559 return State.Stack[State.Stack.size() - 2].LastSpace;
1561 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1562 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1563 State.Stack.size() > 1) {
1564 return State.Stack[State.Stack.size() - 2].LastSpace;
1566 if ((Style.BreakBeforeCloseBracketFunction ||
1567 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1568 Style.BreakBeforeCloseBracketSwitch) &&
1569 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1570 return State.Stack[State.Stack.size() - 2].LastSpace;
1572 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1573 State.Stack.size() > 1) {
1574 return State.Stack[State.Stack.size() - 2].LastSpace;
1576 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1577 return State.Stack[State.Stack.size() - 2].LastSpace;
1585 if (Current.is(tok::identifier) && Current.Next &&
1586 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1587 (Current.Next->is(TT_DictLiteral) ||
1588 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1589 return CurrentState.Indent;
1591 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1592 State.StartOfStringLiteral != 0) {
1593 return State.StartOfStringLiteral - 1;
1595 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1596 return State.StartOfStringLiteral;
1597 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1598 return CurrentState.FirstLessLess;
1599 if (NextNonComment->isMemberAccess()) {
1600 if (CurrentState.CallContinuation == 0)
1601 return ContinuationIndent;
1602 return CurrentState.CallContinuation;
1604 if (CurrentState.QuestionColumn != 0 &&
1605 ((NextNonComment->is(tok::colon) &&
1606 NextNonComment->is(TT_ConditionalExpr)) ||
1607 Previous.is(TT_ConditionalExpr))) {
1608 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1609 !NextNonComment->Next->FakeLParens.empty() &&
1611 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1613 !CurrentState.IsWrappedConditional) {
1618 unsigned Indent = CurrentState.Indent.Total;
1619 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1620 Indent -= Style.ContinuationIndentWidth;
1621 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1625 return CurrentState.QuestionColumn;
1627 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1628 return CurrentState.VariablePos;
1629 if (Current.is(TT_RequiresClause)) {
1630 if (Style.IndentRequiresClause)
1631 return CurrentState.Indent + Style.IndentWidth;
1632 switch (Style.RequiresClausePosition) {
1633 case FormatStyle::RCPS_OwnLine:
1634 case FormatStyle::RCPS_WithFollowing:
1635 case FormatStyle::RCPS_OwnLineWithBrace:
1636 return CurrentState.Indent;
1641 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1642 TT_InheritanceComma)) {
1643 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1645 if ((PreviousNonComment &&
1646 (PreviousNonComment->ClosesTemplateDeclaration ||
1647 PreviousNonComment->ClosesRequiresClause ||
1648 (PreviousNonComment->is(TT_AttributeMacro) &&
1649 Current.isNot(tok::l_paren) &&
1650 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1651 TT_PointerOrReference)) ||
1652 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1653 TT_FunctionAnnotationRParen,
1655 TT_LeadingJavaAnnotation))) ||
1656 (!Style.IndentWrappedFunctionNames &&
1657 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1658 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1659 CurrentState.Indent);
1661 if (NextNonComment->is(TT_SelectorName)) {
1662 if (!CurrentState.ObjCSelectorNameFound) {
1663 auto MinIndent = CurrentState.Indent;
1666 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1667 Style.ContinuationIndentWidth);
1678 return MinIndent.addPadding(
1679 std::max(NextNonComment->LongestObjCSelectorName,
1680 NextNonComment->ColumnWidth) -
1681 NextNonComment->ColumnWidth);
1683 if (!CurrentState.AlignColons)
1684 return CurrentState.Indent;
1685 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1686 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1687 return CurrentState.Indent;
1689 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1690 return CurrentState.ColonPos;
1691 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1692 if (CurrentState.StartOfArraySubscripts != 0) {
1693 return CurrentState.StartOfArraySubscripts;
1694 }
else if (Style.isCSharp()) {
1696 return CurrentState.Indent;
1698 return ContinuationIndent;
1703 if (State.Line->InPragmaDirective) {
1704 FormatToken *PragmaType = State.Line->First->Next->Next;
1705 if (PragmaType && PragmaType->TokenText ==
"omp")
1706 return CurrentState.Indent + Style.ContinuationIndentWidth;
1711 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1712 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1713 return CurrentState.Indent;
1716 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1717 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1718 return ContinuationIndent;
1720 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1721 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1722 return ContinuationIndent;
1724 if (NextNonComment->is(TT_CtorInitializerComma))
1725 return CurrentState.Indent;
1726 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1727 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1728 return CurrentState.Indent;
1730 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1731 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1732 return CurrentState.Indent;
1735 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1736 !Current.isBinaryOperator() &&
1737 Current.isNoneOf(tok::colon, tok::comment)) {
1738 return ContinuationIndent;
1740 if (Current.is(TT_ProtoExtensionLSquare))
1741 return CurrentState.Indent;
1742 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1743 return CurrentState.Indent - Current.Tok.getLength() -
1744 Current.SpacesRequiredBefore;
1746 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1747 CurrentState.UnindentOperator) {
1748 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1749 NextNonComment->SpacesRequiredBefore;
1751 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1752 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1755 return CurrentState.Indent + Style.ContinuationIndentWidth;
1757 return CurrentState.Indent;
1762 const FormatStyle &Style) {
1769 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1772unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1773 bool DryRun,
bool Newline) {
1774 assert(State.Stack.size());
1776 auto &CurrentState = State.Stack.back();
1778 if (Current.is(TT_CSharpGenericTypeConstraint))
1779 CurrentState.IsCSharpGenericTypeConstraint =
true;
1780 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1781 CurrentState.NoLineBreakInOperand =
false;
1782 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1783 CurrentState.AvoidBinPacking =
true;
1784 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1785 if (CurrentState.FirstLessLess == 0)
1786 CurrentState.FirstLessLess = State.Column;
1788 CurrentState.LastOperatorWrapped = Newline;
1790 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1791 CurrentState.LastOperatorWrapped = Newline;
1792 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1793 Current.Previous->isNot(TT_ConditionalExpr)) {
1794 CurrentState.LastOperatorWrapped = Newline;
1796 if (Current.is(TT_ArraySubscriptLSquare) &&
1797 CurrentState.StartOfArraySubscripts == 0) {
1798 CurrentState.StartOfArraySubscripts = State.Column;
1802 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1804 if (
Tok.MustBreakBefore)
1808 return Next &&
Next->MustBreakBefore;
1810 if (IsWrappedConditional(Current))
1811 CurrentState.IsWrappedConditional =
true;
1812 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1813 CurrentState.QuestionColumn = State.Column;
1814 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1819 CurrentState.QuestionColumn = State.Column;
1821 if (!Current.opensScope() && !Current.closesScope() &&
1822 Current.isNot(TT_PointerOrReference)) {
1823 State.LowestLevelOnLine =
1824 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1826 if (Current.isMemberAccess())
1827 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1828 if (Current.is(TT_SelectorName))
1829 CurrentState.ObjCSelectorNameFound =
true;
1830 if (Current.is(TT_CtorInitializerColon) &&
1831 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1837 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1838 FormatStyle::BCIS_BeforeComma
1841 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1842 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1843 CurrentState.AvoidBinPacking =
true;
1844 CurrentState.BreakBeforeParameter =
1845 Style.ColumnLimit > 0 &&
1846 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1847 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1849 CurrentState.BreakBeforeParameter =
false;
1852 if (Current.is(TT_CtorInitializerColon) &&
1853 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1854 CurrentState.Indent =
1855 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1856 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1857 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1858 CurrentState.AvoidBinPacking =
true;
1860 CurrentState.BreakBeforeParameter =
false;
1862 if (Current.is(TT_InheritanceColon)) {
1863 CurrentState.Indent =
1864 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1866 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1867 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1868 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1869 CurrentState.LastSpace = State.Column;
1870 if (Current.is(TT_RequiresExpression) &&
1871 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1872 CurrentState.NestedBlockIndent = State.Column;
1884 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1886 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1887 !CurrentState.HasMultipleNestedBlocks) {
1888 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1889 for (ParenState &PState : llvm::drop_end(State.Stack))
1890 PState.NoLineBreak =
true;
1891 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1893 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1894 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1895 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1896 TT_CtorInitializerColon)))) {
1897 CurrentState.NestedBlockInlined =
1901 moveStatePastFakeLParens(State, Newline);
1902 moveStatePastScopeCloser(State);
1905 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1906 !State.Stack.back().NoLineBreakInOperand;
1907 moveStatePastScopeOpener(State, Newline);
1908 moveStatePastFakeRParens(State);
1910 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1911 State.StartOfStringLiteral = State.Column + 1;
1912 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1913 State.StartOfStringLiteral = State.Column + 1;
1914 }
else if (Current.is(TT_TableGenMultiLineString) &&
1915 State.StartOfStringLiteral == 0) {
1916 State.StartOfStringLiteral = State.Column + 1;
1917 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1918 State.StartOfStringLiteral = State.Column;
1919 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1920 !Current.isStringLiteral()) {
1921 State.StartOfStringLiteral = 0;
1924 State.Column += Current.ColumnWidth;
1925 State.NextToken = State.NextToken->Next;
1930 if (Style.isVerilog() && State.NextToken &&
1931 State.NextToken->MustBreakBefore &&
1932 Keywords.isVerilogEndOfLabel(Current)) {
1933 State.FirstIndent += Style.IndentWidth;
1934 CurrentState.Indent = State.FirstIndent;
1938 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1941 Current.Role->formatFromToken(State,
this, DryRun);
1948 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1953void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1956 if (Current.FakeLParens.empty())
1964 bool SkipFirstExtraIndent =
1967 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1969 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1971 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1972 const auto &CurrentState = State.Stack.back();
1973 ParenState NewParenState = CurrentState;
1974 NewParenState.Tok =
nullptr;
1975 NewParenState.ContainsLineBreak =
false;
1976 NewParenState.LastOperatorWrapped =
true;
1977 NewParenState.IsChainedConditional =
false;
1978 NewParenState.IsWrappedConditional =
false;
1979 NewParenState.UnindentOperator =
false;
1980 NewParenState.NoLineBreak =
1981 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1985 NewParenState.AvoidBinPacking =
false;
1990 if (!Current.isTrailingComment() &&
1991 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1994 (!Style.isJava() && PrecedenceLevel > 0)) &&
1995 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1996 Current.NestingLevel == 0) &&
1997 (!Style.isTableGen() ||
1999 TT_TableGenDAGArgListCommaToBreak)))) {
2000 NewParenState.Indent =
2001 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
2002 IndentationAndAlignment(CurrentState.LastSpace)});
2009 State.Stack.size() > 1) {
2010 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
2011 Style.ContinuationIndentWidth;
2021 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
2022 NewParenState.UnindentOperator =
true;
2024 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
2025 NewParenState.AlignedTo =
Previous;
2035 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2037 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2038 NewParenState.StartOfFunctionCall = State.Column;
2048 &PrecedenceLevel == &Current.FakeLParens.back() &&
2049 !CurrentState.IsWrappedConditional) {
2050 NewParenState.IsChainedConditional =
true;
2051 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2054 !Current.isTrailingComment())) {
2055 NewParenState.Indent += Style.ContinuationIndentWidth;
2058 NewParenState.BreakBeforeParameter =
false;
2059 State.Stack.push_back(NewParenState);
2060 SkipFirstExtraIndent =
false;
2064void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2065 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2066 unsigned VariablePos = State.Stack.back().VariablePos;
2067 if (State.Stack.size() == 1) {
2071 State.Stack.pop_back();
2072 State.Stack.back().VariablePos = VariablePos;
2075 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2078 State.Stack.back().LastSpace -= Style.IndentWidth;
2082void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2085 if (!Current.opensScope())
2088 const auto &CurrentState = State.Stack.back();
2091 if (Current.isOneOf(tok::less, tok::l_paren) &&
2092 CurrentState.IsCSharpGenericTypeConstraint) {
2096 if (Current.MatchingParen && Current.is(
BK_Block)) {
2097 moveStateToNewBlock(State, Newline);
2104 const auto *Prev =
Tok->getPreviousNonComment();
2107 return Prev->is(tok::comma);
2108 }(Current.MatchingParen);
2110 IndentationAndAlignment NewIndent = 0;
2111 unsigned LastSpace = CurrentState.LastSpace;
2112 bool AvoidBinPacking;
2113 bool BreakBeforeParameter =
false;
2114 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2115 CurrentState.NestedBlockIndent);
2116 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2118 if (Current.opensBlockOrBlockTypeList(Style)) {
2119 NewIndent = Style.IndentWidth +
2120 std::min(State.Column, CurrentState.NestedBlockIndent);
2121 }
else if (Current.is(tok::l_brace)) {
2122 const auto Width = Style.BracedInitializerIndentWidth;
2123 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2124 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2126 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2128 const FormatToken *NextNonComment = Current.getNextNonComment();
2130 EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() ||
2131 Style.PackArguments.BinPack == FormatStyle::BPAS_OnePerLine ||
2133 NextNonComment->isOneOf(TT_DesignatedInitializerPeriod,
2134 TT_DesignatedInitializerLSquare));
2135 BreakBeforeParameter = EndsInComma;
2136 if (Current.ParameterCount > 1)
2137 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2139 NewIndent = IndentationAndAlignment(std::max(
2140 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2141 Style.ContinuationIndentWidth;
2143 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2144 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2150 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2151 NewIndent = State.Column +
Next->TokenText.size() + 2;
2158 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2159 NewIndent = std::max(NewIndent, CurrentState.Indent);
2160 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2166 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2167 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
2168 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter)) ||
2169 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2171 bool BinPackDeclaration =
2173 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
2174 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter)) ||
2177 bool GenericSelection =
2178 Current.getPreviousNonComment() &&
2179 Current.getPreviousNonComment()->is(tok::kw__Generic);
2182 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2183 (Style.isJavaScript() && EndsInComma) ||
2184 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2185 (!State.Line->MustBeDeclaration &&
2186 Style.PackArguments.BinPack == FormatStyle::BPAS_OnePerLine) ||
2187 (Style.ExperimentalAutoDetectBinPacking &&
2191 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2192 Style.ObjCBreakBeforeNestedBlockParam) {
2193 if (Style.ColumnLimit) {
2198 BreakBeforeParameter =
true;
2204 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2205 if (
Tok->MustBreakBefore ||
2206 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2207 BreakBeforeParameter =
true;
2214 if (Style.isJavaScript() && EndsInComma)
2215 BreakBeforeParameter =
true;
2221 Current.Children.empty() &&
2222 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2223 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2224 (Current.is(TT_TemplateOpener) &&
2225 CurrentState.ContainsUnwrappedBuilder));
2226 State.Stack.push_back(
2227 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2228 auto &NewState = State.Stack.back();
2229 NewState.NestedBlockIndent = NestedBlockIndent;
2230 NewState.BreakBeforeParameter = BreakBeforeParameter;
2231 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2233 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2234 Current.is(tok::l_paren)) {
2238 if (next->is(TT_LambdaLSquare)) {
2239 NewState.HasMultipleNestedBlocks =
true;
2246 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2248 Current.Previous->is(tok::at);
2251void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2253 if (!Current.closesScope())
2258 if (State.Stack.size() > 1 &&
2259 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2260 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2261 State.NextToken->is(TT_TemplateCloser) ||
2262 State.NextToken->is(TT_TableGenListCloser) ||
2263 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2264 State.Stack.pop_back();
2267 auto &CurrentState = State.Stack.back();
2279 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2280 Current.MatchingParen->Previous) {
2281 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2282 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2283 CurrentScopeOpener.MatchingParen) {
2284 int NecessarySpaceInLine =
2286 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2287 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2288 Style.ColumnLimit) {
2289 CurrentState.BreakBeforeParameter =
false;
2294 if (Current.is(tok::r_square)) {
2296 const FormatToken *NextNonComment = Current.getNextNonComment();
2297 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2298 CurrentState.StartOfArraySubscripts = 0;
2302void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2303 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2304 State.NextToken->is(TT_LambdaLBrace) &&
2305 !State.Line->MightBeFunctionDecl) {
2306 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2307 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2309 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2311 unsigned NewIndent =
2312 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2313 ? Style.ObjCBlockIndentWidth
2314 : Style.IndentWidth);
2321 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2322 State.NextToken->is(TT_LambdaLBrace);
2324 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2325 State.Stack.back().LastSpace,
2326 true, NoLineBreak));
2327 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2328 State.Stack.back().BreakBeforeParameter =
true;
2334 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2335 if (LastNewlinePos == StringRef::npos) {
2336 return StartColumn +
2344unsigned ContinuationIndenter::reformatRawStringLiteral(
2346 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2347 unsigned StartColumn = State.Column - Current.ColumnWidth;
2349 StringRef NewDelimiter =
2351 if (NewDelimiter.empty())
2352 NewDelimiter = OldDelimiter;
2355 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2356 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2359 std::string RawText = std::string(
2360 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2361 if (NewDelimiter != OldDelimiter) {
2364 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2365 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2366 NewDelimiter = OldDelimiter;
2369 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2370 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2373 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2384 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2406 unsigned CurrentIndent =
2407 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2408 ? State.Stack.back().NestedBlockIndent
2409 : State.Stack.back().Indent.Total;
2410 unsigned NextStartColumn = ContentStartsOnNewline
2411 ? CurrentIndent + Style.IndentWidth
2422 unsigned LastStartColumn =
2423 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2426 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2427 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2432 return addMultilineToken(Current, State);
2434 if (NewDelimiter != OldDelimiter) {
2437 SourceLocation PrefixDelimiterStart =
2438 Current.Tok.getLocation().getLocWithOffset(2);
2439 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2440 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2443 <<
"Failed to update the prefix delimiter of a raw string: "
2444 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2448 SourceLocation SuffixDelimiterStart =
2449 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2450 1 - OldDelimiter.size());
2451 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2452 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2455 <<
"Failed to update the suffix delimiter of a raw string: "
2456 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2459 SourceLocation OriginLoc =
2460 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2461 for (
const tooling::Replacement &Fix : Fixes.first) {
2462 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2463 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2464 Fix.getLength(), Fix.getReplacementText()));
2466 llvm::errs() <<
"Failed to reformat raw string: "
2467 << llvm::toString(std::move(Err)) <<
"\n";
2472 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2473 State.Column = RawLastLineEndColumn + NewSuffixSize;
2477 unsigned PrefixExcessCharacters =
2478 StartColumn + NewPrefixSize > Style.ColumnLimit
2479 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2482 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2485 for (ParenState &
Paren : State.Stack)
2486 Paren.BreakBeforeParameter =
true;
2488 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2491unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2494 for (ParenState &
Paren : State.Stack)
2495 Paren.BreakBeforeParameter =
true;
2497 unsigned ColumnsUsed = State.Column;
2500 State.Column = Current.LastLineColumnWidth;
2503 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2507unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2509 bool AllowBreak,
bool Newline) {
2510 unsigned Penalty = 0;
2513 auto RawStringStyle = getRawStringStyle(Current, State);
2514 if (RawStringStyle && !Current.Finalized) {
2515 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2517 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2520 Penalty = addMultilineToken(Current, State);
2523 LineState OriginalState = State;
2527 bool Strict =
false;
2530 bool Exceeded =
false;
2531 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2532 Current, State, AllowBreak,
true, Strict);
2536 LineState StrictState = OriginalState;
2537 unsigned StrictPenalty =
2538 breakProtrudingToken(Current, StrictState, AllowBreak,
2541 Strict = StrictPenalty <= Penalty;
2543 Penalty = StrictPenalty;
2544 State = std::move(StrictState);
2550 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2555 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2556 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2565 auto Tok = Current.getPreviousNonComment();
2566 if (!
Tok ||
Tok->isNot(tok::l_paren))
2568 Tok =
Tok->getPreviousNonComment();
2571 if (
Tok->is(TT_TemplateCloser)) {
2572 Tok =
Tok->MatchingParen;
2574 Tok =
Tok->getPreviousNonComment();
2576 if (!
Tok ||
Tok->isNot(tok::identifier))
2578 return Tok->TokenText;
2581std::optional<FormatStyle>
2582ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2583 const LineState &State) {
2584 if (!Current.isStringLiteral())
2585 return std::nullopt;
2588 return std::nullopt;
2590 if (!RawStringStyle && Delimiter->empty()) {
2594 if (!RawStringStyle)
2595 return std::nullopt;
2597 return RawStringStyle;
2600std::unique_ptr<BreakableToken>
2601ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2603 unsigned StartColumn = State.Column - Current.ColumnWidth;
2604 if (Current.isStringLiteral()) {
2607 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2621 if (Current.IsUnterminatedLiteral)
2625 if (State.Stack.back().IsInsideObjCArrayLiteral)
2632 if (Style.isVerilog() && Current.Previous &&
2633 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2636 StringRef
Text = Current.TokenText;
2646 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2649 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2650 Text.ends_with(
"'")) {
2652 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2653 Text.ends_with(
"\"")) {
2655 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2660 return std::make_unique<BreakableStringLiteralUsingOperators>(
2661 Current, QuoteStyle,
2672 if ((
Text.ends_with(Postfix =
"\"") &&
2673 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2674 Text.starts_with(Prefix =
"u\"") ||
2675 Text.starts_with(Prefix =
"U\"") ||
2676 Text.starts_with(Prefix =
"u8\"") ||
2677 Text.starts_with(Prefix =
"L\""))) ||
2678 (
Text.starts_with(Prefix =
"_T(\"") &&
2679 Text.ends_with(Postfix =
"\")"))) {
2680 return std::make_unique<BreakableStringLiteral>(
2682 State.Line->InPPDirective, Encoding, Style);
2684 }
else if (Current.is(TT_BlockComment)) {
2685 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2692 return std::make_unique<BreakableBlockComment>(
2693 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2694 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2695 }
else if (Current.is(TT_LineComment) &&
2696 (!Current.Previous ||
2697 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2698 bool RegularComments = [&]() {
2699 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2701 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2706 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2707 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2711 return std::make_unique<BreakableLineCommentSection>(
2712 Current, StartColumn,
false, Encoding, Style);
2717std::pair<unsigned, bool>
2718ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2720 bool DryRun,
bool Strict) {
2721 std::unique_ptr<const BreakableToken> Token =
2722 createBreakableToken(Current, State, AllowBreak);
2725 assert(Token->getLineCount() > 0);
2727 if (Current.is(TT_LineComment)) {
2729 ColumnLimit = Style.ColumnLimit;
2731 if (ColumnLimit == 0) {
2734 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2736 if (Current.UnbreakableTailLength >= ColumnLimit)
2740 unsigned StartColumn = State.Column - Current.ColumnWidth;
2741 unsigned NewBreakPenalty = Current.isStringLiteral()
2742 ? Style.PenaltyBreakString
2743 : Style.PenaltyBreakComment;
2746 bool Exceeded =
false;
2748 bool BreakInserted = Token->introducesBreakBeforeToken();
2751 bool NewBreakBefore =
false;
2755 bool Reflow =
false;
2758 unsigned TailOffset = 0;
2760 unsigned ContentStartColumn =
2761 Token->getContentStartColumn(0,
false);
2763 unsigned RemainingTokenColumns =
2764 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2767 Token->adaptStartOfLine(0, Whitespaces);
2769 unsigned ContentIndent = 0;
2770 unsigned Penalty = 0;
2771 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2772 << StartColumn <<
".\n");
2773 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2774 LineIndex != EndIndex; ++LineIndex) {
2775 LLVM_DEBUG(llvm::dbgs()
2776 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2777 NewBreakBefore =
false;
2781 bool TryReflow = Reflow;
2783 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2784 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2785 << (ContentStartColumn + RemainingTokenColumns)
2786 <<
", space: " << ColumnLimit
2787 <<
", reflown prefix: " << ContentStartColumn
2788 <<
", offset in line: " << TailOffset <<
"\n");
2794 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2795 ContentStartColumn, CommentPragmasRegex);
2796 if (
Split.first == StringRef::npos) {
2799 if (LineIndex < EndIndex - 1) {
2802 Penalty += Style.PenaltyExcessCharacter *
2803 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2805 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2808 assert(
Split.first != 0);
2810 if (Token->supportsReflow()) {
2830 unsigned ToSplitColumns = Token->getRangeLength(
2831 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2832 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2835 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2836 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2839 unsigned ToNextSplitColumns = 0;
2840 if (NextSplit.first == StringRef::npos) {
2841 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2842 ContentStartColumn);
2844 ToNextSplitColumns = Token->getRangeLength(
2845 LineIndex, TailOffset,
2846 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2850 ToNextSplitColumns =
2851 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2852 LLVM_DEBUG(llvm::dbgs()
2853 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2854 LLVM_DEBUG(llvm::dbgs()
2855 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2858 bool ContinueOnLine =
2859 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2860 unsigned ExcessCharactersPenalty = 0;
2861 if (!ContinueOnLine && !Strict) {
2864 ExcessCharactersPenalty =
2865 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2866 Style.PenaltyExcessCharacter;
2867 LLVM_DEBUG(llvm::dbgs()
2868 <<
" Penalty excess: " << ExcessCharactersPenalty
2869 <<
"\n break : " << NewBreakPenalty <<
"\n");
2870 if (ExcessCharactersPenalty < NewBreakPenalty) {
2872 ContinueOnLine =
true;
2875 if (ContinueOnLine) {
2876 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2881 Token->compressWhitespace(LineIndex, TailOffset, Split,
2885 ContentStartColumn += ToSplitColumns + 1;
2886 Penalty += ExcessCharactersPenalty;
2888 RemainingTokenColumns = Token->getRemainingLength(
2889 LineIndex, TailOffset, ContentStartColumn);
2893 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2898 ContentIndent = Token->getContentIndent(LineIndex);
2899 LLVM_DEBUG(llvm::dbgs()
2900 <<
" ContentIndent: " << ContentIndent <<
"\n");
2901 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2904 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2905 LineIndex, TailOffset +
Split.first +
Split.second,
2906 ContentStartColumn);
2907 if (NewRemainingTokenColumns == 0) {
2910 ContentStartColumn =
2911 Token->getContentStartColumn(LineIndex,
true);
2912 NewRemainingTokenColumns = Token->getRemainingLength(
2913 LineIndex, TailOffset +
Split.first +
Split.second,
2914 ContentStartColumn);
2920 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2925 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2926 <<
", " <<
Split.second <<
"\n");
2928 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2932 Penalty += NewBreakPenalty;
2934 RemainingTokenColumns = NewRemainingTokenColumns;
2935 BreakInserted =
true;
2936 NewBreakBefore =
true;
2940 if (LineIndex + 1 != EndIndex) {
2941 unsigned NextLineIndex = LineIndex + 1;
2942 if (NewBreakBefore) {
2961 ContentStartColumn += RemainingTokenColumns + 1;
2966 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2967 LLVM_DEBUG(llvm::dbgs()
2968 <<
" Size of reflown text: " << ContentStartColumn
2969 <<
"\n Potential reflow split: ");
2970 if (SplitBeforeNext.first != StringRef::npos) {
2971 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2972 << SplitBeforeNext.second <<
"\n");
2973 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2976 RemainingTokenColumns = Token->getRemainingLength(
2977 NextLineIndex, TailOffset, ContentStartColumn);
2979 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2980 LLVM_DEBUG(llvm::dbgs()
2981 <<
" Over limit after reflow, need: "
2982 << (ContentStartColumn + RemainingTokenColumns)
2983 <<
", space: " << ColumnLimit
2984 <<
", reflown prefix: " << ContentStartColumn
2985 <<
", offset in line: " << TailOffset <<
"\n");
2991 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2992 ContentStartColumn, CommentPragmasRegex);
2993 if (
Split.first == StringRef::npos) {
2994 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
3000 unsigned ToSplitColumns = Token->getRangeLength(
3001 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
3002 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
3003 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
3004 << (ContentStartColumn + ToSplitColumns)
3005 <<
", space: " << ColumnLimit);
3006 unsigned ExcessCharactersPenalty =
3007 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
3008 Style.PenaltyExcessCharacter;
3009 if (NewBreakPenalty < ExcessCharactersPenalty)
3015 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3023 ContentStartColumn =
3024 Token->getContentStartColumn(NextLineIndex,
false);
3025 RemainingTokenColumns = Token->getRemainingLength(
3026 NextLineIndex, TailOffset, ContentStartColumn);
3029 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3044 if (NewBreakBefore) {
3045 assert(Penalty >= NewBreakPenalty);
3046 Penalty -= NewBreakPenalty;
3049 Token->reflow(NextLineIndex, Whitespaces);
3055 Token->getSplitAfterLastLine(TailOffset);
3056 if (SplitAfterLastLine.first != StringRef::npos) {
3057 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3061 Penalty += Style.PenaltyExcessCharacter *
3062 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3065 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3068 ContentStartColumn =
3069 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3070 RemainingTokenColumns = Token->getRemainingLength(
3071 Token->getLineCount() - 1,
3072 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3073 ContentStartColumn);
3076 State.Column = ContentStartColumn + RemainingTokenColumns -
3077 Current.UnbreakableTailLength;
3079 if (BreakInserted) {
3081 Token->updateAfterBroken(Whitespaces);
3086 if (Current.isNot(TT_LineComment))
3087 for (ParenState &
Paren : State.Stack)
3088 Paren.BreakBeforeParameter =
true;
3090 if (Current.is(TT_BlockComment))
3091 State.NoContinuation =
true;
3093 State.Stack.back().LastSpace = StartColumn;
3096 Token->updateNextToken(State);
3098 return {Penalty, Exceeded};
3103 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3106bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3108 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3113 if (Current.
TokenText.starts_with(
"R\""))
3117 if (Current.getNextNonComment() &&
3118 Current.getNextNonComment()->isStringLiteral()) {
3121 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3123 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...