23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "format-indenter"
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
89 if (!
Tok.MatchingParen)
93 int MatchingStackIndex = Stack.size() - 1;
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].
Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
103 for (; End->
Next; End = End->
Next) {
106 if (!End->
Next->closesScope())
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
120 if (!
Tok.NextOperator)
122 return Tok.NextOperator->TotalLength -
Tok.TotalLength;
128 return Tok.isMemberAccess() &&
Tok.Previous &&
Tok.Previous->closesScope();
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
149 const FormatStyle &Style) {
150 return Style.BreakBinaryOperations != FormatStyle::BBO_Never &&
152 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None
158 const FormatStyle &Style) {
159 if (LessTok.
isNot(tok::less))
161 return Style.isTextProto() ||
162 (Style.Language == FormatStyle::LK_Proto &&
179 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
180 if (LParenPos == StringRef::npos)
182 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
185 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
188 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
197 FormatStyle::LanguageKind
Language) {
198 for (
const auto &Format : Style.RawStringFormats)
200 return StringRef(Format.CanonicalDelimiter);
205 const FormatStyle &CodeStyle) {
207 std::optional<FormatStyle> LanguageStyle =
209 if (!LanguageStyle) {
210 FormatStyle PredefinedStyle;
216 LanguageStyle = PredefinedStyle;
218 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;
226std::optional<FormatStyle>
234std::optional<FormatStyle>
236 StringRef EnclosingFunction)
const {
248 bool BinPackInconclusiveFunctions)
249 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
250 Whitespaces(Whitespaces), Encoding(Encoding),
251 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
252 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
255 unsigned FirstStartColumn,
260 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
261 State.Column = FirstStartColumn;
263 State.Column = FirstIndent;
267 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
273 State.NextToken =
Line->First;
274 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
277 State.NoContinuation =
false;
278 State.StartOfStringLiteral = 0;
279 State.NoLineBreak =
false;
280 State.StartOfLineLevel = 0;
281 State.LowestLevelOnLine = 0;
282 State.IgnoreStackForComparison =
false;
284 if (Style.isTextProto()) {
287 auto &CurrentState = State.Stack.back();
288 CurrentState.AvoidBinPacking =
true;
289 CurrentState.BreakBeforeParameter =
true;
290 CurrentState.AlignColons =
false;
294 moveStateToNextToken(State, DryRun,
false);
301 const auto &CurrentState = State.Stack.back();
303 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
304 Current.closesBlockOrBlockTypeList(Style))) {
312 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
321 State.LowestLevelOnLine < State.StartOfLineLevel &&
325 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
330 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
331 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
332 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
333 return Style.isCpp() &&
334 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;
339 if (Current.
is(TT_FunctionDeclarationName)) {
340 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&
345 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {
346 assert(State.Column >= State.FirstIndent);
347 if (State.Column - State.FirstIndent < 6)
355 Current.isBlockIndentedInitRBrace(Style)) {
356 return CurrentState.BreakBeforeClosingBrace;
361 if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
362 Current.
is(tok::r_paren)) {
363 return CurrentState.BreakBeforeClosingParen;
366 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
367 return CurrentState.BreakBeforeClosingAngle;
371 if (!Current.
isOneOf(TT_BinaryOperator, tok::comma) &&
375 (!Style.BraceWrapping.BeforeLambdaBody ||
376 Current.
isNot(TT_LambdaLBrace)) &&
377 CurrentState.NoLineBreakInOperand) {
384 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
386 Previous.MatchingParen->Previous->MatchingParen &&
387 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
389 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
393 return !State.NoLineBreak && !CurrentState.NoLineBreak;
399 const auto &CurrentState = State.Stack.back();
400 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
401 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
406 (Current.
is(TT_InlineASMColon) &&
407 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
408 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
409 Style.ColumnLimit > 0)))) {
412 if (CurrentState.BreakBeforeClosingBrace &&
413 (Current.closesBlockOrBlockTypeList(Style) ||
414 (Current.
is(tok::r_brace) &&
415 Current.isBlockIndentedInitRBrace(Style)))) {
418 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
420 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
422 if (Style.Language == FormatStyle::LK_ObjC &&
423 Style.ObjCBreakBeforeNestedBlockParam &&
425 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
430 if (CurrentState.IsCSharpGenericTypeConstraint &&
431 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
435 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
436 State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() &&
442 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||
443 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
445 (!Style.BreakBeforeTernaryOperators &&
446 Previous.is(TT_ConditionalExpr))) &&
447 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
448 !Current.
isOneOf(tok::r_paren, tok::r_brace)) {
451 if (CurrentState.IsChainedConditional &&
452 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
453 Current.
is(tok::colon)) ||
454 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
459 (
Previous.is(TT_ArrayInitializerLSquare) &&
462 Style.ColumnLimit > 0 &&
468 const FormatToken &BreakConstructorInitializersToken =
469 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
472 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
473 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
475 CurrentState.BreakBeforeParameter) &&
476 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
481 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
482 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
485 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
486 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
487 (Style.ObjCBreakBeforeNestedBlockParam ||
488 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
492 unsigned NewLineColumn = getNewLineColumn(State);
493 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
495 (State.Column > NewLineColumn ||
501 (CurrentState.CallContinuation != 0 ||
502 CurrentState.BreakBeforeParameter) &&
508 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
509 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
515 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
520 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
523 if (Style.AlwaysBreakBeforeMultilineStrings &&
524 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
526 !
Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
527 Keywords.kw_dollar) &&
528 !
Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
529 nextIsMultilineString(State)) {
537 const auto PreviousPrecedence =
Previous.getPrecedence();
539 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
540 const bool LHSIsBinaryExpr =
553 const bool IsComparison =
558 Previous.Previous->isNot(TT_BinaryOperator);
564 CurrentState.BreakBeforeParameter) {
569 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
570 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
574 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
579 if (
Previous.ClosesTemplateDeclaration) {
580 if (Current.
is(tok::kw_concept)) {
581 switch (Style.BreakBeforeConceptDeclarations) {
582 case FormatStyle::BBCDS_Allowed:
584 case FormatStyle::BBCDS_Always:
586 case FormatStyle::BBCDS_Never:
590 if (Current.
is(TT_RequiresClause)) {
591 switch (Style.RequiresClausePosition) {
592 case FormatStyle::RCPS_SingleLine:
593 case FormatStyle::RCPS_WithPreceding:
599 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
600 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
603 if (
Previous.is(TT_FunctionAnnotationRParen) &&
607 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
608 Current.
isNot(TT_LeadingJavaAnnotation)) {
613 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
617 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
619 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
623 if (Current.
is(TT_FunctionDeclarationName) &&
624 !State.Line->ReturnTypeWrapped &&
626 (!Style.isCSharp() ||
627 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
630 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
631 CurrentState.BreakBeforeParameter) {
633 if (
Tok->is(TT_LineComment))
635 if (
Tok->is(TT_TemplateCloser)) {
639 if (
Tok->FirstAfterPPLine)
651 !Current.
isOneOf(tok::r_brace, tok::comment)) {
655 if (Current.
is(tok::lessless) &&
658 Previous.TokenText ==
"\'\\n\'")))) {
665 if (State.NoContinuation)
673 unsigned ExtraSpaces) {
675 assert(State.NextToken->Previous);
678 assert(!State.Stack.empty());
679 State.NoContinuation =
false;
681 if (Current.
is(TT_ImplicitStringLiteral) &&
682 (!
Previous.Tok.getIdentifierInfo() ||
683 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
684 tok::pp_not_keyword)) {
690 State.Column = EndColumn;
692 unsigned StartColumn =
694 assert(EndColumn >= StartColumn);
695 State.Column += EndColumn - StartColumn;
697 moveStateToNextToken(State, DryRun,
false);
701 unsigned Penalty = 0;
703 Penalty = addTokenOnNewLine(State, DryRun);
705 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
707 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
710void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
711 unsigned ExtraSpaces) {
713 assert(State.NextToken->Previous);
715 auto &CurrentState = State.Stack.back();
722 auto DisallowLineBreaks = [&] {
723 if (!Style.isCpp() ||
724 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
732 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
735 const auto *Prev = Current.getPreviousNonComment();
736 if (!Prev || Prev->isNot(tok::l_paren))
739 if (Prev->BlockParameterCount == 0)
743 if (Prev->BlockParameterCount > 1)
750 const auto *Comma = Prev->
Role->lastComma();
754 const auto *
Next = Comma->getNextNonComment();
755 return Next && !
Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
758 if (DisallowLineBreaks())
759 State.NoLineBreak =
true;
761 if (Current.
is(tok::equal) &&
762 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
763 CurrentState.VariablePos == 0 &&
765 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
766 CurrentState.VariablePos = State.Column;
769 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
770 CurrentState.VariablePos -=
Tok->ColumnWidth;
771 if (
Tok->SpacesRequiredBefore != 0)
775 if (
Previous.PartOfMultiVariableDeclStmt)
776 CurrentState.LastSpace = CurrentState.VariablePos;
782 int PPColumnCorrection = 0;
786 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
793 if (Style.UseTab != FormatStyle::UT_Never)
794 PPColumnCorrection = -1;
795 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
801 Whitespaces.replaceWhitespace(Current, 0, Spaces,
802 State.
Column + Spaces + PPColumnCorrection,
808 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
809 Current.
is(TT_InheritanceColon)) {
810 CurrentState.NoLineBreak =
true;
812 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
814 CurrentState.NoLineBreak =
true;
817 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
818 unsigned MinIndent = std::max(
819 State.
FirstIndent + Style.ContinuationIndentWidth, CurrentState.Indent);
822 CurrentState.AlignColons =
false;
826 CurrentState.ColonPos = FirstColonPos;
834 auto IsStartOfBracedList = [&]() {
836 Style.Cpp11BracedListStyle;
838 if (!
Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
839 !IsStartOfBracedList()) {
844 if (
Tok.Previous->isIf())
845 return Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak;
846 return !
Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
848 !(Style.isJavaScript() &&
Tok.Previous->is(Keywords.kw_await));
851 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
852 Tok.Previous->is(tok::identifier);
855 if (!Style.isJavaScript())
857 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
858 if (Prev->is(TT_TemplateString) && Prev->opensScope())
860 if (Prev->opensScope() ||
861 (Prev->is(TT_TemplateString) && Prev->closesScope())) {
868 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
869 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
871 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
878 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
880 if (
Tok.is(TT_UnaryOperator) ||
881 (Style.isJavaScript() &&
882 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
887 TT_LambdaDefinitionLParen) &&
891 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok))
894 return !
Next ||
Next->isMemberAccess() ||
895 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
897 if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak ||
898 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) &&
899 IsOpeningBracket(
Previous) && State.
Column > getNewLineColumn(State) &&
910 !StartsSimpleOneArgList(Current)) {
911 CurrentState.NoLineBreak =
true;
915 CurrentState.NoLineBreak =
true;
921 if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign &&
922 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
924 Previous.isNot(TT_TableGenDAGArgOpener) &&
925 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
927 (Current.
isNot(TT_LineComment) ||
929 !IsInTemplateString(Current)) {
930 CurrentState.Indent = State.
Column + Spaces;
931 CurrentState.IsAligned =
true;
934 CurrentState.NoLineBreak =
true;
936 CurrentState.NoLineBreak =
true;
939 State.
Column > getNewLineColumn(State)) {
940 CurrentState.ContainsUnwrappedBuilder =
true;
943 if (Current.
is(TT_LambdaArrow) && Style.isJava())
944 CurrentState.NoLineBreak =
true;
945 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
954 CurrentState.NoLineBreak =
true;
961 const FormatToken *P = Current.getPreviousNonComment();
962 if (Current.
isNot(tok::comment) && P &&
963 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
964 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
965 !P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
969 bool BreakBeforeOperator =
970 P->MustBreakBefore || P->is(tok::lessless) ||
971 (P->is(TT_BinaryOperator) &&
972 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
973 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
977 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
978 P->isNot(TT_ConditionalExpr);
979 if ((!BreakBeforeOperator &&
981 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
982 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
983 CurrentState.NoLineBreakInOperand =
true;
988 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
993 CurrentState.LastSpace = State.
Column;
994 CurrentState.NestedBlockIndent = State.
Column;
995 }
else if (!Current.
isOneOf(tok::comment, tok::caret) &&
997 Previous.isNot(TT_OverloadedOperator)) ||
999 CurrentState.LastSpace = State.
Column;
1000 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1002 Style.BreakConstructorInitializers ==
1003 FormatStyle::BCIS_AfterColon) {
1004 CurrentState.Indent = State.
Column;
1005 CurrentState.LastSpace = State.
Column;
1006 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1007 CurrentState.LastSpace = State.
Column;
1008 }
else if (
Previous.is(TT_BinaryOperator) &&
1015 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1016 CurrentState.LastSpace = State.
Column;
1017 }
else if (
Previous.is(TT_InheritanceColon)) {
1018 CurrentState.Indent = State.
Column;
1019 CurrentState.LastSpace = State.
Column;
1020 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1021 CurrentState.ColonPos = State.
Column;
1022 }
else if (
Previous.opensScope()) {
1030 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1031 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1032 CurrentState.LastSpace = State.
Column;
1038unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1041 assert(State.NextToken->Previous);
1043 auto &CurrentState = State.Stack.back();
1047 unsigned Penalty = 0;
1049 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1051 if (!NextNonComment)
1052 NextNonComment = &Current;
1055 if (!CurrentState.ContainsLineBreak)
1057 CurrentState.ContainsLineBreak =
true;
1059 Penalty += State.NextToken->SplitPenalty;
1064 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1065 (State.Column <= Style.ColumnLimit / 3 ||
1066 CurrentState.BreakBeforeParameter)) {
1067 Penalty += Style.PenaltyBreakFirstLessLess;
1070 State.Column = getNewLineColumn(State);
1084 if (State.Column > State.FirstIndent) {
1086 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1099 if (Current.isNot(TT_LambdaArrow) &&
1100 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1101 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1102 !Current.isOneOf(Keywords.kw_async, Keywords.kw_function))) {
1103 CurrentState.NestedBlockIndent = State.Column;
1106 if (NextNonComment->isMemberAccess()) {
1107 if (CurrentState.CallContinuation == 0)
1108 CurrentState.CallContinuation = State.Column;
1109 }
else if (NextNonComment->is(TT_SelectorName)) {
1110 if (!CurrentState.ObjCSelectorNameFound) {
1111 if (NextNonComment->LongestObjCSelectorName == 0) {
1112 CurrentState.AlignColons =
false;
1114 CurrentState.ColonPos =
1116 ? std::max(CurrentState.Indent,
1117 State.FirstIndent + Style.ContinuationIndentWidth)
1122 }
else if (CurrentState.AlignColons &&
1123 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1124 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1126 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1127 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1137 if (State.Stack.size() > 1) {
1138 State.Stack[State.Stack.size() - 2].LastSpace =
1139 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1140 Style.ContinuationIndentWidth;
1144 if ((PreviousNonComment &&
1145 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1146 !CurrentState.AvoidBinPacking) ||
1148 CurrentState.BreakBeforeParameter =
false;
1150 if (PreviousNonComment &&
1151 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1152 PreviousNonComment->ClosesRequiresClause) &&
1153 Current.NestingLevel == 0) {
1154 CurrentState.BreakBeforeParameter =
false;
1156 if (NextNonComment->is(tok::question) ||
1157 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1158 CurrentState.BreakBeforeParameter =
true;
1160 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1161 CurrentState.BreakBeforeParameter =
false;
1165 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1168 !Current.MatchingParen->Children.empty()) {
1176 bool ContinuePPDirective =
1178 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1179 CurrentState.IsAligned, ContinuePPDirective);
1182 if (!Current.isTrailingComment())
1183 CurrentState.LastSpace = State.Column;
1184 if (Current.is(tok::lessless)) {
1188 CurrentState.LastSpace += 3;
1191 State.StartOfLineLevel = Current.NestingLevel;
1192 State.LowestLevelOnLine = Current.NestingLevel;
1196 bool NestedBlockSpecialCase =
1197 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1198 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1199 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1200 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1202 NestedBlockSpecialCase =
1203 NestedBlockSpecialCase ||
1204 (Current.MatchingParen &&
1205 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1206 if (!NestedBlockSpecialCase) {
1207 auto ParentLevelIt = std::next(State.Stack.rbegin());
1208 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1209 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1224 auto FindCurrentLevel = [&](
const auto &It) {
1225 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1226 return PState.Tok != nullptr;
1229 auto MaybeIncrement = [&](
const auto &It) {
1230 return It != State.Stack.rend() ? std::next(It) : It;
1232 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1233 auto LevelContainingLambdaIt =
1234 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1235 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1237 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1238 I->BreakBeforeParameter =
true;
1241 if (PreviousNonComment &&
1242 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1243 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1244 !PreviousNonComment->ClosesRequiresClause) ||
1245 Current.NestingLevel != 0) &&
1246 !PreviousNonComment->isOneOf(
1247 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1248 TT_LeadingJavaAnnotation) &&
1249 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1252 (!Style.BraceWrapping.BeforeLambdaBody ||
1253 Current.isNot(TT_LambdaLBrace))) {
1254 CurrentState.BreakBeforeParameter =
true;
1259 if (PreviousNonComment &&
1260 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1262 CurrentState.BreakBeforeClosingBrace =
true;
1265 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1266 CurrentState.BreakBeforeClosingParen =
1267 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
1270 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1271 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1273 if (CurrentState.AvoidBinPacking) {
1278 bool PreviousIsBreakingCtorInitializerColon =
1279 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1280 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1281 bool AllowAllConstructorInitializersOnNextLine =
1282 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1283 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1284 if (!(
Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1285 PreviousIsBreakingCtorInitializerColon) ||
1286 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1287 State.Line->MustBeDeclaration) ||
1288 (!Style.AllowAllArgumentsOnNextLine &&
1289 !State.Line->MustBeDeclaration) ||
1290 (!AllowAllConstructorInitializersOnNextLine &&
1291 PreviousIsBreakingCtorInitializerColon) ||
1293 CurrentState.BreakBeforeParameter =
true;
1299 if (PreviousIsBreakingCtorInitializerColon &&
1300 AllowAllConstructorInitializersOnNextLine) {
1301 CurrentState.BreakBeforeParameter =
false;
1306 CurrentState.BreakBeforeParameter =
true;
1311unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1312 if (!State.NextToken || !State.NextToken->Previous)
1316 const auto &CurrentState = State.Stack.back();
1318 if (CurrentState.IsCSharpGenericTypeConstraint &&
1319 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1320 return CurrentState.ColonPos + 2;
1325 unsigned ContinuationIndent =
1326 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1327 Style.ContinuationIndentWidth;
1328 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1330 if (!NextNonComment)
1331 NextNonComment = &Current;
1334 if (Style.isJava() &&
1335 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1336 return std::max(CurrentState.LastSpace,
1337 CurrentState.Indent + Style.ContinuationIndentWidth);
1342 if (Style.isVerilog() && PreviousNonComment &&
1343 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1344 return State.FirstIndent;
1347 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1348 State.Line->First->is(tok::kw_enum)) {
1349 return (Style.IndentWidth * State.Line->First->IndentLevel) +
1353 if (Style.BraceWrapping.BeforeLambdaBody &&
1354 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1355 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1356 ? CurrentState.Indent
1357 : State.FirstIndent;
1358 return From + Style.IndentWidth;
1361 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1362 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1363 if (Current.NestingLevel == 0 ||
1364 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1365 State.NextToken->is(TT_LambdaLBrace))) {
1366 return State.FirstIndent;
1368 return CurrentState.Indent;
1370 if (Current.is(TT_LambdaArrow) &&
1371 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1372 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
1373 return ContinuationIndent;
1375 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1376 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1377 State.Stack.size() > 1) {
1378 if (Current.closesBlockOrBlockTypeList(Style))
1379 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1380 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1381 return State.Stack[State.Stack.size() - 2].LastSpace;
1382 return State.FirstIndent;
1399 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1401 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1402 return State.Stack[State.Stack.size() - 2].LastSpace;
1406 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1407 State.Stack.size() > 1) {
1408 return State.Stack[State.Stack.size() - 2].LastSpace;
1410 if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
1411 (Current.is(tok::r_paren) ||
1412 (Current.is(tok::r_brace) && Current.MatchingParen &&
1414 State.Stack.size() > 1) {
1415 return State.Stack[State.Stack.size() - 2].LastSpace;
1417 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1418 State.Stack.size() > 1) {
1419 return State.Stack[State.Stack.size() - 2].LastSpace;
1421 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1422 return State.Stack[State.Stack.size() - 2].LastSpace;
1430 if (Current.is(tok::identifier) && Current.Next &&
1431 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1432 (Current.Next->is(TT_DictLiteral) ||
1433 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1434 return CurrentState.Indent;
1436 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1437 State.StartOfStringLiteral != 0) {
1438 return State.StartOfStringLiteral - 1;
1440 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1441 return State.StartOfStringLiteral;
1442 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1443 return CurrentState.FirstLessLess;
1444 if (NextNonComment->isMemberAccess()) {
1445 if (CurrentState.CallContinuation == 0)
1446 return ContinuationIndent;
1447 return CurrentState.CallContinuation;
1449 if (CurrentState.QuestionColumn != 0 &&
1450 ((NextNonComment->is(tok::colon) &&
1451 NextNonComment->is(TT_ConditionalExpr)) ||
1452 Previous.is(TT_ConditionalExpr))) {
1453 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1454 !NextNonComment->Next->FakeLParens.empty() &&
1456 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1458 !CurrentState.IsWrappedConditional) {
1463 unsigned Indent = CurrentState.Indent;
1464 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1465 Indent -= Style.ContinuationIndentWidth;
1466 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1470 return CurrentState.QuestionColumn;
1472 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1473 return CurrentState.VariablePos;
1474 if (Current.is(TT_RequiresClause)) {
1475 if (Style.IndentRequiresClause)
1476 return CurrentState.Indent + Style.IndentWidth;
1477 switch (Style.RequiresClausePosition) {
1478 case FormatStyle::RCPS_OwnLine:
1479 case FormatStyle::RCPS_WithFollowing:
1480 case FormatStyle::RCPS_OwnLineWithBrace:
1481 return CurrentState.Indent;
1486 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1487 TT_InheritanceComma)) {
1488 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1490 if ((PreviousNonComment &&
1491 (PreviousNonComment->ClosesTemplateDeclaration ||
1492 PreviousNonComment->ClosesRequiresClause ||
1493 (PreviousNonComment->is(TT_AttributeMacro) &&
1494 Current.isNot(tok::l_paren) &&
1495 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1496 TT_PointerOrReference)) ||
1497 PreviousNonComment->isOneOf(
1498 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1499 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1500 (!Style.IndentWrappedFunctionNames &&
1501 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1502 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1504 if (NextNonComment->is(TT_SelectorName)) {
1505 if (!CurrentState.ObjCSelectorNameFound) {
1506 unsigned MinIndent = CurrentState.Indent;
1508 MinIndent = std::max(MinIndent,
1509 State.FirstIndent + Style.ContinuationIndentWidth);
1521 std::max(NextNonComment->LongestObjCSelectorName,
1522 NextNonComment->ColumnWidth) -
1523 NextNonComment->ColumnWidth;
1525 if (!CurrentState.AlignColons)
1526 return CurrentState.Indent;
1527 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1528 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1529 return CurrentState.Indent;
1531 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1532 return CurrentState.ColonPos;
1533 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1534 if (CurrentState.StartOfArraySubscripts != 0) {
1535 return CurrentState.StartOfArraySubscripts;
1536 }
else if (Style.isCSharp()) {
1538 return CurrentState.Indent;
1540 return ContinuationIndent;
1545 if (State.Line->InPragmaDirective) {
1546 FormatToken *PragmaType = State.Line->First->Next->Next;
1547 if (PragmaType && PragmaType->TokenText ==
"omp")
1548 return CurrentState.Indent + Style.ContinuationIndentWidth;
1553 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1554 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1555 return CurrentState.Indent;
1558 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1559 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1560 return ContinuationIndent;
1562 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1563 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1564 return ContinuationIndent;
1566 if (NextNonComment->is(TT_CtorInitializerComma))
1567 return CurrentState.Indent;
1568 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1569 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1570 return CurrentState.Indent;
1572 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1573 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1574 return CurrentState.Indent;
1577 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1578 !Current.isBinaryOperator() &&
1579 !Current.isOneOf(tok::colon, tok::comment)) {
1580 return ContinuationIndent;
1582 if (Current.is(TT_ProtoExtensionLSquare))
1583 return CurrentState.Indent;
1584 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1585 return CurrentState.Indent - Current.Tok.getLength() -
1586 Current.SpacesRequiredBefore;
1588 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1589 CurrentState.UnindentOperator) {
1590 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1591 NextNonComment->SpacesRequiredBefore;
1593 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1594 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1597 return CurrentState.Indent + Style.ContinuationIndentWidth;
1599 return CurrentState.Indent;
1604 const FormatStyle &Style) {
1611 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1614unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1615 bool DryRun,
bool Newline) {
1616 assert(State.Stack.size());
1618 auto &CurrentState = State.Stack.back();
1620 if (Current.is(TT_CSharpGenericTypeConstraint))
1621 CurrentState.IsCSharpGenericTypeConstraint =
true;
1622 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1623 CurrentState.NoLineBreakInOperand =
false;
1624 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1625 CurrentState.AvoidBinPacking =
true;
1626 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1627 if (CurrentState.FirstLessLess == 0)
1628 CurrentState.FirstLessLess = State.Column;
1630 CurrentState.LastOperatorWrapped = Newline;
1632 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1633 CurrentState.LastOperatorWrapped = Newline;
1634 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1635 Current.Previous->isNot(TT_ConditionalExpr)) {
1636 CurrentState.LastOperatorWrapped = Newline;
1638 if (Current.is(TT_ArraySubscriptLSquare) &&
1639 CurrentState.StartOfArraySubscripts == 0) {
1640 CurrentState.StartOfArraySubscripts = State.Column;
1644 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1646 if (
Tok.MustBreakBefore)
1650 return Next &&
Next->MustBreakBefore;
1652 if (IsWrappedConditional(Current))
1653 CurrentState.IsWrappedConditional =
true;
1654 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1655 CurrentState.QuestionColumn = State.Column;
1656 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1661 CurrentState.QuestionColumn = State.Column;
1663 if (!Current.opensScope() && !Current.closesScope() &&
1664 Current.isNot(TT_PointerOrReference)) {
1665 State.LowestLevelOnLine =
1666 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1668 if (Current.isMemberAccess())
1669 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1670 if (Current.is(TT_SelectorName))
1671 CurrentState.ObjCSelectorNameFound =
true;
1672 if (Current.is(TT_CtorInitializerColon) &&
1673 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1679 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1680 FormatStyle::BCIS_BeforeComma
1683 CurrentState.NestedBlockIndent = CurrentState.Indent;
1684 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1685 CurrentState.AvoidBinPacking =
true;
1686 CurrentState.BreakBeforeParameter =
1687 Style.ColumnLimit > 0 &&
1688 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1689 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1691 CurrentState.BreakBeforeParameter =
false;
1694 if (Current.is(TT_CtorInitializerColon) &&
1695 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1696 CurrentState.Indent =
1697 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1698 CurrentState.NestedBlockIndent = CurrentState.Indent;
1699 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1700 CurrentState.AvoidBinPacking =
true;
1702 CurrentState.BreakBeforeParameter =
false;
1704 if (Current.is(TT_InheritanceColon)) {
1705 CurrentState.Indent =
1706 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1708 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1709 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1710 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1711 CurrentState.LastSpace = State.Column;
1712 if (Current.is(TT_RequiresExpression) &&
1713 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1714 CurrentState.NestedBlockIndent = State.Column;
1726 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1728 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1729 !CurrentState.HasMultipleNestedBlocks) {
1730 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1731 for (ParenState &PState : llvm::drop_end(State.Stack))
1732 PState.NoLineBreak =
true;
1733 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1735 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1736 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1737 !
Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1738 TT_CtorInitializerColon)))) {
1739 CurrentState.NestedBlockInlined =
1743 moveStatePastFakeLParens(State, Newline);
1744 moveStatePastScopeCloser(State);
1747 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1748 !State.Stack.back().NoLineBreakInOperand;
1749 moveStatePastScopeOpener(State, Newline);
1750 moveStatePastFakeRParens(State);
1752 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1753 State.StartOfStringLiteral = State.Column + 1;
1754 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1755 State.StartOfStringLiteral = State.Column + 1;
1756 }
else if (Current.is(TT_TableGenMultiLineString) &&
1757 State.StartOfStringLiteral == 0) {
1758 State.StartOfStringLiteral = State.Column + 1;
1759 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1760 State.StartOfStringLiteral = State.Column;
1761 }
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1762 !Current.isStringLiteral()) {
1763 State.StartOfStringLiteral = 0;
1766 State.Column += Current.ColumnWidth;
1767 State.NextToken = State.NextToken->Next;
1772 if (Style.isVerilog() && State.NextToken &&
1773 State.NextToken->MustBreakBefore &&
1774 Keywords.isVerilogEndOfLabel(Current)) {
1775 State.FirstIndent += Style.IndentWidth;
1776 CurrentState.Indent = State.FirstIndent;
1780 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1783 Current.Role->formatFromToken(State,
this, DryRun);
1790 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1795void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1798 if (Current.FakeLParens.empty())
1806 bool SkipFirstExtraIndent =
1809 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1811 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1813 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1814 const auto &CurrentState = State.Stack.back();
1815 ParenState NewParenState = CurrentState;
1816 NewParenState.Tok =
nullptr;
1817 NewParenState.ContainsLineBreak =
false;
1818 NewParenState.LastOperatorWrapped =
true;
1819 NewParenState.IsChainedConditional =
false;
1820 NewParenState.IsWrappedConditional =
false;
1821 NewParenState.UnindentOperator =
false;
1822 NewParenState.NoLineBreak =
1823 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1827 NewParenState.AvoidBinPacking =
false;
1832 if (!Current.isTrailingComment() &&
1833 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1836 (!Style.isJava() && PrecedenceLevel > 0)) &&
1837 (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign ||
1838 PrecedenceLevel >
prec::Comma || Current.NestingLevel == 0) &&
1839 (!Style.isTableGen() ||
1841 TT_TableGenDAGArgListCommaToBreak)))) {
1842 NewParenState.Indent = std::max(
1843 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1850 State.Stack.size() > 1) {
1851 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1852 Style.ContinuationIndentWidth;
1862 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1863 NewParenState.UnindentOperator =
true;
1865 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1866 NewParenState.IsAligned =
true;
1876 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1878 Current.isNot(TT_UnaryOperator) &&
1879 Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) {
1880 NewParenState.StartOfFunctionCall = State.Column;
1890 &PrecedenceLevel == &Current.FakeLParens.back() &&
1891 !CurrentState.IsWrappedConditional) {
1892 NewParenState.IsChainedConditional =
true;
1893 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1896 !Current.isTrailingComment())) {
1897 NewParenState.Indent += Style.ContinuationIndentWidth;
1900 NewParenState.BreakBeforeParameter =
false;
1901 State.Stack.push_back(NewParenState);
1902 SkipFirstExtraIndent =
false;
1906void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
1907 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1908 unsigned VariablePos = State.Stack.back().VariablePos;
1909 if (State.Stack.size() == 1) {
1913 State.Stack.pop_back();
1914 State.Stack.back().VariablePos = VariablePos;
1917 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
1920 State.Stack.back().LastSpace -= Style.IndentWidth;
1924void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
1927 if (!Current.opensScope())
1930 const auto &CurrentState = State.Stack.back();
1933 if (Current.isOneOf(tok::less, tok::l_paren) &&
1934 CurrentState.IsCSharpGenericTypeConstraint) {
1938 if (Current.MatchingParen && Current.is(
BK_Block)) {
1939 moveStateToNewBlock(State, Newline);
1946 const auto *Prev =
Tok->getPreviousNonComment();
1949 return Prev->is(tok::comma);
1950 }(Current.MatchingParen);
1953 unsigned LastSpace = CurrentState.LastSpace;
1954 bool AvoidBinPacking;
1955 bool BreakBeforeParameter =
false;
1956 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1957 CurrentState.NestedBlockIndent);
1958 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1960 if (Current.opensBlockOrBlockTypeList(Style)) {
1961 NewIndent = Style.IndentWidth +
1962 std::min(State.Column, CurrentState.NestedBlockIndent);
1963 }
else if (Current.is(tok::l_brace)) {
1964 const auto Width = Style.BracedInitializerIndentWidth;
1965 NewIndent = CurrentState.LastSpace +
1966 (Width < 0 ? Style.ContinuationIndentWidth : Width);
1968 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
1970 const FormatToken *NextNonComment = Current.getNextNonComment();
1971 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1972 Style.isProto() || !Style.BinPackArguments ||
1973 (NextNonComment && NextNonComment->isOneOf(
1974 TT_DesignatedInitializerPeriod,
1975 TT_DesignatedInitializerLSquare));
1976 BreakBeforeParameter = EndsInComma;
1977 if (Current.ParameterCount > 1)
1978 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1981 Style.ContinuationIndentWidth +
1982 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1984 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1985 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
1991 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
1992 NewIndent = State.Column +
Next->TokenText.size() + 2;
1999 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2000 NewIndent = std::max(NewIndent, CurrentState.Indent);
2001 LastSpace = std::max(LastSpace, CurrentState.Indent);
2007 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2008 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2009 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2011 bool BinPackDeclaration =
2013 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2016 bool GenericSelection =
2017 Current.getPreviousNonComment() &&
2018 Current.getPreviousNonComment()->is(tok::kw__Generic);
2021 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2022 (Style.isJavaScript() && EndsInComma) ||
2023 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2024 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2025 (Style.ExperimentalAutoDetectBinPacking &&
2029 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2030 Style.ObjCBreakBeforeNestedBlockParam) {
2031 if (Style.ColumnLimit) {
2036 BreakBeforeParameter =
true;
2042 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2043 if (
Tok->MustBreakBefore ||
2044 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2045 BreakBeforeParameter =
true;
2052 if (Style.isJavaScript() && EndsInComma)
2053 BreakBeforeParameter =
true;
2059 Current.Children.empty() &&
2060 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2061 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2062 (Current.is(TT_TemplateOpener) &&
2063 CurrentState.ContainsUnwrappedBuilder));
2064 State.Stack.push_back(
2065 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2066 auto &NewState = State.Stack.back();
2067 NewState.NestedBlockIndent = NestedBlockIndent;
2068 NewState.BreakBeforeParameter = BreakBeforeParameter;
2069 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2071 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2072 Current.is(tok::l_paren)) {
2076 if (next->is(TT_LambdaLSquare)) {
2077 NewState.HasMultipleNestedBlocks =
true;
2084 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2086 Current.Previous->is(tok::at);
2089void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2091 if (!Current.closesScope())
2096 if (State.Stack.size() > 1 &&
2097 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2098 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2099 State.NextToken->is(TT_TemplateCloser) ||
2100 State.NextToken->is(TT_TableGenListCloser) ||
2101 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2102 State.Stack.pop_back();
2105 auto &CurrentState = State.Stack.back();
2117 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2118 Current.MatchingParen->Previous) {
2119 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2120 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2121 CurrentScopeOpener.MatchingParen) {
2122 int NecessarySpaceInLine =
2124 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2125 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2126 Style.ColumnLimit) {
2127 CurrentState.BreakBeforeParameter =
false;
2132 if (Current.is(tok::r_square)) {
2134 const FormatToken *NextNonComment = Current.getNextNonComment();
2135 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2136 CurrentState.StartOfArraySubscripts = 0;
2140void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2141 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2142 State.NextToken->is(TT_LambdaLBrace) &&
2143 !State.Line->MightBeFunctionDecl) {
2144 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2145 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2147 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2149 unsigned NewIndent =
2150 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2151 ? Style.ObjCBlockIndentWidth
2152 : Style.IndentWidth);
2159 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2160 State.NextToken->is(TT_LambdaLBrace);
2162 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2163 State.Stack.back().LastSpace,
2164 true, NoLineBreak));
2165 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2166 State.Stack.back().BreakBeforeParameter =
true;
2172 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2173 if (LastNewlinePos == StringRef::npos) {
2174 return StartColumn +
2182unsigned ContinuationIndenter::reformatRawStringLiteral(
2184 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2185 unsigned StartColumn = State.Column - Current.ColumnWidth;
2187 StringRef NewDelimiter =
2189 if (NewDelimiter.empty())
2190 NewDelimiter = OldDelimiter;
2193 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2194 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2197 std::string RawText = std::string(
2198 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2199 if (NewDelimiter != OldDelimiter) {
2202 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2203 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2204 NewDelimiter = OldDelimiter;
2207 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2208 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2211 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2222 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2244 unsigned CurrentIndent =
2245 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2246 ? State.Stack.back().NestedBlockIndent
2247 : State.Stack.back().Indent;
2248 unsigned NextStartColumn = ContentStartsOnNewline
2249 ? CurrentIndent + Style.IndentWidth
2260 unsigned LastStartColumn =
2261 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2264 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2265 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2270 return addMultilineToken(Current, State);
2272 if (NewDelimiter != OldDelimiter) {
2275 SourceLocation PrefixDelimiterStart =
2276 Current.Tok.getLocation().getLocWithOffset(2);
2277 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2278 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2281 <<
"Failed to update the prefix delimiter of a raw string: "
2282 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2286 SourceLocation SuffixDelimiterStart =
2287 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2288 1 - OldDelimiter.size());
2289 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2290 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2293 <<
"Failed to update the suffix delimiter of a raw string: "
2294 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2297 SourceLocation OriginLoc =
2298 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2299 for (
const tooling::Replacement &Fix : Fixes.first) {
2300 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2301 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2302 Fix.getLength(), Fix.getReplacementText()));
2304 llvm::errs() <<
"Failed to reformat raw string: "
2305 << llvm::toString(std::move(Err)) <<
"\n";
2310 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2311 State.Column = RawLastLineEndColumn + NewSuffixSize;
2315 unsigned PrefixExcessCharacters =
2316 StartColumn + NewPrefixSize > Style.ColumnLimit
2317 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2320 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2323 for (ParenState &
Paren : State.Stack)
2324 Paren.BreakBeforeParameter =
true;
2326 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2329unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2332 for (ParenState &
Paren : State.Stack)
2333 Paren.BreakBeforeParameter =
true;
2335 unsigned ColumnsUsed = State.Column;
2338 State.Column = Current.LastLineColumnWidth;
2341 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2345unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2347 bool AllowBreak,
bool Newline) {
2348 unsigned Penalty = 0;
2351 auto RawStringStyle = getRawStringStyle(Current, State);
2352 if (RawStringStyle && !Current.Finalized) {
2353 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2355 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2358 Penalty = addMultilineToken(Current, State);
2361 LineState OriginalState = State;
2365 bool Strict =
false;
2368 bool Exceeded =
false;
2369 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2370 Current, State, AllowBreak,
true, Strict);
2374 LineState StrictState = OriginalState;
2375 unsigned StrictPenalty =
2376 breakProtrudingToken(Current, StrictState, AllowBreak,
2379 Strict = StrictPenalty <= Penalty;
2381 Penalty = StrictPenalty;
2382 State = StrictState;
2388 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2393 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2394 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2403 auto Tok = Current.getPreviousNonComment();
2404 if (!
Tok ||
Tok->isNot(tok::l_paren))
2406 Tok =
Tok->getPreviousNonComment();
2409 if (
Tok->is(TT_TemplateCloser)) {
2410 Tok =
Tok->MatchingParen;
2412 Tok =
Tok->getPreviousNonComment();
2414 if (!
Tok ||
Tok->isNot(tok::identifier))
2416 return Tok->TokenText;
2419std::optional<FormatStyle>
2420ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2421 const LineState &State) {
2422 if (!Current.isStringLiteral())
2423 return std::nullopt;
2426 return std::nullopt;
2428 if (!RawStringStyle && Delimiter->empty()) {
2432 if (!RawStringStyle)
2433 return std::nullopt;
2435 return RawStringStyle;
2438std::unique_ptr<BreakableToken>
2439ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2441 unsigned StartColumn = State.Column - Current.ColumnWidth;
2442 if (Current.isStringLiteral()) {
2445 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2459 if (Current.IsUnterminatedLiteral)
2463 if (State.Stack.back().IsInsideObjCArrayLiteral)
2470 if (Style.isVerilog() && Current.Previous &&
2471 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2474 StringRef
Text = Current.TokenText;
2484 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2487 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2488 Text.ends_with(
"'")) {
2490 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2491 Text.ends_with(
"\"")) {
2493 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2498 return std::make_unique<BreakableStringLiteralUsingOperators>(
2499 Current, QuoteStyle,
2510 if ((
Text.ends_with(Postfix =
"\"") &&
2511 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2512 Text.starts_with(Prefix =
"u\"") ||
2513 Text.starts_with(Prefix =
"U\"") ||
2514 Text.starts_with(Prefix =
"u8\"") ||
2515 Text.starts_with(Prefix =
"L\""))) ||
2516 (
Text.starts_with(Prefix =
"_T(\"") &&
2517 Text.ends_with(Postfix =
"\")"))) {
2518 return std::make_unique<BreakableStringLiteral>(
2520 State.Line->InPPDirective, Encoding, Style);
2522 }
else if (Current.is(TT_BlockComment)) {
2523 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2530 return std::make_unique<BreakableBlockComment>(
2531 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2532 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2533 }
else if (Current.is(TT_LineComment) &&
2534 (!Current.Previous ||
2535 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2536 bool RegularComments = [&]() {
2537 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2539 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2544 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2545 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2549 return std::make_unique<BreakableLineCommentSection>(
2550 Current, StartColumn,
false, Encoding, Style);
2555std::pair<unsigned, bool>
2556ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2558 bool DryRun,
bool Strict) {
2559 std::unique_ptr<const BreakableToken> Token =
2560 createBreakableToken(Current, State, AllowBreak);
2563 assert(Token->getLineCount() > 0);
2565 if (Current.is(TT_LineComment)) {
2567 ColumnLimit = Style.ColumnLimit;
2569 if (ColumnLimit == 0) {
2572 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2574 if (Current.UnbreakableTailLength >= ColumnLimit)
2578 unsigned StartColumn = State.Column - Current.ColumnWidth;
2579 unsigned NewBreakPenalty = Current.isStringLiteral()
2580 ? Style.PenaltyBreakString
2581 : Style.PenaltyBreakComment;
2584 bool Exceeded =
false;
2586 bool BreakInserted = Token->introducesBreakBeforeToken();
2589 bool NewBreakBefore =
false;
2593 bool Reflow =
false;
2596 unsigned TailOffset = 0;
2598 unsigned ContentStartColumn =
2599 Token->getContentStartColumn(0,
false);
2601 unsigned RemainingTokenColumns =
2602 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2605 Token->adaptStartOfLine(0, Whitespaces);
2607 unsigned ContentIndent = 0;
2608 unsigned Penalty = 0;
2609 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2610 << StartColumn <<
".\n");
2611 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2612 LineIndex != EndIndex; ++LineIndex) {
2613 LLVM_DEBUG(llvm::dbgs()
2614 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2615 NewBreakBefore =
false;
2619 bool TryReflow = Reflow;
2621 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2622 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2623 << (ContentStartColumn + RemainingTokenColumns)
2624 <<
", space: " << ColumnLimit
2625 <<
", reflown prefix: " << ContentStartColumn
2626 <<
", offset in line: " << TailOffset <<
"\n");
2632 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2633 ContentStartColumn, CommentPragmasRegex);
2634 if (
Split.first == StringRef::npos) {
2637 if (LineIndex < EndIndex - 1) {
2640 Penalty += Style.PenaltyExcessCharacter *
2641 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2643 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2646 assert(
Split.first != 0);
2648 if (Token->supportsReflow()) {
2668 unsigned ToSplitColumns = Token->getRangeLength(
2669 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2670 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2673 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2674 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2677 unsigned ToNextSplitColumns = 0;
2678 if (NextSplit.first == StringRef::npos) {
2679 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2680 ContentStartColumn);
2682 ToNextSplitColumns = Token->getRangeLength(
2683 LineIndex, TailOffset,
2684 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2688 ToNextSplitColumns =
2689 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2690 LLVM_DEBUG(llvm::dbgs()
2691 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2692 LLVM_DEBUG(llvm::dbgs()
2693 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2696 bool ContinueOnLine =
2697 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2698 unsigned ExcessCharactersPenalty = 0;
2699 if (!ContinueOnLine && !Strict) {
2702 ExcessCharactersPenalty =
2703 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2704 Style.PenaltyExcessCharacter;
2705 LLVM_DEBUG(llvm::dbgs()
2706 <<
" Penalty excess: " << ExcessCharactersPenalty
2707 <<
"\n break : " << NewBreakPenalty <<
"\n");
2708 if (ExcessCharactersPenalty < NewBreakPenalty) {
2710 ContinueOnLine =
true;
2713 if (ContinueOnLine) {
2714 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2719 Token->compressWhitespace(LineIndex, TailOffset, Split,
2723 ContentStartColumn += ToSplitColumns + 1;
2724 Penalty += ExcessCharactersPenalty;
2726 RemainingTokenColumns = Token->getRemainingLength(
2727 LineIndex, TailOffset, ContentStartColumn);
2731 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2736 ContentIndent = Token->getContentIndent(LineIndex);
2737 LLVM_DEBUG(llvm::dbgs()
2738 <<
" ContentIndent: " << ContentIndent <<
"\n");
2739 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2742 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2743 LineIndex, TailOffset +
Split.first +
Split.second,
2744 ContentStartColumn);
2745 if (NewRemainingTokenColumns == 0) {
2748 ContentStartColumn =
2749 Token->getContentStartColumn(LineIndex,
true);
2750 NewRemainingTokenColumns = Token->getRemainingLength(
2751 LineIndex, TailOffset +
Split.first +
Split.second,
2752 ContentStartColumn);
2758 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2763 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2764 <<
", " <<
Split.second <<
"\n");
2766 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2770 Penalty += NewBreakPenalty;
2772 RemainingTokenColumns = NewRemainingTokenColumns;
2773 BreakInserted =
true;
2774 NewBreakBefore =
true;
2778 if (LineIndex + 1 != EndIndex) {
2779 unsigned NextLineIndex = LineIndex + 1;
2780 if (NewBreakBefore) {
2799 ContentStartColumn += RemainingTokenColumns + 1;
2804 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2805 LLVM_DEBUG(llvm::dbgs()
2806 <<
" Size of reflown text: " << ContentStartColumn
2807 <<
"\n Potential reflow split: ");
2808 if (SplitBeforeNext.first != StringRef::npos) {
2809 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2810 << SplitBeforeNext.second <<
"\n");
2811 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2814 RemainingTokenColumns = Token->getRemainingLength(
2815 NextLineIndex, TailOffset, ContentStartColumn);
2817 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2818 LLVM_DEBUG(llvm::dbgs()
2819 <<
" Over limit after reflow, need: "
2820 << (ContentStartColumn + RemainingTokenColumns)
2821 <<
", space: " << ColumnLimit
2822 <<
", reflown prefix: " << ContentStartColumn
2823 <<
", offset in line: " << TailOffset <<
"\n");
2829 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2830 ContentStartColumn, CommentPragmasRegex);
2831 if (
Split.first == StringRef::npos) {
2832 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2838 unsigned ToSplitColumns = Token->getRangeLength(
2839 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2840 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2841 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2842 << (ContentStartColumn + ToSplitColumns)
2843 <<
", space: " << ColumnLimit);
2844 unsigned ExcessCharactersPenalty =
2845 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2846 Style.PenaltyExcessCharacter;
2847 if (NewBreakPenalty < ExcessCharactersPenalty)
2853 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2861 ContentStartColumn =
2862 Token->getContentStartColumn(NextLineIndex,
false);
2863 RemainingTokenColumns = Token->getRemainingLength(
2864 NextLineIndex, TailOffset, ContentStartColumn);
2867 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2882 if (NewBreakBefore) {
2883 assert(Penalty >= NewBreakPenalty);
2884 Penalty -= NewBreakPenalty;
2887 Token->reflow(NextLineIndex, Whitespaces);
2893 Token->getSplitAfterLastLine(TailOffset);
2894 if (SplitAfterLastLine.first != StringRef::npos) {
2895 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2899 Penalty += Style.PenaltyExcessCharacter *
2900 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2903 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2906 ContentStartColumn =
2907 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2908 RemainingTokenColumns = Token->getRemainingLength(
2909 Token->getLineCount() - 1,
2910 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2911 ContentStartColumn);
2914 State.Column = ContentStartColumn + RemainingTokenColumns -
2915 Current.UnbreakableTailLength;
2917 if (BreakInserted) {
2919 Token->updateAfterBroken(Whitespaces);
2924 if (Current.isNot(TT_LineComment))
2925 for (ParenState &
Paren : State.Stack)
2926 Paren.BreakBeforeParameter =
true;
2928 if (Current.is(TT_BlockComment))
2929 State.NoContinuation =
true;
2931 State.Stack.back().LastSpace = StartColumn;
2934 Token->updateNextToken(State);
2936 return {Penalty, Exceeded};
2941 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2944bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2946 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
2951 if (Current.
TokenText.starts_with(
"R\""))
2955 if (Current.getNextNonComment() &&
2956 Current.getNextNonComment()->isStringLiteral()) {
2959 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
2961 Style.ColumnLimit) {
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
Defines and computes precedence levels for binary/ternary operators.
static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
WhitespaceManager class manages whitespace around tokens and their replacements.
__DEVICE__ int max(int __a, int __b)
This class handles loading and caching of source files into memory.
SourceLocation getEnd() const
SourceLocation getBegin() const
Token - This structure provides full information about a lexed token.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
The JSON file list parser is used to communicate input to InstallAPI.
unsigned TabWidth
The number of columns used for tab stops.
std::vector< RawStringFormat > RawStringFormats
Defines hints for detecting supported languages code blocks in raw strings.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Language
The language for the input, used to select and validate the language standard and possible actions.
const FunctionProtoType * T
BinPackStyle ObjCBinPackProtocolList
Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...
unsigned MaxEmptyLinesToKeep
The maximum number of consecutive empty lines to keep.
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...