23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "format-indenter"
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
89 if (!
Tok.MatchingParen)
93 int MatchingStackIndex = Stack.size() - 1;
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].
Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
103 for (; End->
Next; End = End->
Next) {
106 if (!End->
Next->closesScope())
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
120 if (!
Tok.NextOperator)
122 return Tok.NextOperator->TotalLength -
Tok.TotalLength;
128 return Tok.isMemberAccess() &&
Tok.Previous &&
Tok.Previous->closesScope();
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
151 while (
Last->NextOperator)
153 return Last->OperatorIndex + 2;
158 const FormatStyle &Style) {
164 bool BreakBefore = Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
179 const auto OperatorBreakStyle =
180 Style.BreakBinaryOperations.getStyleForOperator(OpToken->
Tok.
getKind());
181 if (OperatorBreakStyle == FormatStyle::BBO_Never)
185 const unsigned MinChain =
186 Style.BreakBinaryOperations.getMinChainLengthForOperator(
192 const FormatStyle &Style) {
193 if (LessTok.
isNot(tok::less))
195 return Style.isTextProto() ||
196 (Style.Language == FormatStyle::LK_Proto &&
213 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
214 if (LParenPos == StringRef::npos)
216 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
219 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
222 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
231 FormatStyle::LanguageKind
Language) {
232 for (
const auto &Format : Style.RawStringFormats)
234 return StringRef(Format.CanonicalDelimiter);
239 const FormatStyle &CodeStyle) {
241 std::optional<FormatStyle> LanguageStyle =
243 if (!LanguageStyle) {
244 FormatStyle PredefinedStyle;
250 LanguageStyle = PredefinedStyle;
252 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;
260std::optional<FormatStyle>
268std::optional<FormatStyle>
270 StringRef EnclosingFunction)
const {
293 *
this = *
this + Spaces;
321 bool BinPackInconclusiveFunctions)
322 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
323 Whitespaces(Whitespaces), Encoding(Encoding),
324 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
325 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
328 unsigned FirstStartColumn,
333 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
334 State.Column = FirstStartColumn;
336 State.Column = FirstIndent;
340 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
346 State.NextToken =
Line->First;
347 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
350 State.NoContinuation =
false;
351 State.StartOfStringLiteral = 0;
352 State.NoLineBreak =
false;
353 State.StartOfLineLevel = 0;
354 State.LowestLevelOnLine = 0;
355 State.IgnoreStackForComparison =
false;
357 if (Style.isTextProto()) {
360 auto &CurrentState = State.Stack.back();
361 CurrentState.AvoidBinPacking =
true;
362 CurrentState.BreakBeforeParameter =
true;
363 CurrentState.AlignColons =
false;
367 moveStateToNextToken(State, DryRun,
false);
374 const auto &CurrentState = State.Stack.back();
376 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
377 Current.closesBlockOrBlockTypeList(Style))) {
385 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
394 State.LowestLevelOnLine < State.StartOfLineLevel &&
398 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
403 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
404 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
405 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
406 return Style.isCpp() &&
407 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
412 if (Current.
is(TT_FunctionDeclarationName)) {
413 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&
418 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
419 assert(State.Column >= State.FirstIndent);
420 if (State.Column - State.FirstIndent < 6)
428 Current.isBlockIndentedInitRBrace(Style)) {
429 return CurrentState.BreakBeforeClosingBrace;
434 if ((Style.BreakBeforeCloseBracketFunction ||
435 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
436 Style.BreakBeforeCloseBracketSwitch) &&
437 Current.
is(tok::r_paren)) {
438 return CurrentState.BreakBeforeClosingParen;
441 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
442 return CurrentState.BreakBeforeClosingAngle;
446 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
450 (!Style.BraceWrapping.BeforeLambdaBody ||
451 Current.
isNot(TT_LambdaLBrace)) &&
452 CurrentState.NoLineBreakInOperand) {
459 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
461 Previous.MatchingParen->Previous->MatchingParen &&
462 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
464 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
468 return !State.NoLineBreak && !CurrentState.NoLineBreak;
474 const auto &CurrentState = State.Stack.back();
475 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
476 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
481 (Current.
is(TT_InlineASMColon) &&
482 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
483 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
484 Style.ColumnLimit > 0)))) {
487 if (CurrentState.BreakBeforeClosingBrace &&
488 (Current.closesBlockOrBlockTypeList(Style) ||
490 Current.isBlockIndentedInitRBrace(Style)))) {
493 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
495 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
497 if (Style.Language == FormatStyle::LK_ObjC &&
498 Style.ObjCBreakBeforeNestedBlockParam &&
500 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
505 if (CurrentState.IsCSharpGenericTypeConstraint &&
506 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
510 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
511 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
517 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||
518 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
520 (!Style.BreakBeforeTernaryOperators &&
521 Previous.is(TT_ConditionalExpr))) &&
522 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
523 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
526 if (CurrentState.IsChainedConditional &&
527 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
528 Current.
is(tok::colon)) ||
529 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
534 (
Previous.is(TT_ArrayInitializerLSquare) &&
537 Style.ColumnLimit > 0 &&
543 const FormatToken &BreakConstructorInitializersToken =
544 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
547 if (Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterComma &&
548 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
549 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
551 CurrentState.BreakBeforeParameter) &&
552 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
557 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
558 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
561 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
562 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
563 (Style.ObjCBreakBeforeNestedBlockParam ||
564 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
568 unsigned NewLineColumn = getNewLineColumn(State).Total;
569 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
571 (State.Column > NewLineColumn ||
577 (CurrentState.CallContinuation != 0 ||
578 CurrentState.BreakBeforeParameter) &&
584 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
585 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
591 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
596 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
599 if (Style.AlwaysBreakBeforeMultilineStrings &&
600 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
602 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
603 Keywords.kw_dollar) &&
604 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
605 nextIsMultilineString(State)) {
613 const auto PreviousPrecedence =
Previous.getPrecedence();
615 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
616 const bool LHSIsBinaryExpr =
629 const bool IsComparison =
634 Previous.Previous->isNot(TT_BinaryOperator);
640 CurrentState.BreakBeforeParameter) {
645 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
646 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
650 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
655 if (
Previous.ClosesTemplateDeclaration) {
656 if (Current.
is(tok::kw_concept)) {
657 switch (Style.BreakBeforeConceptDeclarations) {
658 case FormatStyle::BBCDS_Allowed:
660 case FormatStyle::BBCDS_Always:
662 case FormatStyle::BBCDS_Never:
666 if (Current.
is(TT_RequiresClause)) {
667 switch (Style.RequiresClausePosition) {
668 case FormatStyle::RCPS_SingleLine:
669 case FormatStyle::RCPS_WithPreceding:
675 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
676 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
679 if (
Previous.is(TT_FunctionAnnotationRParen) &&
683 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
684 Current.
isNot(TT_LeadingJavaAnnotation)) {
689 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
693 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
695 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
699 if (Current.
is(TT_FunctionDeclarationName) &&
700 !State.Line->ReturnTypeWrapped &&
702 (!Style.isCSharp() ||
703 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
706 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
707 CurrentState.BreakBeforeParameter) {
709 if (
Tok->is(TT_LineComment))
711 if (
Tok->is(TT_TemplateCloser)) {
716 if (
Tok->FirstAfterPPLine)
728 Current.
isNoneOf(tok::r_brace, tok::comment)) {
732 if (Current.
is(tok::lessless) &&
735 Previous.TokenText ==
"\'\\n\'")))) {
742 if (State.NoContinuation)
750 unsigned ExtraSpaces) {
752 assert(State.NextToken->Previous);
755 assert(!State.Stack.empty());
756 State.NoContinuation =
false;
758 if (Current.
is(TT_ImplicitStringLiteral) &&
759 (!
Previous.Tok.getIdentifierInfo() ||
760 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
761 tok::pp_not_keyword)) {
767 State.Column = EndColumn;
769 unsigned StartColumn =
771 assert(EndColumn >= StartColumn);
772 State.Column += EndColumn - StartColumn;
774 moveStateToNextToken(State, DryRun,
false);
778 unsigned Penalty = 0;
780 Penalty = addTokenOnNewLine(State, DryRun);
782 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
784 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
787void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
788 unsigned ExtraSpaces) {
790 assert(State.NextToken->Previous);
792 auto &CurrentState = State.Stack.back();
799 auto DisallowLineBreaks = [&] {
800 if (!Style.isCpp() ||
801 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
809 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
812 const auto *Prev = Current.getPreviousNonComment();
813 if (!Prev || Prev->isNot(tok::l_paren))
816 if (Prev->BlockParameterCount == 0)
820 if (Prev->BlockParameterCount > 1)
827 const auto *Comma = Prev->
Role->lastComma();
831 const auto *
Next = Comma->getNextNonComment();
832 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
835 if (DisallowLineBreaks())
836 State.NoLineBreak =
true;
838 if (Current.
is(tok::equal) &&
839 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
840 CurrentState.VariablePos == 0 &&
842 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
843 CurrentState.VariablePos = State.Column;
846 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
847 CurrentState.VariablePos -=
Tok->ColumnWidth;
848 if (
Tok->SpacesRequiredBefore != 0)
852 if (
Previous.PartOfMultiVariableDeclStmt)
853 CurrentState.LastSpace = CurrentState.VariablePos;
859 int PPColumnCorrection = 0;
863 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
870 if (Style.UseTab != FormatStyle::UT_Never)
871 PPColumnCorrection = -1;
872 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
878 const bool ContinuePPDirective =
880 Whitespaces.replaceWhitespace(Current, 0, Spaces,
881 State.
Column + Spaces + PPColumnCorrection,
882 false, ContinuePPDirective);
887 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
888 Current.
is(TT_InheritanceColon)) {
889 CurrentState.NoLineBreak =
true;
891 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
893 CurrentState.NoLineBreak =
true;
896 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
898 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
899 CurrentState.Indent.Total);
902 CurrentState.AlignColons =
false;
906 CurrentState.ColonPos = FirstColonPos;
914 auto IsStartOfBracedList = [&]() {
916 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
918 if (IsStartOfBracedList())
919 return Style.BreakAfterOpenBracketBracedList;
920 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
924 if (
Tok.Previous->isIf())
925 return Style.BreakAfterOpenBracketIf;
926 if (
Tok.Previous->isLoop(Style))
927 return Style.BreakAfterOpenBracketLoop;
928 if (
Tok.Previous->is(tok::kw_switch))
929 return Style.BreakAfterOpenBracketSwitch;
930 if (Style.BreakAfterOpenBracketFunction) {
931 return !
Tok.Previous->is(TT_CastRParen) &&
932 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
937 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
938 Tok.Previous->is(tok::identifier);
940 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
941 if (!Style.isJavaScript())
943 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
944 if (Prev->is(TT_TemplateString) && Prev->opensScope())
946 if (Prev->opensScope() && !NestBlocks)
948 if (Prev->is(TT_TemplateString) && Prev->closesScope())
954 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
955 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
957 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
964 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
966 if (
Tok.is(TT_UnaryOperator) ||
967 (Style.isJavaScript() &&
968 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
971 const auto *
Previous = TokAfterLParen.Previous;
975 Previous->Previous->is(tok::kw_switch))) {
978 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
979 TT_LambdaDefinitionLParen) &&
983 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
986 return !
Next ||
Next->isMemberAccess() ||
987 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
990 State.
Column > getNewLineColumn(State).Total &&
1001 !StartsSimpleOneArgList(Current)) {
1002 CurrentState.NoLineBreak =
true;
1006 CurrentState.NoLineBreak =
true;
1012 if (Style.AlignAfterOpenBracket &&
1013 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1014 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1015 TT_TableGenDAGArgOpener,
1016 TT_TableGenDAGArgOpenerToBreak) &&
1018 (Current.
isNot(TT_LineComment) ||
1020 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||
1022 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,
1024 Previous.is(TT_VerilogMultiLineListLParen)) &&
1025 !IsInTemplateString(Current,
false)) {
1026 CurrentState.Indent = State.
Column + Spaces;
1027 CurrentState.IsAligned =
true;
1030 CurrentState.NoLineBreak =
true;
1032 CurrentState.NoLineBreak =
true;
1035 State.
Column > getNewLineColumn(State).Total) {
1036 CurrentState.ContainsUnwrappedBuilder =
true;
1039 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1040 CurrentState.NoLineBreak =
true;
1041 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1050 CurrentState.NoLineBreak =
true;
1057 const FormatToken *P = Current.getPreviousNonComment();
1058 if (Current.
isNot(tok::comment) && P &&
1059 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1060 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1061 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1065 bool BreakBeforeOperator =
1066 P->MustBreakBefore || P->is(tok::lessless) ||
1067 (P->is(TT_BinaryOperator) &&
1068 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1069 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1073 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1074 P->isNot(TT_ConditionalExpr);
1075 if ((!BreakBeforeOperator &&
1077 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1078 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1079 CurrentState.NoLineBreakInOperand =
true;
1084 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1089 CurrentState.LastSpace = State.
Column;
1090 CurrentState.NestedBlockIndent = State.
Column;
1091 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1093 Previous.isNot(TT_OverloadedOperator)) ||
1095 CurrentState.LastSpace = State.
Column;
1096 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1098 Style.BreakConstructorInitializers ==
1099 FormatStyle::BCIS_AfterColon) {
1100 CurrentState.Indent = State.
Column;
1101 CurrentState.LastSpace = State.
Column;
1102 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1103 CurrentState.LastSpace = State.
Column;
1104 }
else if (
Previous.is(TT_BinaryOperator) &&
1111 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1112 CurrentState.LastSpace = State.
Column;
1113 }
else if (
Previous.is(TT_InheritanceColon)) {
1114 CurrentState.Indent = State.
Column;
1115 CurrentState.LastSpace = State.
Column;
1116 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1117 CurrentState.ColonPos = State.
Column;
1118 }
else if (
Previous.opensScope()) {
1126 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1127 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1128 CurrentState.LastSpace = State.
Column;
1134unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1137 assert(State.NextToken->Previous);
1139 auto &CurrentState = State.Stack.back();
1143 unsigned Penalty = 0;
1145 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1147 if (!NextNonComment)
1148 NextNonComment = &Current;
1151 if (!CurrentState.ContainsLineBreak)
1153 CurrentState.ContainsLineBreak =
true;
1155 Penalty += State.NextToken->SplitPenalty;
1160 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1161 (State.Column <= Style.ColumnLimit / 3 ||
1162 CurrentState.BreakBeforeParameter)) {
1163 Penalty += Style.PenaltyBreakFirstLessLess;
1166 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1167 State.Column = TotalColumn;
1181 if (State.Column > State.FirstIndent) {
1183 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1196 if (Current.isNot(TT_LambdaArrow) &&
1197 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1198 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1199 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1200 CurrentState.NestedBlockIndent = State.Column;
1203 if (NextNonComment->isMemberAccess()) {
1204 if (CurrentState.CallContinuation == 0)
1205 CurrentState.CallContinuation = State.Column;
1206 }
else if (NextNonComment->is(TT_SelectorName)) {
1207 if (!CurrentState.ObjCSelectorNameFound) {
1208 if (NextNonComment->LongestObjCSelectorName == 0) {
1209 CurrentState.AlignColons =
false;
1211 CurrentState.ColonPos =
1213 ? std::max(CurrentState.Indent.Total,
1214 State.FirstIndent + Style.ContinuationIndentWidth)
1215 : CurrentState.
Indent.Total) +
1219 }
else if (CurrentState.AlignColons &&
1220 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1221 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1223 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1224 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1234 if (State.Stack.size() > 1) {
1235 State.Stack[State.Stack.size() - 2].LastSpace =
1236 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1237 Style.ContinuationIndentWidth;
1241 if ((PreviousNonComment &&
1242 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1243 !CurrentState.AvoidBinPacking) ||
1245 CurrentState.BreakBeforeParameter =
false;
1247 if (PreviousNonComment &&
1248 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1249 PreviousNonComment->ClosesRequiresClause) &&
1250 Current.NestingLevel == 0) {
1251 CurrentState.BreakBeforeParameter =
false;
1253 if (NextNonComment->is(tok::question) ||
1254 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1255 CurrentState.BreakBeforeParameter =
true;
1257 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1258 CurrentState.BreakBeforeParameter =
false;
1262 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1265 !Current.MatchingParen->Children.empty()) {
1273 const bool ContinuePPDirective = State.Line->InPPDirective &&
1275 Current.isNot(TT_LineComment);
1276 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1277 CurrentState.IsAligned, ContinuePPDirective,
1278 IndentedFromColumn);
1281 if (!Current.isTrailingComment())
1282 CurrentState.LastSpace = State.Column;
1283 if (Current.is(tok::lessless)) {
1287 CurrentState.LastSpace += 3;
1290 State.StartOfLineLevel = Current.NestingLevel;
1291 State.LowestLevelOnLine = Current.NestingLevel;
1295 bool NestedBlockSpecialCase =
1296 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1297 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1298 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1299 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1301 NestedBlockSpecialCase =
1302 NestedBlockSpecialCase ||
1303 (Current.MatchingParen &&
1304 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1305 if (!NestedBlockSpecialCase) {
1306 auto ParentLevelIt = std::next(State.Stack.rbegin());
1307 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1308 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1323 auto FindCurrentLevel = [&](
const auto &It) {
1324 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1325 return PState.Tok != nullptr;
1328 auto MaybeIncrement = [&](
const auto &It) {
1329 return It != State.Stack.rend() ? std::next(It) : It;
1331 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1332 auto LevelContainingLambdaIt =
1333 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1334 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1336 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1337 I->BreakBeforeParameter =
true;
1340 if (PreviousNonComment &&
1341 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1342 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1343 !PreviousNonComment->ClosesRequiresClause) ||
1344 Current.NestingLevel != 0) &&
1345 PreviousNonComment->isNoneOf(
1346 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1347 TT_LeadingJavaAnnotation) &&
1348 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1351 (!Style.BraceWrapping.BeforeLambdaBody ||
1352 Current.isNot(TT_LambdaLBrace))) {
1353 CurrentState.BreakBeforeParameter =
true;
1358 if (PreviousNonComment &&
1359 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1361 CurrentState.BreakBeforeClosingBrace =
true;
1364 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1365 if (
auto Previous = PreviousNonComment->Previous) {
1367 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1368 }
else if (
Previous->isLoop(Style)) {
1369 CurrentState.BreakBeforeClosingParen =
1370 Style.BreakBeforeCloseBracketLoop;
1371 }
else if (
Previous->is(tok::kw_switch)) {
1372 CurrentState.BreakBeforeClosingParen =
1373 Style.BreakBeforeCloseBracketSwitch;
1375 CurrentState.BreakBeforeClosingParen =
1376 Style.BreakBeforeCloseBracketFunction;
1381 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1382 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1384 if (CurrentState.AvoidBinPacking) {
1389 bool PreviousIsBreakingCtorInitializerColon =
1390 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1391 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1392 bool AllowAllConstructorInitializersOnNextLine =
1393 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1394 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1395 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1396 !PreviousIsBreakingCtorInitializerColon) ||
1397 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1398 State.Line->MustBeDeclaration) ||
1399 (!Style.AllowAllArgumentsOnNextLine &&
1400 !State.Line->MustBeDeclaration) ||
1401 (!AllowAllConstructorInitializersOnNextLine &&
1402 PreviousIsBreakingCtorInitializerColon) ||
1404 CurrentState.BreakBeforeParameter =
true;
1410 if (PreviousIsBreakingCtorInitializerColon &&
1411 AllowAllConstructorInitializersOnNextLine) {
1412 CurrentState.BreakBeforeParameter =
false;
1417 CurrentState.BreakBeforeParameter =
true;
1423ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1424 if (!State.NextToken || !State.NextToken->Previous)
1428 const auto &CurrentState = State.Stack.back();
1430 if (CurrentState.IsCSharpGenericTypeConstraint &&
1431 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1432 return CurrentState.ColonPos + 2;
1437 const auto ContinuationIndent =
1438 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1439 CurrentState.Indent) +
1440 Style.ContinuationIndentWidth;
1441 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1443 if (!NextNonComment)
1444 NextNonComment = &Current;
1447 if (Style.isJava() &&
1448 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1449 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1450 CurrentState.Indent + Style.ContinuationIndentWidth);
1455 if (Style.isVerilog() && PreviousNonComment &&
1456 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1457 return State.FirstIndent;
1460 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1461 State.Line->First->is(tok::kw_enum)) {
1462 return IndentationAndAlignment(Style.IndentWidth *
1463 State.Line->First->IndentLevel) +
1467 if (Style.BraceWrapping.BeforeLambdaBody &&
1468 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1469 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1470 ? CurrentState.Indent
1471 : State.FirstIndent;
1472 return From + Style.IndentWidth;
1475 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1476 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1477 if (Current.NestingLevel == 0 ||
1478 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1479 State.NextToken->is(TT_LambdaLBrace))) {
1480 return State.FirstIndent;
1482 return CurrentState.Indent;
1484 if (Current.is(TT_LambdaArrow) &&
1485 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1486 tok::kw_consteval, tok::kw_static,
1487 TT_AttributeRSquare)) {
1488 return ContinuationIndent;
1490 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1491 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1492 State.Stack.size() > 1) {
1493 if (Current.closesBlockOrBlockTypeList(Style))
1494 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1495 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1496 return State.Stack[State.Stack.size() - 2].LastSpace;
1497 return State.FirstIndent;
1514 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1516 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1517 return State.Stack[State.Stack.size() - 2].LastSpace;
1521 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1522 State.Stack.size() > 1) {
1523 return State.Stack[State.Stack.size() - 2].LastSpace;
1525 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1526 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1527 State.Stack.size() > 1) {
1528 return State.Stack[State.Stack.size() - 2].LastSpace;
1530 if ((Style.BreakBeforeCloseBracketFunction ||
1531 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1532 Style.BreakBeforeCloseBracketSwitch) &&
1533 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1534 return State.Stack[State.Stack.size() - 2].LastSpace;
1536 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1537 State.Stack.size() > 1) {
1538 return State.Stack[State.Stack.size() - 2].LastSpace;
1540 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1541 return State.Stack[State.Stack.size() - 2].LastSpace;
1549 if (Current.is(tok::identifier) && Current.Next &&
1550 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1551 (Current.Next->is(TT_DictLiteral) ||
1552 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1553 return CurrentState.Indent;
1555 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1556 State.StartOfStringLiteral != 0) {
1557 return State.StartOfStringLiteral - 1;
1559 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1560 return State.StartOfStringLiteral;
1561 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1562 return CurrentState.FirstLessLess;
1563 if (NextNonComment->isMemberAccess()) {
1564 if (CurrentState.CallContinuation == 0)
1565 return ContinuationIndent;
1566 return CurrentState.CallContinuation;
1568 if (CurrentState.QuestionColumn != 0 &&
1569 ((NextNonComment->is(tok::colon) &&
1570 NextNonComment->is(TT_ConditionalExpr)) ||
1571 Previous.is(TT_ConditionalExpr))) {
1572 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1573 !NextNonComment->Next->FakeLParens.empty() &&
1575 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1577 !CurrentState.IsWrappedConditional) {
1582 unsigned Indent = CurrentState.Indent.Total;
1583 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1584 Indent -= Style.ContinuationIndentWidth;
1585 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1589 return CurrentState.QuestionColumn;
1591 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1592 return CurrentState.VariablePos;
1593 if (Current.is(TT_RequiresClause)) {
1594 if (Style.IndentRequiresClause)
1595 return CurrentState.Indent + Style.IndentWidth;
1596 switch (Style.RequiresClausePosition) {
1597 case FormatStyle::RCPS_OwnLine:
1598 case FormatStyle::RCPS_WithFollowing:
1599 case FormatStyle::RCPS_OwnLineWithBrace:
1600 return CurrentState.Indent;
1605 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1606 TT_InheritanceComma)) {
1607 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1609 if ((PreviousNonComment &&
1610 (PreviousNonComment->ClosesTemplateDeclaration ||
1611 PreviousNonComment->ClosesRequiresClause ||
1612 (PreviousNonComment->is(TT_AttributeMacro) &&
1613 Current.isNot(tok::l_paren) &&
1614 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1615 TT_PointerOrReference)) ||
1616 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1617 TT_FunctionAnnotationRParen,
1619 TT_LeadingJavaAnnotation))) ||
1620 (!Style.IndentWrappedFunctionNames &&
1621 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1622 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1623 CurrentState.Indent);
1625 if (NextNonComment->is(TT_SelectorName)) {
1626 if (!CurrentState.ObjCSelectorNameFound) {
1627 auto MinIndent = CurrentState.Indent;
1630 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1631 Style.ContinuationIndentWidth);
1642 return MinIndent.addPadding(
1643 std::max(NextNonComment->LongestObjCSelectorName,
1644 NextNonComment->ColumnWidth) -
1645 NextNonComment->ColumnWidth);
1647 if (!CurrentState.AlignColons)
1648 return CurrentState.Indent;
1649 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1650 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1651 return CurrentState.Indent;
1653 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1654 return CurrentState.ColonPos;
1655 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1656 if (CurrentState.StartOfArraySubscripts != 0) {
1657 return CurrentState.StartOfArraySubscripts;
1658 }
else if (Style.isCSharp()) {
1660 return CurrentState.Indent;
1662 return ContinuationIndent;
1667 if (State.Line->InPragmaDirective) {
1668 FormatToken *PragmaType = State.Line->First->Next->Next;
1669 if (PragmaType && PragmaType->TokenText ==
"omp")
1670 return CurrentState.Indent + Style.ContinuationIndentWidth;
1675 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1676 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1677 return CurrentState.Indent;
1680 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1681 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1682 return ContinuationIndent;
1684 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1685 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1686 return ContinuationIndent;
1688 if (NextNonComment->is(TT_CtorInitializerComma))
1689 return CurrentState.Indent;
1690 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1691 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1692 return CurrentState.Indent;
1694 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1695 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1696 return CurrentState.Indent;
1699 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1700 !Current.isBinaryOperator() &&
1701 Current.isNoneOf(tok::colon, tok::comment)) {
1702 return ContinuationIndent;
1704 if (Current.is(TT_ProtoExtensionLSquare))
1705 return CurrentState.Indent;
1706 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1707 return CurrentState.Indent - Current.Tok.getLength() -
1708 Current.SpacesRequiredBefore;
1710 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1711 CurrentState.UnindentOperator) {
1712 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1713 NextNonComment->SpacesRequiredBefore;
1715 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1716 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1719 return CurrentState.Indent + Style.ContinuationIndentWidth;
1721 return CurrentState.Indent;
1726 const FormatStyle &Style) {
1733 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1736unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1737 bool DryRun,
bool Newline) {
1738 assert(State.Stack.size());
1740 auto &CurrentState = State.Stack.back();
1742 if (Current.is(TT_CSharpGenericTypeConstraint))
1743 CurrentState.IsCSharpGenericTypeConstraint =
true;
1744 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1745 CurrentState.NoLineBreakInOperand =
false;
1746 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1747 CurrentState.AvoidBinPacking =
true;
1748 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1749 if (CurrentState.FirstLessLess == 0)
1750 CurrentState.FirstLessLess = State.Column;
1752 CurrentState.LastOperatorWrapped = Newline;
1754 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1755 CurrentState.LastOperatorWrapped = Newline;
1756 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1757 Current.Previous->isNot(TT_ConditionalExpr)) {
1758 CurrentState.LastOperatorWrapped = Newline;
1760 if (Current.is(TT_ArraySubscriptLSquare) &&
1761 CurrentState.StartOfArraySubscripts == 0) {
1762 CurrentState.StartOfArraySubscripts = State.Column;
1766 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1768 if (
Tok.MustBreakBefore)
1772 return Next &&
Next->MustBreakBefore;
1774 if (IsWrappedConditional(Current))
1775 CurrentState.IsWrappedConditional =
true;
1776 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1777 CurrentState.QuestionColumn = State.Column;
1778 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1783 CurrentState.QuestionColumn = State.Column;
1785 if (!Current.opensScope() && !Current.closesScope() &&
1786 Current.isNot(TT_PointerOrReference)) {
1787 State.LowestLevelOnLine =
1788 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1790 if (Current.isMemberAccess())
1791 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1792 if (Current.is(TT_SelectorName))
1793 CurrentState.ObjCSelectorNameFound =
true;
1794 if (Current.is(TT_CtorInitializerColon) &&
1795 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1801 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1802 FormatStyle::BCIS_BeforeComma
1805 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1806 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1807 CurrentState.AvoidBinPacking =
true;
1808 CurrentState.BreakBeforeParameter =
1809 Style.ColumnLimit > 0 &&
1810 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1811 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1813 CurrentState.BreakBeforeParameter =
false;
1816 if (Current.is(TT_CtorInitializerColon) &&
1817 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1818 CurrentState.Indent =
1819 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1820 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1821 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1822 CurrentState.AvoidBinPacking =
true;
1824 CurrentState.BreakBeforeParameter =
false;
1826 if (Current.is(TT_InheritanceColon)) {
1827 CurrentState.Indent =
1828 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1830 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1831 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1832 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1833 CurrentState.LastSpace = State.Column;
1834 if (Current.is(TT_RequiresExpression) &&
1835 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1836 CurrentState.NestedBlockIndent = State.Column;
1848 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1850 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1851 !CurrentState.HasMultipleNestedBlocks) {
1852 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1853 for (ParenState &PState : llvm::drop_end(State.Stack))
1854 PState.NoLineBreak =
true;
1855 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1857 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1858 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1859 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1860 TT_CtorInitializerColon)))) {
1861 CurrentState.NestedBlockInlined =
1865 moveStatePastFakeLParens(State, Newline);
1866 moveStatePastScopeCloser(State);
1869 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1870 !State.Stack.back().NoLineBreakInOperand;
1871 moveStatePastScopeOpener(State, Newline);
1872 moveStatePastFakeRParens(State);
1874 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1875 State.StartOfStringLiteral = State.Column + 1;
1876 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1877 State.StartOfStringLiteral = State.Column + 1;
1878 }
else if (Current.is(TT_TableGenMultiLineString) &&
1879 State.StartOfStringLiteral == 0) {
1880 State.StartOfStringLiteral = State.Column + 1;
1881 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1882 State.StartOfStringLiteral = State.Column;
1883 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1884 !Current.isStringLiteral()) {
1885 State.StartOfStringLiteral = 0;
1888 State.Column += Current.ColumnWidth;
1889 State.NextToken = State.NextToken->Next;
1894 if (Style.isVerilog() && State.NextToken &&
1895 State.NextToken->MustBreakBefore &&
1896 Keywords.isVerilogEndOfLabel(Current)) {
1897 State.FirstIndent += Style.IndentWidth;
1898 CurrentState.Indent = State.FirstIndent;
1902 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1905 Current.Role->formatFromToken(State,
this, DryRun);
1912 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1917void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1920 if (Current.FakeLParens.empty())
1928 bool SkipFirstExtraIndent =
1931 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1933 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1935 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1936 const auto &CurrentState = State.Stack.back();
1937 ParenState NewParenState = CurrentState;
1938 NewParenState.Tok =
nullptr;
1939 NewParenState.ContainsLineBreak =
false;
1940 NewParenState.LastOperatorWrapped =
true;
1941 NewParenState.IsChainedConditional =
false;
1942 NewParenState.IsWrappedConditional =
false;
1943 NewParenState.UnindentOperator =
false;
1944 NewParenState.NoLineBreak =
1945 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1949 NewParenState.AvoidBinPacking =
false;
1954 if (!Current.isTrailingComment() &&
1955 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1958 (!Style.isJava() && PrecedenceLevel > 0)) &&
1959 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1960 Current.NestingLevel == 0) &&
1961 (!Style.isTableGen() ||
1963 TT_TableGenDAGArgListCommaToBreak)))) {
1964 NewParenState.Indent =
1965 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1966 IndentationAndAlignment(CurrentState.LastSpace)});
1973 State.Stack.size() > 1) {
1974 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1975 Style.ContinuationIndentWidth;
1985 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1986 NewParenState.UnindentOperator =
true;
1988 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1989 NewParenState.IsAligned =
true;
1999 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2001 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2002 NewParenState.StartOfFunctionCall = State.Column;
2012 &PrecedenceLevel == &Current.FakeLParens.back() &&
2013 !CurrentState.IsWrappedConditional) {
2014 NewParenState.IsChainedConditional =
true;
2015 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2018 !Current.isTrailingComment())) {
2019 NewParenState.Indent += Style.ContinuationIndentWidth;
2022 NewParenState.BreakBeforeParameter =
false;
2023 State.Stack.push_back(NewParenState);
2024 SkipFirstExtraIndent =
false;
2028void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2029 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2030 unsigned VariablePos = State.Stack.back().VariablePos;
2031 if (State.Stack.size() == 1) {
2035 State.Stack.pop_back();
2036 State.Stack.back().VariablePos = VariablePos;
2039 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2042 State.Stack.back().LastSpace -= Style.IndentWidth;
2046void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2049 if (!Current.opensScope())
2052 const auto &CurrentState = State.Stack.back();
2055 if (Current.isOneOf(tok::less, tok::l_paren) &&
2056 CurrentState.IsCSharpGenericTypeConstraint) {
2060 if (Current.MatchingParen && Current.is(
BK_Block)) {
2061 moveStateToNewBlock(State, Newline);
2068 const auto *Prev =
Tok->getPreviousNonComment();
2071 return Prev->is(tok::comma);
2072 }(Current.MatchingParen);
2074 IndentationAndAlignment NewIndent = 0;
2075 unsigned LastSpace = CurrentState.LastSpace;
2076 bool AvoidBinPacking;
2077 bool BreakBeforeParameter =
false;
2078 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2079 CurrentState.NestedBlockIndent);
2080 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2082 if (Current.opensBlockOrBlockTypeList(Style)) {
2083 NewIndent = Style.IndentWidth +
2084 std::min(State.Column, CurrentState.NestedBlockIndent);
2085 }
else if (Current.is(tok::l_brace)) {
2086 const auto Width = Style.BracedInitializerIndentWidth;
2087 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2088 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2090 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2092 const FormatToken *NextNonComment = Current.getNextNonComment();
2093 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2094 Style.isProto() || !Style.BinPackArguments ||
2095 (NextNonComment && NextNonComment->isOneOf(
2096 TT_DesignatedInitializerPeriod,
2097 TT_DesignatedInitializerLSquare));
2098 BreakBeforeParameter = EndsInComma;
2099 if (Current.ParameterCount > 1)
2100 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2102 NewIndent = IndentationAndAlignment(std::max(
2103 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2104 Style.ContinuationIndentWidth;
2106 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2107 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2113 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2114 NewIndent = State.Column +
Next->TokenText.size() + 2;
2121 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2122 NewIndent = std::max(NewIndent, CurrentState.Indent);
2123 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2129 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2130 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2131 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2133 bool BinPackDeclaration =
2135 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2138 bool GenericSelection =
2139 Current.getPreviousNonComment() &&
2140 Current.getPreviousNonComment()->is(tok::kw__Generic);
2143 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2144 (Style.isJavaScript() && EndsInComma) ||
2145 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2146 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2147 (Style.ExperimentalAutoDetectBinPacking &&
2151 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2152 Style.ObjCBreakBeforeNestedBlockParam) {
2153 if (Style.ColumnLimit) {
2158 BreakBeforeParameter =
true;
2164 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2165 if (
Tok->MustBreakBefore ||
2166 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2167 BreakBeforeParameter =
true;
2174 if (Style.isJavaScript() && EndsInComma)
2175 BreakBeforeParameter =
true;
2181 Current.Children.empty() &&
2182 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2183 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2184 (Current.is(TT_TemplateOpener) &&
2185 CurrentState.ContainsUnwrappedBuilder));
2186 State.Stack.push_back(
2187 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2188 auto &NewState = State.Stack.back();
2189 NewState.NestedBlockIndent = NestedBlockIndent;
2190 NewState.BreakBeforeParameter = BreakBeforeParameter;
2191 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2193 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2194 Current.is(tok::l_paren)) {
2198 if (next->is(TT_LambdaLSquare)) {
2199 NewState.HasMultipleNestedBlocks =
true;
2206 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2208 Current.Previous->is(tok::at);
2211void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2213 if (!Current.closesScope())
2218 if (State.Stack.size() > 1 &&
2219 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2220 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2221 State.NextToken->is(TT_TemplateCloser) ||
2222 State.NextToken->is(TT_TableGenListCloser) ||
2223 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2224 State.Stack.pop_back();
2227 auto &CurrentState = State.Stack.back();
2239 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2240 Current.MatchingParen->Previous) {
2241 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2242 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2243 CurrentScopeOpener.MatchingParen) {
2244 int NecessarySpaceInLine =
2246 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2247 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2248 Style.ColumnLimit) {
2249 CurrentState.BreakBeforeParameter =
false;
2254 if (Current.is(tok::r_square)) {
2256 const FormatToken *NextNonComment = Current.getNextNonComment();
2257 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2258 CurrentState.StartOfArraySubscripts = 0;
2262void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2263 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2264 State.NextToken->is(TT_LambdaLBrace) &&
2265 !State.Line->MightBeFunctionDecl) {
2266 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2267 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2269 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2271 unsigned NewIndent =
2272 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2273 ? Style.ObjCBlockIndentWidth
2274 : Style.IndentWidth);
2281 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2282 State.NextToken->is(TT_LambdaLBrace);
2284 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2285 State.Stack.back().LastSpace,
2286 true, NoLineBreak));
2287 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2288 State.Stack.back().BreakBeforeParameter =
true;
2294 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2295 if (LastNewlinePos == StringRef::npos) {
2296 return StartColumn +
2304unsigned ContinuationIndenter::reformatRawStringLiteral(
2306 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2307 unsigned StartColumn = State.Column - Current.ColumnWidth;
2309 StringRef NewDelimiter =
2311 if (NewDelimiter.empty())
2312 NewDelimiter = OldDelimiter;
2315 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2316 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2319 std::string RawText = std::string(
2320 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2321 if (NewDelimiter != OldDelimiter) {
2324 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2325 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2326 NewDelimiter = OldDelimiter;
2329 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2330 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2333 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2344 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2366 unsigned CurrentIndent =
2367 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2368 ? State.Stack.back().NestedBlockIndent
2369 : State.Stack.back().Indent.Total;
2370 unsigned NextStartColumn = ContentStartsOnNewline
2371 ? CurrentIndent + Style.IndentWidth
2382 unsigned LastStartColumn =
2383 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2386 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2387 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2392 return addMultilineToken(Current, State);
2394 if (NewDelimiter != OldDelimiter) {
2397 SourceLocation PrefixDelimiterStart =
2398 Current.Tok.getLocation().getLocWithOffset(2);
2399 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2400 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2403 <<
"Failed to update the prefix delimiter of a raw string: "
2404 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2408 SourceLocation SuffixDelimiterStart =
2409 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2410 1 - OldDelimiter.size());
2411 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2412 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2415 <<
"Failed to update the suffix delimiter of a raw string: "
2416 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2419 SourceLocation OriginLoc =
2420 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2421 for (
const tooling::Replacement &Fix : Fixes.first) {
2422 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2423 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2424 Fix.getLength(), Fix.getReplacementText()));
2426 llvm::errs() <<
"Failed to reformat raw string: "
2427 << llvm::toString(std::move(Err)) <<
"\n";
2432 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2433 State.Column = RawLastLineEndColumn + NewSuffixSize;
2437 unsigned PrefixExcessCharacters =
2438 StartColumn + NewPrefixSize > Style.ColumnLimit
2439 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2442 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2445 for (ParenState &
Paren : State.Stack)
2446 Paren.BreakBeforeParameter =
true;
2448 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2451unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2454 for (ParenState &
Paren : State.Stack)
2455 Paren.BreakBeforeParameter =
true;
2457 unsigned ColumnsUsed = State.Column;
2460 State.Column = Current.LastLineColumnWidth;
2463 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2467unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2469 bool AllowBreak,
bool Newline) {
2470 unsigned Penalty = 0;
2473 auto RawStringStyle = getRawStringStyle(Current, State);
2474 if (RawStringStyle && !Current.Finalized) {
2475 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2477 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2480 Penalty = addMultilineToken(Current, State);
2483 LineState OriginalState = State;
2487 bool Strict =
false;
2490 bool Exceeded =
false;
2491 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2492 Current, State, AllowBreak,
true, Strict);
2496 LineState StrictState = OriginalState;
2497 unsigned StrictPenalty =
2498 breakProtrudingToken(Current, StrictState, AllowBreak,
2501 Strict = StrictPenalty <= Penalty;
2503 Penalty = StrictPenalty;
2504 State = std::move(StrictState);
2510 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2515 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2516 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2525 auto Tok = Current.getPreviousNonComment();
2526 if (!
Tok ||
Tok->isNot(tok::l_paren))
2528 Tok =
Tok->getPreviousNonComment();
2531 if (
Tok->is(TT_TemplateCloser)) {
2532 Tok =
Tok->MatchingParen;
2534 Tok =
Tok->getPreviousNonComment();
2536 if (!
Tok ||
Tok->isNot(tok::identifier))
2538 return Tok->TokenText;
2541std::optional<FormatStyle>
2542ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2543 const LineState &State) {
2544 if (!Current.isStringLiteral())
2545 return std::nullopt;
2548 return std::nullopt;
2550 if (!RawStringStyle && Delimiter->empty()) {
2554 if (!RawStringStyle)
2555 return std::nullopt;
2557 return RawStringStyle;
2560std::unique_ptr<BreakableToken>
2561ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2563 unsigned StartColumn = State.Column - Current.ColumnWidth;
2564 if (Current.isStringLiteral()) {
2567 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2581 if (Current.IsUnterminatedLiteral)
2585 if (State.Stack.back().IsInsideObjCArrayLiteral)
2592 if (Style.isVerilog() && Current.Previous &&
2593 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2596 StringRef
Text = Current.TokenText;
2606 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2609 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2610 Text.ends_with(
"'")) {
2612 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2613 Text.ends_with(
"\"")) {
2615 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2620 return std::make_unique<BreakableStringLiteralUsingOperators>(
2621 Current, QuoteStyle,
2632 if ((
Text.ends_with(Postfix =
"\"") &&
2633 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2634 Text.starts_with(Prefix =
"u\"") ||
2635 Text.starts_with(Prefix =
"U\"") ||
2636 Text.starts_with(Prefix =
"u8\"") ||
2637 Text.starts_with(Prefix =
"L\""))) ||
2638 (
Text.starts_with(Prefix =
"_T(\"") &&
2639 Text.ends_with(Postfix =
"\")"))) {
2640 return std::make_unique<BreakableStringLiteral>(
2642 State.Line->InPPDirective, Encoding, Style);
2644 }
else if (Current.is(TT_BlockComment)) {
2645 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2652 return std::make_unique<BreakableBlockComment>(
2653 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2654 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2655 }
else if (Current.is(TT_LineComment) &&
2656 (!Current.Previous ||
2657 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2658 bool RegularComments = [&]() {
2659 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2661 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2666 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2667 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2671 return std::make_unique<BreakableLineCommentSection>(
2672 Current, StartColumn,
false, Encoding, Style);
2677std::pair<unsigned, bool>
2678ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2680 bool DryRun,
bool Strict) {
2681 std::unique_ptr<const BreakableToken> Token =
2682 createBreakableToken(Current, State, AllowBreak);
2685 assert(Token->getLineCount() > 0);
2687 if (Current.is(TT_LineComment)) {
2689 ColumnLimit = Style.ColumnLimit;
2691 if (ColumnLimit == 0) {
2694 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2696 if (Current.UnbreakableTailLength >= ColumnLimit)
2700 unsigned StartColumn = State.Column - Current.ColumnWidth;
2701 unsigned NewBreakPenalty = Current.isStringLiteral()
2702 ? Style.PenaltyBreakString
2703 : Style.PenaltyBreakComment;
2706 bool Exceeded =
false;
2708 bool BreakInserted = Token->introducesBreakBeforeToken();
2711 bool NewBreakBefore =
false;
2715 bool Reflow =
false;
2718 unsigned TailOffset = 0;
2720 unsigned ContentStartColumn =
2721 Token->getContentStartColumn(0,
false);
2723 unsigned RemainingTokenColumns =
2724 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2727 Token->adaptStartOfLine(0, Whitespaces);
2729 unsigned ContentIndent = 0;
2730 unsigned Penalty = 0;
2731 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2732 << StartColumn <<
".\n");
2733 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2734 LineIndex != EndIndex; ++LineIndex) {
2735 LLVM_DEBUG(llvm::dbgs()
2736 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2737 NewBreakBefore =
false;
2741 bool TryReflow = Reflow;
2743 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2744 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2745 << (ContentStartColumn + RemainingTokenColumns)
2746 <<
", space: " << ColumnLimit
2747 <<
", reflown prefix: " << ContentStartColumn
2748 <<
", offset in line: " << TailOffset <<
"\n");
2754 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2755 ContentStartColumn, CommentPragmasRegex);
2756 if (
Split.first == StringRef::npos) {
2759 if (LineIndex < EndIndex - 1) {
2762 Penalty += Style.PenaltyExcessCharacter *
2763 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2765 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2768 assert(
Split.first != 0);
2770 if (Token->supportsReflow()) {
2790 unsigned ToSplitColumns = Token->getRangeLength(
2791 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2792 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2795 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2796 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2799 unsigned ToNextSplitColumns = 0;
2800 if (NextSplit.first == StringRef::npos) {
2801 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2802 ContentStartColumn);
2804 ToNextSplitColumns = Token->getRangeLength(
2805 LineIndex, TailOffset,
2806 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2810 ToNextSplitColumns =
2811 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2812 LLVM_DEBUG(llvm::dbgs()
2813 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2814 LLVM_DEBUG(llvm::dbgs()
2815 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2818 bool ContinueOnLine =
2819 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2820 unsigned ExcessCharactersPenalty = 0;
2821 if (!ContinueOnLine && !Strict) {
2824 ExcessCharactersPenalty =
2825 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2826 Style.PenaltyExcessCharacter;
2827 LLVM_DEBUG(llvm::dbgs()
2828 <<
" Penalty excess: " << ExcessCharactersPenalty
2829 <<
"\n break : " << NewBreakPenalty <<
"\n");
2830 if (ExcessCharactersPenalty < NewBreakPenalty) {
2832 ContinueOnLine =
true;
2835 if (ContinueOnLine) {
2836 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2841 Token->compressWhitespace(LineIndex, TailOffset, Split,
2845 ContentStartColumn += ToSplitColumns + 1;
2846 Penalty += ExcessCharactersPenalty;
2848 RemainingTokenColumns = Token->getRemainingLength(
2849 LineIndex, TailOffset, ContentStartColumn);
2853 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2858 ContentIndent = Token->getContentIndent(LineIndex);
2859 LLVM_DEBUG(llvm::dbgs()
2860 <<
" ContentIndent: " << ContentIndent <<
"\n");
2861 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2864 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2865 LineIndex, TailOffset +
Split.first +
Split.second,
2866 ContentStartColumn);
2867 if (NewRemainingTokenColumns == 0) {
2870 ContentStartColumn =
2871 Token->getContentStartColumn(LineIndex,
true);
2872 NewRemainingTokenColumns = Token->getRemainingLength(
2873 LineIndex, TailOffset +
Split.first +
Split.second,
2874 ContentStartColumn);
2880 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2885 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2886 <<
", " <<
Split.second <<
"\n");
2888 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2892 Penalty += NewBreakPenalty;
2894 RemainingTokenColumns = NewRemainingTokenColumns;
2895 BreakInserted =
true;
2896 NewBreakBefore =
true;
2900 if (LineIndex + 1 != EndIndex) {
2901 unsigned NextLineIndex = LineIndex + 1;
2902 if (NewBreakBefore) {
2921 ContentStartColumn += RemainingTokenColumns + 1;
2926 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2927 LLVM_DEBUG(llvm::dbgs()
2928 <<
" Size of reflown text: " << ContentStartColumn
2929 <<
"\n Potential reflow split: ");
2930 if (SplitBeforeNext.first != StringRef::npos) {
2931 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2932 << SplitBeforeNext.second <<
"\n");
2933 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2936 RemainingTokenColumns = Token->getRemainingLength(
2937 NextLineIndex, TailOffset, ContentStartColumn);
2939 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2940 LLVM_DEBUG(llvm::dbgs()
2941 <<
" Over limit after reflow, need: "
2942 << (ContentStartColumn + RemainingTokenColumns)
2943 <<
", space: " << ColumnLimit
2944 <<
", reflown prefix: " << ContentStartColumn
2945 <<
", offset in line: " << TailOffset <<
"\n");
2951 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2952 ContentStartColumn, CommentPragmasRegex);
2953 if (
Split.first == StringRef::npos) {
2954 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2960 unsigned ToSplitColumns = Token->getRangeLength(
2961 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2962 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2963 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2964 << (ContentStartColumn + ToSplitColumns)
2965 <<
", space: " << ColumnLimit);
2966 unsigned ExcessCharactersPenalty =
2967 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2968 Style.PenaltyExcessCharacter;
2969 if (NewBreakPenalty < ExcessCharactersPenalty)
2975 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2983 ContentStartColumn =
2984 Token->getContentStartColumn(NextLineIndex,
false);
2985 RemainingTokenColumns = Token->getRemainingLength(
2986 NextLineIndex, TailOffset, ContentStartColumn);
2989 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3004 if (NewBreakBefore) {
3005 assert(Penalty >= NewBreakPenalty);
3006 Penalty -= NewBreakPenalty;
3009 Token->reflow(NextLineIndex, Whitespaces);
3015 Token->getSplitAfterLastLine(TailOffset);
3016 if (SplitAfterLastLine.first != StringRef::npos) {
3017 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3021 Penalty += Style.PenaltyExcessCharacter *
3022 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3025 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3028 ContentStartColumn =
3029 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3030 RemainingTokenColumns = Token->getRemainingLength(
3031 Token->getLineCount() - 1,
3032 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3033 ContentStartColumn);
3036 State.Column = ContentStartColumn + RemainingTokenColumns -
3037 Current.UnbreakableTailLength;
3039 if (BreakInserted) {
3041 Token->updateAfterBroken(Whitespaces);
3046 if (Current.isNot(TT_LineComment))
3047 for (ParenState &
Paren : State.Stack)
3048 Paren.BreakBeforeParameter =
true;
3050 if (Current.is(TT_BlockComment))
3051 State.NoContinuation =
true;
3053 State.Stack.back().LastSpace = StartColumn;
3056 Token->updateNextToken(State);
3058 return {Penalty, Exceeded};
3063 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3066bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3068 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3073 if (Current.
TokenText.starts_with(
"R\""))
3077 if (Current.getNextNonComment() &&
3078 Current.getNextNonComment()->isStringLiteral()) {
3081 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3083 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...