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 nullptr, 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) ||
1021 Previous.is(TT_VerilogMultiLineListLParen)) &&
1022 !IsInTemplateString(Current,
false)) {
1023 CurrentState.Indent = State.
Column + Spaces;
1024 CurrentState.AlignedTo = &
Previous;
1027 CurrentState.NoLineBreak =
true;
1029 CurrentState.NoLineBreak =
true;
1032 State.
Column > getNewLineColumn(State).Total) {
1033 CurrentState.ContainsUnwrappedBuilder =
true;
1036 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1037 CurrentState.NoLineBreak =
true;
1038 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1047 CurrentState.NoLineBreak =
true;
1054 const FormatToken *P = Current.getPreviousNonComment();
1055 if (Current.
isNot(tok::comment) && P &&
1056 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1057 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1058 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1062 bool BreakBeforeOperator =
1063 P->MustBreakBefore || P->is(tok::lessless) ||
1064 (P->is(TT_BinaryOperator) &&
1065 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1066 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1070 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1071 P->isNot(TT_ConditionalExpr);
1072 if ((!BreakBeforeOperator &&
1074 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1075 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1076 CurrentState.NoLineBreakInOperand =
true;
1081 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1086 CurrentState.LastSpace = State.
Column;
1087 CurrentState.NestedBlockIndent = State.
Column;
1088 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1090 Previous.isNot(TT_OverloadedOperator)) ||
1092 CurrentState.LastSpace = State.
Column;
1093 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1095 Style.BreakConstructorInitializers ==
1096 FormatStyle::BCIS_AfterColon) {
1097 CurrentState.Indent = State.
Column;
1098 CurrentState.LastSpace = State.
Column;
1099 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1100 CurrentState.LastSpace = State.
Column;
1101 }
else if (
Previous.is(TT_BinaryOperator) &&
1108 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1109 CurrentState.LastSpace = State.
Column;
1110 }
else if (
Previous.is(TT_InheritanceColon)) {
1111 CurrentState.Indent = State.
Column;
1112 CurrentState.LastSpace = State.
Column;
1113 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1114 CurrentState.ColonPos = State.
Column;
1115 }
else if (
Previous.opensScope()) {
1123 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1124 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1125 CurrentState.LastSpace = State.
Column;
1131unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1134 assert(State.NextToken->Previous);
1136 auto &CurrentState = State.Stack.back();
1140 unsigned Penalty = 0;
1142 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1144 if (!NextNonComment)
1145 NextNonComment = &Current;
1148 if (!CurrentState.ContainsLineBreak)
1150 CurrentState.ContainsLineBreak =
true;
1152 Penalty += State.NextToken->SplitPenalty;
1157 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1158 (State.Column <= Style.ColumnLimit / 3 ||
1159 CurrentState.BreakBeforeParameter)) {
1160 Penalty += Style.PenaltyBreakFirstLessLess;
1163 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1164 State.Column = TotalColumn;
1178 if (State.Column > State.FirstIndent) {
1180 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1193 if (Current.isNot(TT_LambdaArrow) &&
1194 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1195 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1196 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1197 CurrentState.NestedBlockIndent = State.Column;
1200 if (NextNonComment->isMemberAccess()) {
1201 if (CurrentState.CallContinuation == 0)
1202 CurrentState.CallContinuation = State.Column;
1203 }
else if (NextNonComment->is(TT_SelectorName)) {
1204 if (!CurrentState.ObjCSelectorNameFound) {
1205 if (NextNonComment->LongestObjCSelectorName == 0) {
1206 CurrentState.AlignColons =
false;
1208 CurrentState.ColonPos =
1210 ? std::max(CurrentState.Indent.Total,
1211 State.FirstIndent + Style.ContinuationIndentWidth)
1212 : CurrentState.
Indent.Total) +
1216 }
else if (CurrentState.AlignColons &&
1217 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1218 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1220 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1221 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1231 if (State.Stack.size() > 1) {
1232 State.Stack[State.Stack.size() - 2].LastSpace =
1233 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1234 Style.ContinuationIndentWidth;
1238 switch (Style.BreakInheritanceList) {
1239 case FormatStyle::BILS_BeforeColon:
1240 case FormatStyle::BILS_AfterComma:
1241 if (Current.is(TT_InheritanceColon) ||
Previous.is(TT_InheritanceComma)) {
1242 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1243 tok::kw_class, tok::kw_struct, tok::kw_union);
1246 case FormatStyle::BILS_BeforeComma:
1247 if (Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma)) {
1248 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1249 tok::kw_class, tok::kw_struct, tok::kw_union);
1252 case FormatStyle::BILS_AfterColon:
1253 if (
Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma))
1254 CurrentState.AlignedTo = &
Previous;
1258 if ((PreviousNonComment &&
1259 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1260 !CurrentState.AvoidBinPacking) ||
1262 CurrentState.BreakBeforeParameter =
false;
1264 if (PreviousNonComment &&
1265 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1266 PreviousNonComment->ClosesRequiresClause) &&
1267 Current.NestingLevel == 0) {
1268 CurrentState.BreakBeforeParameter =
false;
1270 if (NextNonComment->is(tok::question) ||
1271 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1272 CurrentState.BreakBeforeParameter =
true;
1274 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1275 CurrentState.BreakBeforeParameter =
false;
1276 CurrentState.AlignedTo = &Current;
1281 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1284 !Current.MatchingParen->Children.empty()) {
1292 const bool ContinuePPDirective = State.Line->InPPDirective &&
1294 Current.isNot(TT_LineComment);
1295 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1296 CurrentState.AlignedTo, ContinuePPDirective,
1297 IndentedFromColumn);
1300 if (!Current.isTrailingComment())
1301 CurrentState.LastSpace = State.Column;
1302 if (Current.is(tok::lessless)) {
1306 CurrentState.LastSpace += 3;
1309 State.StartOfLineLevel = Current.NestingLevel;
1310 State.LowestLevelOnLine = Current.NestingLevel;
1314 bool NestedBlockSpecialCase =
1315 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1316 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1317 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1318 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1320 NestedBlockSpecialCase =
1321 NestedBlockSpecialCase ||
1322 (Current.MatchingParen &&
1323 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1324 if (!NestedBlockSpecialCase) {
1325 auto ParentLevelIt = std::next(State.Stack.rbegin());
1326 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1327 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1342 auto FindCurrentLevel = [&](
const auto &It) {
1343 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1344 return PState.Tok != nullptr;
1347 auto MaybeIncrement = [&](
const auto &It) {
1348 return It != State.Stack.rend() ? std::next(It) : It;
1350 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1351 auto LevelContainingLambdaIt =
1352 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1353 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1355 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1356 I->BreakBeforeParameter =
true;
1359 if (PreviousNonComment &&
1360 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1361 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1362 !PreviousNonComment->ClosesRequiresClause) ||
1363 Current.NestingLevel != 0) &&
1364 PreviousNonComment->isNoneOf(
1365 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1366 TT_LeadingJavaAnnotation) &&
1367 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1370 (!Style.BraceWrapping.BeforeLambdaBody ||
1371 Current.isNot(TT_LambdaLBrace))) {
1372 CurrentState.BreakBeforeParameter =
true;
1377 if (PreviousNonComment &&
1378 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1380 CurrentState.BreakBeforeClosingBrace =
true;
1383 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1384 if (
auto Previous = PreviousNonComment->Previous) {
1386 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1387 }
else if (
Previous->isLoop(Style)) {
1388 CurrentState.BreakBeforeClosingParen =
1389 Style.BreakBeforeCloseBracketLoop;
1390 }
else if (
Previous->is(tok::kw_switch)) {
1391 CurrentState.BreakBeforeClosingParen =
1392 Style.BreakBeforeCloseBracketSwitch;
1394 CurrentState.BreakBeforeClosingParen =
1395 Style.BreakBeforeCloseBracketFunction;
1400 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1401 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1403 if (CurrentState.AvoidBinPacking) {
1408 bool PreviousIsBreakingCtorInitializerColon =
1409 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1410 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1411 bool AllowAllConstructorInitializersOnNextLine =
1412 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1413 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1414 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1415 !PreviousIsBreakingCtorInitializerColon) ||
1416 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1417 State.Line->MustBeDeclaration) ||
1418 (!Style.AllowAllArgumentsOnNextLine &&
1419 !State.Line->MustBeDeclaration) ||
1420 (!AllowAllConstructorInitializersOnNextLine &&
1421 PreviousIsBreakingCtorInitializerColon) ||
1423 CurrentState.BreakBeforeParameter =
true;
1429 if (PreviousIsBreakingCtorInitializerColon &&
1430 AllowAllConstructorInitializersOnNextLine) {
1431 CurrentState.BreakBeforeParameter =
false;
1436 CurrentState.BreakBeforeParameter =
true;
1442ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1443 if (!State.NextToken || !State.NextToken->Previous)
1447 const auto &CurrentState = State.Stack.back();
1449 if (CurrentState.IsCSharpGenericTypeConstraint &&
1450 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1451 return CurrentState.ColonPos + 2;
1456 const auto ContinuationIndent =
1457 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1458 CurrentState.Indent) +
1459 Style.ContinuationIndentWidth;
1460 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1462 if (!NextNonComment)
1463 NextNonComment = &Current;
1466 if (Style.isJava() &&
1467 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1468 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1469 CurrentState.Indent + Style.ContinuationIndentWidth);
1474 if (Style.isVerilog() && PreviousNonComment &&
1475 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1476 return State.FirstIndent;
1479 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1480 State.Line->First->is(tok::kw_enum)) {
1481 return IndentationAndAlignment(Style.IndentWidth *
1482 State.Line->First->IndentLevel) +
1486 if (Style.BraceWrapping.BeforeLambdaBody &&
1487 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1488 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1489 ? CurrentState.Indent
1490 : State.FirstIndent;
1491 return From + Style.IndentWidth;
1494 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1495 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1496 if (Current.NestingLevel == 0 ||
1497 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1498 State.NextToken->is(TT_LambdaLBrace))) {
1499 return State.FirstIndent;
1501 return CurrentState.Indent;
1503 if (Current.is(TT_LambdaArrow) &&
1504 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1505 tok::kw_consteval, tok::kw_static,
1506 TT_AttributeRSquare)) {
1507 return ContinuationIndent;
1509 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1510 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1511 State.Stack.size() > 1) {
1512 if (Current.closesBlockOrBlockTypeList(Style))
1513 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1514 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1515 return State.Stack[State.Stack.size() - 2].LastSpace;
1516 return State.FirstIndent;
1533 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1535 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1536 return State.Stack[State.Stack.size() - 2].LastSpace;
1540 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1541 State.Stack.size() > 1) {
1542 return State.Stack[State.Stack.size() - 2].LastSpace;
1544 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1545 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1546 State.Stack.size() > 1) {
1547 return State.Stack[State.Stack.size() - 2].LastSpace;
1549 if ((Style.BreakBeforeCloseBracketFunction ||
1550 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1551 Style.BreakBeforeCloseBracketSwitch) &&
1552 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1553 return State.Stack[State.Stack.size() - 2].LastSpace;
1555 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1556 State.Stack.size() > 1) {
1557 return State.Stack[State.Stack.size() - 2].LastSpace;
1559 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1560 return State.Stack[State.Stack.size() - 2].LastSpace;
1568 if (Current.is(tok::identifier) && Current.Next &&
1569 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1570 (Current.Next->is(TT_DictLiteral) ||
1571 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1572 return CurrentState.Indent;
1574 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1575 State.StartOfStringLiteral != 0) {
1576 return State.StartOfStringLiteral - 1;
1578 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1579 return State.StartOfStringLiteral;
1580 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1581 return CurrentState.FirstLessLess;
1582 if (NextNonComment->isMemberAccess()) {
1583 if (CurrentState.CallContinuation == 0)
1584 return ContinuationIndent;
1585 return CurrentState.CallContinuation;
1587 if (CurrentState.QuestionColumn != 0 &&
1588 ((NextNonComment->is(tok::colon) &&
1589 NextNonComment->is(TT_ConditionalExpr)) ||
1590 Previous.is(TT_ConditionalExpr))) {
1591 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1592 !NextNonComment->Next->FakeLParens.empty() &&
1594 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1596 !CurrentState.IsWrappedConditional) {
1601 unsigned Indent = CurrentState.Indent.Total;
1602 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1603 Indent -= Style.ContinuationIndentWidth;
1604 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1608 return CurrentState.QuestionColumn;
1610 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1611 return CurrentState.VariablePos;
1612 if (Current.is(TT_RequiresClause)) {
1613 if (Style.IndentRequiresClause)
1614 return CurrentState.Indent + Style.IndentWidth;
1615 switch (Style.RequiresClausePosition) {
1616 case FormatStyle::RCPS_OwnLine:
1617 case FormatStyle::RCPS_WithFollowing:
1618 case FormatStyle::RCPS_OwnLineWithBrace:
1619 return CurrentState.Indent;
1624 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1625 TT_InheritanceComma)) {
1626 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1628 if ((PreviousNonComment &&
1629 (PreviousNonComment->ClosesTemplateDeclaration ||
1630 PreviousNonComment->ClosesRequiresClause ||
1631 (PreviousNonComment->is(TT_AttributeMacro) &&
1632 Current.isNot(tok::l_paren) &&
1633 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1634 TT_PointerOrReference)) ||
1635 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1636 TT_FunctionAnnotationRParen,
1638 TT_LeadingJavaAnnotation))) ||
1639 (!Style.IndentWrappedFunctionNames &&
1640 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1641 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1642 CurrentState.Indent);
1644 if (NextNonComment->is(TT_SelectorName)) {
1645 if (!CurrentState.ObjCSelectorNameFound) {
1646 auto MinIndent = CurrentState.Indent;
1649 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1650 Style.ContinuationIndentWidth);
1661 return MinIndent.addPadding(
1662 std::max(NextNonComment->LongestObjCSelectorName,
1663 NextNonComment->ColumnWidth) -
1664 NextNonComment->ColumnWidth);
1666 if (!CurrentState.AlignColons)
1667 return CurrentState.Indent;
1668 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1669 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1670 return CurrentState.Indent;
1672 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1673 return CurrentState.ColonPos;
1674 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1675 if (CurrentState.StartOfArraySubscripts != 0) {
1676 return CurrentState.StartOfArraySubscripts;
1677 }
else if (Style.isCSharp()) {
1679 return CurrentState.Indent;
1681 return ContinuationIndent;
1686 if (State.Line->InPragmaDirective) {
1687 FormatToken *PragmaType = State.Line->First->Next->Next;
1688 if (PragmaType && PragmaType->TokenText ==
"omp")
1689 return CurrentState.Indent + Style.ContinuationIndentWidth;
1694 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1695 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1696 return CurrentState.Indent;
1699 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1700 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1701 return ContinuationIndent;
1703 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1704 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1705 return ContinuationIndent;
1707 if (NextNonComment->is(TT_CtorInitializerComma))
1708 return CurrentState.Indent;
1709 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1710 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1711 return CurrentState.Indent;
1713 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1714 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1715 return CurrentState.Indent;
1718 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1719 !Current.isBinaryOperator() &&
1720 Current.isNoneOf(tok::colon, tok::comment)) {
1721 return ContinuationIndent;
1723 if (Current.is(TT_ProtoExtensionLSquare))
1724 return CurrentState.Indent;
1725 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1726 return CurrentState.Indent - Current.Tok.getLength() -
1727 Current.SpacesRequiredBefore;
1729 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1730 CurrentState.UnindentOperator) {
1731 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1732 NextNonComment->SpacesRequiredBefore;
1734 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1735 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1738 return CurrentState.Indent + Style.ContinuationIndentWidth;
1740 return CurrentState.Indent;
1745 const FormatStyle &Style) {
1752 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1755unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1756 bool DryRun,
bool Newline) {
1757 assert(State.Stack.size());
1759 auto &CurrentState = State.Stack.back();
1761 if (Current.is(TT_CSharpGenericTypeConstraint))
1762 CurrentState.IsCSharpGenericTypeConstraint =
true;
1763 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1764 CurrentState.NoLineBreakInOperand =
false;
1765 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1766 CurrentState.AvoidBinPacking =
true;
1767 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1768 if (CurrentState.FirstLessLess == 0)
1769 CurrentState.FirstLessLess = State.Column;
1771 CurrentState.LastOperatorWrapped = Newline;
1773 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1774 CurrentState.LastOperatorWrapped = Newline;
1775 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1776 Current.Previous->isNot(TT_ConditionalExpr)) {
1777 CurrentState.LastOperatorWrapped = Newline;
1779 if (Current.is(TT_ArraySubscriptLSquare) &&
1780 CurrentState.StartOfArraySubscripts == 0) {
1781 CurrentState.StartOfArraySubscripts = State.Column;
1785 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1787 if (
Tok.MustBreakBefore)
1791 return Next &&
Next->MustBreakBefore;
1793 if (IsWrappedConditional(Current))
1794 CurrentState.IsWrappedConditional =
true;
1795 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1796 CurrentState.QuestionColumn = State.Column;
1797 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1802 CurrentState.QuestionColumn = State.Column;
1804 if (!Current.opensScope() && !Current.closesScope() &&
1805 Current.isNot(TT_PointerOrReference)) {
1806 State.LowestLevelOnLine =
1807 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1809 if (Current.isMemberAccess())
1810 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1811 if (Current.is(TT_SelectorName))
1812 CurrentState.ObjCSelectorNameFound =
true;
1813 if (Current.is(TT_CtorInitializerColon) &&
1814 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1820 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1821 FormatStyle::BCIS_BeforeComma
1824 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1825 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1826 CurrentState.AvoidBinPacking =
true;
1827 CurrentState.BreakBeforeParameter =
1828 Style.ColumnLimit > 0 &&
1829 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1830 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1832 CurrentState.BreakBeforeParameter =
false;
1835 if (Current.is(TT_CtorInitializerColon) &&
1836 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1837 CurrentState.Indent =
1838 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1839 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1840 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1841 CurrentState.AvoidBinPacking =
true;
1843 CurrentState.BreakBeforeParameter =
false;
1845 if (Current.is(TT_InheritanceColon)) {
1846 CurrentState.Indent =
1847 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1849 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1850 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1851 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1852 CurrentState.LastSpace = State.Column;
1853 if (Current.is(TT_RequiresExpression) &&
1854 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1855 CurrentState.NestedBlockIndent = State.Column;
1867 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1869 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1870 !CurrentState.HasMultipleNestedBlocks) {
1871 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1872 for (ParenState &PState : llvm::drop_end(State.Stack))
1873 PState.NoLineBreak =
true;
1874 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1876 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1877 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1878 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1879 TT_CtorInitializerColon)))) {
1880 CurrentState.NestedBlockInlined =
1884 moveStatePastFakeLParens(State, Newline);
1885 moveStatePastScopeCloser(State);
1888 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1889 !State.Stack.back().NoLineBreakInOperand;
1890 moveStatePastScopeOpener(State, Newline);
1891 moveStatePastFakeRParens(State);
1893 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1894 State.StartOfStringLiteral = State.Column + 1;
1895 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1896 State.StartOfStringLiteral = State.Column + 1;
1897 }
else if (Current.is(TT_TableGenMultiLineString) &&
1898 State.StartOfStringLiteral == 0) {
1899 State.StartOfStringLiteral = State.Column + 1;
1900 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1901 State.StartOfStringLiteral = State.Column;
1902 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1903 !Current.isStringLiteral()) {
1904 State.StartOfStringLiteral = 0;
1907 State.Column += Current.ColumnWidth;
1908 State.NextToken = State.NextToken->Next;
1913 if (Style.isVerilog() && State.NextToken &&
1914 State.NextToken->MustBreakBefore &&
1915 Keywords.isVerilogEndOfLabel(Current)) {
1916 State.FirstIndent += Style.IndentWidth;
1917 CurrentState.Indent = State.FirstIndent;
1921 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1924 Current.Role->formatFromToken(State,
this, DryRun);
1931 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1936void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1939 if (Current.FakeLParens.empty())
1947 bool SkipFirstExtraIndent =
1950 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1952 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1954 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1955 const auto &CurrentState = State.Stack.back();
1956 ParenState NewParenState = CurrentState;
1957 NewParenState.Tok =
nullptr;
1958 NewParenState.ContainsLineBreak =
false;
1959 NewParenState.LastOperatorWrapped =
true;
1960 NewParenState.IsChainedConditional =
false;
1961 NewParenState.IsWrappedConditional =
false;
1962 NewParenState.UnindentOperator =
false;
1963 NewParenState.NoLineBreak =
1964 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1968 NewParenState.AvoidBinPacking =
false;
1973 if (!Current.isTrailingComment() &&
1974 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1977 (!Style.isJava() && PrecedenceLevel > 0)) &&
1978 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1979 Current.NestingLevel == 0) &&
1980 (!Style.isTableGen() ||
1982 TT_TableGenDAGArgListCommaToBreak)))) {
1983 NewParenState.Indent =
1984 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1985 IndentationAndAlignment(CurrentState.LastSpace)});
1992 State.Stack.size() > 1) {
1993 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1994 Style.ContinuationIndentWidth;
2004 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
2005 NewParenState.UnindentOperator =
true;
2007 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
2008 NewParenState.AlignedTo =
Previous;
2018 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2020 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2021 NewParenState.StartOfFunctionCall = State.Column;
2031 &PrecedenceLevel == &Current.FakeLParens.back() &&
2032 !CurrentState.IsWrappedConditional) {
2033 NewParenState.IsChainedConditional =
true;
2034 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2037 !Current.isTrailingComment())) {
2038 NewParenState.Indent += Style.ContinuationIndentWidth;
2041 NewParenState.BreakBeforeParameter =
false;
2042 State.Stack.push_back(NewParenState);
2043 SkipFirstExtraIndent =
false;
2047void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2048 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2049 unsigned VariablePos = State.Stack.back().VariablePos;
2050 if (State.Stack.size() == 1) {
2054 State.Stack.pop_back();
2055 State.Stack.back().VariablePos = VariablePos;
2058 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2061 State.Stack.back().LastSpace -= Style.IndentWidth;
2065void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2068 if (!Current.opensScope())
2071 const auto &CurrentState = State.Stack.back();
2074 if (Current.isOneOf(tok::less, tok::l_paren) &&
2075 CurrentState.IsCSharpGenericTypeConstraint) {
2079 if (Current.MatchingParen && Current.is(
BK_Block)) {
2080 moveStateToNewBlock(State, Newline);
2087 const auto *Prev =
Tok->getPreviousNonComment();
2090 return Prev->is(tok::comma);
2091 }(Current.MatchingParen);
2093 IndentationAndAlignment NewIndent = 0;
2094 unsigned LastSpace = CurrentState.LastSpace;
2095 bool AvoidBinPacking;
2096 bool BreakBeforeParameter =
false;
2097 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2098 CurrentState.NestedBlockIndent);
2099 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2101 if (Current.opensBlockOrBlockTypeList(Style)) {
2102 NewIndent = Style.IndentWidth +
2103 std::min(State.Column, CurrentState.NestedBlockIndent);
2104 }
else if (Current.is(tok::l_brace)) {
2105 const auto Width = Style.BracedInitializerIndentWidth;
2106 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2107 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2109 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2111 const FormatToken *NextNonComment = Current.getNextNonComment();
2112 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2113 Style.isProto() || !Style.BinPackArguments ||
2114 (NextNonComment && NextNonComment->isOneOf(
2115 TT_DesignatedInitializerPeriod,
2116 TT_DesignatedInitializerLSquare));
2117 BreakBeforeParameter = EndsInComma;
2118 if (Current.ParameterCount > 1)
2119 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2121 NewIndent = IndentationAndAlignment(std::max(
2122 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2123 Style.ContinuationIndentWidth;
2125 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2126 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2132 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2133 NewIndent = State.Column +
Next->TokenText.size() + 2;
2140 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2141 NewIndent = std::max(NewIndent, CurrentState.Indent);
2142 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2148 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2149 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2150 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2152 bool BinPackDeclaration =
2154 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2157 bool GenericSelection =
2158 Current.getPreviousNonComment() &&
2159 Current.getPreviousNonComment()->is(tok::kw__Generic);
2162 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2163 (Style.isJavaScript() && EndsInComma) ||
2164 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2165 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2166 (Style.ExperimentalAutoDetectBinPacking &&
2170 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2171 Style.ObjCBreakBeforeNestedBlockParam) {
2172 if (Style.ColumnLimit) {
2177 BreakBeforeParameter =
true;
2183 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2184 if (
Tok->MustBreakBefore ||
2185 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2186 BreakBeforeParameter =
true;
2193 if (Style.isJavaScript() && EndsInComma)
2194 BreakBeforeParameter =
true;
2200 Current.Children.empty() &&
2201 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2202 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2203 (Current.is(TT_TemplateOpener) &&
2204 CurrentState.ContainsUnwrappedBuilder));
2205 State.Stack.push_back(
2206 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2207 auto &NewState = State.Stack.back();
2208 NewState.NestedBlockIndent = NestedBlockIndent;
2209 NewState.BreakBeforeParameter = BreakBeforeParameter;
2210 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2212 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2213 Current.is(tok::l_paren)) {
2217 if (next->is(TT_LambdaLSquare)) {
2218 NewState.HasMultipleNestedBlocks =
true;
2225 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2227 Current.Previous->is(tok::at);
2230void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2232 if (!Current.closesScope())
2237 if (State.Stack.size() > 1 &&
2238 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2239 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2240 State.NextToken->is(TT_TemplateCloser) ||
2241 State.NextToken->is(TT_TableGenListCloser) ||
2242 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2243 State.Stack.pop_back();
2246 auto &CurrentState = State.Stack.back();
2258 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2259 Current.MatchingParen->Previous) {
2260 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2261 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2262 CurrentScopeOpener.MatchingParen) {
2263 int NecessarySpaceInLine =
2265 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2266 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2267 Style.ColumnLimit) {
2268 CurrentState.BreakBeforeParameter =
false;
2273 if (Current.is(tok::r_square)) {
2275 const FormatToken *NextNonComment = Current.getNextNonComment();
2276 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2277 CurrentState.StartOfArraySubscripts = 0;
2281void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2282 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2283 State.NextToken->is(TT_LambdaLBrace) &&
2284 !State.Line->MightBeFunctionDecl) {
2285 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2286 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2288 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2290 unsigned NewIndent =
2291 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2292 ? Style.ObjCBlockIndentWidth
2293 : Style.IndentWidth);
2300 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2301 State.NextToken->is(TT_LambdaLBrace);
2303 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2304 State.Stack.back().LastSpace,
2305 true, NoLineBreak));
2306 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2307 State.Stack.back().BreakBeforeParameter =
true;
2313 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2314 if (LastNewlinePos == StringRef::npos) {
2315 return StartColumn +
2323unsigned ContinuationIndenter::reformatRawStringLiteral(
2325 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2326 unsigned StartColumn = State.Column - Current.ColumnWidth;
2328 StringRef NewDelimiter =
2330 if (NewDelimiter.empty())
2331 NewDelimiter = OldDelimiter;
2334 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2335 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2338 std::string RawText = std::string(
2339 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2340 if (NewDelimiter != OldDelimiter) {
2343 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2344 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2345 NewDelimiter = OldDelimiter;
2348 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2349 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2352 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2363 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2385 unsigned CurrentIndent =
2386 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2387 ? State.Stack.back().NestedBlockIndent
2388 : State.Stack.back().Indent.Total;
2389 unsigned NextStartColumn = ContentStartsOnNewline
2390 ? CurrentIndent + Style.IndentWidth
2401 unsigned LastStartColumn =
2402 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2405 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2406 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2411 return addMultilineToken(Current, State);
2413 if (NewDelimiter != OldDelimiter) {
2416 SourceLocation PrefixDelimiterStart =
2417 Current.Tok.getLocation().getLocWithOffset(2);
2418 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2419 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2422 <<
"Failed to update the prefix delimiter of a raw string: "
2423 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2427 SourceLocation SuffixDelimiterStart =
2428 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2429 1 - OldDelimiter.size());
2430 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2431 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2434 <<
"Failed to update the suffix delimiter of a raw string: "
2435 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2438 SourceLocation OriginLoc =
2439 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2440 for (
const tooling::Replacement &Fix : Fixes.first) {
2441 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2442 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2443 Fix.getLength(), Fix.getReplacementText()));
2445 llvm::errs() <<
"Failed to reformat raw string: "
2446 << llvm::toString(std::move(Err)) <<
"\n";
2451 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2452 State.Column = RawLastLineEndColumn + NewSuffixSize;
2456 unsigned PrefixExcessCharacters =
2457 StartColumn + NewPrefixSize > Style.ColumnLimit
2458 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2461 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2464 for (ParenState &
Paren : State.Stack)
2465 Paren.BreakBeforeParameter =
true;
2467 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2470unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2473 for (ParenState &
Paren : State.Stack)
2474 Paren.BreakBeforeParameter =
true;
2476 unsigned ColumnsUsed = State.Column;
2479 State.Column = Current.LastLineColumnWidth;
2482 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2486unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2488 bool AllowBreak,
bool Newline) {
2489 unsigned Penalty = 0;
2492 auto RawStringStyle = getRawStringStyle(Current, State);
2493 if (RawStringStyle && !Current.Finalized) {
2494 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2496 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2499 Penalty = addMultilineToken(Current, State);
2502 LineState OriginalState = State;
2506 bool Strict =
false;
2509 bool Exceeded =
false;
2510 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2511 Current, State, AllowBreak,
true, Strict);
2515 LineState StrictState = OriginalState;
2516 unsigned StrictPenalty =
2517 breakProtrudingToken(Current, StrictState, AllowBreak,
2520 Strict = StrictPenalty <= Penalty;
2522 Penalty = StrictPenalty;
2523 State = std::move(StrictState);
2529 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2534 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2535 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2544 auto Tok = Current.getPreviousNonComment();
2545 if (!
Tok ||
Tok->isNot(tok::l_paren))
2547 Tok =
Tok->getPreviousNonComment();
2550 if (
Tok->is(TT_TemplateCloser)) {
2551 Tok =
Tok->MatchingParen;
2553 Tok =
Tok->getPreviousNonComment();
2555 if (!
Tok ||
Tok->isNot(tok::identifier))
2557 return Tok->TokenText;
2560std::optional<FormatStyle>
2561ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2562 const LineState &State) {
2563 if (!Current.isStringLiteral())
2564 return std::nullopt;
2567 return std::nullopt;
2569 if (!RawStringStyle && Delimiter->empty()) {
2573 if (!RawStringStyle)
2574 return std::nullopt;
2576 return RawStringStyle;
2579std::unique_ptr<BreakableToken>
2580ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2582 unsigned StartColumn = State.Column - Current.ColumnWidth;
2583 if (Current.isStringLiteral()) {
2586 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2600 if (Current.IsUnterminatedLiteral)
2604 if (State.Stack.back().IsInsideObjCArrayLiteral)
2611 if (Style.isVerilog() && Current.Previous &&
2612 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2615 StringRef
Text = Current.TokenText;
2625 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2628 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2629 Text.ends_with(
"'")) {
2631 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2632 Text.ends_with(
"\"")) {
2634 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2639 return std::make_unique<BreakableStringLiteralUsingOperators>(
2640 Current, QuoteStyle,
2651 if ((
Text.ends_with(Postfix =
"\"") &&
2652 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2653 Text.starts_with(Prefix =
"u\"") ||
2654 Text.starts_with(Prefix =
"U\"") ||
2655 Text.starts_with(Prefix =
"u8\"") ||
2656 Text.starts_with(Prefix =
"L\""))) ||
2657 (
Text.starts_with(Prefix =
"_T(\"") &&
2658 Text.ends_with(Postfix =
"\")"))) {
2659 return std::make_unique<BreakableStringLiteral>(
2661 State.Line->InPPDirective, Encoding, Style);
2663 }
else if (Current.is(TT_BlockComment)) {
2664 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2671 return std::make_unique<BreakableBlockComment>(
2672 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2673 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2674 }
else if (Current.is(TT_LineComment) &&
2675 (!Current.Previous ||
2676 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2677 bool RegularComments = [&]() {
2678 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2680 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2685 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2686 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2690 return std::make_unique<BreakableLineCommentSection>(
2691 Current, StartColumn,
false, Encoding, Style);
2696std::pair<unsigned, bool>
2697ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2699 bool DryRun,
bool Strict) {
2700 std::unique_ptr<const BreakableToken> Token =
2701 createBreakableToken(Current, State, AllowBreak);
2704 assert(Token->getLineCount() > 0);
2706 if (Current.is(TT_LineComment)) {
2708 ColumnLimit = Style.ColumnLimit;
2710 if (ColumnLimit == 0) {
2713 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2715 if (Current.UnbreakableTailLength >= ColumnLimit)
2719 unsigned StartColumn = State.Column - Current.ColumnWidth;
2720 unsigned NewBreakPenalty = Current.isStringLiteral()
2721 ? Style.PenaltyBreakString
2722 : Style.PenaltyBreakComment;
2725 bool Exceeded =
false;
2727 bool BreakInserted = Token->introducesBreakBeforeToken();
2730 bool NewBreakBefore =
false;
2734 bool Reflow =
false;
2737 unsigned TailOffset = 0;
2739 unsigned ContentStartColumn =
2740 Token->getContentStartColumn(0,
false);
2742 unsigned RemainingTokenColumns =
2743 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2746 Token->adaptStartOfLine(0, Whitespaces);
2748 unsigned ContentIndent = 0;
2749 unsigned Penalty = 0;
2750 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2751 << StartColumn <<
".\n");
2752 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2753 LineIndex != EndIndex; ++LineIndex) {
2754 LLVM_DEBUG(llvm::dbgs()
2755 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2756 NewBreakBefore =
false;
2760 bool TryReflow = Reflow;
2762 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2763 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2764 << (ContentStartColumn + RemainingTokenColumns)
2765 <<
", space: " << ColumnLimit
2766 <<
", reflown prefix: " << ContentStartColumn
2767 <<
", offset in line: " << TailOffset <<
"\n");
2773 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2774 ContentStartColumn, CommentPragmasRegex);
2775 if (
Split.first == StringRef::npos) {
2778 if (LineIndex < EndIndex - 1) {
2781 Penalty += Style.PenaltyExcessCharacter *
2782 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2784 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2787 assert(
Split.first != 0);
2789 if (Token->supportsReflow()) {
2809 unsigned ToSplitColumns = Token->getRangeLength(
2810 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2811 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2814 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2815 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2818 unsigned ToNextSplitColumns = 0;
2819 if (NextSplit.first == StringRef::npos) {
2820 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2821 ContentStartColumn);
2823 ToNextSplitColumns = Token->getRangeLength(
2824 LineIndex, TailOffset,
2825 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2829 ToNextSplitColumns =
2830 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2831 LLVM_DEBUG(llvm::dbgs()
2832 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2833 LLVM_DEBUG(llvm::dbgs()
2834 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2837 bool ContinueOnLine =
2838 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2839 unsigned ExcessCharactersPenalty = 0;
2840 if (!ContinueOnLine && !Strict) {
2843 ExcessCharactersPenalty =
2844 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2845 Style.PenaltyExcessCharacter;
2846 LLVM_DEBUG(llvm::dbgs()
2847 <<
" Penalty excess: " << ExcessCharactersPenalty
2848 <<
"\n break : " << NewBreakPenalty <<
"\n");
2849 if (ExcessCharactersPenalty < NewBreakPenalty) {
2851 ContinueOnLine =
true;
2854 if (ContinueOnLine) {
2855 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2860 Token->compressWhitespace(LineIndex, TailOffset, Split,
2864 ContentStartColumn += ToSplitColumns + 1;
2865 Penalty += ExcessCharactersPenalty;
2867 RemainingTokenColumns = Token->getRemainingLength(
2868 LineIndex, TailOffset, ContentStartColumn);
2872 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2877 ContentIndent = Token->getContentIndent(LineIndex);
2878 LLVM_DEBUG(llvm::dbgs()
2879 <<
" ContentIndent: " << ContentIndent <<
"\n");
2880 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2883 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2884 LineIndex, TailOffset +
Split.first +
Split.second,
2885 ContentStartColumn);
2886 if (NewRemainingTokenColumns == 0) {
2889 ContentStartColumn =
2890 Token->getContentStartColumn(LineIndex,
true);
2891 NewRemainingTokenColumns = Token->getRemainingLength(
2892 LineIndex, TailOffset +
Split.first +
Split.second,
2893 ContentStartColumn);
2899 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2904 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2905 <<
", " <<
Split.second <<
"\n");
2907 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2911 Penalty += NewBreakPenalty;
2913 RemainingTokenColumns = NewRemainingTokenColumns;
2914 BreakInserted =
true;
2915 NewBreakBefore =
true;
2919 if (LineIndex + 1 != EndIndex) {
2920 unsigned NextLineIndex = LineIndex + 1;
2921 if (NewBreakBefore) {
2940 ContentStartColumn += RemainingTokenColumns + 1;
2945 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2946 LLVM_DEBUG(llvm::dbgs()
2947 <<
" Size of reflown text: " << ContentStartColumn
2948 <<
"\n Potential reflow split: ");
2949 if (SplitBeforeNext.first != StringRef::npos) {
2950 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2951 << SplitBeforeNext.second <<
"\n");
2952 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2955 RemainingTokenColumns = Token->getRemainingLength(
2956 NextLineIndex, TailOffset, ContentStartColumn);
2958 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2959 LLVM_DEBUG(llvm::dbgs()
2960 <<
" Over limit after reflow, need: "
2961 << (ContentStartColumn + RemainingTokenColumns)
2962 <<
", space: " << ColumnLimit
2963 <<
", reflown prefix: " << ContentStartColumn
2964 <<
", offset in line: " << TailOffset <<
"\n");
2970 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2971 ContentStartColumn, CommentPragmasRegex);
2972 if (
Split.first == StringRef::npos) {
2973 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2979 unsigned ToSplitColumns = Token->getRangeLength(
2980 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2981 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2982 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2983 << (ContentStartColumn + ToSplitColumns)
2984 <<
", space: " << ColumnLimit);
2985 unsigned ExcessCharactersPenalty =
2986 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2987 Style.PenaltyExcessCharacter;
2988 if (NewBreakPenalty < ExcessCharactersPenalty)
2994 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3002 ContentStartColumn =
3003 Token->getContentStartColumn(NextLineIndex,
false);
3004 RemainingTokenColumns = Token->getRemainingLength(
3005 NextLineIndex, TailOffset, ContentStartColumn);
3008 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3023 if (NewBreakBefore) {
3024 assert(Penalty >= NewBreakPenalty);
3025 Penalty -= NewBreakPenalty;
3028 Token->reflow(NextLineIndex, Whitespaces);
3034 Token->getSplitAfterLastLine(TailOffset);
3035 if (SplitAfterLastLine.first != StringRef::npos) {
3036 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3040 Penalty += Style.PenaltyExcessCharacter *
3041 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3044 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3047 ContentStartColumn =
3048 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3049 RemainingTokenColumns = Token->getRemainingLength(
3050 Token->getLineCount() - 1,
3051 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3052 ContentStartColumn);
3055 State.Column = ContentStartColumn + RemainingTokenColumns -
3056 Current.UnbreakableTailLength;
3058 if (BreakInserted) {
3060 Token->updateAfterBroken(Whitespaces);
3065 if (Current.isNot(TT_LineComment))
3066 for (ParenState &
Paren : State.Stack)
3067 Paren.BreakBeforeParameter =
true;
3069 if (Current.is(TT_BlockComment))
3070 State.NoContinuation =
true;
3072 State.Stack.back().LastSpace = StartColumn;
3075 Token->updateNextToken(State);
3077 return {Penalty, Exceeded};
3082 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3085bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3087 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3092 if (Current.
TokenText.starts_with(
"R\""))
3096 if (Current.getNextNonComment() &&
3097 Current.getNextNonComment()->isStringLiteral()) {
3100 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3102 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...