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 &&
149 const FormatStyle &Style) {
150 return Style.BreakBinaryOperations != FormatStyle::BBO_Never &&
152 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None
158 const FormatStyle &Style) {
159 if (LessTok.
isNot(tok::less))
161 return Style.isTextProto() ||
162 (Style.Language == FormatStyle::LK_Proto &&
179 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
180 if (LParenPos == StringRef::npos)
182 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
185 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
188 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
197 FormatStyle::LanguageKind
Language) {
198 for (
const auto &Format : Style.RawStringFormats)
200 return StringRef(Format.CanonicalDelimiter);
205 const FormatStyle &CodeStyle) {
207 std::optional<FormatStyle> LanguageStyle =
209 if (!LanguageStyle) {
210 FormatStyle PredefinedStyle;
216 LanguageStyle = PredefinedStyle;
218 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;
226std::optional<FormatStyle>
234std::optional<FormatStyle>
236 StringRef EnclosingFunction)
const {
259 *
this = *
this + Spaces;
287 bool BinPackInconclusiveFunctions)
288 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
289 Whitespaces(Whitespaces), Encoding(Encoding),
290 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
291 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
294 unsigned FirstStartColumn,
299 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
300 State.Column = FirstStartColumn;
302 State.Column = FirstIndent;
306 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
312 State.NextToken =
Line->First;
313 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
316 State.NoContinuation =
false;
317 State.StartOfStringLiteral = 0;
318 State.NoLineBreak =
false;
319 State.StartOfLineLevel = 0;
320 State.LowestLevelOnLine = 0;
321 State.IgnoreStackForComparison =
false;
323 if (Style.isTextProto()) {
326 auto &CurrentState = State.Stack.back();
327 CurrentState.AvoidBinPacking =
true;
328 CurrentState.BreakBeforeParameter =
true;
329 CurrentState.AlignColons =
false;
333 moveStateToNextToken(State, DryRun,
false);
340 const auto &CurrentState = State.Stack.back();
342 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
343 Current.closesBlockOrBlockTypeList(Style))) {
351 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
360 State.LowestLevelOnLine < State.StartOfLineLevel &&
364 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
369 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
370 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
371 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
372 return Style.isCpp() &&
373 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
378 if (Current.
is(TT_FunctionDeclarationName)) {
379 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&
384 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
385 assert(State.Column >= State.FirstIndent);
386 if (State.Column - State.FirstIndent < 6)
394 Current.isBlockIndentedInitRBrace(Style)) {
395 return CurrentState.BreakBeforeClosingBrace;
400 if ((Style.BreakBeforeCloseBracketFunction ||
401 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
402 Style.BreakBeforeCloseBracketSwitch) &&
403 Current.
is(tok::r_paren)) {
404 return CurrentState.BreakBeforeClosingParen;
407 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
408 return CurrentState.BreakBeforeClosingAngle;
412 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
416 (!Style.BraceWrapping.BeforeLambdaBody ||
417 Current.
isNot(TT_LambdaLBrace)) &&
418 CurrentState.NoLineBreakInOperand) {
425 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
427 Previous.MatchingParen->Previous->MatchingParen &&
428 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
430 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
434 return !State.NoLineBreak && !CurrentState.NoLineBreak;
440 const auto &CurrentState = State.Stack.back();
441 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
442 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
447 (Current.
is(TT_InlineASMColon) &&
448 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
449 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
450 Style.ColumnLimit > 0)))) {
453 if (CurrentState.BreakBeforeClosingBrace &&
454 (Current.closesBlockOrBlockTypeList(Style) ||
456 Current.isBlockIndentedInitRBrace(Style)))) {
459 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
461 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
463 if (Style.Language == FormatStyle::LK_ObjC &&
464 Style.ObjCBreakBeforeNestedBlockParam &&
466 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
471 if (CurrentState.IsCSharpGenericTypeConstraint &&
472 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
476 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
477 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
483 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||
484 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
486 (!Style.BreakBeforeTernaryOperators &&
487 Previous.is(TT_ConditionalExpr))) &&
488 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
489 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
492 if (CurrentState.IsChainedConditional &&
493 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
494 Current.
is(tok::colon)) ||
495 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
500 (
Previous.is(TT_ArrayInitializerLSquare) &&
503 Style.ColumnLimit > 0 &&
509 const FormatToken &BreakConstructorInitializersToken =
510 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
513 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
514 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
516 CurrentState.BreakBeforeParameter) &&
517 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
522 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
523 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
526 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
527 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
528 (Style.ObjCBreakBeforeNestedBlockParam ||
529 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
533 unsigned NewLineColumn = getNewLineColumn(State).Total;
534 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
536 (State.Column > NewLineColumn ||
542 (CurrentState.CallContinuation != 0 ||
543 CurrentState.BreakBeforeParameter) &&
549 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
550 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
556 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
561 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
564 if (Style.AlwaysBreakBeforeMultilineStrings &&
565 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
567 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
568 Keywords.kw_dollar) &&
569 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
570 nextIsMultilineString(State)) {
578 const auto PreviousPrecedence =
Previous.getPrecedence();
580 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
581 const bool LHSIsBinaryExpr =
594 const bool IsComparison =
599 Previous.Previous->isNot(TT_BinaryOperator);
605 CurrentState.BreakBeforeParameter) {
610 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
611 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
615 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
620 if (
Previous.ClosesTemplateDeclaration) {
621 if (Current.
is(tok::kw_concept)) {
622 switch (Style.BreakBeforeConceptDeclarations) {
623 case FormatStyle::BBCDS_Allowed:
625 case FormatStyle::BBCDS_Always:
627 case FormatStyle::BBCDS_Never:
631 if (Current.
is(TT_RequiresClause)) {
632 switch (Style.RequiresClausePosition) {
633 case FormatStyle::RCPS_SingleLine:
634 case FormatStyle::RCPS_WithPreceding:
640 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
641 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
644 if (
Previous.is(TT_FunctionAnnotationRParen) &&
648 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
649 Current.
isNot(TT_LeadingJavaAnnotation)) {
654 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
658 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
660 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
664 if (Current.
is(TT_FunctionDeclarationName) &&
665 !State.Line->ReturnTypeWrapped &&
667 (!Style.isCSharp() ||
668 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
671 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
672 CurrentState.BreakBeforeParameter) {
674 if (
Tok->is(TT_LineComment))
676 if (
Tok->is(TT_TemplateCloser)) {
680 if (
Tok->FirstAfterPPLine)
692 Current.
isNoneOf(tok::r_brace, tok::comment)) {
696 if (Current.
is(tok::lessless) &&
699 Previous.TokenText ==
"\'\\n\'")))) {
706 if (State.NoContinuation)
714 unsigned ExtraSpaces) {
716 assert(State.NextToken->Previous);
719 assert(!State.Stack.empty());
720 State.NoContinuation =
false;
722 if (Current.
is(TT_ImplicitStringLiteral) &&
723 (!
Previous.Tok.getIdentifierInfo() ||
724 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
725 tok::pp_not_keyword)) {
731 State.Column = EndColumn;
733 unsigned StartColumn =
735 assert(EndColumn >= StartColumn);
736 State.Column += EndColumn - StartColumn;
738 moveStateToNextToken(State, DryRun,
false);
742 unsigned Penalty = 0;
744 Penalty = addTokenOnNewLine(State, DryRun);
746 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
748 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
751void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
752 unsigned ExtraSpaces) {
754 assert(State.NextToken->Previous);
756 auto &CurrentState = State.Stack.back();
763 auto DisallowLineBreaks = [&] {
764 if (!Style.isCpp() ||
765 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
773 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
776 const auto *Prev = Current.getPreviousNonComment();
777 if (!Prev || Prev->isNot(tok::l_paren))
780 if (Prev->BlockParameterCount == 0)
784 if (Prev->BlockParameterCount > 1)
791 const auto *Comma = Prev->
Role->lastComma();
795 const auto *
Next = Comma->getNextNonComment();
796 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
799 if (DisallowLineBreaks())
800 State.NoLineBreak =
true;
802 if (Current.
is(tok::equal) &&
803 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
804 CurrentState.VariablePos == 0 &&
806 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
807 CurrentState.VariablePos = State.Column;
810 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
811 CurrentState.VariablePos -=
Tok->ColumnWidth;
812 if (
Tok->SpacesRequiredBefore != 0)
816 if (
Previous.PartOfMultiVariableDeclStmt)
817 CurrentState.LastSpace = CurrentState.VariablePos;
823 int PPColumnCorrection = 0;
827 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
834 if (Style.UseTab != FormatStyle::UT_Never)
835 PPColumnCorrection = -1;
836 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
842 const bool ContinuePPDirective =
844 Whitespaces.replaceWhitespace(Current, 0, Spaces,
845 State.
Column + Spaces + PPColumnCorrection,
846 false, ContinuePPDirective);
851 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
852 Current.
is(TT_InheritanceColon)) {
853 CurrentState.NoLineBreak =
true;
855 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
857 CurrentState.NoLineBreak =
true;
860 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
862 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
863 CurrentState.Indent.Total);
866 CurrentState.AlignColons =
false;
870 CurrentState.ColonPos = FirstColonPos;
878 auto IsStartOfBracedList = [&]() {
880 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
882 if (IsStartOfBracedList())
883 return Style.BreakAfterOpenBracketBracedList;
884 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
888 if (
Tok.Previous->isIf())
889 return Style.BreakAfterOpenBracketIf;
890 if (
Tok.Previous->isLoop(Style))
891 return Style.BreakAfterOpenBracketLoop;
892 if (
Tok.Previous->is(tok::kw_switch))
893 return Style.BreakAfterOpenBracketSwitch;
894 if (Style.BreakAfterOpenBracketFunction) {
895 return !
Tok.Previous->is(TT_CastRParen) &&
896 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
901 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
902 Tok.Previous->is(tok::identifier);
904 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
905 if (!Style.isJavaScript())
907 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
908 if (Prev->is(TT_TemplateString) && Prev->opensScope())
910 if (Prev->opensScope() && !NestBlocks)
912 if (Prev->is(TT_TemplateString) && Prev->closesScope())
918 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
919 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
921 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
928 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
930 if (
Tok.is(TT_UnaryOperator) ||
931 (Style.isJavaScript() &&
932 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
935 const auto *
Previous = TokAfterLParen.Previous;
939 Previous->Previous->is(tok::kw_switch))) {
942 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
943 TT_LambdaDefinitionLParen) &&
947 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
950 return !
Next ||
Next->isMemberAccess() ||
951 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
954 State.
Column > getNewLineColumn(State).Total &&
965 !StartsSimpleOneArgList(Current)) {
966 CurrentState.NoLineBreak =
true;
970 CurrentState.NoLineBreak =
true;
976 if (Style.AlignAfterOpenBracket &&
977 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
978 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
979 TT_TableGenDAGArgOpener,
980 TT_TableGenDAGArgOpenerToBreak) &&
982 (Current.
isNot(TT_LineComment) ||
984 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||
986 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,
988 Previous.is(TT_VerilogMultiLineListLParen)) &&
989 !IsInTemplateString(Current,
false)) {
990 CurrentState.Indent = State.
Column + Spaces;
991 CurrentState.IsAligned =
true;
994 CurrentState.NoLineBreak =
true;
996 CurrentState.NoLineBreak =
true;
999 State.
Column > getNewLineColumn(State).Total) {
1000 CurrentState.ContainsUnwrappedBuilder =
true;
1003 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1004 CurrentState.NoLineBreak =
true;
1005 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1014 CurrentState.NoLineBreak =
true;
1021 const FormatToken *P = Current.getPreviousNonComment();
1022 if (Current.
isNot(tok::comment) && P &&
1023 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1024 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1025 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1029 bool BreakBeforeOperator =
1030 P->MustBreakBefore || P->is(tok::lessless) ||
1031 (P->is(TT_BinaryOperator) &&
1032 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1033 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1037 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1038 P->isNot(TT_ConditionalExpr);
1039 if ((!BreakBeforeOperator &&
1041 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1042 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1043 CurrentState.NoLineBreakInOperand =
true;
1048 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1053 CurrentState.LastSpace = State.
Column;
1054 CurrentState.NestedBlockIndent = State.
Column;
1055 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1057 Previous.isNot(TT_OverloadedOperator)) ||
1059 CurrentState.LastSpace = State.
Column;
1060 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1062 Style.BreakConstructorInitializers ==
1063 FormatStyle::BCIS_AfterColon) {
1064 CurrentState.Indent = State.
Column;
1065 CurrentState.LastSpace = State.
Column;
1066 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1067 CurrentState.LastSpace = State.
Column;
1068 }
else if (
Previous.is(TT_BinaryOperator) &&
1075 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1076 CurrentState.LastSpace = State.
Column;
1077 }
else if (
Previous.is(TT_InheritanceColon)) {
1078 CurrentState.Indent = State.
Column;
1079 CurrentState.LastSpace = State.
Column;
1080 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1081 CurrentState.ColonPos = State.
Column;
1082 }
else if (
Previous.opensScope()) {
1090 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1091 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1092 CurrentState.LastSpace = State.
Column;
1098unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1101 assert(State.NextToken->Previous);
1103 auto &CurrentState = State.Stack.back();
1107 unsigned Penalty = 0;
1109 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1111 if (!NextNonComment)
1112 NextNonComment = &Current;
1115 if (!CurrentState.ContainsLineBreak)
1117 CurrentState.ContainsLineBreak =
true;
1119 Penalty += State.NextToken->SplitPenalty;
1124 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1125 (State.Column <= Style.ColumnLimit / 3 ||
1126 CurrentState.BreakBeforeParameter)) {
1127 Penalty += Style.PenaltyBreakFirstLessLess;
1130 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1131 State.Column = TotalColumn;
1145 if (State.Column > State.FirstIndent) {
1147 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1160 if (Current.isNot(TT_LambdaArrow) &&
1161 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1162 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1163 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1164 CurrentState.NestedBlockIndent = State.Column;
1167 if (NextNonComment->isMemberAccess()) {
1168 if (CurrentState.CallContinuation == 0)
1169 CurrentState.CallContinuation = State.Column;
1170 }
else if (NextNonComment->is(TT_SelectorName)) {
1171 if (!CurrentState.ObjCSelectorNameFound) {
1172 if (NextNonComment->LongestObjCSelectorName == 0) {
1173 CurrentState.AlignColons =
false;
1175 CurrentState.ColonPos =
1177 ? std::max(CurrentState.Indent.Total,
1178 State.FirstIndent + Style.ContinuationIndentWidth)
1179 : CurrentState.
Indent.Total) +
1183 }
else if (CurrentState.AlignColons &&
1184 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1185 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1187 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1188 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1198 if (State.Stack.size() > 1) {
1199 State.Stack[State.Stack.size() - 2].LastSpace =
1200 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1201 Style.ContinuationIndentWidth;
1205 if ((PreviousNonComment &&
1206 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1207 !CurrentState.AvoidBinPacking) ||
1209 CurrentState.BreakBeforeParameter =
false;
1211 if (PreviousNonComment &&
1212 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1213 PreviousNonComment->ClosesRequiresClause) &&
1214 Current.NestingLevel == 0) {
1215 CurrentState.BreakBeforeParameter =
false;
1217 if (NextNonComment->is(tok::question) ||
1218 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1219 CurrentState.BreakBeforeParameter =
true;
1221 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1222 CurrentState.BreakBeforeParameter =
false;
1226 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1229 !Current.MatchingParen->Children.empty()) {
1237 const bool ContinuePPDirective = State.Line->InPPDirective &&
1239 Current.isNot(TT_LineComment);
1240 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1241 CurrentState.IsAligned, ContinuePPDirective,
1242 IndentedFromColumn);
1245 if (!Current.isTrailingComment())
1246 CurrentState.LastSpace = State.Column;
1247 if (Current.is(tok::lessless)) {
1251 CurrentState.LastSpace += 3;
1254 State.StartOfLineLevel = Current.NestingLevel;
1255 State.LowestLevelOnLine = Current.NestingLevel;
1259 bool NestedBlockSpecialCase =
1260 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1261 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1262 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1263 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1265 NestedBlockSpecialCase =
1266 NestedBlockSpecialCase ||
1267 (Current.MatchingParen &&
1268 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1269 if (!NestedBlockSpecialCase) {
1270 auto ParentLevelIt = std::next(State.Stack.rbegin());
1271 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1272 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1287 auto FindCurrentLevel = [&](
const auto &It) {
1288 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1289 return PState.Tok != nullptr;
1292 auto MaybeIncrement = [&](
const auto &It) {
1293 return It != State.Stack.rend() ? std::next(It) : It;
1295 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1296 auto LevelContainingLambdaIt =
1297 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1298 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1300 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1301 I->BreakBeforeParameter =
true;
1304 if (PreviousNonComment &&
1305 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1306 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1307 !PreviousNonComment->ClosesRequiresClause) ||
1308 Current.NestingLevel != 0) &&
1309 PreviousNonComment->isNoneOf(
1310 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1311 TT_LeadingJavaAnnotation) &&
1312 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1315 (!Style.BraceWrapping.BeforeLambdaBody ||
1316 Current.isNot(TT_LambdaLBrace))) {
1317 CurrentState.BreakBeforeParameter =
true;
1322 if (PreviousNonComment &&
1323 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1325 CurrentState.BreakBeforeClosingBrace =
true;
1328 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1329 if (
auto Previous = PreviousNonComment->Previous) {
1331 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1332 }
else if (
Previous->isLoop(Style)) {
1333 CurrentState.BreakBeforeClosingParen =
1334 Style.BreakBeforeCloseBracketLoop;
1335 }
else if (
Previous->is(tok::kw_switch)) {
1336 CurrentState.BreakBeforeClosingParen =
1337 Style.BreakBeforeCloseBracketSwitch;
1339 CurrentState.BreakBeforeClosingParen =
1340 Style.BreakBeforeCloseBracketFunction;
1345 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1346 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1348 if (CurrentState.AvoidBinPacking) {
1353 bool PreviousIsBreakingCtorInitializerColon =
1354 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1355 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1356 bool AllowAllConstructorInitializersOnNextLine =
1357 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1358 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1359 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1360 !PreviousIsBreakingCtorInitializerColon) ||
1361 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1362 State.Line->MustBeDeclaration) ||
1363 (!Style.AllowAllArgumentsOnNextLine &&
1364 !State.Line->MustBeDeclaration) ||
1365 (!AllowAllConstructorInitializersOnNextLine &&
1366 PreviousIsBreakingCtorInitializerColon) ||
1368 CurrentState.BreakBeforeParameter =
true;
1374 if (PreviousIsBreakingCtorInitializerColon &&
1375 AllowAllConstructorInitializersOnNextLine) {
1376 CurrentState.BreakBeforeParameter =
false;
1381 CurrentState.BreakBeforeParameter =
true;
1387ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1388 if (!State.NextToken || !State.NextToken->Previous)
1392 const auto &CurrentState = State.Stack.back();
1394 if (CurrentState.IsCSharpGenericTypeConstraint &&
1395 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1396 return CurrentState.ColonPos + 2;
1401 const auto ContinuationIndent =
1402 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1403 CurrentState.Indent) +
1404 Style.ContinuationIndentWidth;
1405 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1407 if (!NextNonComment)
1408 NextNonComment = &Current;
1411 if (Style.isJava() &&
1412 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1413 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1414 CurrentState.Indent + Style.ContinuationIndentWidth);
1419 if (Style.isVerilog() && PreviousNonComment &&
1420 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1421 return State.FirstIndent;
1424 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1425 State.Line->First->is(tok::kw_enum)) {
1426 return IndentationAndAlignment(Style.IndentWidth *
1427 State.Line->First->IndentLevel) +
1431 if (Style.BraceWrapping.BeforeLambdaBody &&
1432 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1433 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1434 ? CurrentState.Indent
1435 : State.FirstIndent;
1436 return From + Style.IndentWidth;
1439 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1440 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1441 if (Current.NestingLevel == 0 ||
1442 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1443 State.NextToken->is(TT_LambdaLBrace))) {
1444 return State.FirstIndent;
1446 return CurrentState.Indent;
1448 if (Current.is(TT_LambdaArrow) &&
1449 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1450 tok::kw_consteval, tok::kw_static,
1451 TT_AttributeRSquare)) {
1452 return ContinuationIndent;
1454 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1455 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1456 State.Stack.size() > 1) {
1457 if (Current.closesBlockOrBlockTypeList(Style))
1458 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1459 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1460 return State.Stack[State.Stack.size() - 2].LastSpace;
1461 return State.FirstIndent;
1478 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1480 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1481 return State.Stack[State.Stack.size() - 2].LastSpace;
1485 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1486 State.Stack.size() > 1) {
1487 return State.Stack[State.Stack.size() - 2].LastSpace;
1489 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1490 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1491 State.Stack.size() > 1) {
1492 return State.Stack[State.Stack.size() - 2].LastSpace;
1494 if ((Style.BreakBeforeCloseBracketFunction ||
1495 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1496 Style.BreakBeforeCloseBracketSwitch) &&
1497 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1498 return State.Stack[State.Stack.size() - 2].LastSpace;
1500 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1501 State.Stack.size() > 1) {
1502 return State.Stack[State.Stack.size() - 2].LastSpace;
1504 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1505 return State.Stack[State.Stack.size() - 2].LastSpace;
1513 if (Current.is(tok::identifier) && Current.Next &&
1514 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1515 (Current.Next->is(TT_DictLiteral) ||
1516 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1517 return CurrentState.Indent;
1519 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1520 State.StartOfStringLiteral != 0) {
1521 return State.StartOfStringLiteral - 1;
1523 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1524 return State.StartOfStringLiteral;
1525 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1526 return CurrentState.FirstLessLess;
1527 if (NextNonComment->isMemberAccess()) {
1528 if (CurrentState.CallContinuation == 0)
1529 return ContinuationIndent;
1530 return CurrentState.CallContinuation;
1532 if (CurrentState.QuestionColumn != 0 &&
1533 ((NextNonComment->is(tok::colon) &&
1534 NextNonComment->is(TT_ConditionalExpr)) ||
1535 Previous.is(TT_ConditionalExpr))) {
1536 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1537 !NextNonComment->Next->FakeLParens.empty() &&
1539 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1541 !CurrentState.IsWrappedConditional) {
1546 unsigned Indent = CurrentState.Indent.Total;
1547 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1548 Indent -= Style.ContinuationIndentWidth;
1549 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1553 return CurrentState.QuestionColumn;
1555 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1556 return CurrentState.VariablePos;
1557 if (Current.is(TT_RequiresClause)) {
1558 if (Style.IndentRequiresClause)
1559 return CurrentState.Indent + Style.IndentWidth;
1560 switch (Style.RequiresClausePosition) {
1561 case FormatStyle::RCPS_OwnLine:
1562 case FormatStyle::RCPS_WithFollowing:
1563 case FormatStyle::RCPS_OwnLineWithBrace:
1564 return CurrentState.Indent;
1569 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1570 TT_InheritanceComma)) {
1571 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1573 if ((PreviousNonComment &&
1574 (PreviousNonComment->ClosesTemplateDeclaration ||
1575 PreviousNonComment->ClosesRequiresClause ||
1576 (PreviousNonComment->is(TT_AttributeMacro) &&
1577 Current.isNot(tok::l_paren) &&
1578 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1579 TT_PointerOrReference)) ||
1580 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1581 TT_FunctionAnnotationRParen,
1583 TT_LeadingJavaAnnotation))) ||
1584 (!Style.IndentWrappedFunctionNames &&
1585 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1586 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1587 CurrentState.Indent);
1589 if (NextNonComment->is(TT_SelectorName)) {
1590 if (!CurrentState.ObjCSelectorNameFound) {
1591 auto MinIndent = CurrentState.Indent;
1594 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1595 Style.ContinuationIndentWidth);
1606 return MinIndent.addPadding(
1607 std::max(NextNonComment->LongestObjCSelectorName,
1608 NextNonComment->ColumnWidth) -
1609 NextNonComment->ColumnWidth);
1611 if (!CurrentState.AlignColons)
1612 return CurrentState.Indent;
1613 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1614 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1615 return CurrentState.Indent;
1617 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1618 return CurrentState.ColonPos;
1619 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1620 if (CurrentState.StartOfArraySubscripts != 0) {
1621 return CurrentState.StartOfArraySubscripts;
1622 }
else if (Style.isCSharp()) {
1624 return CurrentState.Indent;
1626 return ContinuationIndent;
1631 if (State.Line->InPragmaDirective) {
1632 FormatToken *PragmaType = State.Line->First->Next->Next;
1633 if (PragmaType && PragmaType->TokenText ==
"omp")
1634 return CurrentState.Indent + Style.ContinuationIndentWidth;
1639 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1640 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1641 return CurrentState.Indent;
1644 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1645 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1646 return ContinuationIndent;
1648 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1649 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1650 return ContinuationIndent;
1652 if (NextNonComment->is(TT_CtorInitializerComma))
1653 return CurrentState.Indent;
1654 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1655 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1656 return CurrentState.Indent;
1658 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1659 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1660 return CurrentState.Indent;
1663 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1664 !Current.isBinaryOperator() &&
1665 Current.isNoneOf(tok::colon, tok::comment)) {
1666 return ContinuationIndent;
1668 if (Current.is(TT_ProtoExtensionLSquare))
1669 return CurrentState.Indent;
1670 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1671 return CurrentState.Indent - Current.Tok.getLength() -
1672 Current.SpacesRequiredBefore;
1674 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1675 CurrentState.UnindentOperator) {
1676 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1677 NextNonComment->SpacesRequiredBefore;
1679 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1680 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1683 return CurrentState.Indent + Style.ContinuationIndentWidth;
1685 return CurrentState.Indent;
1690 const FormatStyle &Style) {
1697 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1700unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1701 bool DryRun,
bool Newline) {
1702 assert(State.Stack.size());
1704 auto &CurrentState = State.Stack.back();
1706 if (Current.is(TT_CSharpGenericTypeConstraint))
1707 CurrentState.IsCSharpGenericTypeConstraint =
true;
1708 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1709 CurrentState.NoLineBreakInOperand =
false;
1710 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1711 CurrentState.AvoidBinPacking =
true;
1712 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1713 if (CurrentState.FirstLessLess == 0)
1714 CurrentState.FirstLessLess = State.Column;
1716 CurrentState.LastOperatorWrapped = Newline;
1718 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1719 CurrentState.LastOperatorWrapped = Newline;
1720 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1721 Current.Previous->isNot(TT_ConditionalExpr)) {
1722 CurrentState.LastOperatorWrapped = Newline;
1724 if (Current.is(TT_ArraySubscriptLSquare) &&
1725 CurrentState.StartOfArraySubscripts == 0) {
1726 CurrentState.StartOfArraySubscripts = State.Column;
1730 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1732 if (
Tok.MustBreakBefore)
1736 return Next &&
Next->MustBreakBefore;
1738 if (IsWrappedConditional(Current))
1739 CurrentState.IsWrappedConditional =
true;
1740 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1741 CurrentState.QuestionColumn = State.Column;
1742 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1747 CurrentState.QuestionColumn = State.Column;
1749 if (!Current.opensScope() && !Current.closesScope() &&
1750 Current.isNot(TT_PointerOrReference)) {
1751 State.LowestLevelOnLine =
1752 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1754 if (Current.isMemberAccess())
1755 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1756 if (Current.is(TT_SelectorName))
1757 CurrentState.ObjCSelectorNameFound =
true;
1758 if (Current.is(TT_CtorInitializerColon) &&
1759 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1765 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1766 FormatStyle::BCIS_BeforeComma
1769 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1770 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1771 CurrentState.AvoidBinPacking =
true;
1772 CurrentState.BreakBeforeParameter =
1773 Style.ColumnLimit > 0 &&
1774 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1775 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1777 CurrentState.BreakBeforeParameter =
false;
1780 if (Current.is(TT_CtorInitializerColon) &&
1781 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1782 CurrentState.Indent =
1783 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1784 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1785 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1786 CurrentState.AvoidBinPacking =
true;
1788 CurrentState.BreakBeforeParameter =
false;
1790 if (Current.is(TT_InheritanceColon)) {
1791 CurrentState.Indent =
1792 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1794 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1795 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1796 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1797 CurrentState.LastSpace = State.Column;
1798 if (Current.is(TT_RequiresExpression) &&
1799 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1800 CurrentState.NestedBlockIndent = State.Column;
1812 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1814 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1815 !CurrentState.HasMultipleNestedBlocks) {
1816 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1817 for (ParenState &PState : llvm::drop_end(State.Stack))
1818 PState.NoLineBreak =
true;
1819 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1821 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1822 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1823 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1824 TT_CtorInitializerColon)))) {
1825 CurrentState.NestedBlockInlined =
1829 moveStatePastFakeLParens(State, Newline);
1830 moveStatePastScopeCloser(State);
1833 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1834 !State.Stack.back().NoLineBreakInOperand;
1835 moveStatePastScopeOpener(State, Newline);
1836 moveStatePastFakeRParens(State);
1838 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1839 State.StartOfStringLiteral = State.Column + 1;
1840 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1841 State.StartOfStringLiteral = State.Column + 1;
1842 }
else if (Current.is(TT_TableGenMultiLineString) &&
1843 State.StartOfStringLiteral == 0) {
1844 State.StartOfStringLiteral = State.Column + 1;
1845 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1846 State.StartOfStringLiteral = State.Column;
1847 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1848 !Current.isStringLiteral()) {
1849 State.StartOfStringLiteral = 0;
1852 State.Column += Current.ColumnWidth;
1853 State.NextToken = State.NextToken->Next;
1858 if (Style.isVerilog() && State.NextToken &&
1859 State.NextToken->MustBreakBefore &&
1860 Keywords.isVerilogEndOfLabel(Current)) {
1861 State.FirstIndent += Style.IndentWidth;
1862 CurrentState.Indent = State.FirstIndent;
1866 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1869 Current.Role->formatFromToken(State,
this, DryRun);
1876 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1881void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1884 if (Current.FakeLParens.empty())
1892 bool SkipFirstExtraIndent =
1895 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1897 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1899 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1900 const auto &CurrentState = State.Stack.back();
1901 ParenState NewParenState = CurrentState;
1902 NewParenState.Tok =
nullptr;
1903 NewParenState.ContainsLineBreak =
false;
1904 NewParenState.LastOperatorWrapped =
true;
1905 NewParenState.IsChainedConditional =
false;
1906 NewParenState.IsWrappedConditional =
false;
1907 NewParenState.UnindentOperator =
false;
1908 NewParenState.NoLineBreak =
1909 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1913 NewParenState.AvoidBinPacking =
false;
1918 if (!Current.isTrailingComment() &&
1919 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1922 (!Style.isJava() && PrecedenceLevel > 0)) &&
1923 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1924 Current.NestingLevel == 0) &&
1925 (!Style.isTableGen() ||
1927 TT_TableGenDAGArgListCommaToBreak)))) {
1928 NewParenState.Indent =
1929 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1930 IndentationAndAlignment(CurrentState.LastSpace)});
1937 State.Stack.size() > 1) {
1938 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1939 Style.ContinuationIndentWidth;
1949 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1950 NewParenState.UnindentOperator =
true;
1952 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1953 NewParenState.IsAligned =
true;
1963 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1965 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
1966 NewParenState.StartOfFunctionCall = State.Column;
1976 &PrecedenceLevel == &Current.FakeLParens.back() &&
1977 !CurrentState.IsWrappedConditional) {
1978 NewParenState.IsChainedConditional =
true;
1979 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1982 !Current.isTrailingComment())) {
1983 NewParenState.Indent += Style.ContinuationIndentWidth;
1986 NewParenState.BreakBeforeParameter =
false;
1987 State.Stack.push_back(NewParenState);
1988 SkipFirstExtraIndent =
false;
1992void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
1993 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1994 unsigned VariablePos = State.Stack.back().VariablePos;
1995 if (State.Stack.size() == 1) {
1999 State.Stack.pop_back();
2000 State.Stack.back().VariablePos = VariablePos;
2003 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2006 State.Stack.back().LastSpace -= Style.IndentWidth;
2010void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2013 if (!Current.opensScope())
2016 const auto &CurrentState = State.Stack.back();
2019 if (Current.isOneOf(tok::less, tok::l_paren) &&
2020 CurrentState.IsCSharpGenericTypeConstraint) {
2024 if (Current.MatchingParen && Current.is(
BK_Block)) {
2025 moveStateToNewBlock(State, Newline);
2032 const auto *Prev =
Tok->getPreviousNonComment();
2035 return Prev->is(tok::comma);
2036 }(Current.MatchingParen);
2038 IndentationAndAlignment NewIndent = 0;
2039 unsigned LastSpace = CurrentState.LastSpace;
2040 bool AvoidBinPacking;
2041 bool BreakBeforeParameter =
false;
2042 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2043 CurrentState.NestedBlockIndent);
2044 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2046 if (Current.opensBlockOrBlockTypeList(Style)) {
2047 NewIndent = Style.IndentWidth +
2048 std::min(State.Column, CurrentState.NestedBlockIndent);
2049 }
else if (Current.is(tok::l_brace)) {
2050 const auto Width = Style.BracedInitializerIndentWidth;
2051 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2052 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2054 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2056 const FormatToken *NextNonComment = Current.getNextNonComment();
2057 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2058 Style.isProto() || !Style.BinPackArguments ||
2059 (NextNonComment && NextNonComment->isOneOf(
2060 TT_DesignatedInitializerPeriod,
2061 TT_DesignatedInitializerLSquare));
2062 BreakBeforeParameter = EndsInComma;
2063 if (Current.ParameterCount > 1)
2064 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2066 NewIndent = IndentationAndAlignment(std::max(
2067 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2068 Style.ContinuationIndentWidth;
2070 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2071 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2077 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2078 NewIndent = State.Column +
Next->TokenText.size() + 2;
2085 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2086 NewIndent = std::max(NewIndent, CurrentState.Indent);
2087 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2093 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2094 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2095 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2097 bool BinPackDeclaration =
2099 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2102 bool GenericSelection =
2103 Current.getPreviousNonComment() &&
2104 Current.getPreviousNonComment()->is(tok::kw__Generic);
2107 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2108 (Style.isJavaScript() && EndsInComma) ||
2109 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2110 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2111 (Style.ExperimentalAutoDetectBinPacking &&
2115 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2116 Style.ObjCBreakBeforeNestedBlockParam) {
2117 if (Style.ColumnLimit) {
2122 BreakBeforeParameter =
true;
2128 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2129 if (
Tok->MustBreakBefore ||
2130 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2131 BreakBeforeParameter =
true;
2138 if (Style.isJavaScript() && EndsInComma)
2139 BreakBeforeParameter =
true;
2145 Current.Children.empty() &&
2146 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2147 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2148 (Current.is(TT_TemplateOpener) &&
2149 CurrentState.ContainsUnwrappedBuilder));
2150 State.Stack.push_back(
2151 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2152 auto &NewState = State.Stack.back();
2153 NewState.NestedBlockIndent = NestedBlockIndent;
2154 NewState.BreakBeforeParameter = BreakBeforeParameter;
2155 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2157 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2158 Current.is(tok::l_paren)) {
2162 if (next->is(TT_LambdaLSquare)) {
2163 NewState.HasMultipleNestedBlocks =
true;
2170 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2172 Current.Previous->is(tok::at);
2175void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2177 if (!Current.closesScope())
2182 if (State.Stack.size() > 1 &&
2183 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2184 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2185 State.NextToken->is(TT_TemplateCloser) ||
2186 State.NextToken->is(TT_TableGenListCloser) ||
2187 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2188 State.Stack.pop_back();
2191 auto &CurrentState = State.Stack.back();
2203 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2204 Current.MatchingParen->Previous) {
2205 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2206 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2207 CurrentScopeOpener.MatchingParen) {
2208 int NecessarySpaceInLine =
2210 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2211 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2212 Style.ColumnLimit) {
2213 CurrentState.BreakBeforeParameter =
false;
2218 if (Current.is(tok::r_square)) {
2220 const FormatToken *NextNonComment = Current.getNextNonComment();
2221 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2222 CurrentState.StartOfArraySubscripts = 0;
2226void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2227 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2228 State.NextToken->is(TT_LambdaLBrace) &&
2229 !State.Line->MightBeFunctionDecl) {
2230 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2231 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2233 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2235 unsigned NewIndent =
2236 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2237 ? Style.ObjCBlockIndentWidth
2238 : Style.IndentWidth);
2245 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2246 State.NextToken->is(TT_LambdaLBrace);
2248 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2249 State.Stack.back().LastSpace,
2250 true, NoLineBreak));
2251 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2252 State.Stack.back().BreakBeforeParameter =
true;
2258 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2259 if (LastNewlinePos == StringRef::npos) {
2260 return StartColumn +
2268unsigned ContinuationIndenter::reformatRawStringLiteral(
2270 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2271 unsigned StartColumn = State.Column - Current.ColumnWidth;
2273 StringRef NewDelimiter =
2275 if (NewDelimiter.empty())
2276 NewDelimiter = OldDelimiter;
2279 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2280 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2283 std::string RawText = std::string(
2284 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2285 if (NewDelimiter != OldDelimiter) {
2288 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2289 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2290 NewDelimiter = OldDelimiter;
2293 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2294 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2297 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2308 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2330 unsigned CurrentIndent =
2331 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2332 ? State.Stack.back().NestedBlockIndent
2333 : State.Stack.back().Indent.Total;
2334 unsigned NextStartColumn = ContentStartsOnNewline
2335 ? CurrentIndent + Style.IndentWidth
2346 unsigned LastStartColumn =
2347 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2350 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2351 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2356 return addMultilineToken(Current, State);
2358 if (NewDelimiter != OldDelimiter) {
2361 SourceLocation PrefixDelimiterStart =
2362 Current.Tok.getLocation().getLocWithOffset(2);
2363 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2364 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2367 <<
"Failed to update the prefix delimiter of a raw string: "
2368 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2372 SourceLocation SuffixDelimiterStart =
2373 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2374 1 - OldDelimiter.size());
2375 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2376 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2379 <<
"Failed to update the suffix delimiter of a raw string: "
2380 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2383 SourceLocation OriginLoc =
2384 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2385 for (
const tooling::Replacement &Fix : Fixes.first) {
2386 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2387 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2388 Fix.getLength(), Fix.getReplacementText()));
2390 llvm::errs() <<
"Failed to reformat raw string: "
2391 << llvm::toString(std::move(Err)) <<
"\n";
2396 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2397 State.Column = RawLastLineEndColumn + NewSuffixSize;
2401 unsigned PrefixExcessCharacters =
2402 StartColumn + NewPrefixSize > Style.ColumnLimit
2403 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2406 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2409 for (ParenState &
Paren : State.Stack)
2410 Paren.BreakBeforeParameter =
true;
2412 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2415unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2418 for (ParenState &
Paren : State.Stack)
2419 Paren.BreakBeforeParameter =
true;
2421 unsigned ColumnsUsed = State.Column;
2424 State.Column = Current.LastLineColumnWidth;
2427 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2431unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2433 bool AllowBreak,
bool Newline) {
2434 unsigned Penalty = 0;
2437 auto RawStringStyle = getRawStringStyle(Current, State);
2438 if (RawStringStyle && !Current.Finalized) {
2439 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2441 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2444 Penalty = addMultilineToken(Current, State);
2447 LineState OriginalState = State;
2451 bool Strict =
false;
2454 bool Exceeded =
false;
2455 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2456 Current, State, AllowBreak,
true, Strict);
2460 LineState StrictState = OriginalState;
2461 unsigned StrictPenalty =
2462 breakProtrudingToken(Current, StrictState, AllowBreak,
2465 Strict = StrictPenalty <= Penalty;
2467 Penalty = StrictPenalty;
2468 State = StrictState;
2474 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2479 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2480 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2489 auto Tok = Current.getPreviousNonComment();
2490 if (!
Tok ||
Tok->isNot(tok::l_paren))
2492 Tok =
Tok->getPreviousNonComment();
2495 if (
Tok->is(TT_TemplateCloser)) {
2496 Tok =
Tok->MatchingParen;
2498 Tok =
Tok->getPreviousNonComment();
2500 if (!
Tok ||
Tok->isNot(tok::identifier))
2502 return Tok->TokenText;
2505std::optional<FormatStyle>
2506ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2507 const LineState &State) {
2508 if (!Current.isStringLiteral())
2509 return std::nullopt;
2512 return std::nullopt;
2514 if (!RawStringStyle && Delimiter->empty()) {
2518 if (!RawStringStyle)
2519 return std::nullopt;
2521 return RawStringStyle;
2524std::unique_ptr<BreakableToken>
2525ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2527 unsigned StartColumn = State.Column - Current.ColumnWidth;
2528 if (Current.isStringLiteral()) {
2531 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2545 if (Current.IsUnterminatedLiteral)
2549 if (State.Stack.back().IsInsideObjCArrayLiteral)
2556 if (Style.isVerilog() && Current.Previous &&
2557 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2560 StringRef
Text = Current.TokenText;
2570 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2573 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2574 Text.ends_with(
"'")) {
2576 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2577 Text.ends_with(
"\"")) {
2579 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2584 return std::make_unique<BreakableStringLiteralUsingOperators>(
2585 Current, QuoteStyle,
2596 if ((
Text.ends_with(Postfix =
"\"") &&
2597 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2598 Text.starts_with(Prefix =
"u\"") ||
2599 Text.starts_with(Prefix =
"U\"") ||
2600 Text.starts_with(Prefix =
"u8\"") ||
2601 Text.starts_with(Prefix =
"L\""))) ||
2602 (
Text.starts_with(Prefix =
"_T(\"") &&
2603 Text.ends_with(Postfix =
"\")"))) {
2604 return std::make_unique<BreakableStringLiteral>(
2606 State.Line->InPPDirective, Encoding, Style);
2608 }
else if (Current.is(TT_BlockComment)) {
2609 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2616 return std::make_unique<BreakableBlockComment>(
2617 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2618 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2619 }
else if (Current.is(TT_LineComment) &&
2620 (!Current.Previous ||
2621 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2622 bool RegularComments = [&]() {
2623 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2625 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2630 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2631 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2635 return std::make_unique<BreakableLineCommentSection>(
2636 Current, StartColumn,
false, Encoding, Style);
2641std::pair<unsigned, bool>
2642ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2644 bool DryRun,
bool Strict) {
2645 std::unique_ptr<const BreakableToken> Token =
2646 createBreakableToken(Current, State, AllowBreak);
2649 assert(Token->getLineCount() > 0);
2651 if (Current.is(TT_LineComment)) {
2653 ColumnLimit = Style.ColumnLimit;
2655 if (ColumnLimit == 0) {
2658 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2660 if (Current.UnbreakableTailLength >= ColumnLimit)
2664 unsigned StartColumn = State.Column - Current.ColumnWidth;
2665 unsigned NewBreakPenalty = Current.isStringLiteral()
2666 ? Style.PenaltyBreakString
2667 : Style.PenaltyBreakComment;
2670 bool Exceeded =
false;
2672 bool BreakInserted = Token->introducesBreakBeforeToken();
2675 bool NewBreakBefore =
false;
2679 bool Reflow =
false;
2682 unsigned TailOffset = 0;
2684 unsigned ContentStartColumn =
2685 Token->getContentStartColumn(0,
false);
2687 unsigned RemainingTokenColumns =
2688 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2691 Token->adaptStartOfLine(0, Whitespaces);
2693 unsigned ContentIndent = 0;
2694 unsigned Penalty = 0;
2695 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2696 << StartColumn <<
".\n");
2697 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2698 LineIndex != EndIndex; ++LineIndex) {
2699 LLVM_DEBUG(llvm::dbgs()
2700 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2701 NewBreakBefore =
false;
2705 bool TryReflow = Reflow;
2707 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2708 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2709 << (ContentStartColumn + RemainingTokenColumns)
2710 <<
", space: " << ColumnLimit
2711 <<
", reflown prefix: " << ContentStartColumn
2712 <<
", offset in line: " << TailOffset <<
"\n");
2718 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2719 ContentStartColumn, CommentPragmasRegex);
2720 if (
Split.first == StringRef::npos) {
2723 if (LineIndex < EndIndex - 1) {
2726 Penalty += Style.PenaltyExcessCharacter *
2727 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2729 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2732 assert(
Split.first != 0);
2734 if (Token->supportsReflow()) {
2754 unsigned ToSplitColumns = Token->getRangeLength(
2755 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2756 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2759 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2760 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2763 unsigned ToNextSplitColumns = 0;
2764 if (NextSplit.first == StringRef::npos) {
2765 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2766 ContentStartColumn);
2768 ToNextSplitColumns = Token->getRangeLength(
2769 LineIndex, TailOffset,
2770 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2774 ToNextSplitColumns =
2775 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2776 LLVM_DEBUG(llvm::dbgs()
2777 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2778 LLVM_DEBUG(llvm::dbgs()
2779 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2782 bool ContinueOnLine =
2783 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2784 unsigned ExcessCharactersPenalty = 0;
2785 if (!ContinueOnLine && !Strict) {
2788 ExcessCharactersPenalty =
2789 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2790 Style.PenaltyExcessCharacter;
2791 LLVM_DEBUG(llvm::dbgs()
2792 <<
" Penalty excess: " << ExcessCharactersPenalty
2793 <<
"\n break : " << NewBreakPenalty <<
"\n");
2794 if (ExcessCharactersPenalty < NewBreakPenalty) {
2796 ContinueOnLine =
true;
2799 if (ContinueOnLine) {
2800 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2805 Token->compressWhitespace(LineIndex, TailOffset, Split,
2809 ContentStartColumn += ToSplitColumns + 1;
2810 Penalty += ExcessCharactersPenalty;
2812 RemainingTokenColumns = Token->getRemainingLength(
2813 LineIndex, TailOffset, ContentStartColumn);
2817 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2822 ContentIndent = Token->getContentIndent(LineIndex);
2823 LLVM_DEBUG(llvm::dbgs()
2824 <<
" ContentIndent: " << ContentIndent <<
"\n");
2825 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2828 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2829 LineIndex, TailOffset +
Split.first +
Split.second,
2830 ContentStartColumn);
2831 if (NewRemainingTokenColumns == 0) {
2834 ContentStartColumn =
2835 Token->getContentStartColumn(LineIndex,
true);
2836 NewRemainingTokenColumns = Token->getRemainingLength(
2837 LineIndex, TailOffset +
Split.first +
Split.second,
2838 ContentStartColumn);
2844 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2849 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2850 <<
", " <<
Split.second <<
"\n");
2852 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2856 Penalty += NewBreakPenalty;
2858 RemainingTokenColumns = NewRemainingTokenColumns;
2859 BreakInserted =
true;
2860 NewBreakBefore =
true;
2864 if (LineIndex + 1 != EndIndex) {
2865 unsigned NextLineIndex = LineIndex + 1;
2866 if (NewBreakBefore) {
2885 ContentStartColumn += RemainingTokenColumns + 1;
2890 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2891 LLVM_DEBUG(llvm::dbgs()
2892 <<
" Size of reflown text: " << ContentStartColumn
2893 <<
"\n Potential reflow split: ");
2894 if (SplitBeforeNext.first != StringRef::npos) {
2895 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2896 << SplitBeforeNext.second <<
"\n");
2897 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2900 RemainingTokenColumns = Token->getRemainingLength(
2901 NextLineIndex, TailOffset, ContentStartColumn);
2903 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2904 LLVM_DEBUG(llvm::dbgs()
2905 <<
" Over limit after reflow, need: "
2906 << (ContentStartColumn + RemainingTokenColumns)
2907 <<
", space: " << ColumnLimit
2908 <<
", reflown prefix: " << ContentStartColumn
2909 <<
", offset in line: " << TailOffset <<
"\n");
2915 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2916 ContentStartColumn, CommentPragmasRegex);
2917 if (
Split.first == StringRef::npos) {
2918 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2924 unsigned ToSplitColumns = Token->getRangeLength(
2925 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2926 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2927 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2928 << (ContentStartColumn + ToSplitColumns)
2929 <<
", space: " << ColumnLimit);
2930 unsigned ExcessCharactersPenalty =
2931 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2932 Style.PenaltyExcessCharacter;
2933 if (NewBreakPenalty < ExcessCharactersPenalty)
2939 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2947 ContentStartColumn =
2948 Token->getContentStartColumn(NextLineIndex,
false);
2949 RemainingTokenColumns = Token->getRemainingLength(
2950 NextLineIndex, TailOffset, ContentStartColumn);
2953 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2968 if (NewBreakBefore) {
2969 assert(Penalty >= NewBreakPenalty);
2970 Penalty -= NewBreakPenalty;
2973 Token->reflow(NextLineIndex, Whitespaces);
2979 Token->getSplitAfterLastLine(TailOffset);
2980 if (SplitAfterLastLine.first != StringRef::npos) {
2981 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2985 Penalty += Style.PenaltyExcessCharacter *
2986 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2989 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2992 ContentStartColumn =
2993 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2994 RemainingTokenColumns = Token->getRemainingLength(
2995 Token->getLineCount() - 1,
2996 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2997 ContentStartColumn);
3000 State.Column = ContentStartColumn + RemainingTokenColumns -
3001 Current.UnbreakableTailLength;
3003 if (BreakInserted) {
3005 Token->updateAfterBroken(Whitespaces);
3010 if (Current.isNot(TT_LineComment))
3011 for (ParenState &
Paren : State.Stack)
3012 Paren.BreakBeforeParameter =
true;
3014 if (Current.is(TT_BlockComment))
3015 State.NoContinuation =
true;
3017 State.Stack.back().LastSpace = StartColumn;
3020 Token->updateNextToken(State);
3022 return {Penalty, Exceeded};
3027 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3030bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3032 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3037 if (Current.
TokenText.starts_with(
"R\""))
3041 if (Current.getNextNonComment() &&
3042 Current.getNextNonComment()->isStringLiteral()) {
3045 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3047 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)) {....
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.
const FunctionProtoType * T
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...