23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "format-indenter"
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
89 if (!
Tok.MatchingParen)
93 int MatchingStackIndex = Stack.size() - 1;
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].
Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
103 for (; End->
Next; End = End->
Next) {
106 if (!End->
Next->closesScope())
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
120 if (!
Tok.NextOperator)
122 return Tok.NextOperator->TotalLength -
Tok.TotalLength;
128 return Tok.isMemberAccess() &&
Tok.Previous &&
Tok.Previous->closesScope();
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
151 while (
Last->NextOperator)
153 return Last->OperatorIndex + 2;
158 const FormatStyle &Style) {
164 bool BreakBefore = Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
179 const auto OperatorBreakStyle =
180 Style.BreakBinaryOperations.getStyleForOperator(OpToken->
Tok.
getKind());
181 if (OperatorBreakStyle == FormatStyle::BBO_Never)
185 const unsigned MinChain =
186 Style.BreakBinaryOperations.getMinChainLengthForOperator(
192 const FormatStyle &Style) {
193 if (LessTok.
isNot(tok::less))
195 return Style.isTextProto() ||
196 (Style.Language == FormatStyle::LK_Proto &&
213 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
214 if (LParenPos == StringRef::npos)
216 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
219 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
222 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
231 FormatStyle::LanguageKind
Language) {
232 for (
const auto &Format : Style.RawStringFormats)
234 return StringRef(Format.CanonicalDelimiter);
239 const FormatStyle &CodeStyle) {
241 std::optional<FormatStyle> LanguageStyle =
243 if (!LanguageStyle) {
244 FormatStyle PredefinedStyle;
250 LanguageStyle = PredefinedStyle;
252 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;
260std::optional<FormatStyle>
268std::optional<FormatStyle>
270 StringRef EnclosingFunction)
const {
293 *
this = *
this + Spaces;
321 bool BinPackInconclusiveFunctions)
322 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
323 Whitespaces(Whitespaces), Encoding(Encoding),
324 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
325 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
328 unsigned FirstStartColumn,
333 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
334 State.Column = FirstStartColumn;
336 State.Column = FirstIndent;
340 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
346 State.NextToken =
Line->First;
347 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
350 State.NoContinuation =
false;
351 State.StartOfStringLiteral = 0;
352 State.NoLineBreak =
false;
353 State.StartOfLineLevel = 0;
354 State.LowestLevelOnLine = 0;
355 State.IgnoreStackForComparison =
false;
357 if (Style.isTextProto()) {
360 auto &CurrentState = State.Stack.back();
361 CurrentState.AvoidBinPacking =
true;
362 CurrentState.BreakBeforeParameter =
true;
363 CurrentState.AlignColons =
false;
367 moveStateToNextToken(State, DryRun,
false);
374 const auto &CurrentState = State.Stack.back();
376 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
377 Current.closesBlockOrBlockTypeList(Style))) {
385 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
394 State.LowestLevelOnLine < State.StartOfLineLevel &&
398 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
403 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
404 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
405 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
406 return Style.isCpp() &&
407 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
412 if (Current.
is(TT_FunctionDeclarationName)) {
413 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&
418 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
419 assert(State.Column >= State.FirstIndent);
420 if (State.Column - State.FirstIndent < 6)
428 Current.isBlockIndentedInitRBrace(Style)) {
429 return CurrentState.BreakBeforeClosingBrace;
434 if ((Style.BreakBeforeCloseBracketFunction ||
435 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
436 Style.BreakBeforeCloseBracketSwitch) &&
437 Current.
is(tok::r_paren)) {
438 return CurrentState.BreakBeforeClosingParen;
441 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
442 return CurrentState.BreakBeforeClosingAngle;
446 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
450 (!Style.BraceWrapping.BeforeLambdaBody ||
451 Current.
isNot(TT_LambdaLBrace)) &&
452 CurrentState.NoLineBreakInOperand) {
459 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
461 Previous.MatchingParen->Previous->MatchingParen &&
462 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
464 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
468 return !State.NoLineBreak && !CurrentState.NoLineBreak;
474 const auto &CurrentState = State.Stack.back();
475 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
476 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
481 (Current.
is(TT_InlineASMColon) &&
482 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
483 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
484 Style.ColumnLimit > 0)))) {
487 if (CurrentState.BreakBeforeClosingBrace &&
488 (Current.closesBlockOrBlockTypeList(Style) ||
490 Current.isBlockIndentedInitRBrace(Style)))) {
493 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
495 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
497 if (Style.Language == FormatStyle::LK_ObjC &&
498 Style.ObjCBreakBeforeNestedBlockParam &&
500 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
505 if (CurrentState.IsCSharpGenericTypeConstraint &&
506 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
510 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
511 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
517 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
518 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter))) ||
519 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
521 (!Style.BreakBeforeTernaryOperators &&
522 Previous.is(TT_ConditionalExpr))) &&
523 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
524 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
527 if (CurrentState.IsChainedConditional &&
528 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
529 Current.
is(tok::colon)) ||
530 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
535 (
Previous.is(TT_ArrayInitializerLSquare) &&
538 Style.ColumnLimit > 0 &&
544 const FormatToken &BreakConstructorInitializersToken =
545 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
548 if (Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterComma &&
549 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
550 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
552 CurrentState.BreakBeforeParameter) &&
553 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
558 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
559 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
562 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
563 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
564 (Style.ObjCBreakBeforeNestedBlockParam ||
565 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
569 unsigned NewLineColumn = getNewLineColumn(State).Total;
570 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
572 (State.Column > NewLineColumn ||
578 (CurrentState.CallContinuation != 0 ||
579 CurrentState.BreakBeforeParameter) &&
585 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
586 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
592 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
597 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
600 if (Style.AlwaysBreakBeforeMultilineStrings &&
601 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
603 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
604 Keywords.kw_dollar) &&
605 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
606 nextIsMultilineString(State)) {
614 const auto PreviousPrecedence =
Previous.getPrecedence();
616 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
617 const bool LHSIsBinaryExpr =
630 const bool IsComparison =
635 Previous.Previous->isNot(TT_BinaryOperator);
641 CurrentState.BreakBeforeParameter) {
646 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
647 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
651 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
656 if (
Previous.ClosesTemplateDeclaration) {
657 if (Current.
is(tok::kw_concept)) {
658 switch (Style.BreakBeforeConceptDeclarations) {
659 case FormatStyle::BBCDS_Allowed:
661 case FormatStyle::BBCDS_Always:
663 case FormatStyle::BBCDS_Never:
667 if (Current.
is(TT_RequiresClause)) {
668 switch (Style.RequiresClausePosition) {
669 case FormatStyle::RCPS_SingleLine:
670 case FormatStyle::RCPS_WithPreceding:
676 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
677 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
680 if (
Previous.is(TT_FunctionAnnotationRParen) &&
684 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
685 Current.
isNot(TT_LeadingJavaAnnotation)) {
690 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
694 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
696 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
700 if (Current.
is(TT_FunctionDeclarationName) &&
701 !State.Line->ReturnTypeWrapped &&
703 (!Style.isCSharp() ||
704 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
707 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
708 CurrentState.BreakBeforeParameter) {
710 if (
Tok->is(TT_LineComment))
712 if (
Tok->is(TT_TemplateCloser)) {
717 if (
Tok->FirstAfterPPLine)
729 Current.
isNoneOf(tok::r_brace, tok::comment)) {
733 if (Current.
is(tok::lessless) &&
736 Previous.TokenText ==
"\'\\n\'")))) {
743 if (State.NoContinuation)
751 unsigned ExtraSpaces) {
753 assert(State.NextToken->Previous);
756 assert(!State.Stack.empty());
757 State.NoContinuation =
false;
759 if (Current.
is(TT_ImplicitStringLiteral) &&
760 (!
Previous.Tok.getIdentifierInfo() ||
761 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
762 tok::pp_not_keyword)) {
768 State.Column = EndColumn;
770 unsigned StartColumn =
772 assert(EndColumn >= StartColumn);
773 State.Column += EndColumn - StartColumn;
775 moveStateToNextToken(State, DryRun,
false);
779 unsigned Penalty = 0;
781 Penalty = addTokenOnNewLine(State, DryRun);
783 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
785 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
788void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
789 unsigned ExtraSpaces) {
791 assert(State.NextToken->Previous);
793 auto &CurrentState = State.Stack.back();
800 auto DisallowLineBreaks = [&] {
801 if (!Style.isCpp() ||
802 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
810 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
813 const auto *Prev = Current.getPreviousNonComment();
814 if (!Prev || Prev->isNot(tok::l_paren))
817 if (Prev->BlockParameterCount == 0)
821 if (Prev->BlockParameterCount > 1)
828 const auto *Comma = Prev->
Role->lastComma();
832 const auto *
Next = Comma->getNextNonComment();
833 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
836 if (DisallowLineBreaks())
837 State.NoLineBreak =
true;
839 if (Current.
is(tok::equal) &&
840 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
841 CurrentState.VariablePos == 0 &&
843 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
844 CurrentState.VariablePos = State.Column;
847 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
848 CurrentState.VariablePos -=
Tok->ColumnWidth;
849 if (
Tok->SpacesRequiredBefore != 0)
853 if (
Previous.PartOfMultiVariableDeclStmt)
854 CurrentState.LastSpace = CurrentState.VariablePos;
860 int PPColumnCorrection = 0;
864 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
871 if (Style.UseTab != FormatStyle::UT_Never)
872 PPColumnCorrection = -1;
873 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
879 const bool ContinuePPDirective =
881 Whitespaces.replaceWhitespace(Current, 0, Spaces,
882 State.
Column + Spaces + PPColumnCorrection,
883 nullptr, ContinuePPDirective);
888 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
889 Current.
is(TT_InheritanceColon)) {
890 CurrentState.NoLineBreak =
true;
892 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
894 CurrentState.NoLineBreak =
true;
897 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
899 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
900 CurrentState.Indent.Total);
903 CurrentState.AlignColons =
false;
907 CurrentState.ColonPos = FirstColonPos;
915 auto IsStartOfBracedList = [&]() {
917 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
919 if (IsStartOfBracedList())
920 return Style.BreakAfterOpenBracketBracedList;
921 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
925 if (
Tok.Previous->isIf())
926 return Style.BreakAfterOpenBracketIf;
927 if (
Tok.Previous->isLoop(Style))
928 return Style.BreakAfterOpenBracketLoop;
929 if (
Tok.Previous->is(tok::kw_switch))
930 return Style.BreakAfterOpenBracketSwitch;
931 if (Style.BreakAfterOpenBracketFunction) {
932 return !
Tok.Previous->is(TT_CastRParen) &&
933 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
938 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
939 Tok.Previous->is(tok::identifier);
941 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
942 if (!Style.isJavaScript())
944 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
945 if (Prev->is(TT_TemplateString) && Prev->opensScope())
947 if (Prev->opensScope() && !NestBlocks)
949 if (Prev->is(TT_TemplateString) && Prev->closesScope())
955 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
956 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
958 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
965 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
967 if (
Tok.is(TT_UnaryOperator) ||
968 (Style.isJavaScript() &&
969 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
972 const auto *
Previous = TokAfterLParen.Previous;
976 Previous->Previous->is(tok::kw_switch))) {
979 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
980 TT_LambdaDefinitionLParen) &&
984 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
987 return !
Next ||
Next->isMemberAccess() ||
988 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
991 State.
Column > getNewLineColumn(State).Total &&
1002 !StartsSimpleOneArgList(Current)) {
1003 CurrentState.NoLineBreak =
true;
1007 CurrentState.NoLineBreak =
true;
1013 if (Style.AlignAfterOpenBracket &&
1014 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1015 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1016 TT_TableGenDAGArgOpener,
1017 TT_TableGenDAGArgOpenerToBreak) &&
1019 (Current.
isNot(TT_LineComment) ||
1021 Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall) ||
1022 Previous.is(TT_VerilogMultiLineListLParen)) &&
1023 !IsInTemplateString(Current,
false)) {
1024 CurrentState.Indent = State.
Column + Spaces;
1025 CurrentState.AlignedTo = &
Previous;
1028 CurrentState.NoLineBreak =
true;
1030 CurrentState.NoLineBreak =
true;
1033 State.
Column > getNewLineColumn(State).Total) {
1034 CurrentState.ContainsUnwrappedBuilder =
true;
1037 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1038 CurrentState.NoLineBreak =
true;
1039 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1048 CurrentState.NoLineBreak =
true;
1055 const FormatToken *P = Current.getPreviousNonComment();
1056 if (Current.
isNot(tok::comment) && P &&
1057 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1058 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1059 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1063 bool BreakBeforeOperator =
1064 P->MustBreakBefore || P->is(tok::lessless) ||
1065 (P->is(TT_BinaryOperator) &&
1066 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
1067 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1071 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1072 P->isNot(TT_ConditionalExpr);
1073 if ((!BreakBeforeOperator &&
1075 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1076 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1077 CurrentState.NoLineBreakInOperand =
true;
1082 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1087 CurrentState.LastSpace = State.
Column;
1088 CurrentState.NestedBlockIndent = State.
Column;
1089 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1091 Previous.isNot(TT_OverloadedOperator)) ||
1093 CurrentState.LastSpace = State.
Column;
1094 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1096 Style.BreakConstructorInitializers ==
1097 FormatStyle::BCIS_AfterColon) {
1098 CurrentState.Indent = State.
Column;
1099 CurrentState.LastSpace = State.
Column;
1100 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1101 CurrentState.LastSpace = State.
Column;
1102 }
else if (
Previous.is(TT_BinaryOperator) &&
1109 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1110 CurrentState.LastSpace = State.
Column;
1111 }
else if (
Previous.is(TT_InheritanceColon)) {
1112 CurrentState.Indent = State.
Column;
1113 CurrentState.LastSpace = State.
Column;
1114 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1115 CurrentState.ColonPos = State.
Column;
1116 }
else if (
Previous.opensScope()) {
1124 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1125 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1126 CurrentState.LastSpace = State.
Column;
1132unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1135 assert(State.NextToken->Previous);
1137 auto &CurrentState = State.Stack.back();
1141 unsigned Penalty = 0;
1143 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1145 if (!NextNonComment)
1146 NextNonComment = &Current;
1149 if (!CurrentState.ContainsLineBreak)
1151 CurrentState.ContainsLineBreak =
true;
1153 Penalty += State.NextToken->SplitPenalty;
1158 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1159 (State.Column <= Style.ColumnLimit / 3 ||
1160 CurrentState.BreakBeforeParameter)) {
1161 Penalty += Style.PenaltyBreakFirstLessLess;
1164 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1165 State.Column = TotalColumn;
1179 if (State.Column > State.FirstIndent) {
1181 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1194 if (Current.isNot(TT_LambdaArrow) &&
1195 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1196 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1197 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1198 CurrentState.NestedBlockIndent = State.Column;
1201 if (NextNonComment->isMemberAccess()) {
1202 if (CurrentState.CallContinuation == 0)
1203 CurrentState.CallContinuation = State.Column;
1204 }
else if (NextNonComment->is(TT_SelectorName)) {
1205 if (!CurrentState.ObjCSelectorNameFound) {
1206 if (NextNonComment->LongestObjCSelectorName == 0) {
1207 CurrentState.AlignColons =
false;
1209 CurrentState.ColonPos =
1211 ? std::max(CurrentState.Indent.Total,
1212 State.FirstIndent + Style.ContinuationIndentWidth)
1213 : CurrentState.
Indent.Total) +
1217 }
else if (CurrentState.AlignColons &&
1218 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1219 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1221 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1222 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1232 if (State.Stack.size() > 1) {
1233 State.Stack[State.Stack.size() - 2].LastSpace =
1234 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1235 Style.ContinuationIndentWidth;
1239 switch (Style.BreakInheritanceList) {
1240 case FormatStyle::BILS_BeforeColon:
1241 case FormatStyle::BILS_AfterComma:
1242 if (Current.is(TT_InheritanceColon) ||
Previous.is(TT_InheritanceComma)) {
1243 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1244 tok::kw_class, tok::kw_struct, tok::kw_union);
1247 case FormatStyle::BILS_BeforeComma:
1248 if (Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma)) {
1249 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1250 tok::kw_class, tok::kw_struct, tok::kw_union);
1253 case FormatStyle::BILS_AfterColon:
1254 if (
Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma))
1255 CurrentState.AlignedTo = &
Previous;
1259 if ((PreviousNonComment &&
1260 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1261 !CurrentState.AvoidBinPacking) ||
1263 CurrentState.BreakBeforeParameter =
false;
1265 if (PreviousNonComment &&
1266 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1267 PreviousNonComment->ClosesRequiresClause) &&
1268 Current.NestingLevel == 0) {
1269 CurrentState.BreakBeforeParameter =
false;
1271 if (NextNonComment->is(tok::question) ||
1272 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1273 CurrentState.BreakBeforeParameter =
true;
1275 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1276 CurrentState.BreakBeforeParameter =
false;
1277 CurrentState.AlignedTo = &Current;
1282 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1285 !Current.MatchingParen->Children.empty()) {
1293 const bool ContinuePPDirective = State.Line->InPPDirective &&
1295 Current.isNot(TT_LineComment);
1296 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1297 CurrentState.AlignedTo, ContinuePPDirective,
1298 IndentedFromColumn);
1301 if (!Current.isTrailingComment())
1302 CurrentState.LastSpace = State.Column;
1303 if (Current.is(tok::lessless)) {
1307 CurrentState.LastSpace += 3;
1310 State.StartOfLineLevel = Current.NestingLevel;
1311 State.LowestLevelOnLine = Current.NestingLevel;
1315 bool NestedBlockSpecialCase =
1316 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1317 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1318 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1319 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1321 NestedBlockSpecialCase =
1322 NestedBlockSpecialCase ||
1323 (Current.MatchingParen &&
1324 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1325 if (!NestedBlockSpecialCase) {
1326 auto ParentLevelIt = std::next(State.Stack.rbegin());
1327 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1328 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1343 auto FindCurrentLevel = [&](
const auto &It) {
1344 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1345 return PState.Tok != nullptr;
1348 auto MaybeIncrement = [&](
const auto &It) {
1349 return It != State.Stack.rend() ? std::next(It) : It;
1351 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1352 auto LevelContainingLambdaIt =
1353 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1354 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1356 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1357 I->BreakBeforeParameter =
true;
1360 if (PreviousNonComment &&
1361 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1362 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1363 !PreviousNonComment->ClosesRequiresClause) ||
1364 Current.NestingLevel != 0) &&
1365 PreviousNonComment->isNoneOf(
1366 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1367 TT_LeadingJavaAnnotation) &&
1368 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1371 (!Style.BraceWrapping.BeforeLambdaBody ||
1372 Current.isNot(TT_LambdaLBrace))) {
1373 CurrentState.BreakBeforeParameter =
true;
1378 if (PreviousNonComment &&
1379 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1381 CurrentState.BreakBeforeClosingBrace =
true;
1384 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1385 if (
auto Previous = PreviousNonComment->Previous) {
1387 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1388 }
else if (
Previous->isLoop(Style)) {
1389 CurrentState.BreakBeforeClosingParen =
1390 Style.BreakBeforeCloseBracketLoop;
1391 }
else if (
Previous->is(tok::kw_switch)) {
1392 CurrentState.BreakBeforeClosingParen =
1393 Style.BreakBeforeCloseBracketSwitch;
1395 CurrentState.BreakBeforeClosingParen =
1396 Style.BreakBeforeCloseBracketFunction;
1401 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1402 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1404 if (CurrentState.AvoidBinPacking) {
1409 bool PreviousIsBreakingCtorInitializerColon =
1410 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1411 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1412 bool AllowAllConstructorInitializersOnNextLine =
1413 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1414 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1415 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1416 !PreviousIsBreakingCtorInitializerColon) ||
1417 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1418 State.Line->MustBeDeclaration) ||
1419 (!Style.AllowAllArgumentsOnNextLine &&
1420 !State.Line->MustBeDeclaration) ||
1421 (!AllowAllConstructorInitializersOnNextLine &&
1422 PreviousIsBreakingCtorInitializerColon) ||
1424 CurrentState.BreakBeforeParameter =
true;
1430 if (PreviousIsBreakingCtorInitializerColon &&
1431 AllowAllConstructorInitializersOnNextLine) {
1432 CurrentState.BreakBeforeParameter =
false;
1437 CurrentState.BreakBeforeParameter =
true;
1443ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1444 if (!State.NextToken || !State.NextToken->Previous)
1448 const auto &CurrentState = State.Stack.back();
1450 if (CurrentState.IsCSharpGenericTypeConstraint &&
1451 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1452 return CurrentState.ColonPos + 2;
1457 const auto ContinuationIndent =
1458 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1459 CurrentState.Indent) +
1460 Style.ContinuationIndentWidth;
1461 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1463 if (!NextNonComment)
1464 NextNonComment = &Current;
1467 if (Style.isJava() &&
1468 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1469 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1470 CurrentState.Indent + Style.ContinuationIndentWidth);
1475 if (Style.isVerilog() && PreviousNonComment &&
1476 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1477 return State.FirstIndent;
1480 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1481 State.Line->First->is(tok::kw_enum)) {
1482 return IndentationAndAlignment(Style.IndentWidth *
1483 State.Line->First->IndentLevel) +
1487 if (Style.BraceWrapping.BeforeLambdaBody &&
1488 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1489 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1490 ? CurrentState.Indent
1491 : State.FirstIndent;
1492 return From + Style.IndentWidth;
1495 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1496 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1497 if (Current.NestingLevel == 0 ||
1498 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1499 State.NextToken->is(TT_LambdaLBrace))) {
1500 return State.FirstIndent;
1502 return CurrentState.Indent;
1504 if (Current.is(TT_LambdaArrow) &&
1505 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1506 tok::kw_consteval, tok::kw_static,
1507 TT_AttributeRSquare)) {
1508 return ContinuationIndent;
1510 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1511 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1512 State.Stack.size() > 1) {
1513 if (Current.closesBlockOrBlockTypeList(Style))
1514 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1515 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1516 return State.Stack[State.Stack.size() - 2].LastSpace;
1517 return State.FirstIndent;
1534 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1536 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1537 return State.Stack[State.Stack.size() - 2].LastSpace;
1541 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1542 State.Stack.size() > 1) {
1543 return State.Stack[State.Stack.size() - 2].LastSpace;
1545 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1546 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1547 State.Stack.size() > 1) {
1548 return State.Stack[State.Stack.size() - 2].LastSpace;
1550 if ((Style.BreakBeforeCloseBracketFunction ||
1551 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1552 Style.BreakBeforeCloseBracketSwitch) &&
1553 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1554 return State.Stack[State.Stack.size() - 2].LastSpace;
1556 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1557 State.Stack.size() > 1) {
1558 return State.Stack[State.Stack.size() - 2].LastSpace;
1560 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1561 return State.Stack[State.Stack.size() - 2].LastSpace;
1569 if (Current.is(tok::identifier) && Current.Next &&
1570 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1571 (Current.Next->is(TT_DictLiteral) ||
1572 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1573 return CurrentState.Indent;
1575 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1576 State.StartOfStringLiteral != 0) {
1577 return State.StartOfStringLiteral - 1;
1579 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1580 return State.StartOfStringLiteral;
1581 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1582 return CurrentState.FirstLessLess;
1583 if (NextNonComment->isMemberAccess()) {
1584 if (CurrentState.CallContinuation == 0)
1585 return ContinuationIndent;
1586 return CurrentState.CallContinuation;
1588 if (CurrentState.QuestionColumn != 0 &&
1589 ((NextNonComment->is(tok::colon) &&
1590 NextNonComment->is(TT_ConditionalExpr)) ||
1591 Previous.is(TT_ConditionalExpr))) {
1592 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1593 !NextNonComment->Next->FakeLParens.empty() &&
1595 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1597 !CurrentState.IsWrappedConditional) {
1602 unsigned Indent = CurrentState.Indent.Total;
1603 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1604 Indent -= Style.ContinuationIndentWidth;
1605 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1609 return CurrentState.QuestionColumn;
1611 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1612 return CurrentState.VariablePos;
1613 if (Current.is(TT_RequiresClause)) {
1614 if (Style.IndentRequiresClause)
1615 return CurrentState.Indent + Style.IndentWidth;
1616 switch (Style.RequiresClausePosition) {
1617 case FormatStyle::RCPS_OwnLine:
1618 case FormatStyle::RCPS_WithFollowing:
1619 case FormatStyle::RCPS_OwnLineWithBrace:
1620 return CurrentState.Indent;
1625 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1626 TT_InheritanceComma)) {
1627 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1629 if ((PreviousNonComment &&
1630 (PreviousNonComment->ClosesTemplateDeclaration ||
1631 PreviousNonComment->ClosesRequiresClause ||
1632 (PreviousNonComment->is(TT_AttributeMacro) &&
1633 Current.isNot(tok::l_paren) &&
1634 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1635 TT_PointerOrReference)) ||
1636 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1637 TT_FunctionAnnotationRParen,
1639 TT_LeadingJavaAnnotation))) ||
1640 (!Style.IndentWrappedFunctionNames &&
1641 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1642 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1643 CurrentState.Indent);
1645 if (NextNonComment->is(TT_SelectorName)) {
1646 if (!CurrentState.ObjCSelectorNameFound) {
1647 auto MinIndent = CurrentState.Indent;
1650 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1651 Style.ContinuationIndentWidth);
1662 return MinIndent.addPadding(
1663 std::max(NextNonComment->LongestObjCSelectorName,
1664 NextNonComment->ColumnWidth) -
1665 NextNonComment->ColumnWidth);
1667 if (!CurrentState.AlignColons)
1668 return CurrentState.Indent;
1669 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1670 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1671 return CurrentState.Indent;
1673 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1674 return CurrentState.ColonPos;
1675 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1676 if (CurrentState.StartOfArraySubscripts != 0) {
1677 return CurrentState.StartOfArraySubscripts;
1678 }
else if (Style.isCSharp()) {
1680 return CurrentState.Indent;
1682 return ContinuationIndent;
1687 if (State.Line->InPragmaDirective) {
1688 FormatToken *PragmaType = State.Line->First->Next->Next;
1689 if (PragmaType && PragmaType->TokenText ==
"omp")
1690 return CurrentState.Indent + Style.ContinuationIndentWidth;
1695 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1696 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1697 return CurrentState.Indent;
1700 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1701 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1702 return ContinuationIndent;
1704 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1705 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1706 return ContinuationIndent;
1708 if (NextNonComment->is(TT_CtorInitializerComma))
1709 return CurrentState.Indent;
1710 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1711 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1712 return CurrentState.Indent;
1714 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1715 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1716 return CurrentState.Indent;
1719 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1720 !Current.isBinaryOperator() &&
1721 Current.isNoneOf(tok::colon, tok::comment)) {
1722 return ContinuationIndent;
1724 if (Current.is(TT_ProtoExtensionLSquare))
1725 return CurrentState.Indent;
1726 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1727 return CurrentState.Indent - Current.Tok.getLength() -
1728 Current.SpacesRequiredBefore;
1730 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1731 CurrentState.UnindentOperator) {
1732 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1733 NextNonComment->SpacesRequiredBefore;
1735 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1736 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1739 return CurrentState.Indent + Style.ContinuationIndentWidth;
1741 return CurrentState.Indent;
1746 const FormatStyle &Style) {
1753 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1756unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1757 bool DryRun,
bool Newline) {
1758 assert(State.Stack.size());
1760 auto &CurrentState = State.Stack.back();
1762 if (Current.is(TT_CSharpGenericTypeConstraint))
1763 CurrentState.IsCSharpGenericTypeConstraint =
true;
1764 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1765 CurrentState.NoLineBreakInOperand =
false;
1766 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1767 CurrentState.AvoidBinPacking =
true;
1768 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1769 if (CurrentState.FirstLessLess == 0)
1770 CurrentState.FirstLessLess = State.Column;
1772 CurrentState.LastOperatorWrapped = Newline;
1774 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1775 CurrentState.LastOperatorWrapped = Newline;
1776 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1777 Current.Previous->isNot(TT_ConditionalExpr)) {
1778 CurrentState.LastOperatorWrapped = Newline;
1780 if (Current.is(TT_ArraySubscriptLSquare) &&
1781 CurrentState.StartOfArraySubscripts == 0) {
1782 CurrentState.StartOfArraySubscripts = State.Column;
1786 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1788 if (
Tok.MustBreakBefore)
1792 return Next &&
Next->MustBreakBefore;
1794 if (IsWrappedConditional(Current))
1795 CurrentState.IsWrappedConditional =
true;
1796 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1797 CurrentState.QuestionColumn = State.Column;
1798 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1803 CurrentState.QuestionColumn = State.Column;
1805 if (!Current.opensScope() && !Current.closesScope() &&
1806 Current.isNot(TT_PointerOrReference)) {
1807 State.LowestLevelOnLine =
1808 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1810 if (Current.isMemberAccess())
1811 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1812 if (Current.is(TT_SelectorName))
1813 CurrentState.ObjCSelectorNameFound =
true;
1814 if (Current.is(TT_CtorInitializerColon) &&
1815 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1821 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1822 FormatStyle::BCIS_BeforeComma
1825 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1826 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1827 CurrentState.AvoidBinPacking =
true;
1828 CurrentState.BreakBeforeParameter =
1829 Style.ColumnLimit > 0 &&
1830 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1831 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1833 CurrentState.BreakBeforeParameter =
false;
1836 if (Current.is(TT_CtorInitializerColon) &&
1837 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1838 CurrentState.Indent =
1839 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1840 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1841 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1842 CurrentState.AvoidBinPacking =
true;
1844 CurrentState.BreakBeforeParameter =
false;
1846 if (Current.is(TT_InheritanceColon)) {
1847 CurrentState.Indent =
1848 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1850 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1851 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1852 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1853 CurrentState.LastSpace = State.Column;
1854 if (Current.is(TT_RequiresExpression) &&
1855 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1856 CurrentState.NestedBlockIndent = State.Column;
1868 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1870 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1871 !CurrentState.HasMultipleNestedBlocks) {
1872 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1873 for (ParenState &PState : llvm::drop_end(State.Stack))
1874 PState.NoLineBreak =
true;
1875 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1877 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1878 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1879 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1880 TT_CtorInitializerColon)))) {
1881 CurrentState.NestedBlockInlined =
1885 moveStatePastFakeLParens(State, Newline);
1886 moveStatePastScopeCloser(State);
1889 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1890 !State.Stack.back().NoLineBreakInOperand;
1891 moveStatePastScopeOpener(State, Newline);
1892 moveStatePastFakeRParens(State);
1894 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1895 State.StartOfStringLiteral = State.Column + 1;
1896 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1897 State.StartOfStringLiteral = State.Column + 1;
1898 }
else if (Current.is(TT_TableGenMultiLineString) &&
1899 State.StartOfStringLiteral == 0) {
1900 State.StartOfStringLiteral = State.Column + 1;
1901 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1902 State.StartOfStringLiteral = State.Column;
1903 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1904 !Current.isStringLiteral()) {
1905 State.StartOfStringLiteral = 0;
1908 State.Column += Current.ColumnWidth;
1909 State.NextToken = State.NextToken->Next;
1914 if (Style.isVerilog() && State.NextToken &&
1915 State.NextToken->MustBreakBefore &&
1916 Keywords.isVerilogEndOfLabel(Current)) {
1917 State.FirstIndent += Style.IndentWidth;
1918 CurrentState.Indent = State.FirstIndent;
1922 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1925 Current.Role->formatFromToken(State,
this, DryRun);
1932 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1937void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1940 if (Current.FakeLParens.empty())
1948 bool SkipFirstExtraIndent =
1951 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1953 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1955 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1956 const auto &CurrentState = State.Stack.back();
1957 ParenState NewParenState = CurrentState;
1958 NewParenState.Tok =
nullptr;
1959 NewParenState.ContainsLineBreak =
false;
1960 NewParenState.LastOperatorWrapped =
true;
1961 NewParenState.IsChainedConditional =
false;
1962 NewParenState.IsWrappedConditional =
false;
1963 NewParenState.UnindentOperator =
false;
1964 NewParenState.NoLineBreak =
1965 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1969 NewParenState.AvoidBinPacking =
false;
1974 if (!Current.isTrailingComment() &&
1975 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1978 (!Style.isJava() && PrecedenceLevel > 0)) &&
1979 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1980 Current.NestingLevel == 0) &&
1981 (!Style.isTableGen() ||
1983 TT_TableGenDAGArgListCommaToBreak)))) {
1984 NewParenState.Indent =
1985 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
1986 IndentationAndAlignment(CurrentState.LastSpace)});
1993 State.Stack.size() > 1) {
1994 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1995 Style.ContinuationIndentWidth;
2005 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
2006 NewParenState.UnindentOperator =
true;
2008 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
2009 NewParenState.AlignedTo =
Previous;
2019 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2021 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2022 NewParenState.StartOfFunctionCall = State.Column;
2032 &PrecedenceLevel == &Current.FakeLParens.back() &&
2033 !CurrentState.IsWrappedConditional) {
2034 NewParenState.IsChainedConditional =
true;
2035 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2038 !Current.isTrailingComment())) {
2039 NewParenState.Indent += Style.ContinuationIndentWidth;
2042 NewParenState.BreakBeforeParameter =
false;
2043 State.Stack.push_back(NewParenState);
2044 SkipFirstExtraIndent =
false;
2048void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2049 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2050 unsigned VariablePos = State.Stack.back().VariablePos;
2051 if (State.Stack.size() == 1) {
2055 State.Stack.pop_back();
2056 State.Stack.back().VariablePos = VariablePos;
2059 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2062 State.Stack.back().LastSpace -= Style.IndentWidth;
2066void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2069 if (!Current.opensScope())
2072 const auto &CurrentState = State.Stack.back();
2075 if (Current.isOneOf(tok::less, tok::l_paren) &&
2076 CurrentState.IsCSharpGenericTypeConstraint) {
2080 if (Current.MatchingParen && Current.is(
BK_Block)) {
2081 moveStateToNewBlock(State, Newline);
2088 const auto *Prev =
Tok->getPreviousNonComment();
2091 return Prev->is(tok::comma);
2092 }(Current.MatchingParen);
2094 IndentationAndAlignment NewIndent = 0;
2095 unsigned LastSpace = CurrentState.LastSpace;
2096 bool AvoidBinPacking;
2097 bool BreakBeforeParameter =
false;
2098 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2099 CurrentState.NestedBlockIndent);
2100 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2102 if (Current.opensBlockOrBlockTypeList(Style)) {
2103 NewIndent = Style.IndentWidth +
2104 std::min(State.Column, CurrentState.NestedBlockIndent);
2105 }
else if (Current.is(tok::l_brace)) {
2106 const auto Width = Style.BracedInitializerIndentWidth;
2107 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2108 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2110 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2112 const FormatToken *NextNonComment = Current.getNextNonComment();
2114 EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() ||
2115 Style.PackArguments.BinPack == FormatStyle::BPAS_OnePerLine ||
2117 NextNonComment->isOneOf(TT_DesignatedInitializerPeriod,
2118 TT_DesignatedInitializerLSquare));
2119 BreakBeforeParameter = EndsInComma;
2120 if (Current.ParameterCount > 1)
2121 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2123 NewIndent = IndentationAndAlignment(std::max(
2124 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2125 Style.ContinuationIndentWidth;
2127 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2128 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2134 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2135 NewIndent = State.Column +
Next->TokenText.size() + 2;
2142 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2143 NewIndent = std::max(NewIndent, CurrentState.Indent);
2144 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2150 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2151 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
2152 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter)) ||
2153 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2155 bool BinPackDeclaration =
2157 (Style.PackParameters.BinPack == FormatStyle::BPPS_BinPack ||
2158 Style.PackParameters.BinPack == FormatStyle::BPPS_UseBreakAfter)) ||
2161 bool GenericSelection =
2162 Current.getPreviousNonComment() &&
2163 Current.getPreviousNonComment()->is(tok::kw__Generic);
2166 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2167 (Style.isJavaScript() && EndsInComma) ||
2168 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2169 (!State.Line->MustBeDeclaration &&
2170 Style.PackArguments.BinPack == FormatStyle::BPAS_OnePerLine) ||
2171 (Style.ExperimentalAutoDetectBinPacking &&
2175 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2176 Style.ObjCBreakBeforeNestedBlockParam) {
2177 if (Style.ColumnLimit) {
2182 BreakBeforeParameter =
true;
2188 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2189 if (
Tok->MustBreakBefore ||
2190 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2191 BreakBeforeParameter =
true;
2198 if (Style.isJavaScript() && EndsInComma)
2199 BreakBeforeParameter =
true;
2205 Current.Children.empty() &&
2206 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2207 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2208 (Current.is(TT_TemplateOpener) &&
2209 CurrentState.ContainsUnwrappedBuilder));
2210 State.Stack.push_back(
2211 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2212 auto &NewState = State.Stack.back();
2213 NewState.NestedBlockIndent = NestedBlockIndent;
2214 NewState.BreakBeforeParameter = BreakBeforeParameter;
2215 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2217 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2218 Current.is(tok::l_paren)) {
2222 if (next->is(TT_LambdaLSquare)) {
2223 NewState.HasMultipleNestedBlocks =
true;
2230 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2232 Current.Previous->is(tok::at);
2235void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2237 if (!Current.closesScope())
2242 if (State.Stack.size() > 1 &&
2243 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2244 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2245 State.NextToken->is(TT_TemplateCloser) ||
2246 State.NextToken->is(TT_TableGenListCloser) ||
2247 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2248 State.Stack.pop_back();
2251 auto &CurrentState = State.Stack.back();
2263 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2264 Current.MatchingParen->Previous) {
2265 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2266 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2267 CurrentScopeOpener.MatchingParen) {
2268 int NecessarySpaceInLine =
2270 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2271 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2272 Style.ColumnLimit) {
2273 CurrentState.BreakBeforeParameter =
false;
2278 if (Current.is(tok::r_square)) {
2280 const FormatToken *NextNonComment = Current.getNextNonComment();
2281 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2282 CurrentState.StartOfArraySubscripts = 0;
2286void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2287 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2288 State.NextToken->is(TT_LambdaLBrace) &&
2289 !State.Line->MightBeFunctionDecl) {
2290 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2291 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2293 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2295 unsigned NewIndent =
2296 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2297 ? Style.ObjCBlockIndentWidth
2298 : Style.IndentWidth);
2305 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2306 State.NextToken->is(TT_LambdaLBrace);
2308 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2309 State.Stack.back().LastSpace,
2310 true, NoLineBreak));
2311 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2312 State.Stack.back().BreakBeforeParameter =
true;
2318 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2319 if (LastNewlinePos == StringRef::npos) {
2320 return StartColumn +
2328unsigned ContinuationIndenter::reformatRawStringLiteral(
2330 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2331 unsigned StartColumn = State.Column - Current.ColumnWidth;
2333 StringRef NewDelimiter =
2335 if (NewDelimiter.empty())
2336 NewDelimiter = OldDelimiter;
2339 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2340 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2343 std::string RawText = std::string(
2344 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2345 if (NewDelimiter != OldDelimiter) {
2348 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2349 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2350 NewDelimiter = OldDelimiter;
2353 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2354 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2357 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2368 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2390 unsigned CurrentIndent =
2391 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2392 ? State.Stack.back().NestedBlockIndent
2393 : State.Stack.back().Indent.Total;
2394 unsigned NextStartColumn = ContentStartsOnNewline
2395 ? CurrentIndent + Style.IndentWidth
2406 unsigned LastStartColumn =
2407 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2410 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2411 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2416 return addMultilineToken(Current, State);
2418 if (NewDelimiter != OldDelimiter) {
2421 SourceLocation PrefixDelimiterStart =
2422 Current.Tok.getLocation().getLocWithOffset(2);
2423 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2424 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2427 <<
"Failed to update the prefix delimiter of a raw string: "
2428 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2432 SourceLocation SuffixDelimiterStart =
2433 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2434 1 - OldDelimiter.size());
2435 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2436 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2439 <<
"Failed to update the suffix delimiter of a raw string: "
2440 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2443 SourceLocation OriginLoc =
2444 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2445 for (
const tooling::Replacement &Fix : Fixes.first) {
2446 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2447 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2448 Fix.getLength(), Fix.getReplacementText()));
2450 llvm::errs() <<
"Failed to reformat raw string: "
2451 << llvm::toString(std::move(Err)) <<
"\n";
2456 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2457 State.Column = RawLastLineEndColumn + NewSuffixSize;
2461 unsigned PrefixExcessCharacters =
2462 StartColumn + NewPrefixSize > Style.ColumnLimit
2463 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2466 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2469 for (ParenState &
Paren : State.Stack)
2470 Paren.BreakBeforeParameter =
true;
2472 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2475unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2478 for (ParenState &
Paren : State.Stack)
2479 Paren.BreakBeforeParameter =
true;
2481 unsigned ColumnsUsed = State.Column;
2484 State.Column = Current.LastLineColumnWidth;
2487 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2491unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2493 bool AllowBreak,
bool Newline) {
2494 unsigned Penalty = 0;
2497 auto RawStringStyle = getRawStringStyle(Current, State);
2498 if (RawStringStyle && !Current.Finalized) {
2499 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2501 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2504 Penalty = addMultilineToken(Current, State);
2507 LineState OriginalState = State;
2511 bool Strict =
false;
2514 bool Exceeded =
false;
2515 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2516 Current, State, AllowBreak,
true, Strict);
2520 LineState StrictState = OriginalState;
2521 unsigned StrictPenalty =
2522 breakProtrudingToken(Current, StrictState, AllowBreak,
2525 Strict = StrictPenalty <= Penalty;
2527 Penalty = StrictPenalty;
2528 State = std::move(StrictState);
2534 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2539 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2540 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2549 auto Tok = Current.getPreviousNonComment();
2550 if (!
Tok ||
Tok->isNot(tok::l_paren))
2552 Tok =
Tok->getPreviousNonComment();
2555 if (
Tok->is(TT_TemplateCloser)) {
2556 Tok =
Tok->MatchingParen;
2558 Tok =
Tok->getPreviousNonComment();
2560 if (!
Tok ||
Tok->isNot(tok::identifier))
2562 return Tok->TokenText;
2565std::optional<FormatStyle>
2566ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2567 const LineState &State) {
2568 if (!Current.isStringLiteral())
2569 return std::nullopt;
2572 return std::nullopt;
2574 if (!RawStringStyle && Delimiter->empty()) {
2578 if (!RawStringStyle)
2579 return std::nullopt;
2581 return RawStringStyle;
2584std::unique_ptr<BreakableToken>
2585ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2587 unsigned StartColumn = State.Column - Current.ColumnWidth;
2588 if (Current.isStringLiteral()) {
2591 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2605 if (Current.IsUnterminatedLiteral)
2609 if (State.Stack.back().IsInsideObjCArrayLiteral)
2616 if (Style.isVerilog() && Current.Previous &&
2617 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2620 StringRef
Text = Current.TokenText;
2630 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2633 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2634 Text.ends_with(
"'")) {
2636 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2637 Text.ends_with(
"\"")) {
2639 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2644 return std::make_unique<BreakableStringLiteralUsingOperators>(
2645 Current, QuoteStyle,
2656 if ((
Text.ends_with(Postfix =
"\"") &&
2657 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2658 Text.starts_with(Prefix =
"u\"") ||
2659 Text.starts_with(Prefix =
"U\"") ||
2660 Text.starts_with(Prefix =
"u8\"") ||
2661 Text.starts_with(Prefix =
"L\""))) ||
2662 (
Text.starts_with(Prefix =
"_T(\"") &&
2663 Text.ends_with(Postfix =
"\")"))) {
2664 return std::make_unique<BreakableStringLiteral>(
2666 State.Line->InPPDirective, Encoding, Style);
2668 }
else if (Current.is(TT_BlockComment)) {
2669 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2676 return std::make_unique<BreakableBlockComment>(
2677 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2678 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2679 }
else if (Current.is(TT_LineComment) &&
2680 (!Current.Previous ||
2681 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2682 bool RegularComments = [&]() {
2683 for (
const FormatToken *T = &Current; T && T->is(TT_LineComment);
2685 if (!(T->TokenText.starts_with(
"//") || T->TokenText.starts_with(
"#")))
2690 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2691 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2695 return std::make_unique<BreakableLineCommentSection>(
2696 Current, StartColumn,
false, Encoding, Style);
2701std::pair<unsigned, bool>
2702ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2704 bool DryRun,
bool Strict) {
2705 std::unique_ptr<const BreakableToken> Token =
2706 createBreakableToken(Current, State, AllowBreak);
2709 assert(Token->getLineCount() > 0);
2711 if (Current.is(TT_LineComment)) {
2713 ColumnLimit = Style.ColumnLimit;
2715 if (ColumnLimit == 0) {
2718 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2720 if (Current.UnbreakableTailLength >= ColumnLimit)
2724 unsigned StartColumn = State.Column - Current.ColumnWidth;
2725 unsigned NewBreakPenalty = Current.isStringLiteral()
2726 ? Style.PenaltyBreakString
2727 : Style.PenaltyBreakComment;
2730 bool Exceeded =
false;
2732 bool BreakInserted = Token->introducesBreakBeforeToken();
2735 bool NewBreakBefore =
false;
2739 bool Reflow =
false;
2742 unsigned TailOffset = 0;
2744 unsigned ContentStartColumn =
2745 Token->getContentStartColumn(0,
false);
2747 unsigned RemainingTokenColumns =
2748 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2751 Token->adaptStartOfLine(0, Whitespaces);
2753 unsigned ContentIndent = 0;
2754 unsigned Penalty = 0;
2755 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2756 << StartColumn <<
".\n");
2757 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2758 LineIndex != EndIndex; ++LineIndex) {
2759 LLVM_DEBUG(llvm::dbgs()
2760 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2761 NewBreakBefore =
false;
2765 bool TryReflow = Reflow;
2767 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2768 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2769 << (ContentStartColumn + RemainingTokenColumns)
2770 <<
", space: " << ColumnLimit
2771 <<
", reflown prefix: " << ContentStartColumn
2772 <<
", offset in line: " << TailOffset <<
"\n");
2778 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2779 ContentStartColumn, CommentPragmasRegex);
2780 if (
Split.first == StringRef::npos) {
2783 if (LineIndex < EndIndex - 1) {
2786 Penalty += Style.PenaltyExcessCharacter *
2787 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2789 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2792 assert(
Split.first != 0);
2794 if (Token->supportsReflow()) {
2814 unsigned ToSplitColumns = Token->getRangeLength(
2815 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2816 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2819 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2820 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2823 unsigned ToNextSplitColumns = 0;
2824 if (NextSplit.first == StringRef::npos) {
2825 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2826 ContentStartColumn);
2828 ToNextSplitColumns = Token->getRangeLength(
2829 LineIndex, TailOffset,
2830 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2834 ToNextSplitColumns =
2835 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2836 LLVM_DEBUG(llvm::dbgs()
2837 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2838 LLVM_DEBUG(llvm::dbgs()
2839 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2842 bool ContinueOnLine =
2843 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2844 unsigned ExcessCharactersPenalty = 0;
2845 if (!ContinueOnLine && !Strict) {
2848 ExcessCharactersPenalty =
2849 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2850 Style.PenaltyExcessCharacter;
2851 LLVM_DEBUG(llvm::dbgs()
2852 <<
" Penalty excess: " << ExcessCharactersPenalty
2853 <<
"\n break : " << NewBreakPenalty <<
"\n");
2854 if (ExcessCharactersPenalty < NewBreakPenalty) {
2856 ContinueOnLine =
true;
2859 if (ContinueOnLine) {
2860 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2865 Token->compressWhitespace(LineIndex, TailOffset, Split,
2869 ContentStartColumn += ToSplitColumns + 1;
2870 Penalty += ExcessCharactersPenalty;
2872 RemainingTokenColumns = Token->getRemainingLength(
2873 LineIndex, TailOffset, ContentStartColumn);
2877 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2882 ContentIndent = Token->getContentIndent(LineIndex);
2883 LLVM_DEBUG(llvm::dbgs()
2884 <<
" ContentIndent: " << ContentIndent <<
"\n");
2885 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2888 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2889 LineIndex, TailOffset +
Split.first +
Split.second,
2890 ContentStartColumn);
2891 if (NewRemainingTokenColumns == 0) {
2894 ContentStartColumn =
2895 Token->getContentStartColumn(LineIndex,
true);
2896 NewRemainingTokenColumns = Token->getRemainingLength(
2897 LineIndex, TailOffset +
Split.first +
Split.second,
2898 ContentStartColumn);
2904 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2909 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2910 <<
", " <<
Split.second <<
"\n");
2912 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2916 Penalty += NewBreakPenalty;
2918 RemainingTokenColumns = NewRemainingTokenColumns;
2919 BreakInserted =
true;
2920 NewBreakBefore =
true;
2924 if (LineIndex + 1 != EndIndex) {
2925 unsigned NextLineIndex = LineIndex + 1;
2926 if (NewBreakBefore) {
2945 ContentStartColumn += RemainingTokenColumns + 1;
2950 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2951 LLVM_DEBUG(llvm::dbgs()
2952 <<
" Size of reflown text: " << ContentStartColumn
2953 <<
"\n Potential reflow split: ");
2954 if (SplitBeforeNext.first != StringRef::npos) {
2955 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2956 << SplitBeforeNext.second <<
"\n");
2957 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2960 RemainingTokenColumns = Token->getRemainingLength(
2961 NextLineIndex, TailOffset, ContentStartColumn);
2963 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2964 LLVM_DEBUG(llvm::dbgs()
2965 <<
" Over limit after reflow, need: "
2966 << (ContentStartColumn + RemainingTokenColumns)
2967 <<
", space: " << ColumnLimit
2968 <<
", reflown prefix: " << ContentStartColumn
2969 <<
", offset in line: " << TailOffset <<
"\n");
2975 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2976 ContentStartColumn, CommentPragmasRegex);
2977 if (
Split.first == StringRef::npos) {
2978 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2984 unsigned ToSplitColumns = Token->getRangeLength(
2985 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2986 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2987 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2988 << (ContentStartColumn + ToSplitColumns)
2989 <<
", space: " << ColumnLimit);
2990 unsigned ExcessCharactersPenalty =
2991 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2992 Style.PenaltyExcessCharacter;
2993 if (NewBreakPenalty < ExcessCharactersPenalty)
2999 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3007 ContentStartColumn =
3008 Token->getContentStartColumn(NextLineIndex,
false);
3009 RemainingTokenColumns = Token->getRemainingLength(
3010 NextLineIndex, TailOffset, ContentStartColumn);
3013 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3028 if (NewBreakBefore) {
3029 assert(Penalty >= NewBreakPenalty);
3030 Penalty -= NewBreakPenalty;
3033 Token->reflow(NextLineIndex, Whitespaces);
3039 Token->getSplitAfterLastLine(TailOffset);
3040 if (SplitAfterLastLine.first != StringRef::npos) {
3041 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3045 Penalty += Style.PenaltyExcessCharacter *
3046 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3049 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3052 ContentStartColumn =
3053 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3054 RemainingTokenColumns = Token->getRemainingLength(
3055 Token->getLineCount() - 1,
3056 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3057 ContentStartColumn);
3060 State.Column = ContentStartColumn + RemainingTokenColumns -
3061 Current.UnbreakableTailLength;
3063 if (BreakInserted) {
3065 Token->updateAfterBroken(Whitespaces);
3070 if (Current.isNot(TT_LineComment))
3071 for (ParenState &
Paren : State.Stack)
3072 Paren.BreakBeforeParameter =
true;
3074 if (Current.is(TT_BlockComment))
3075 State.NoContinuation =
true;
3077 State.Stack.back().LastSpace = StartColumn;
3080 Token->updateNextToken(State);
3082 return {Penalty, Exceeded};
3087 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3090bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3092 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3097 if (Current.
TokenText.starts_with(
"R\""))
3101 if (Current.getNextNonComment() &&
3102 Current.getNextNonComment()->isStringLiteral()) {
3105 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3107 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...