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.BreakBeforeCloseBracketFunction ||
362 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
363 Style.BreakBeforeCloseBracketSwitch) &&
364 Current.
is(tok::r_paren)) {
365 return CurrentState.BreakBeforeClosingParen;
368 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
369 return CurrentState.BreakBeforeClosingAngle;
373 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
377 (!Style.BraceWrapping.BeforeLambdaBody ||
378 Current.
isNot(TT_LambdaLBrace)) &&
379 CurrentState.NoLineBreakInOperand) {
386 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
388 Previous.MatchingParen->Previous->MatchingParen &&
389 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
391 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
395 return !State.NoLineBreak && !CurrentState.NoLineBreak;
401 const auto &CurrentState = State.Stack.back();
402 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
403 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
408 (Current.
is(TT_InlineASMColon) &&
409 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
410 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&
411 Style.ColumnLimit > 0)))) {
414 if (CurrentState.BreakBeforeClosingBrace &&
415 (Current.closesBlockOrBlockTypeList(Style) ||
417 Current.isBlockIndentedInitRBrace(Style)))) {
420 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
422 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
424 if (Style.Language == FormatStyle::LK_ObjC &&
425 Style.ObjCBreakBeforeNestedBlockParam &&
427 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
432 if (CurrentState.IsCSharpGenericTypeConstraint &&
433 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
437 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
438 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
444 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||
445 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
447 (!Style.BreakBeforeTernaryOperators &&
448 Previous.is(TT_ConditionalExpr))) &&
449 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
450 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
453 if (CurrentState.IsChainedConditional &&
454 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
455 Current.
is(tok::colon)) ||
456 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
461 (
Previous.is(TT_ArrayInitializerLSquare) &&
464 Style.ColumnLimit > 0 &&
470 const FormatToken &BreakConstructorInitializersToken =
471 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
474 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
475 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
477 CurrentState.BreakBeforeParameter) &&
478 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
483 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
484 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
487 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
488 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
489 (Style.ObjCBreakBeforeNestedBlockParam ||
490 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
494 unsigned NewLineColumn = getNewLineColumn(State);
495 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
497 (State.Column > NewLineColumn ||
503 (CurrentState.CallContinuation != 0 ||
504 CurrentState.BreakBeforeParameter) &&
510 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
511 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
517 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
522 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
525 if (Style.AlwaysBreakBeforeMultilineStrings &&
526 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
528 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
529 Keywords.kw_dollar) &&
530 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
531 nextIsMultilineString(State)) {
539 const auto PreviousPrecedence =
Previous.getPrecedence();
541 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
542 const bool LHSIsBinaryExpr =
555 const bool IsComparison =
560 Previous.Previous->isNot(TT_BinaryOperator);
566 CurrentState.BreakBeforeParameter) {
571 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
572 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
576 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
581 if (
Previous.ClosesTemplateDeclaration) {
582 if (Current.
is(tok::kw_concept)) {
583 switch (Style.BreakBeforeConceptDeclarations) {
584 case FormatStyle::BBCDS_Allowed:
586 case FormatStyle::BBCDS_Always:
588 case FormatStyle::BBCDS_Never:
592 if (Current.
is(TT_RequiresClause)) {
593 switch (Style.RequiresClausePosition) {
594 case FormatStyle::RCPS_SingleLine:
595 case FormatStyle::RCPS_WithPreceding:
601 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&
602 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
605 if (
Previous.is(TT_FunctionAnnotationRParen) &&
609 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
610 Current.
isNot(TT_LeadingJavaAnnotation)) {
615 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
619 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
621 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
625 if (Current.
is(TT_FunctionDeclarationName) &&
626 !State.Line->ReturnTypeWrapped &&
628 (!Style.isCSharp() ||
629 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
632 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
633 CurrentState.BreakBeforeParameter) {
635 if (
Tok->is(TT_LineComment))
637 if (
Tok->is(TT_TemplateCloser)) {
641 if (
Tok->FirstAfterPPLine)
653 Current.
isNoneOf(tok::r_brace, tok::comment)) {
657 if (Current.
is(tok::lessless) &&
660 Previous.TokenText ==
"\'\\n\'")))) {
667 if (State.NoContinuation)
675 unsigned ExtraSpaces) {
677 assert(State.NextToken->Previous);
680 assert(!State.Stack.empty());
681 State.NoContinuation =
false;
683 if (Current.
is(TT_ImplicitStringLiteral) &&
684 (!
Previous.Tok.getIdentifierInfo() ||
685 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
686 tok::pp_not_keyword)) {
692 State.Column = EndColumn;
694 unsigned StartColumn =
696 assert(EndColumn >= StartColumn);
697 State.Column += EndColumn - StartColumn;
699 moveStateToNextToken(State, DryRun,
false);
703 unsigned Penalty = 0;
705 Penalty = addTokenOnNewLine(State, DryRun);
707 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
709 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
712void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
713 unsigned ExtraSpaces) {
715 assert(State.NextToken->Previous);
717 auto &CurrentState = State.Stack.back();
724 auto DisallowLineBreaks = [&] {
725 if (!Style.isCpp() ||
726 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {
734 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
737 const auto *Prev = Current.getPreviousNonComment();
738 if (!Prev || Prev->isNot(tok::l_paren))
741 if (Prev->BlockParameterCount == 0)
745 if (Prev->BlockParameterCount > 1)
752 const auto *Comma = Prev->
Role->lastComma();
756 const auto *
Next = Comma->getNextNonComment();
757 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
760 if (DisallowLineBreaks())
761 State.NoLineBreak =
true;
763 if (Current.
is(tok::equal) &&
764 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
765 CurrentState.VariablePos == 0 &&
767 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
768 CurrentState.VariablePos = State.Column;
771 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
772 CurrentState.VariablePos -=
Tok->ColumnWidth;
773 if (
Tok->SpacesRequiredBefore != 0)
777 if (
Previous.PartOfMultiVariableDeclStmt)
778 CurrentState.LastSpace = CurrentState.VariablePos;
784 int PPColumnCorrection = 0;
788 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {
795 if (Style.UseTab != FormatStyle::UT_Never)
796 PPColumnCorrection = -1;
797 }
else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {
803 const bool ContinuePPDirective =
805 Whitespaces.replaceWhitespace(Current, 0, Spaces,
806 State.
Column + Spaces + PPColumnCorrection,
807 false, ContinuePPDirective);
812 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
813 Current.
is(TT_InheritanceColon)) {
814 CurrentState.NoLineBreak =
true;
816 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&
818 CurrentState.NoLineBreak =
true;
821 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
822 unsigned MinIndent = std::max(
823 State.
FirstIndent + Style.ContinuationIndentWidth, CurrentState.Indent);
826 CurrentState.AlignColons =
false;
830 CurrentState.ColonPos = FirstColonPos;
838 auto IsStartOfBracedList = [&]() {
840 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;
842 if (IsStartOfBracedList())
843 return Style.BreakAfterOpenBracketBracedList;
844 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
848 if (
Tok.Previous->isIf())
849 return Style.BreakAfterOpenBracketIf;
850 if (
Tok.Previous->isLoop(Style))
851 return Style.BreakAfterOpenBracketLoop;
852 if (
Tok.Previous->is(tok::kw_switch))
853 return Style.BreakAfterOpenBracketSwitch;
854 if (Style.BreakAfterOpenBracketFunction) {
855 return !
Tok.Previous->is(TT_CastRParen) &&
856 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
861 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
862 Tok.Previous->is(tok::identifier);
864 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
865 if (!Style.isJavaScript())
867 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
868 if (Prev->is(TT_TemplateString) && Prev->opensScope())
870 if (Prev->opensScope() && !NestBlocks)
872 if (Prev->is(TT_TemplateString) && Prev->closesScope())
878 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
879 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
881 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
888 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
890 if (
Tok.is(TT_UnaryOperator) ||
891 (Style.isJavaScript() &&
892 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
895 const auto *
Previous = TokAfterLParen.Previous;
899 Previous->Previous->is(tok::kw_switch))) {
902 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
903 TT_LambdaDefinitionLParen) &&
907 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
910 return !
Next ||
Next->isMemberAccess() ||
911 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
913 if (IsOpeningBracket(
Previous) && State.
Column > getNewLineColumn(State) &&
924 !StartsSimpleOneArgList(Current)) {
925 CurrentState.NoLineBreak =
true;
929 CurrentState.NoLineBreak =
true;
935 if (Style.AlignAfterOpenBracket &&
936 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
937 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
938 TT_TableGenDAGArgOpener,
939 TT_TableGenDAGArgOpenerToBreak) &&
941 (Current.
isNot(TT_LineComment) ||
943 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||
945 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,
947 Previous.is(TT_VerilogMultiLineListLParen)) &&
948 !IsInTemplateString(Current,
false)) {
949 CurrentState.Indent = State.
Column + Spaces;
950 CurrentState.IsAligned =
true;
953 CurrentState.NoLineBreak =
true;
955 CurrentState.NoLineBreak =
true;
958 State.
Column > getNewLineColumn(State)) {
959 CurrentState.ContainsUnwrappedBuilder =
true;
962 if (Current.
is(TT_LambdaArrow) && Style.isJava())
963 CurrentState.NoLineBreak =
true;
964 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
973 CurrentState.NoLineBreak =
true;
980 const FormatToken *P = Current.getPreviousNonComment();
981 if (Current.
isNot(tok::comment) && P &&
982 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
983 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
984 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
988 bool BreakBeforeOperator =
989 P->MustBreakBefore || P->is(tok::lessless) ||
990 (P->is(TT_BinaryOperator) &&
991 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
992 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
996 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
997 P->isNot(TT_ConditionalExpr);
998 if ((!BreakBeforeOperator &&
1000 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||
1001 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1002 CurrentState.NoLineBreakInOperand =
true;
1007 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1012 CurrentState.LastSpace = State.
Column;
1013 CurrentState.NestedBlockIndent = State.
Column;
1014 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1016 Previous.isNot(TT_OverloadedOperator)) ||
1018 CurrentState.LastSpace = State.
Column;
1019 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1021 Style.BreakConstructorInitializers ==
1022 FormatStyle::BCIS_AfterColon) {
1023 CurrentState.Indent = State.
Column;
1024 CurrentState.LastSpace = State.
Column;
1025 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1026 CurrentState.LastSpace = State.
Column;
1027 }
else if (
Previous.is(TT_BinaryOperator) &&
1034 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)
1035 CurrentState.LastSpace = State.
Column;
1036 }
else if (
Previous.is(TT_InheritanceColon)) {
1037 CurrentState.Indent = State.
Column;
1038 CurrentState.LastSpace = State.
Column;
1039 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1040 CurrentState.ColonPos = State.
Column;
1041 }
else if (
Previous.opensScope()) {
1049 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1050 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1051 CurrentState.LastSpace = State.
Column;
1057unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1060 assert(State.NextToken->Previous);
1062 auto &CurrentState = State.Stack.back();
1066 unsigned Penalty = 0;
1068 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1070 if (!NextNonComment)
1071 NextNonComment = &Current;
1074 if (!CurrentState.ContainsLineBreak)
1076 CurrentState.ContainsLineBreak =
true;
1078 Penalty += State.NextToken->SplitPenalty;
1083 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1084 (State.Column <= Style.ColumnLimit / 3 ||
1085 CurrentState.BreakBeforeParameter)) {
1086 Penalty += Style.PenaltyBreakFirstLessLess;
1089 State.Column = getNewLineColumn(State);
1103 if (State.Column > State.FirstIndent) {
1105 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1118 if (Current.isNot(TT_LambdaArrow) &&
1119 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1120 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1121 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1122 CurrentState.NestedBlockIndent = State.Column;
1125 if (NextNonComment->isMemberAccess()) {
1126 if (CurrentState.CallContinuation == 0)
1127 CurrentState.CallContinuation = State.Column;
1128 }
else if (NextNonComment->is(TT_SelectorName)) {
1129 if (!CurrentState.ObjCSelectorNameFound) {
1130 if (NextNonComment->LongestObjCSelectorName == 0) {
1131 CurrentState.AlignColons =
false;
1133 CurrentState.ColonPos =
1135 ? std::max(CurrentState.Indent,
1136 State.FirstIndent + Style.ContinuationIndentWidth)
1141 }
else if (CurrentState.AlignColons &&
1142 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1143 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1145 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1146 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1156 if (State.Stack.size() > 1) {
1157 State.Stack[State.Stack.size() - 2].LastSpace =
1158 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1159 Style.ContinuationIndentWidth;
1163 if ((PreviousNonComment &&
1164 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1165 !CurrentState.AvoidBinPacking) ||
1167 CurrentState.BreakBeforeParameter =
false;
1169 if (PreviousNonComment &&
1170 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1171 PreviousNonComment->ClosesRequiresClause) &&
1172 Current.NestingLevel == 0) {
1173 CurrentState.BreakBeforeParameter =
false;
1175 if (NextNonComment->is(tok::question) ||
1176 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1177 CurrentState.BreakBeforeParameter =
true;
1179 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1180 CurrentState.BreakBeforeParameter =
false;
1184 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1187 !Current.MatchingParen->Children.empty()) {
1195 const bool ContinuePPDirective = State.Line->InPPDirective &&
1197 Current.isNot(TT_LineComment);
1198 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1199 CurrentState.IsAligned, ContinuePPDirective);
1202 if (!Current.isTrailingComment())
1203 CurrentState.LastSpace = State.Column;
1204 if (Current.is(tok::lessless)) {
1208 CurrentState.LastSpace += 3;
1211 State.StartOfLineLevel = Current.NestingLevel;
1212 State.LowestLevelOnLine = Current.NestingLevel;
1216 bool NestedBlockSpecialCase =
1217 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1218 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1219 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&
1220 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1222 NestedBlockSpecialCase =
1223 NestedBlockSpecialCase ||
1224 (Current.MatchingParen &&
1225 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1226 if (!NestedBlockSpecialCase) {
1227 auto ParentLevelIt = std::next(State.Stack.rbegin());
1228 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1229 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1244 auto FindCurrentLevel = [&](
const auto &It) {
1245 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1246 return PState.Tok != nullptr;
1249 auto MaybeIncrement = [&](
const auto &It) {
1250 return It != State.Stack.rend() ? std::next(It) : It;
1252 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1253 auto LevelContainingLambdaIt =
1254 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1255 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1257 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1258 I->BreakBeforeParameter =
true;
1261 if (PreviousNonComment &&
1262 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1263 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1264 !PreviousNonComment->ClosesRequiresClause) ||
1265 Current.NestingLevel != 0) &&
1266 PreviousNonComment->isNoneOf(
1267 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1268 TT_LeadingJavaAnnotation) &&
1269 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1272 (!Style.BraceWrapping.BeforeLambdaBody ||
1273 Current.isNot(TT_LambdaLBrace))) {
1274 CurrentState.BreakBeforeParameter =
true;
1279 if (PreviousNonComment &&
1280 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1282 CurrentState.BreakBeforeClosingBrace =
true;
1285 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1286 if (
auto Previous = PreviousNonComment->Previous) {
1288 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1289 }
else if (
Previous->isLoop(Style)) {
1290 CurrentState.BreakBeforeClosingParen =
1291 Style.BreakBeforeCloseBracketLoop;
1292 }
else if (
Previous->is(tok::kw_switch)) {
1293 CurrentState.BreakBeforeClosingParen =
1294 Style.BreakBeforeCloseBracketSwitch;
1296 CurrentState.BreakBeforeClosingParen =
1297 Style.BreakBeforeCloseBracketFunction;
1302 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1303 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1305 if (CurrentState.AvoidBinPacking) {
1310 bool PreviousIsBreakingCtorInitializerColon =
1311 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1312 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
1313 bool AllowAllConstructorInitializersOnNextLine =
1314 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
1315 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
1316 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1317 !PreviousIsBreakingCtorInitializerColon) ||
1318 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1319 State.Line->MustBeDeclaration) ||
1320 (!Style.AllowAllArgumentsOnNextLine &&
1321 !State.Line->MustBeDeclaration) ||
1322 (!AllowAllConstructorInitializersOnNextLine &&
1323 PreviousIsBreakingCtorInitializerColon) ||
1325 CurrentState.BreakBeforeParameter =
true;
1331 if (PreviousIsBreakingCtorInitializerColon &&
1332 AllowAllConstructorInitializersOnNextLine) {
1333 CurrentState.BreakBeforeParameter =
false;
1338 CurrentState.BreakBeforeParameter =
true;
1343unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1344 if (!State.NextToken || !State.NextToken->Previous)
1348 const auto &CurrentState = State.Stack.back();
1350 if (CurrentState.IsCSharpGenericTypeConstraint &&
1351 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1352 return CurrentState.ColonPos + 2;
1357 unsigned ContinuationIndent =
1358 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1359 Style.ContinuationIndentWidth;
1360 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1362 if (!NextNonComment)
1363 NextNonComment = &Current;
1366 if (Style.isJava() &&
1367 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1368 return std::max(CurrentState.LastSpace,
1369 CurrentState.Indent + Style.ContinuationIndentWidth);
1374 if (Style.isVerilog() && PreviousNonComment &&
1375 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1376 return State.FirstIndent;
1379 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
1380 State.Line->First->is(tok::kw_enum)) {
1381 return (Style.IndentWidth * State.Line->First->IndentLevel) +
1385 if (Style.BraceWrapping.BeforeLambdaBody &&
1386 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1387 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature
1388 ? CurrentState.Indent
1389 : State.FirstIndent;
1390 return From + Style.IndentWidth;
1393 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1394 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1395 if (Current.NestingLevel == 0 ||
1396 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
1397 State.NextToken->is(TT_LambdaLBrace))) {
1398 return State.FirstIndent;
1400 return CurrentState.Indent;
1402 if (Current.is(TT_LambdaArrow) &&
1403 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1404 tok::kw_consteval, tok::kw_static,
1405 TT_AttributeRSquare)) {
1406 return ContinuationIndent;
1408 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1409 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1410 State.Stack.size() > 1) {
1411 if (Current.closesBlockOrBlockTypeList(Style))
1412 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1413 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1414 return State.Stack[State.Stack.size() - 2].LastSpace;
1415 return State.FirstIndent;
1432 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1434 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1435 return State.Stack[State.Stack.size() - 2].LastSpace;
1439 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1440 State.Stack.size() > 1) {
1441 return State.Stack[State.Stack.size() - 2].LastSpace;
1443 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1444 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1445 State.Stack.size() > 1) {
1446 return State.Stack[State.Stack.size() - 2].LastSpace;
1448 if ((Style.BreakBeforeCloseBracketFunction ||
1449 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1450 Style.BreakBeforeCloseBracketSwitch) &&
1451 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1452 return State.Stack[State.Stack.size() - 2].LastSpace;
1454 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1455 State.Stack.size() > 1) {
1456 return State.Stack[State.Stack.size() - 2].LastSpace;
1458 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1459 return State.Stack[State.Stack.size() - 2].LastSpace;
1467 if (Current.is(tok::identifier) && Current.Next &&
1468 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1469 (Current.Next->is(TT_DictLiteral) ||
1470 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1471 return CurrentState.Indent;
1473 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1474 State.StartOfStringLiteral != 0) {
1475 return State.StartOfStringLiteral - 1;
1477 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1478 return State.StartOfStringLiteral;
1479 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1480 return CurrentState.FirstLessLess;
1481 if (NextNonComment->isMemberAccess()) {
1482 if (CurrentState.CallContinuation == 0)
1483 return ContinuationIndent;
1484 return CurrentState.CallContinuation;
1486 if (CurrentState.QuestionColumn != 0 &&
1487 ((NextNonComment->is(tok::colon) &&
1488 NextNonComment->is(TT_ConditionalExpr)) ||
1489 Previous.is(TT_ConditionalExpr))) {
1490 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1491 !NextNonComment->Next->FakeLParens.empty() &&
1493 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1495 !CurrentState.IsWrappedConditional) {
1500 unsigned Indent = CurrentState.Indent;
1501 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1502 Indent -= Style.ContinuationIndentWidth;
1503 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1507 return CurrentState.QuestionColumn;
1509 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1510 return CurrentState.VariablePos;
1511 if (Current.is(TT_RequiresClause)) {
1512 if (Style.IndentRequiresClause)
1513 return CurrentState.Indent + Style.IndentWidth;
1514 switch (Style.RequiresClausePosition) {
1515 case FormatStyle::RCPS_OwnLine:
1516 case FormatStyle::RCPS_WithFollowing:
1517 case FormatStyle::RCPS_OwnLineWithBrace:
1518 return CurrentState.Indent;
1523 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1524 TT_InheritanceComma)) {
1525 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1527 if ((PreviousNonComment &&
1528 (PreviousNonComment->ClosesTemplateDeclaration ||
1529 PreviousNonComment->ClosesRequiresClause ||
1530 (PreviousNonComment->is(TT_AttributeMacro) &&
1531 Current.isNot(tok::l_paren) &&
1532 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1533 TT_PointerOrReference)) ||
1534 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1535 TT_FunctionAnnotationRParen,
1537 TT_LeadingJavaAnnotation))) ||
1538 (!Style.IndentWrappedFunctionNames &&
1539 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1540 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1542 if (NextNonComment->is(TT_SelectorName)) {
1543 if (!CurrentState.ObjCSelectorNameFound) {
1544 unsigned MinIndent = CurrentState.Indent;
1546 MinIndent = std::max(MinIndent,
1547 State.FirstIndent + Style.ContinuationIndentWidth);
1559 std::max(NextNonComment->LongestObjCSelectorName,
1560 NextNonComment->ColumnWidth) -
1561 NextNonComment->ColumnWidth;
1563 if (!CurrentState.AlignColons)
1564 return CurrentState.Indent;
1565 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1566 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1567 return CurrentState.Indent;
1569 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1570 return CurrentState.ColonPos;
1571 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1572 if (CurrentState.StartOfArraySubscripts != 0) {
1573 return CurrentState.StartOfArraySubscripts;
1574 }
else if (Style.isCSharp()) {
1576 return CurrentState.Indent;
1578 return ContinuationIndent;
1583 if (State.Line->InPragmaDirective) {
1584 FormatToken *PragmaType = State.Line->First->Next->Next;
1585 if (PragmaType && PragmaType->TokenText ==
"omp")
1586 return CurrentState.Indent + Style.ContinuationIndentWidth;
1591 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1592 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1593 return CurrentState.Indent;
1596 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1597 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1598 return ContinuationIndent;
1600 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1601 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1602 return ContinuationIndent;
1604 if (NextNonComment->is(TT_CtorInitializerComma))
1605 return CurrentState.Indent;
1606 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1607 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1608 return CurrentState.Indent;
1610 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1611 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
1612 return CurrentState.Indent;
1615 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1616 !Current.isBinaryOperator() &&
1617 Current.isNoneOf(tok::colon, tok::comment)) {
1618 return ContinuationIndent;
1620 if (Current.is(TT_ProtoExtensionLSquare))
1621 return CurrentState.Indent;
1622 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1623 return CurrentState.Indent - Current.Tok.getLength() -
1624 Current.SpacesRequiredBefore;
1626 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1627 CurrentState.UnindentOperator) {
1628 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1629 NextNonComment->SpacesRequiredBefore;
1631 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1632 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1635 return CurrentState.Indent + Style.ContinuationIndentWidth;
1637 return CurrentState.Indent;
1642 const FormatStyle &Style) {
1649 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1652unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1653 bool DryRun,
bool Newline) {
1654 assert(State.Stack.size());
1656 auto &CurrentState = State.Stack.back();
1658 if (Current.is(TT_CSharpGenericTypeConstraint))
1659 CurrentState.IsCSharpGenericTypeConstraint =
true;
1660 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1661 CurrentState.NoLineBreakInOperand =
false;
1662 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1663 CurrentState.AvoidBinPacking =
true;
1664 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1665 if (CurrentState.FirstLessLess == 0)
1666 CurrentState.FirstLessLess = State.Column;
1668 CurrentState.LastOperatorWrapped = Newline;
1670 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1671 CurrentState.LastOperatorWrapped = Newline;
1672 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1673 Current.Previous->isNot(TT_ConditionalExpr)) {
1674 CurrentState.LastOperatorWrapped = Newline;
1676 if (Current.is(TT_ArraySubscriptLSquare) &&
1677 CurrentState.StartOfArraySubscripts == 0) {
1678 CurrentState.StartOfArraySubscripts = State.Column;
1682 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1684 if (
Tok.MustBreakBefore)
1688 return Next &&
Next->MustBreakBefore;
1690 if (IsWrappedConditional(Current))
1691 CurrentState.IsWrappedConditional =
true;
1692 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1693 CurrentState.QuestionColumn = State.Column;
1694 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1699 CurrentState.QuestionColumn = State.Column;
1701 if (!Current.opensScope() && !Current.closesScope() &&
1702 Current.isNot(TT_PointerOrReference)) {
1703 State.LowestLevelOnLine =
1704 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1706 if (Current.isMemberAccess())
1707 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1708 if (Current.is(TT_SelectorName))
1709 CurrentState.ObjCSelectorNameFound =
true;
1710 if (Current.is(TT_CtorInitializerColon) &&
1711 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
1717 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1718 FormatStyle::BCIS_BeforeComma
1721 CurrentState.NestedBlockIndent = CurrentState.Indent;
1722 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
1723 CurrentState.AvoidBinPacking =
true;
1724 CurrentState.BreakBeforeParameter =
1725 Style.ColumnLimit > 0 &&
1726 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&
1727 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;
1729 CurrentState.BreakBeforeParameter =
false;
1732 if (Current.is(TT_CtorInitializerColon) &&
1733 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
1734 CurrentState.Indent =
1735 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1736 CurrentState.NestedBlockIndent = CurrentState.Indent;
1737 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
1738 CurrentState.AvoidBinPacking =
true;
1740 CurrentState.BreakBeforeParameter =
false;
1742 if (Current.is(TT_InheritanceColon)) {
1743 CurrentState.Indent =
1744 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1746 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1747 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1748 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1749 CurrentState.LastSpace = State.Column;
1750 if (Current.is(TT_RequiresExpression) &&
1751 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
1752 CurrentState.NestedBlockIndent = State.Column;
1764 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1766 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1767 !CurrentState.HasMultipleNestedBlocks) {
1768 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1769 for (ParenState &PState : llvm::drop_end(State.Stack))
1770 PState.NoLineBreak =
true;
1771 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1773 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1774 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1775 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1776 TT_CtorInitializerColon)))) {
1777 CurrentState.NestedBlockInlined =
1781 moveStatePastFakeLParens(State, Newline);
1782 moveStatePastScopeCloser(State);
1785 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1786 !State.Stack.back().NoLineBreakInOperand;
1787 moveStatePastScopeOpener(State, Newline);
1788 moveStatePastFakeRParens(State);
1790 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1791 State.StartOfStringLiteral = State.Column + 1;
1792 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1793 State.StartOfStringLiteral = State.Column + 1;
1794 }
else if (Current.is(TT_TableGenMultiLineString) &&
1795 State.StartOfStringLiteral == 0) {
1796 State.StartOfStringLiteral = State.Column + 1;
1797 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1798 State.StartOfStringLiteral = State.Column;
1799 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1800 !Current.isStringLiteral()) {
1801 State.StartOfStringLiteral = 0;
1804 State.Column += Current.ColumnWidth;
1805 State.NextToken = State.NextToken->Next;
1810 if (Style.isVerilog() && State.NextToken &&
1811 State.NextToken->MustBreakBefore &&
1812 Keywords.isVerilogEndOfLabel(Current)) {
1813 State.FirstIndent += Style.IndentWidth;
1814 CurrentState.Indent = State.FirstIndent;
1818 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1821 Current.Role->formatFromToken(State,
this, DryRun);
1828 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1833void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1836 if (Current.FakeLParens.empty())
1844 bool SkipFirstExtraIndent =
1847 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1849 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||
1851 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1852 const auto &CurrentState = State.Stack.back();
1853 ParenState NewParenState = CurrentState;
1854 NewParenState.Tok =
nullptr;
1855 NewParenState.ContainsLineBreak =
false;
1856 NewParenState.LastOperatorWrapped =
true;
1857 NewParenState.IsChainedConditional =
false;
1858 NewParenState.IsWrappedConditional =
false;
1859 NewParenState.UnindentOperator =
false;
1860 NewParenState.NoLineBreak =
1861 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1865 NewParenState.AvoidBinPacking =
false;
1870 if (!Current.isTrailingComment() &&
1871 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||
1874 (!Style.isJava() && PrecedenceLevel > 0)) &&
1875 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
1876 Current.NestingLevel == 0) &&
1877 (!Style.isTableGen() ||
1879 TT_TableGenDAGArgListCommaToBreak)))) {
1880 NewParenState.Indent = std::max(
1881 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1888 State.Stack.size() > 1) {
1889 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1890 Style.ContinuationIndentWidth;
1900 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)
1901 NewParenState.UnindentOperator =
true;
1903 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
1904 NewParenState.IsAligned =
true;
1914 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1916 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
1917 NewParenState.StartOfFunctionCall = State.Column;
1927 &PrecedenceLevel == &Current.FakeLParens.back() &&
1928 !CurrentState.IsWrappedConditional) {
1929 NewParenState.IsChainedConditional =
true;
1930 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1933 !Current.isTrailingComment())) {
1934 NewParenState.Indent += Style.ContinuationIndentWidth;
1937 NewParenState.BreakBeforeParameter =
false;
1938 State.Stack.push_back(NewParenState);
1939 SkipFirstExtraIndent =
false;
1943void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
1944 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1945 unsigned VariablePos = State.Stack.back().VariablePos;
1946 if (State.Stack.size() == 1) {
1950 State.Stack.pop_back();
1951 State.Stack.back().VariablePos = VariablePos;
1954 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
1957 State.Stack.back().LastSpace -= Style.IndentWidth;
1961void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
1964 if (!Current.opensScope())
1967 const auto &CurrentState = State.Stack.back();
1970 if (Current.isOneOf(tok::less, tok::l_paren) &&
1971 CurrentState.IsCSharpGenericTypeConstraint) {
1975 if (Current.MatchingParen && Current.is(
BK_Block)) {
1976 moveStateToNewBlock(State, Newline);
1983 const auto *Prev =
Tok->getPreviousNonComment();
1986 return Prev->is(tok::comma);
1987 }(Current.MatchingParen);
1990 unsigned LastSpace = CurrentState.LastSpace;
1991 bool AvoidBinPacking;
1992 bool BreakBeforeParameter =
false;
1993 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1994 CurrentState.NestedBlockIndent);
1995 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1997 if (Current.opensBlockOrBlockTypeList(Style)) {
1998 NewIndent = Style.IndentWidth +
1999 std::min(State.Column, CurrentState.NestedBlockIndent);
2000 }
else if (Current.is(tok::l_brace)) {
2001 const auto Width = Style.BracedInitializerIndentWidth;
2002 NewIndent = CurrentState.LastSpace +
2003 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2005 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2007 const FormatToken *NextNonComment = Current.getNextNonComment();
2008 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
2009 Style.isProto() || !Style.BinPackArguments ||
2010 (NextNonComment && NextNonComment->isOneOf(
2011 TT_DesignatedInitializerPeriod,
2012 TT_DesignatedInitializerLSquare));
2013 BreakBeforeParameter = EndsInComma;
2014 if (Current.ParameterCount > 1)
2015 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2018 Style.ContinuationIndentWidth +
2019 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
2021 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2022 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
2028 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2029 NewIndent = State.Column +
Next->TokenText.size() + 2;
2036 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2037 NewIndent = std::max(NewIndent, CurrentState.Indent);
2038 LastSpace = std::max(LastSpace, CurrentState.Indent);
2044 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&
2045 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2046 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;
2048 bool BinPackDeclaration =
2050 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||
2053 bool GenericSelection =
2054 Current.getPreviousNonComment() &&
2055 Current.getPreviousNonComment()->is(tok::kw__Generic);
2058 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2059 (Style.isJavaScript() && EndsInComma) ||
2060 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2061 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
2062 (Style.ExperimentalAutoDetectBinPacking &&
2066 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2067 Style.ObjCBreakBeforeNestedBlockParam) {
2068 if (Style.ColumnLimit) {
2073 BreakBeforeParameter =
true;
2079 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2080 if (
Tok->MustBreakBefore ||
2081 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2082 BreakBeforeParameter =
true;
2089 if (Style.isJavaScript() && EndsInComma)
2090 BreakBeforeParameter =
true;
2096 Current.Children.empty() &&
2097 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2098 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2099 (Current.is(TT_TemplateOpener) &&
2100 CurrentState.ContainsUnwrappedBuilder));
2101 State.Stack.push_back(
2102 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2103 auto &NewState = State.Stack.back();
2104 NewState.NestedBlockIndent = NestedBlockIndent;
2105 NewState.BreakBeforeParameter = BreakBeforeParameter;
2106 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2108 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2109 Current.is(tok::l_paren)) {
2113 if (next->is(TT_LambdaLSquare)) {
2114 NewState.HasMultipleNestedBlocks =
true;
2121 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2123 Current.Previous->is(tok::at);
2126void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2128 if (!Current.closesScope())
2133 if (State.Stack.size() > 1 &&
2134 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2135 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2136 State.NextToken->is(TT_TemplateCloser) ||
2137 State.NextToken->is(TT_TableGenListCloser) ||
2138 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2139 State.Stack.pop_back();
2142 auto &CurrentState = State.Stack.back();
2154 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2155 Current.MatchingParen->Previous) {
2156 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2157 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2158 CurrentScopeOpener.MatchingParen) {
2159 int NecessarySpaceInLine =
2161 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2162 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2163 Style.ColumnLimit) {
2164 CurrentState.BreakBeforeParameter =
false;
2169 if (Current.is(tok::r_square)) {
2171 const FormatToken *NextNonComment = Current.getNextNonComment();
2172 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2173 CurrentState.StartOfArraySubscripts = 0;
2177void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2178 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
2179 State.NextToken->is(TT_LambdaLBrace) &&
2180 !State.Line->MightBeFunctionDecl) {
2181 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2182 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2184 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2186 unsigned NewIndent =
2187 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2188 ? Style.ObjCBlockIndentWidth
2189 : Style.IndentWidth);
2196 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2197 State.NextToken->is(TT_LambdaLBrace);
2199 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2200 State.Stack.back().LastSpace,
2201 true, NoLineBreak));
2202 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2203 State.Stack.back().BreakBeforeParameter =
true;
2209 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2210 if (LastNewlinePos == StringRef::npos) {
2211 return StartColumn +
2219unsigned ContinuationIndenter::reformatRawStringLiteral(
2221 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2222 unsigned StartColumn = State.Column - Current.ColumnWidth;
2224 StringRef NewDelimiter =
2226 if (NewDelimiter.empty())
2227 NewDelimiter = OldDelimiter;
2230 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2231 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2234 std::string RawText = std::string(
2235 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2236 if (NewDelimiter != OldDelimiter) {
2239 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2240 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2241 NewDelimiter = OldDelimiter;
2244 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2245 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2248 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2259 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2281 unsigned CurrentIndent =
2282 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2283 ? State.Stack.back().NestedBlockIndent
2284 : State.Stack.back().Indent;
2285 unsigned NextStartColumn = ContentStartsOnNewline
2286 ? CurrentIndent + Style.IndentWidth
2297 unsigned LastStartColumn =
2298 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2301 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2302 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2307 return addMultilineToken(Current, State);
2309 if (NewDelimiter != OldDelimiter) {
2312 SourceLocation PrefixDelimiterStart =
2313 Current.Tok.getLocation().getLocWithOffset(2);
2314 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2315 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2318 <<
"Failed to update the prefix delimiter of a raw string: "
2319 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2323 SourceLocation SuffixDelimiterStart =
2324 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2325 1 - OldDelimiter.size());
2326 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2327 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2330 <<
"Failed to update the suffix delimiter of a raw string: "
2331 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2334 SourceLocation OriginLoc =
2335 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2336 for (
const tooling::Replacement &Fix : Fixes.first) {
2337 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2338 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2339 Fix.getLength(), Fix.getReplacementText()));
2341 llvm::errs() <<
"Failed to reformat raw string: "
2342 << llvm::toString(std::move(Err)) <<
"\n";
2347 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2348 State.Column = RawLastLineEndColumn + NewSuffixSize;
2352 unsigned PrefixExcessCharacters =
2353 StartColumn + NewPrefixSize > Style.ColumnLimit
2354 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2357 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2360 for (ParenState &
Paren : State.Stack)
2361 Paren.BreakBeforeParameter =
true;
2363 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2366unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2369 for (ParenState &
Paren : State.Stack)
2370 Paren.BreakBeforeParameter =
true;
2372 unsigned ColumnsUsed = State.Column;
2375 State.Column = Current.LastLineColumnWidth;
2378 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2382unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2384 bool AllowBreak,
bool Newline) {
2385 unsigned Penalty = 0;
2388 auto RawStringStyle = getRawStringStyle(Current, State);
2389 if (RawStringStyle && !Current.Finalized) {
2390 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2392 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2395 Penalty = addMultilineToken(Current, State);
2398 LineState OriginalState = State;
2402 bool Strict =
false;
2405 bool Exceeded =
false;
2406 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2407 Current, State, AllowBreak,
true, Strict);
2411 LineState StrictState = OriginalState;
2412 unsigned StrictPenalty =
2413 breakProtrudingToken(Current, StrictState, AllowBreak,
2416 Strict = StrictPenalty <= Penalty;
2418 Penalty = StrictPenalty;
2419 State = StrictState;
2425 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2430 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2431 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2440 auto Tok = Current.getPreviousNonComment();
2441 if (!
Tok ||
Tok->isNot(tok::l_paren))
2443 Tok =
Tok->getPreviousNonComment();
2446 if (
Tok->is(TT_TemplateCloser)) {
2447 Tok =
Tok->MatchingParen;
2449 Tok =
Tok->getPreviousNonComment();
2451 if (!
Tok ||
Tok->isNot(tok::identifier))
2453 return Tok->TokenText;
2456std::optional<FormatStyle>
2457ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2458 const LineState &State) {
2459 if (!Current.isStringLiteral())
2460 return std::nullopt;
2463 return std::nullopt;
2465 if (!RawStringStyle && Delimiter->empty()) {
2469 if (!RawStringStyle)
2470 return std::nullopt;
2472 return RawStringStyle;
2475std::unique_ptr<BreakableToken>
2476ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2478 unsigned StartColumn = State.Column - Current.ColumnWidth;
2479 if (Current.isStringLiteral()) {
2482 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2496 if (Current.IsUnterminatedLiteral)
2500 if (State.Stack.back().IsInsideObjCArrayLiteral)
2507 if (Style.isVerilog() && Current.Previous &&
2508 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2511 StringRef
Text = Current.TokenText;
2521 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2524 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2525 Text.ends_with(
"'")) {
2527 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2528 Text.ends_with(
"\"")) {
2530 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2535 return std::make_unique<BreakableStringLiteralUsingOperators>(
2536 Current, QuoteStyle,
2547 if ((
Text.ends_with(Postfix =
"\"") &&
2548 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2549 Text.starts_with(Prefix =
"u\"") ||
2550 Text.starts_with(Prefix =
"U\"") ||
2551 Text.starts_with(Prefix =
"u8\"") ||
2552 Text.starts_with(Prefix =
"L\""))) ||
2553 (
Text.starts_with(Prefix =
"_T(\"") &&
2554 Text.ends_with(Postfix =
"\")"))) {
2555 return std::make_unique<BreakableStringLiteral>(
2557 State.Line->InPPDirective, Encoding, Style);
2559 }
else if (Current.is(TT_BlockComment)) {
2560 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2567 return std::make_unique<BreakableBlockComment>(
2568 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2569 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2570 }
else if (Current.is(TT_LineComment) &&
2571 (!Current.Previous ||
2572 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2573 bool RegularComments = [&]() {
2574 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2576 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2581 if (Style.ReflowComments == FormatStyle::RCS_Never ||
2582 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2586 return std::make_unique<BreakableLineCommentSection>(
2587 Current, StartColumn,
false, Encoding, Style);
2592std::pair<unsigned, bool>
2593ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2595 bool DryRun,
bool Strict) {
2596 std::unique_ptr<const BreakableToken> Token =
2597 createBreakableToken(Current, State, AllowBreak);
2600 assert(Token->getLineCount() > 0);
2602 if (Current.is(TT_LineComment)) {
2604 ColumnLimit = Style.ColumnLimit;
2606 if (ColumnLimit == 0) {
2609 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2611 if (Current.UnbreakableTailLength >= ColumnLimit)
2615 unsigned StartColumn = State.Column - Current.ColumnWidth;
2616 unsigned NewBreakPenalty = Current.isStringLiteral()
2617 ? Style.PenaltyBreakString
2618 : Style.PenaltyBreakComment;
2621 bool Exceeded =
false;
2623 bool BreakInserted = Token->introducesBreakBeforeToken();
2626 bool NewBreakBefore =
false;
2630 bool Reflow =
false;
2633 unsigned TailOffset = 0;
2635 unsigned ContentStartColumn =
2636 Token->getContentStartColumn(0,
false);
2638 unsigned RemainingTokenColumns =
2639 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2642 Token->adaptStartOfLine(0, Whitespaces);
2644 unsigned ContentIndent = 0;
2645 unsigned Penalty = 0;
2646 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2647 << StartColumn <<
".\n");
2648 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2649 LineIndex != EndIndex; ++LineIndex) {
2650 LLVM_DEBUG(llvm::dbgs()
2651 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2652 NewBreakBefore =
false;
2656 bool TryReflow = Reflow;
2658 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2659 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2660 << (ContentStartColumn + RemainingTokenColumns)
2661 <<
", space: " << ColumnLimit
2662 <<
", reflown prefix: " << ContentStartColumn
2663 <<
", offset in line: " << TailOffset <<
"\n");
2669 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2670 ContentStartColumn, CommentPragmasRegex);
2671 if (
Split.first == StringRef::npos) {
2674 if (LineIndex < EndIndex - 1) {
2677 Penalty += Style.PenaltyExcessCharacter *
2678 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2680 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2683 assert(
Split.first != 0);
2685 if (Token->supportsReflow()) {
2705 unsigned ToSplitColumns = Token->getRangeLength(
2706 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2707 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2710 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2711 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2714 unsigned ToNextSplitColumns = 0;
2715 if (NextSplit.first == StringRef::npos) {
2716 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2717 ContentStartColumn);
2719 ToNextSplitColumns = Token->getRangeLength(
2720 LineIndex, TailOffset,
2721 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2725 ToNextSplitColumns =
2726 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2727 LLVM_DEBUG(llvm::dbgs()
2728 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2729 LLVM_DEBUG(llvm::dbgs()
2730 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2733 bool ContinueOnLine =
2734 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2735 unsigned ExcessCharactersPenalty = 0;
2736 if (!ContinueOnLine && !Strict) {
2739 ExcessCharactersPenalty =
2740 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2741 Style.PenaltyExcessCharacter;
2742 LLVM_DEBUG(llvm::dbgs()
2743 <<
" Penalty excess: " << ExcessCharactersPenalty
2744 <<
"\n break : " << NewBreakPenalty <<
"\n");
2745 if (ExcessCharactersPenalty < NewBreakPenalty) {
2747 ContinueOnLine =
true;
2750 if (ContinueOnLine) {
2751 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2756 Token->compressWhitespace(LineIndex, TailOffset, Split,
2760 ContentStartColumn += ToSplitColumns + 1;
2761 Penalty += ExcessCharactersPenalty;
2763 RemainingTokenColumns = Token->getRemainingLength(
2764 LineIndex, TailOffset, ContentStartColumn);
2768 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2773 ContentIndent = Token->getContentIndent(LineIndex);
2774 LLVM_DEBUG(llvm::dbgs()
2775 <<
" ContentIndent: " << ContentIndent <<
"\n");
2776 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2779 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2780 LineIndex, TailOffset +
Split.first +
Split.second,
2781 ContentStartColumn);
2782 if (NewRemainingTokenColumns == 0) {
2785 ContentStartColumn =
2786 Token->getContentStartColumn(LineIndex,
true);
2787 NewRemainingTokenColumns = Token->getRemainingLength(
2788 LineIndex, TailOffset +
Split.first +
Split.second,
2789 ContentStartColumn);
2795 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2800 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2801 <<
", " <<
Split.second <<
"\n");
2803 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2807 Penalty += NewBreakPenalty;
2809 RemainingTokenColumns = NewRemainingTokenColumns;
2810 BreakInserted =
true;
2811 NewBreakBefore =
true;
2815 if (LineIndex + 1 != EndIndex) {
2816 unsigned NextLineIndex = LineIndex + 1;
2817 if (NewBreakBefore) {
2836 ContentStartColumn += RemainingTokenColumns + 1;
2841 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2842 LLVM_DEBUG(llvm::dbgs()
2843 <<
" Size of reflown text: " << ContentStartColumn
2844 <<
"\n Potential reflow split: ");
2845 if (SplitBeforeNext.first != StringRef::npos) {
2846 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2847 << SplitBeforeNext.second <<
"\n");
2848 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2851 RemainingTokenColumns = Token->getRemainingLength(
2852 NextLineIndex, TailOffset, ContentStartColumn);
2854 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2855 LLVM_DEBUG(llvm::dbgs()
2856 <<
" Over limit after reflow, need: "
2857 << (ContentStartColumn + RemainingTokenColumns)
2858 <<
", space: " << ColumnLimit
2859 <<
", reflown prefix: " << ContentStartColumn
2860 <<
", offset in line: " << TailOffset <<
"\n");
2866 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2867 ContentStartColumn, CommentPragmasRegex);
2868 if (
Split.first == StringRef::npos) {
2869 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2875 unsigned ToSplitColumns = Token->getRangeLength(
2876 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2877 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2878 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2879 << (ContentStartColumn + ToSplitColumns)
2880 <<
", space: " << ColumnLimit);
2881 unsigned ExcessCharactersPenalty =
2882 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2883 Style.PenaltyExcessCharacter;
2884 if (NewBreakPenalty < ExcessCharactersPenalty)
2890 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2898 ContentStartColumn =
2899 Token->getContentStartColumn(NextLineIndex,
false);
2900 RemainingTokenColumns = Token->getRemainingLength(
2901 NextLineIndex, TailOffset, ContentStartColumn);
2904 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2919 if (NewBreakBefore) {
2920 assert(Penalty >= NewBreakPenalty);
2921 Penalty -= NewBreakPenalty;
2924 Token->reflow(NextLineIndex, Whitespaces);
2930 Token->getSplitAfterLastLine(TailOffset);
2931 if (SplitAfterLastLine.first != StringRef::npos) {
2932 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2936 Penalty += Style.PenaltyExcessCharacter *
2937 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2940 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2943 ContentStartColumn =
2944 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2945 RemainingTokenColumns = Token->getRemainingLength(
2946 Token->getLineCount() - 1,
2947 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2948 ContentStartColumn);
2951 State.Column = ContentStartColumn + RemainingTokenColumns -
2952 Current.UnbreakableTailLength;
2954 if (BreakInserted) {
2956 Token->updateAfterBroken(Whitespaces);
2961 if (Current.isNot(TT_LineComment))
2962 for (ParenState &
Paren : State.Stack)
2963 Paren.BreakBeforeParameter =
true;
2965 if (Current.is(TT_BlockComment))
2966 State.NoContinuation =
true;
2968 State.Stack.back().LastSpace = StartColumn;
2971 Token->updateNextToken(State);
2973 return {Penalty, Exceeded};
2978 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2981bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2983 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
2988 if (Current.
TokenText.starts_with(
"R\""))
2992 if (Current.getNextNonComment() &&
2993 Current.getNextNonComment()->isStringLiteral()) {
2996 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
2998 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...