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;
783 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
794 if (Style.UseTab != FormatStyle::UT_Never)
795 PPColumnCorrection = -1;
799 Whitespaces.replaceWhitespace(Current, 0, Spaces,
800 State.
Column + Spaces + PPColumnCorrection,
806 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
807 Current.
is(TT_InheritanceColon)) {
808 CurrentState.NoLineBreak =
true;
810 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
812 CurrentState.NoLineBreak =
true;
815 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
816 unsigned MinIndent = std::max(
817 State.
FirstIndent + Style.ContinuationIndentWidth, CurrentState.Indent);
820 CurrentState.AlignColons =
false;
824 CurrentState.ColonPos = FirstColonPos;
832 auto IsStartOfBracedList = [&]() {
834 Style.Cpp11BracedListStyle;
836 if (!
Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
837 !IsStartOfBracedList()) {
842 if (
Tok.Previous->isIf())
843 return Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak;
844 return !
Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
846 !(Style.isJavaScript() &&
Tok.Previous->is(Keywords.kw_await));
849 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
850 Tok.Previous->is(tok::identifier);
853 if (!Style.isJavaScript())
855 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
856 if (Prev->is(TT_TemplateString) && Prev->opensScope())
858 if (Prev->opensScope() ||
859 (Prev->is(TT_TemplateString) && Prev->closesScope())) {
866 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
867 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
869 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
876 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
878 if (
Tok.is(TT_UnaryOperator) ||
879 (Style.isJavaScript() &&
880 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
885 TT_LambdaDefinitionLParen) &&
889 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok))
892 return !
Next ||
Next->isMemberAccess() ||
893 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
895 if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak ||
896 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) &&
897 IsOpeningBracket(
Previous) && State.
Column > getNewLineColumn(State) &&
908 !StartsSimpleOneArgList(Current)) {
909 CurrentState.NoLineBreak =
true;
913 CurrentState.NoLineBreak =
true;
919 if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign &&
920 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
922 Previous.isNot(TT_TableGenDAGArgOpener) &&
923 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
925 (Current.
isNot(TT_LineComment) ||
927 !IsInTemplateString(Current)) {
928 CurrentState.Indent = State.
Column + Spaces;
929 CurrentState.IsAligned =
true;
932 CurrentState.NoLineBreak =
true;
934 CurrentState.NoLineBreak =
true;
937 State.
Column > getNewLineColumn(State)) {
938 CurrentState.ContainsUnwrappedBuilder =
true;
941 if (Current.
is(TT_LambdaArrow) && Style.isJava())
942 CurrentState.NoLineBreak =
true;
943 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
952 CurrentState.NoLineBreak =
true;
959 const FormatToken *P = Current.getPreviousNonComment();
960 if (Current.
isNot(tok::comment) && P &&
961 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
962 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
963 !P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
967 bool BreakBeforeOperator =
968 P->MustBreakBefore || P->is(tok::lessless) ||
969 (P->is(TT_BinaryOperator) &&
970 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
971 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
975 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
976 P->isNot(TT_ConditionalExpr);
977 if ((!BreakBeforeOperator &&
979 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
980 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
981 CurrentState.NoLineBreakInOperand =
true;
986 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
991 CurrentState.LastSpace = State.
Column;
992 CurrentState.NestedBlockIndent = State.
Column;
993 }
else if (!Current.
isOneOf(tok::comment, tok::caret) &&
995 Previous.isNot(TT_OverloadedOperator)) ||
997 CurrentState.LastSpace = State.
Column;
998 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1000 Style.BreakConstructorInitializers ==
1001 FormatStyle::BCIS_AfterColon) {
1002 CurrentState.Indent = State.
Column;
1003 CurrentState.LastSpace = State.
Column;
1004 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1005 CurrentState.LastSpace = State.
Column;
1006 }
else if (
Previous.is(TT_BinaryOperator) &&
1013 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1014 CurrentState.LastSpace = State.
Column;
1015 }
else if (
Previous.is(TT_InheritanceColon)) {
1016 CurrentState.Indent = State.
Column;
1017 CurrentState.LastSpace = State.
Column;
1018 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1019 CurrentState.ColonPos = State.
Column;
1020 }
else if (
Previous.opensScope()) {
1028 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1029 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1030 CurrentState.LastSpace = State.
Column;
1036unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1039 assert(State.NextToken->Previous);
1041 auto &CurrentState = State.Stack.back();
1045 unsigned Penalty = 0;
1047 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1049 if (!NextNonComment)
1050 NextNonComment = &Current;
1053 if (!CurrentState.ContainsLineBreak)
1055 CurrentState.ContainsLineBreak =
true;
1057 Penalty += State.NextToken->SplitPenalty;
1062 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1063 (State.Column <= Style.ColumnLimit / 3 ||
1064 CurrentState.BreakBeforeParameter)) {
1065 Penalty += Style.PenaltyBreakFirstLessLess;
1068 State.Column = getNewLineColumn(State);
1082 if (State.Column > State.FirstIndent) {
1084 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1097 if (Current.isNot(TT_LambdaArrow) &&
1098 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1099 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1100 !Current.isOneOf(Keywords.kw_async, Keywords.kw_function))) {
1101 CurrentState.NestedBlockIndent = State.Column;
1104 if (NextNonComment->isMemberAccess()) {
1105 if (CurrentState.CallContinuation == 0)
1106 CurrentState.CallContinuation = State.Column;
1107 }
else if (NextNonComment->is(TT_SelectorName)) {
1108 if (!CurrentState.ObjCSelectorNameFound) {
1109 if (NextNonComment->LongestObjCSelectorName == 0) {
1110 CurrentState.AlignColons =
false;
1112 CurrentState.ColonPos =
1114 ? std::max(CurrentState.Indent,
1115 State.FirstIndent + Style.ContinuationIndentWidth)
1120 }
else if (CurrentState.AlignColons &&
1121 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1122 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1124 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1125 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1135 if (State.Stack.size() > 1) {
1136 State.Stack[State.Stack.size() - 2].LastSpace =
1137 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1138 Style.ContinuationIndentWidth;
1142 if ((PreviousNonComment &&
1143 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1144 !CurrentState.AvoidBinPacking) ||
1146 CurrentState.BreakBeforeParameter =
false;
1148 if (PreviousNonComment &&
1149 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1150 PreviousNonComment->ClosesRequiresClause) &&
1151 Current.NestingLevel == 0) {
1152 CurrentState.BreakBeforeParameter =
false;
1154 if (NextNonComment->is(tok::question) ||
1155 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1156 CurrentState.BreakBeforeParameter =
true;
1158 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1159 CurrentState.BreakBeforeParameter =
false;
1163 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1166 !Current.MatchingParen->Children.empty()) {
1174 bool ContinuePPDirective =
1176 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1177 CurrentState.IsAligned, ContinuePPDirective);
1180 if (!Current.isTrailingComment())
1181 CurrentState.LastSpace = State.Column;
1182 if (Current.is(tok::lessless)) {
1186 CurrentState.LastSpace += 3;
1189 State.StartOfLineLevel = Current.NestingLevel;
1190 State.LowestLevelOnLine = Current.NestingLevel;
1194 bool NestedBlockSpecialCase =
1195 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1196 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1197 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1198 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1200 NestedBlockSpecialCase =
1201 NestedBlockSpecialCase ||
1202 (Current.MatchingParen &&
1203 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1204 if (!NestedBlockSpecialCase) {
1205 auto ParentLevelIt = std::next(State.Stack.rbegin());
1206 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1207 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1222 auto FindCurrentLevel = [&](
const auto &It) {
1223 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1224 return PState.Tok != nullptr;
1227 auto MaybeIncrement = [&](
const auto &It) {
1228 return It != State.Stack.rend() ? std::next(It) : It;
1230 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1231 auto LevelContainingLambdaIt =
1232 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1233 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1235 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1236 I->BreakBeforeParameter =
true;
1239 if (PreviousNonComment &&
1240 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1241 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1242 !PreviousNonComment->ClosesRequiresClause) ||
1243 Current.NestingLevel != 0) &&
1244 !PreviousNonComment->isOneOf(
1245 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1246 TT_LeadingJavaAnnotation) &&
1247 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1250 (!Style.BraceWrapping.BeforeLambdaBody ||
1251 Current.isNot(TT_LambdaLBrace))) {
1252 CurrentState.BreakBeforeParameter =
true;
1257 if (PreviousNonComment &&
1258 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1260 CurrentState.BreakBeforeClosingBrace =
true;
1263 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1264 CurrentState.BreakBeforeClosingParen =
1265 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
1268 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1269 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1271 if (CurrentState.AvoidBinPacking) {
1276 bool PreviousIsBreakingCtorInitializerColon =
1277 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1278 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1279 bool AllowAllConstructorInitializersOnNextLine =
1280 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1281 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1282 if (!(
Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1283 PreviousIsBreakingCtorInitializerColon) ||
1284 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1285 State.Line->MustBeDeclaration) ||
1286 (!Style.AllowAllArgumentsOnNextLine &&
1287 !State.Line->MustBeDeclaration) ||
1288 (!AllowAllConstructorInitializersOnNextLine &&
1289 PreviousIsBreakingCtorInitializerColon) ||
1291 CurrentState.BreakBeforeParameter =
true;
1297 if (PreviousIsBreakingCtorInitializerColon &&
1298 AllowAllConstructorInitializersOnNextLine) {
1299 CurrentState.BreakBeforeParameter =
false;
1304 CurrentState.BreakBeforeParameter =
true;
1309unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1310 if (!State.NextToken || !State.NextToken->Previous)
1314 const auto &CurrentState = State.Stack.back();
1316 if (CurrentState.IsCSharpGenericTypeConstraint &&
1317 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1318 return CurrentState.ColonPos + 2;
1323 unsigned ContinuationIndent =
1324 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1325 Style.ContinuationIndentWidth;
1326 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1328 if (!NextNonComment)
1329 NextNonComment = &Current;
1332 if (Style.isJava() &&
1333 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1334 return std::max(CurrentState.LastSpace,
1335 CurrentState.Indent + Style.ContinuationIndentWidth);
1340 if (Style.isVerilog() && PreviousNonComment &&
1341 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1342 return State.FirstIndent;
1345 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1346 State.Line->First->is(tok::kw_enum)) {
1347 return (Style.IndentWidth * State.Line->First->IndentLevel) +
1351 if (Style.BraceWrapping.BeforeLambdaBody &&
1352 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1353 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1354 ? CurrentState.Indent
1355 : State.FirstIndent;
1356 return From + Style.IndentWidth;
1359 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1360 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1361 if (Current.NestingLevel == 0 ||
1362 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1363 State.NextToken->is(TT_LambdaLBrace))) {
1364 return State.FirstIndent;
1366 return CurrentState.Indent;
1368 if (Current.is(TT_LambdaArrow) &&
1369 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1370 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
1371 return ContinuationIndent;
1373 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1374 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1375 State.Stack.size() > 1) {
1376 if (Current.closesBlockOrBlockTypeList(Style))
1377 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1378 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1379 return State.Stack[State.Stack.size() - 2].LastSpace;
1380 return State.FirstIndent;
1397 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1399 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1400 return State.Stack[State.Stack.size() - 2].LastSpace;
1404 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1405 State.Stack.size() > 1) {
1406 return State.Stack[State.Stack.size() - 2].LastSpace;
1408 if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
1409 (Current.is(tok::r_paren) ||
1410 (Current.is(tok::r_brace) && Current.MatchingParen &&
1412 State.Stack.size() > 1) {
1413 return State.Stack[State.Stack.size() - 2].LastSpace;
1415 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1416 State.Stack.size() > 1) {
1417 return State.Stack[State.Stack.size() - 2].LastSpace;
1419 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1420 return State.Stack[State.Stack.size() - 2].LastSpace;
1428 if (Current.is(tok::identifier) && Current.Next &&
1429 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1430 (Current.Next->is(TT_DictLiteral) ||
1431 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1432 return CurrentState.Indent;
1434 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1435 State.StartOfStringLiteral != 0) {
1436 return State.StartOfStringLiteral - 1;
1438 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1439 return State.StartOfStringLiteral;
1440 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1441 return CurrentState.FirstLessLess;
1442 if (NextNonComment->isMemberAccess()) {
1443 if (CurrentState.CallContinuation == 0)
1444 return ContinuationIndent;
1445 return CurrentState.CallContinuation;
1447 if (CurrentState.QuestionColumn != 0 &&
1448 ((NextNonComment->is(tok::colon) &&
1449 NextNonComment->is(TT_ConditionalExpr)) ||
1450 Previous.is(TT_ConditionalExpr))) {
1451 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1452 !NextNonComment->Next->FakeLParens.empty() &&
1454 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1456 !CurrentState.IsWrappedConditional) {
1461 unsigned Indent = CurrentState.Indent;
1462 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1463 Indent -= Style.ContinuationIndentWidth;
1464 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1468 return CurrentState.QuestionColumn;
1470 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1471 return CurrentState.VariablePos;
1472 if (Current.is(TT_RequiresClause)) {
1473 if (Style.IndentRequiresClause)
1474 return CurrentState.Indent + Style.IndentWidth;
1475 switch (Style.RequiresClausePosition) {
1476 case FormatStyle::RCPS_OwnLine:
1477 case FormatStyle::RCPS_WithFollowing:
1478 case FormatStyle::RCPS_OwnLineWithBrace:
1479 return CurrentState.Indent;
1484 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1485 TT_InheritanceComma)) {
1486 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1488 if ((PreviousNonComment &&
1489 (PreviousNonComment->ClosesTemplateDeclaration ||
1490 PreviousNonComment->ClosesRequiresClause ||
1491 (PreviousNonComment->is(TT_AttributeMacro) &&
1492 Current.isNot(tok::l_paren) &&
1493 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1494 TT_PointerOrReference)) ||
1495 PreviousNonComment->isOneOf(
1496 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1497 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1498 (!Style.IndentWrappedFunctionNames &&
1499 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1500 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1502 if (NextNonComment->is(TT_SelectorName)) {
1503 if (!CurrentState.ObjCSelectorNameFound) {
1504 unsigned MinIndent = CurrentState.Indent;
1506 MinIndent = std::max(MinIndent,
1507 State.FirstIndent + Style.ContinuationIndentWidth);
1519 std::max(NextNonComment->LongestObjCSelectorName,
1520 NextNonComment->ColumnWidth) -
1521 NextNonComment->ColumnWidth;
1523 if (!CurrentState.AlignColons)
1524 return CurrentState.Indent;
1525 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1526 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1527 return CurrentState.Indent;
1529 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1530 return CurrentState.ColonPos;
1531 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1532 if (CurrentState.StartOfArraySubscripts != 0) {
1533 return CurrentState.StartOfArraySubscripts;
1534 }
else if (Style.isCSharp()) {
1536 return CurrentState.Indent;
1538 return ContinuationIndent;
1543 if (State.Line->InPragmaDirective) {
1544 FormatToken *PragmaType = State.Line->First->Next->Next;
1545 if (PragmaType && PragmaType->TokenText ==
"omp")
1546 return CurrentState.Indent + Style.ContinuationIndentWidth;
1551 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1552 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1553 return CurrentState.Indent;
1556 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1557 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1558 return ContinuationIndent;
1560 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1561 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1562 return ContinuationIndent;
1564 if (NextNonComment->is(TT_CtorInitializerComma))
1565 return CurrentState.Indent;
1566 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1567 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1568 return CurrentState.Indent;
1570 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1571 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1572 return CurrentState.Indent;
1575 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1576 !Current.isBinaryOperator() &&
1577 !Current.isOneOf(tok::colon, tok::comment)) {
1578 return ContinuationIndent;
1580 if (Current.is(TT_ProtoExtensionLSquare))
1581 return CurrentState.Indent;
1582 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1583 return CurrentState.Indent - Current.Tok.getLength() -
1584 Current.SpacesRequiredBefore;
1586 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1587 CurrentState.UnindentOperator) {
1588 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1589 NextNonComment->SpacesRequiredBefore;
1591 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1592 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1595 return CurrentState.Indent + Style.ContinuationIndentWidth;
1597 return CurrentState.Indent;
1602 const FormatStyle &Style) {
1609 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1612unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1613 bool DryRun,
bool Newline) {
1614 assert(State.Stack.size());
1616 auto &CurrentState = State.Stack.back();
1618 if (Current.is(TT_CSharpGenericTypeConstraint))
1619 CurrentState.IsCSharpGenericTypeConstraint =
true;
1620 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1621 CurrentState.NoLineBreakInOperand =
false;
1622 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1623 CurrentState.AvoidBinPacking =
true;
1624 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1625 if (CurrentState.FirstLessLess == 0)
1626 CurrentState.FirstLessLess = State.Column;
1628 CurrentState.LastOperatorWrapped = Newline;
1630 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1631 CurrentState.LastOperatorWrapped = Newline;
1632 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1633 Current.Previous->isNot(TT_ConditionalExpr)) {
1634 CurrentState.LastOperatorWrapped = Newline;
1636 if (Current.is(TT_ArraySubscriptLSquare) &&
1637 CurrentState.StartOfArraySubscripts == 0) {
1638 CurrentState.StartOfArraySubscripts = State.Column;
1642 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1644 if (
Tok.MustBreakBefore)
1648 return Next &&
Next->MustBreakBefore;
1650 if (IsWrappedConditional(Current))
1651 CurrentState.IsWrappedConditional =
true;
1652 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1653 CurrentState.QuestionColumn = State.Column;
1654 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1659 CurrentState.QuestionColumn = State.Column;
1661 if (!Current.opensScope() && !Current.closesScope() &&
1662 Current.isNot(TT_PointerOrReference)) {
1663 State.LowestLevelOnLine =
1664 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1666 if (Current.isMemberAccess())
1667 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1668 if (Current.is(TT_SelectorName))
1669 CurrentState.ObjCSelectorNameFound =
true;
1670 if (Current.is(TT_CtorInitializerColon) &&
1671 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1677 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1678 FormatStyle::BCIS_BeforeComma
1681 CurrentState.NestedBlockIndent = CurrentState.Indent;
1682 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1683 CurrentState.AvoidBinPacking =
true;
1684 CurrentState.BreakBeforeParameter =
1685 Style.ColumnLimit > 0 &&
1686 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1687 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1689 CurrentState.BreakBeforeParameter =
false;
1692 if (Current.is(TT_CtorInitializerColon) &&
1693 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1694 CurrentState.Indent =
1695 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1696 CurrentState.NestedBlockIndent = CurrentState.Indent;
1697 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1698 CurrentState.AvoidBinPacking =
true;
1700 CurrentState.BreakBeforeParameter =
false;
1702 if (Current.is(TT_InheritanceColon)) {
1703 CurrentState.Indent =
1704 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1706 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1707 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1708 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1709 CurrentState.LastSpace = State.Column;
1710 if (Current.is(TT_RequiresExpression) &&
1711 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1712 CurrentState.NestedBlockIndent = State.Column;
1724 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1726 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1727 !CurrentState.HasMultipleNestedBlocks) {
1728 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1729 for (ParenState &PState : llvm::drop_end(State.Stack))
1730 PState.NoLineBreak =
true;
1731 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1733 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1734 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1735 !
Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1736 TT_CtorInitializerColon)))) {
1737 CurrentState.NestedBlockInlined =
1741 moveStatePastFakeLParens(State, Newline);
1742 moveStatePastScopeCloser(State);
1745 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1746 !State.Stack.back().NoLineBreakInOperand;
1747 moveStatePastScopeOpener(State, Newline);
1748 moveStatePastFakeRParens(State);
1750 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1751 State.StartOfStringLiteral = State.Column + 1;
1752 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1753 State.StartOfStringLiteral = State.Column + 1;
1754 }
else if (Current.is(TT_TableGenMultiLineString) &&
1755 State.StartOfStringLiteral == 0) {
1756 State.StartOfStringLiteral = State.Column + 1;
1757 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1758 State.StartOfStringLiteral = State.Column;
1759 }
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1760 !Current.isStringLiteral()) {
1761 State.StartOfStringLiteral = 0;
1764 State.Column += Current.ColumnWidth;
1765 State.NextToken = State.NextToken->Next;
1770 if (Style.isVerilog() && State.NextToken &&
1771 State.NextToken->MustBreakBefore &&
1772 Keywords.isVerilogEndOfLabel(Current)) {
1773 State.FirstIndent += Style.IndentWidth;
1774 CurrentState.Indent = State.FirstIndent;
1778 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1781 Current.Role->formatFromToken(State,
this, DryRun);
1788 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1793void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1796 if (Current.FakeLParens.empty())
1804 bool SkipFirstExtraIndent =
1807 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1809 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1811 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1812 const auto &CurrentState = State.Stack.back();
1813 ParenState NewParenState = CurrentState;
1814 NewParenState.Tok =
nullptr;
1815 NewParenState.ContainsLineBreak =
false;
1816 NewParenState.LastOperatorWrapped =
true;
1817 NewParenState.IsChainedConditional =
false;
1818 NewParenState.IsWrappedConditional =
false;
1819 NewParenState.UnindentOperator =
false;
1820 NewParenState.NoLineBreak =
1821 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1825 NewParenState.AvoidBinPacking =
false;
1830 if (!Current.isTrailingComment() &&
1831 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1834 (!Style.isJava() && PrecedenceLevel > 0)) &&
1835 (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign ||
1836 PrecedenceLevel >
prec::Comma || Current.NestingLevel == 0) &&
1837 (!Style.isTableGen() ||
1839 TT_TableGenDAGArgListCommaToBreak)))) {
1840 NewParenState.Indent = std::max(
1841 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1848 State.Stack.size() > 1) {
1849 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1850 Style.ContinuationIndentWidth;
1860 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1861 NewParenState.UnindentOperator =
true;
1863 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1864 NewParenState.IsAligned =
true;
1874 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1876 Current.isNot(TT_UnaryOperator) &&
1877 Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) {
1878 NewParenState.StartOfFunctionCall = State.Column;
1888 &PrecedenceLevel == &Current.FakeLParens.back() &&
1889 !CurrentState.IsWrappedConditional) {
1890 NewParenState.IsChainedConditional =
true;
1891 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1894 !Current.isTrailingComment())) {
1895 NewParenState.Indent += Style.ContinuationIndentWidth;
1898 NewParenState.BreakBeforeParameter =
false;
1899 State.Stack.push_back(NewParenState);
1900 SkipFirstExtraIndent =
false;
1904void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
1905 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1906 unsigned VariablePos = State.Stack.back().VariablePos;
1907 if (State.Stack.size() == 1) {
1911 State.Stack.pop_back();
1912 State.Stack.back().VariablePos = VariablePos;
1915 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
1918 State.Stack.back().LastSpace -= Style.IndentWidth;
1922void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
1925 if (!Current.opensScope())
1928 const auto &CurrentState = State.Stack.back();
1931 if (Current.isOneOf(tok::less, tok::l_paren) &&
1932 CurrentState.IsCSharpGenericTypeConstraint) {
1936 if (Current.MatchingParen && Current.is(
BK_Block)) {
1937 moveStateToNewBlock(State, Newline);
1944 const auto *Prev =
Tok->getPreviousNonComment();
1947 return Prev->is(tok::comma);
1948 }(Current.MatchingParen);
1951 unsigned LastSpace = CurrentState.LastSpace;
1952 bool AvoidBinPacking;
1953 bool BreakBeforeParameter =
false;
1954 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1955 CurrentState.NestedBlockIndent);
1956 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1958 if (Current.opensBlockOrBlockTypeList(Style)) {
1959 NewIndent = Style.IndentWidth +
1960 std::min(State.Column, CurrentState.NestedBlockIndent);
1961 }
else if (Current.is(tok::l_brace)) {
1962 const auto Width = Style.BracedInitializerIndentWidth;
1963 NewIndent = CurrentState.LastSpace +
1964 (Width < 0 ? Style.ContinuationIndentWidth : Width);
1966 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
1968 const FormatToken *NextNonComment = Current.getNextNonComment();
1969 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1970 Style.isProto() || !Style.BinPackArguments ||
1971 (NextNonComment && NextNonComment->isOneOf(
1972 TT_DesignatedInitializerPeriod,
1973 TT_DesignatedInitializerLSquare));
1974 BreakBeforeParameter = EndsInComma;
1975 if (Current.ParameterCount > 1)
1976 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1979 Style.ContinuationIndentWidth +
1980 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1982 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1983 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
1989 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
1990 NewIndent = State.Column +
Next->TokenText.size() + 2;
1997 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
1998 NewIndent = std::max(NewIndent, CurrentState.Indent);
1999 LastSpace = std::max(LastSpace, CurrentState.Indent);
2005 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2006 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2007 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2009 bool BinPackDeclaration =
2011 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2014 bool GenericSelection =
2015 Current.getPreviousNonComment() &&
2016 Current.getPreviousNonComment()->is(tok::kw__Generic);
2019 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2020 (Style.isJavaScript() && EndsInComma) ||
2021 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2022 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2023 (Style.ExperimentalAutoDetectBinPacking &&
2027 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2028 Style.ObjCBreakBeforeNestedBlockParam) {
2029 if (Style.ColumnLimit) {
2034 BreakBeforeParameter =
true;
2040 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2041 if (
Tok->MustBreakBefore ||
2042 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2043 BreakBeforeParameter =
true;
2050 if (Style.isJavaScript() && EndsInComma)
2051 BreakBeforeParameter =
true;
2057 Current.Children.empty() &&
2058 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2059 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2060 (Current.is(TT_TemplateOpener) &&
2061 CurrentState.ContainsUnwrappedBuilder));
2062 State.Stack.push_back(
2063 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2064 auto &NewState = State.Stack.back();
2065 NewState.NestedBlockIndent = NestedBlockIndent;
2066 NewState.BreakBeforeParameter = BreakBeforeParameter;
2067 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2069 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2070 Current.is(tok::l_paren)) {
2074 if (next->is(TT_LambdaLSquare)) {
2075 NewState.HasMultipleNestedBlocks =
true;
2082 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2084 Current.Previous->is(tok::at);
2087void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2089 if (!Current.closesScope())
2094 if (State.Stack.size() > 1 &&
2095 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2096 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2097 State.NextToken->is(TT_TemplateCloser) ||
2098 State.NextToken->is(TT_TableGenListCloser) ||
2099 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2100 State.Stack.pop_back();
2103 auto &CurrentState = State.Stack.back();
2115 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2116 Current.MatchingParen->Previous) {
2117 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2118 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2119 CurrentScopeOpener.MatchingParen) {
2120 int NecessarySpaceInLine =
2122 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2123 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2124 Style.ColumnLimit) {
2125 CurrentState.BreakBeforeParameter =
false;
2130 if (Current.is(tok::r_square)) {
2132 const FormatToken *NextNonComment = Current.getNextNonComment();
2133 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2134 CurrentState.StartOfArraySubscripts = 0;
2138void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2139 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2140 State.NextToken->is(TT_LambdaLBrace) &&
2141 !State.Line->MightBeFunctionDecl) {
2142 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2143 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2145 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2147 unsigned NewIndent =
2148 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2149 ? Style.ObjCBlockIndentWidth
2150 : Style.IndentWidth);
2157 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2158 State.NextToken->is(TT_LambdaLBrace);
2160 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2161 State.Stack.back().LastSpace,
2162 true, NoLineBreak));
2163 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2164 State.Stack.back().BreakBeforeParameter =
true;
2170 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2171 if (LastNewlinePos == StringRef::npos) {
2172 return StartColumn +
2180unsigned ContinuationIndenter::reformatRawStringLiteral(
2182 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2183 unsigned StartColumn = State.Column - Current.ColumnWidth;
2185 StringRef NewDelimiter =
2187 if (NewDelimiter.empty())
2188 NewDelimiter = OldDelimiter;
2191 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2192 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2195 std::string RawText = std::string(
2196 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2197 if (NewDelimiter != OldDelimiter) {
2200 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2201 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2202 NewDelimiter = OldDelimiter;
2205 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2206 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2209 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2220 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2242 unsigned CurrentIndent =
2243 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2244 ? State.Stack.back().NestedBlockIndent
2245 : State.Stack.back().Indent;
2246 unsigned NextStartColumn = ContentStartsOnNewline
2247 ? CurrentIndent + Style.IndentWidth
2258 unsigned LastStartColumn =
2259 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2262 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2263 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2268 return addMultilineToken(Current, State);
2270 if (NewDelimiter != OldDelimiter) {
2273 SourceLocation PrefixDelimiterStart =
2274 Current.Tok.getLocation().getLocWithOffset(2);
2275 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2276 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2279 <<
"Failed to update the prefix delimiter of a raw string: "
2280 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2284 SourceLocation SuffixDelimiterStart =
2285 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2286 1 - OldDelimiter.size());
2287 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2288 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2291 <<
"Failed to update the suffix delimiter of a raw string: "
2292 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2295 SourceLocation OriginLoc =
2296 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2297 for (
const tooling::Replacement &Fix : Fixes.first) {
2298 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2299 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2300 Fix.getLength(), Fix.getReplacementText()));
2302 llvm::errs() <<
"Failed to reformat raw string: "
2303 << llvm::toString(std::move(Err)) <<
"\n";
2308 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2309 State.Column = RawLastLineEndColumn + NewSuffixSize;
2313 unsigned PrefixExcessCharacters =
2314 StartColumn + NewPrefixSize > Style.ColumnLimit
2315 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2318 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2321 for (ParenState &
Paren : State.Stack)
2322 Paren.BreakBeforeParameter =
true;
2324 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2327unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2330 for (ParenState &
Paren : State.Stack)
2331 Paren.BreakBeforeParameter =
true;
2333 unsigned ColumnsUsed = State.Column;
2336 State.Column = Current.LastLineColumnWidth;
2339 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2343unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2345 bool AllowBreak,
bool Newline) {
2346 unsigned Penalty = 0;
2349 auto RawStringStyle = getRawStringStyle(Current, State);
2350 if (RawStringStyle && !Current.Finalized) {
2351 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2353 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2356 Penalty = addMultilineToken(Current, State);
2359 LineState OriginalState = State;
2363 bool Strict =
false;
2366 bool Exceeded =
false;
2367 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2368 Current, State, AllowBreak,
true, Strict);
2372 LineState StrictState = OriginalState;
2373 unsigned StrictPenalty =
2374 breakProtrudingToken(Current, StrictState, AllowBreak,
2377 Strict = StrictPenalty <= Penalty;
2379 Penalty = StrictPenalty;
2380 State = StrictState;
2386 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2391 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2392 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2401 auto Tok = Current.getPreviousNonComment();
2402 if (!
Tok ||
Tok->isNot(tok::l_paren))
2404 Tok =
Tok->getPreviousNonComment();
2407 if (
Tok->is(TT_TemplateCloser)) {
2408 Tok =
Tok->MatchingParen;
2410 Tok =
Tok->getPreviousNonComment();
2412 if (!
Tok ||
Tok->isNot(tok::identifier))
2414 return Tok->TokenText;
2417std::optional<FormatStyle>
2418ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2419 const LineState &State) {
2420 if (!Current.isStringLiteral())
2421 return std::nullopt;
2424 return std::nullopt;
2426 if (!RawStringStyle && Delimiter->empty()) {
2430 if (!RawStringStyle)
2431 return std::nullopt;
2433 return RawStringStyle;
2436std::unique_ptr<BreakableToken>
2437ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2439 unsigned StartColumn = State.Column - Current.ColumnWidth;
2440 if (Current.isStringLiteral()) {
2443 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2457 if (Current.IsUnterminatedLiteral)
2461 if (State.Stack.back().IsInsideObjCArrayLiteral)
2468 if (Style.isVerilog() && Current.Previous &&
2469 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2472 StringRef
Text = Current.TokenText;
2482 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2485 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2486 Text.ends_with(
"'")) {
2488 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2489 Text.ends_with(
"\"")) {
2491 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2496 return std::make_unique<BreakableStringLiteralUsingOperators>(
2497 Current, QuoteStyle,
2508 if ((
Text.ends_with(Postfix =
"\"") &&
2509 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2510 Text.starts_with(Prefix =
"u\"") ||
2511 Text.starts_with(Prefix =
"U\"") ||
2512 Text.starts_with(Prefix =
"u8\"") ||
2513 Text.starts_with(Prefix =
"L\""))) ||
2514 (
Text.starts_with(Prefix =
"_T(\"") &&
2515 Text.ends_with(Postfix =
"\")"))) {
2516 return std::make_unique<BreakableStringLiteral>(
2518 State.Line->InPPDirective, Encoding, Style);
2520 }
else if (Current.is(TT_BlockComment)) {
2521 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2528 return std::make_unique<BreakableBlockComment>(
2529 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2530 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2531 }
else if (Current.is(TT_LineComment) &&
2532 (!Current.Previous ||
2533 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2534 bool RegularComments = [&]() {
2535 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2537 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2542 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2543 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2547 return std::make_unique<BreakableLineCommentSection>(
2548 Current, StartColumn,
false, Encoding, Style);
2553std::pair<unsigned, bool>
2554ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2556 bool DryRun,
bool Strict) {
2557 std::unique_ptr<const BreakableToken> Token =
2558 createBreakableToken(Current, State, AllowBreak);
2561 assert(Token->getLineCount() > 0);
2563 if (Current.is(TT_LineComment)) {
2565 ColumnLimit = Style.ColumnLimit;
2567 if (ColumnLimit == 0) {
2570 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2572 if (Current.UnbreakableTailLength >= ColumnLimit)
2576 unsigned StartColumn = State.Column - Current.ColumnWidth;
2577 unsigned NewBreakPenalty = Current.isStringLiteral()
2578 ? Style.PenaltyBreakString
2579 : Style.PenaltyBreakComment;
2582 bool Exceeded =
false;
2584 bool BreakInserted = Token->introducesBreakBeforeToken();
2587 bool NewBreakBefore =
false;
2591 bool Reflow =
false;
2594 unsigned TailOffset = 0;
2596 unsigned ContentStartColumn =
2597 Token->getContentStartColumn(0,
false);
2599 unsigned RemainingTokenColumns =
2600 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2603 Token->adaptStartOfLine(0, Whitespaces);
2605 unsigned ContentIndent = 0;
2606 unsigned Penalty = 0;
2607 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2608 << StartColumn <<
".\n");
2609 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2610 LineIndex != EndIndex; ++LineIndex) {
2611 LLVM_DEBUG(llvm::dbgs()
2612 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2613 NewBreakBefore =
false;
2617 bool TryReflow = Reflow;
2619 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2620 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2621 << (ContentStartColumn + RemainingTokenColumns)
2622 <<
", space: " << ColumnLimit
2623 <<
", reflown prefix: " << ContentStartColumn
2624 <<
", offset in line: " << TailOffset <<
"\n");
2630 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2631 ContentStartColumn, CommentPragmasRegex);
2632 if (
Split.first == StringRef::npos) {
2635 if (LineIndex < EndIndex - 1) {
2638 Penalty += Style.PenaltyExcessCharacter *
2639 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2641 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2644 assert(
Split.first != 0);
2646 if (Token->supportsReflow()) {
2666 unsigned ToSplitColumns = Token->getRangeLength(
2667 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2668 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2671 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2672 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2675 unsigned ToNextSplitColumns = 0;
2676 if (NextSplit.first == StringRef::npos) {
2677 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2678 ContentStartColumn);
2680 ToNextSplitColumns = Token->getRangeLength(
2681 LineIndex, TailOffset,
2682 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2686 ToNextSplitColumns =
2687 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2688 LLVM_DEBUG(llvm::dbgs()
2689 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2690 LLVM_DEBUG(llvm::dbgs()
2691 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2694 bool ContinueOnLine =
2695 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2696 unsigned ExcessCharactersPenalty = 0;
2697 if (!ContinueOnLine && !Strict) {
2700 ExcessCharactersPenalty =
2701 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2702 Style.PenaltyExcessCharacter;
2703 LLVM_DEBUG(llvm::dbgs()
2704 <<
" Penalty excess: " << ExcessCharactersPenalty
2705 <<
"\n break : " << NewBreakPenalty <<
"\n");
2706 if (ExcessCharactersPenalty < NewBreakPenalty) {
2708 ContinueOnLine =
true;
2711 if (ContinueOnLine) {
2712 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2717 Token->compressWhitespace(LineIndex, TailOffset, Split,
2721 ContentStartColumn += ToSplitColumns + 1;
2722 Penalty += ExcessCharactersPenalty;
2724 RemainingTokenColumns = Token->getRemainingLength(
2725 LineIndex, TailOffset, ContentStartColumn);
2729 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2734 ContentIndent = Token->getContentIndent(LineIndex);
2735 LLVM_DEBUG(llvm::dbgs()
2736 <<
" ContentIndent: " << ContentIndent <<
"\n");
2737 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2740 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2741 LineIndex, TailOffset +
Split.first +
Split.second,
2742 ContentStartColumn);
2743 if (NewRemainingTokenColumns == 0) {
2746 ContentStartColumn =
2747 Token->getContentStartColumn(LineIndex,
true);
2748 NewRemainingTokenColumns = Token->getRemainingLength(
2749 LineIndex, TailOffset +
Split.first +
Split.second,
2750 ContentStartColumn);
2756 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2761 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2762 <<
", " <<
Split.second <<
"\n");
2764 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2768 Penalty += NewBreakPenalty;
2770 RemainingTokenColumns = NewRemainingTokenColumns;
2771 BreakInserted =
true;
2772 NewBreakBefore =
true;
2776 if (LineIndex + 1 != EndIndex) {
2777 unsigned NextLineIndex = LineIndex + 1;
2778 if (NewBreakBefore) {
2797 ContentStartColumn += RemainingTokenColumns + 1;
2802 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2803 LLVM_DEBUG(llvm::dbgs()
2804 <<
" Size of reflown text: " << ContentStartColumn
2805 <<
"\n Potential reflow split: ");
2806 if (SplitBeforeNext.first != StringRef::npos) {
2807 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2808 << SplitBeforeNext.second <<
"\n");
2809 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2812 RemainingTokenColumns = Token->getRemainingLength(
2813 NextLineIndex, TailOffset, ContentStartColumn);
2815 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2816 LLVM_DEBUG(llvm::dbgs()
2817 <<
" Over limit after reflow, need: "
2818 << (ContentStartColumn + RemainingTokenColumns)
2819 <<
", space: " << ColumnLimit
2820 <<
", reflown prefix: " << ContentStartColumn
2821 <<
", offset in line: " << TailOffset <<
"\n");
2827 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2828 ContentStartColumn, CommentPragmasRegex);
2829 if (
Split.first == StringRef::npos) {
2830 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2836 unsigned ToSplitColumns = Token->getRangeLength(
2837 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2838 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2839 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2840 << (ContentStartColumn + ToSplitColumns)
2841 <<
", space: " << ColumnLimit);
2842 unsigned ExcessCharactersPenalty =
2843 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2844 Style.PenaltyExcessCharacter;
2845 if (NewBreakPenalty < ExcessCharactersPenalty)
2851 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2859 ContentStartColumn =
2860 Token->getContentStartColumn(NextLineIndex,
false);
2861 RemainingTokenColumns = Token->getRemainingLength(
2862 NextLineIndex, TailOffset, ContentStartColumn);
2865 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2880 if (NewBreakBefore) {
2881 assert(Penalty >= NewBreakPenalty);
2882 Penalty -= NewBreakPenalty;
2885 Token->reflow(NextLineIndex, Whitespaces);
2891 Token->getSplitAfterLastLine(TailOffset);
2892 if (SplitAfterLastLine.first != StringRef::npos) {
2893 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2897 Penalty += Style.PenaltyExcessCharacter *
2898 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2901 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2904 ContentStartColumn =
2905 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2906 RemainingTokenColumns = Token->getRemainingLength(
2907 Token->getLineCount() - 1,
2908 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2909 ContentStartColumn);
2912 State.Column = ContentStartColumn + RemainingTokenColumns -
2913 Current.UnbreakableTailLength;
2915 if (BreakInserted) {
2917 Token->updateAfterBroken(Whitespaces);
2922 if (Current.isNot(TT_LineComment))
2923 for (ParenState &
Paren : State.Stack)
2924 Paren.BreakBeforeParameter =
true;
2926 if (Current.is(TT_BlockComment))
2927 State.NoContinuation =
true;
2929 State.Stack.back().LastSpace = StartColumn;
2932 Token->updateNextToken(State);
2934 return {Penalty, Exceeded};
2939 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2942bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2944 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
2949 if (Current.
TokenText.starts_with(
"R\""))
2953 if (Current.getNextNonComment() &&
2954 Current.getNextNonComment()->isStringLiteral()) {
2957 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
2959 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...