23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "format-indenter"
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
89 if (!
Tok.MatchingParen)
93 int MatchingStackIndex = Stack.size() - 1;
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].
Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
103 for (; End->
Next; End = End->
Next) {
106 if (!End->
Next->closesScope())
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
120 if (!
Tok.NextOperator)
122 return Tok.NextOperator->TotalLength -
Tok.TotalLength;
128 return Tok.isMemberAccess() &&
Tok.Previous &&
Tok.Previous->closesScope();
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
151 while (
Last->NextOperator)
153 return Last->OperatorIndex + 2;
179 const auto OperatorBreakStyle =
180 Style.BreakBinaryOperations.getStyleForOperator(OpToken->
Tok.
getKind());
185 const unsigned MinChain =
186 Style.BreakBinaryOperations.getMinChainLengthForOperator(
193 if (LessTok.
isNot(tok::less))
195 return Style.isTextProto() ||
213 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
214 if (LParenPos == StringRef::npos)
216 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
219 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
222 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
232 for (
const auto &Format : Style.RawStringFormats)
234 return StringRef(Format.CanonicalDelimiter);
241 std::optional<FormatStyle> LanguageStyle =
243 if (!LanguageStyle) {
246 RawStringFormat.Language, &PredefinedStyle)) {
248 PredefinedStyle.
Language = RawStringFormat.Language;
250 LanguageStyle = PredefinedStyle;
252 LanguageStyle->ColumnLimit = CodeStyle.
ColumnLimit;
253 for (StringRef Delimiter : RawStringFormat.Delimiters)
255 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)
260std::optional<FormatStyle>
268std::optional<FormatStyle>
270 StringRef EnclosingFunction)
const {
293 *
this = *
this + Spaces;
321 bool BinPackInconclusiveFunctions)
322 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
323 Whitespaces(Whitespaces), Encoding(Encoding),
324 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
325 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
328 unsigned FirstStartColumn,
333 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
334 State.Column = FirstStartColumn;
336 State.Column = FirstIndent;
346 State.NextToken =
Line->First;
347 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
350 State.NoContinuation =
false;
351 State.StartOfStringLiteral = 0;
352 State.NoLineBreak =
false;
353 State.StartOfLineLevel = 0;
354 State.LowestLevelOnLine = 0;
355 State.IgnoreStackForComparison =
false;
357 if (Style.isTextProto()) {
360 auto &CurrentState = State.Stack.back();
361 CurrentState.AvoidBinPacking =
true;
362 CurrentState.BreakBeforeParameter =
true;
363 CurrentState.AlignColons =
false;
367 moveStateToNextToken(State, DryRun,
false);
374 const auto &CurrentState = State.Stack.back();
376 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
377 Current.closesBlockOrBlockTypeList(Style))) {
385 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
394 State.LowestLevelOnLine < State.StartOfLineLevel &&
398 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
403 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
404 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
405 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
406 return Style.isCpp() &&
412 if (Current.
is(TT_FunctionDeclarationName)) {
419 assert(State.Column >= State.FirstIndent);
420 if (State.Column - State.FirstIndent < 6)
428 Current.isBlockIndentedInitRBrace(Style)) {
429 return CurrentState.BreakBeforeClosingBrace;
434 if ((Style.BreakBeforeCloseBracketFunction ||
435 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
436 Style.BreakBeforeCloseBracketSwitch) &&
437 Current.
is(tok::r_paren)) {
438 return CurrentState.BreakBeforeClosingParen;
441 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
442 return CurrentState.BreakBeforeClosingAngle;
446 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
450 (!Style.BraceWrapping.BeforeLambdaBody ||
451 Current.
isNot(TT_LambdaLBrace)) &&
453 (!Style.BraceWrapping.AfterRequiresExpression ||
454 Current.
isNot(TT_RequiresExpressionLBrace)) &&
455 CurrentState.NoLineBreakInOperand) {
462 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
464 Previous.MatchingParen->Previous->MatchingParen &&
465 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
467 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
471 return !State.NoLineBreak && !CurrentState.NoLineBreak;
477 const auto &CurrentState = State.Stack.back();
478 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
479 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
483 if (Style.BraceWrapping.AfterRequiresExpression && Current.
CanBreakBefore &&
484 Current.
is(TT_RequiresExpressionLBrace) &&
489 (Current.
is(TT_InlineASMColon) &&
492 Style.ColumnLimit > 0)))) {
495 if (CurrentState.BreakBeforeClosingBrace &&
496 (Current.closesBlockOrBlockTypeList(Style) ||
498 Current.isBlockIndentedInitRBrace(Style)))) {
501 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
503 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
506 Style.ObjCBreakBeforeNestedBlockParam &&
508 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
513 if (CurrentState.IsCSharpGenericTypeConstraint &&
514 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
518 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
519 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
527 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
529 (!Style.BreakBeforeTernaryOperators &&
530 Previous.is(TT_ConditionalExpr))) &&
531 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
532 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
535 if (CurrentState.IsChainedConditional &&
536 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
537 Current.
is(tok::colon)) ||
538 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
543 (
Previous.is(TT_ArrayInitializerLSquare) &&
546 Style.ColumnLimit > 0 &&
552 const FormatToken &BreakConstructorInitializersToken =
557 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
558 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
560 CurrentState.BreakBeforeParameter) &&
561 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
566 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
567 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
570 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
571 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
572 (Style.ObjCBreakBeforeNestedBlockParam ||
573 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
577 unsigned NewLineColumn = getNewLineColumn(State).Total;
578 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
580 (State.Column > NewLineColumn ||
586 (CurrentState.CallContinuation != 0 ||
587 CurrentState.BreakBeforeParameter) &&
593 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
594 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
600 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
605 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
608 if (Style.AlwaysBreakBeforeMultilineStrings &&
609 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
611 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
612 Keywords.kw_dollar) &&
613 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
614 nextIsMultilineString(State)) {
622 const auto PreviousPrecedence =
Previous.getPrecedence();
624 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
625 const bool LHSIsBinaryExpr =
638 const bool IsComparison =
643 Previous.Previous->isNot(TT_BinaryOperator);
649 CurrentState.BreakBeforeParameter) {
654 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
655 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
659 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
664 if (
Previous.ClosesTemplateDeclaration) {
665 if (Current.
is(tok::kw_concept)) {
666 switch (Style.BreakBeforeConceptDeclarations) {
675 if (Current.
is(TT_RequiresClause)) {
676 switch (Style.RequiresClausePosition) {
688 if (
Previous.is(TT_FunctionAnnotationRParen) &&
692 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
693 Current.
isNot(TT_LeadingJavaAnnotation)) {
698 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
702 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
704 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
708 if (Current.
is(TT_FunctionDeclarationName) &&
709 !State.Line->ReturnTypeWrapped &&
711 (!Style.isCSharp() ||
715 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
716 CurrentState.BreakBeforeParameter) {
718 if (
Tok->is(TT_LineComment))
720 if (
Tok->is(TT_TemplateCloser)) {
725 if (
Tok->FirstAfterPPLine)
737 Current.
isNoneOf(tok::r_brace, tok::comment)) {
741 if (Current.
is(tok::lessless) &&
744 Previous.TokenText ==
"\'\\n\'")))) {
751 if (State.NoContinuation)
759 unsigned ExtraSpaces) {
761 assert(State.NextToken->Previous);
764 assert(!State.Stack.empty());
765 State.NoContinuation =
false;
767 if (Current.
is(TT_ImplicitStringLiteral) &&
768 (!
Previous.Tok.getIdentifierInfo() ||
769 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
770 tok::pp_not_keyword)) {
776 State.Column = EndColumn;
778 unsigned StartColumn =
780 assert(EndColumn >= StartColumn);
781 State.Column += EndColumn - StartColumn;
783 moveStateToNextToken(State, DryRun,
false);
787 unsigned Penalty = 0;
789 Penalty = addTokenOnNewLine(State, DryRun);
791 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
793 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
796void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
797 unsigned ExtraSpaces) {
799 assert(State.NextToken->Previous);
801 auto &CurrentState = State.Stack.back();
808 auto DisallowLineBreaks = [&] {
809 if (!Style.isCpp() ||
818 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
821 const auto *Prev = Current.getPreviousNonComment();
822 if (!Prev || Prev->isNot(tok::l_paren))
825 if (Prev->BlockParameterCount == 0)
829 if (Prev->BlockParameterCount > 1)
836 const auto *Comma = Prev->
Role->lastComma();
840 const auto *
Next = Comma->getNextNonComment();
841 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
844 if (DisallowLineBreaks())
845 State.NoLineBreak =
true;
847 if (Current.
is(tok::equal) &&
848 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
849 CurrentState.VariablePos == 0 &&
851 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
852 CurrentState.VariablePos = State.Column;
855 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
856 CurrentState.VariablePos -=
Tok->ColumnWidth;
857 if (
Tok->SpacesRequiredBefore != 0)
861 if (
Previous.PartOfMultiVariableDeclStmt)
862 CurrentState.LastSpace = CurrentState.VariablePos;
868 int PPColumnCorrection = 0;
880 PPColumnCorrection = -1;
887 const bool ContinuePPDirective =
889 Whitespaces.replaceWhitespace(Current, 0, Spaces,
890 State.
Column + Spaces + PPColumnCorrection,
891 nullptr, ContinuePPDirective);
897 Current.
is(TT_InheritanceColon)) {
898 CurrentState.NoLineBreak =
true;
902 CurrentState.NoLineBreak =
true;
905 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
907 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
908 CurrentState.Indent.Total);
911 CurrentState.AlignColons =
false;
915 CurrentState.ColonPos = FirstColonPos;
923 auto IsStartOfBracedList = [&]() {
927 if (IsStartOfBracedList())
928 return Style.BreakAfterOpenBracketBracedList;
929 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
933 if (
Tok.Previous->isIf())
934 return Style.BreakAfterOpenBracketIf;
935 if (
Tok.Previous->isLoop(Style))
936 return Style.BreakAfterOpenBracketLoop;
937 if (
Tok.Previous->is(tok::kw_switch))
938 return Style.BreakAfterOpenBracketSwitch;
939 if (Style.BreakAfterOpenBracketFunction) {
940 return !
Tok.Previous->is(TT_CastRParen) &&
941 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
946 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
947 Tok.Previous->is(tok::identifier);
949 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
950 if (!Style.isJavaScript())
952 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
953 if (Prev->is(TT_TemplateString) && Prev->opensScope())
955 if (Prev->opensScope() && !NestBlocks)
957 if (Prev->is(TT_TemplateString) && Prev->closesScope())
963 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
964 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
966 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
973 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
975 if (
Tok.is(TT_UnaryOperator) ||
976 (Style.isJavaScript() &&
977 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
980 const auto *
Previous = TokAfterLParen.Previous;
984 Previous->Previous->is(tok::kw_switch))) {
987 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
988 TT_LambdaDefinitionLParen) &&
992 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
995 return !
Next ||
Next->isMemberAccess() ||
996 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
999 State.
Column > getNewLineColumn(State).Total &&
1010 !StartsSimpleOneArgList(Current)) {
1011 CurrentState.NoLineBreak =
true;
1015 CurrentState.NoLineBreak =
true;
1021 if (Style.AlignAfterOpenBracket &&
1022 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1023 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1024 TT_TableGenDAGArgOpener,
1025 TT_TableGenDAGArgOpenerToBreak) &&
1027 (Current.
isNot(TT_LineComment) ||
1030 Previous.is(TT_VerilogMultiLineListLParen)) &&
1031 !IsInTemplateString(Current,
false)) {
1032 CurrentState.Indent = State.
Column + Spaces;
1033 CurrentState.AlignedTo = &
Previous;
1036 CurrentState.NoLineBreak =
true;
1038 CurrentState.NoLineBreak =
true;
1041 State.
Column > getNewLineColumn(State).Total) {
1042 CurrentState.ContainsUnwrappedBuilder =
true;
1045 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1046 CurrentState.NoLineBreak =
true;
1047 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1056 CurrentState.NoLineBreak =
true;
1063 const FormatToken *P = Current.getPreviousNonComment();
1064 if (Current.
isNot(tok::comment) && P &&
1065 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1066 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1067 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1071 bool BreakBeforeOperator =
1072 P->MustBreakBefore || P->is(tok::lessless) ||
1073 (P->is(TT_BinaryOperator) &&
1075 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1079 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1080 P->isNot(TT_ConditionalExpr);
1081 if ((!BreakBeforeOperator &&
1084 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1085 CurrentState.NoLineBreakInOperand =
true;
1090 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1095 CurrentState.LastSpace = State.
Column;
1096 CurrentState.NestedBlockIndent = State.
Column;
1097 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1099 Previous.isNot(TT_OverloadedOperator)) ||
1101 CurrentState.LastSpace = State.
Column;
1102 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1104 Style.BreakConstructorInitializers ==
1106 CurrentState.Indent = State.
Column;
1107 CurrentState.LastSpace = State.
Column;
1108 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1109 CurrentState.LastSpace = State.
Column;
1110 }
else if (
Previous.is(TT_BinaryOperator) &&
1118 CurrentState.LastSpace = State.
Column;
1119 }
else if (
Previous.is(TT_InheritanceColon)) {
1120 CurrentState.Indent = State.
Column;
1121 CurrentState.LastSpace = State.
Column;
1122 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1123 CurrentState.ColonPos = State.
Column;
1124 }
else if (
Previous.opensScope()) {
1132 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1133 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1134 CurrentState.LastSpace = State.
Column;
1140unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1143 assert(State.NextToken->Previous);
1145 auto &CurrentState = State.Stack.back();
1149 unsigned Penalty = 0;
1151 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1153 if (!NextNonComment)
1154 NextNonComment = &Current;
1157 if (!CurrentState.ContainsLineBreak)
1159 CurrentState.ContainsLineBreak =
true;
1161 Penalty += State.NextToken->SplitPenalty;
1166 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1167 (State.Column <= Style.ColumnLimit / 3 ||
1168 CurrentState.BreakBeforeParameter)) {
1169 Penalty += Style.PenaltyBreakFirstLessLess;
1172 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1173 State.Column = TotalColumn;
1187 if (State.Column > State.FirstIndent) {
1189 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1202 if (Current.isNot(TT_LambdaArrow) &&
1203 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1204 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1205 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1206 CurrentState.NestedBlockIndent = State.Column;
1209 if (NextNonComment->isMemberAccess()) {
1210 if (CurrentState.CallContinuation == 0)
1211 CurrentState.CallContinuation = State.Column;
1212 }
else if (NextNonComment->is(TT_SelectorName)) {
1213 if (!CurrentState.ObjCSelectorNameFound) {
1214 if (NextNonComment->LongestObjCSelectorName == 0) {
1215 CurrentState.AlignColons =
false;
1217 CurrentState.ColonPos =
1219 ? std::max(CurrentState.Indent.Total,
1220 State.FirstIndent + Style.ContinuationIndentWidth)
1221 : CurrentState.
Indent.Total) +
1225 }
else if (CurrentState.AlignColons &&
1226 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1227 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1229 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1230 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1240 if (State.Stack.size() > 1) {
1241 State.Stack[State.Stack.size() - 2].LastSpace =
1242 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1243 Style.ContinuationIndentWidth;
1247 switch (Style.BreakInheritanceList) {
1250 if (Current.is(TT_InheritanceColon) ||
Previous.is(TT_InheritanceComma)) {
1251 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1252 tok::kw_class, tok::kw_struct, tok::kw_union);
1256 if (Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma)) {
1257 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1258 tok::kw_class, tok::kw_struct, tok::kw_union);
1262 if (
Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma))
1263 CurrentState.AlignedTo = &
Previous;
1267 if ((PreviousNonComment &&
1268 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1269 !CurrentState.AvoidBinPacking) ||
1271 CurrentState.BreakBeforeParameter =
false;
1273 if (PreviousNonComment &&
1274 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1275 PreviousNonComment->ClosesRequiresClause) &&
1276 Current.NestingLevel == 0) {
1277 CurrentState.BreakBeforeParameter =
false;
1279 if (NextNonComment->is(tok::question) ||
1280 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1281 CurrentState.BreakBeforeParameter =
true;
1283 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1284 CurrentState.BreakBeforeParameter =
false;
1285 CurrentState.AlignedTo = &Current;
1288 Current.is(TT_ConditionalExpr)) {
1289 switch (Style.AlignOperands) {
1291 CurrentState.AlignedTo = Current.is(tok::question)
1292 ? Current.getPrevious(tok::equal)
1293 : Current.getPrevious(tok::question);
1296 if (Current.is(tok::colon))
1297 CurrentState.AlignedTo = Current.getPrevious(tok::question);
1305 unsigned MaxEmptyLinesToKeep = Style.MaxEmptyLinesToKeep + 1;
1306 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1309 !Current.MatchingParen->Children.empty()) {
1313 MaxEmptyLinesToKeep = 1;
1316 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1317 const bool ContinuePPDirective = State.Line->InPPDirective &&
1319 Current.isNot(TT_LineComment);
1320 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1321 CurrentState.AlignedTo, ContinuePPDirective,
1322 IndentedFromColumn);
1325 if (!Current.isTrailingComment())
1326 CurrentState.LastSpace = State.Column;
1327 if (Current.is(tok::lessless)) {
1331 CurrentState.LastSpace += 3;
1334 State.StartOfLineLevel = Current.NestingLevel;
1335 State.LowestLevelOnLine = Current.NestingLevel;
1339 bool NestedBlockSpecialCase =
1340 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1341 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1343 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1345 NestedBlockSpecialCase =
1346 NestedBlockSpecialCase ||
1347 (Current.MatchingParen &&
1348 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1349 if (!NestedBlockSpecialCase) {
1350 auto ParentLevelIt = std::next(State.Stack.rbegin());
1352 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1367 auto FindCurrentLevel = [&](
const auto &It) {
1368 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1369 return PState.Tok != nullptr;
1372 auto MaybeIncrement = [&](
const auto &It) {
1373 return It != State.Stack.rend() ? std::next(It) : It;
1375 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1376 auto LevelContainingLambdaIt =
1377 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1378 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1380 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1381 I->BreakBeforeParameter =
true;
1384 if (PreviousNonComment &&
1385 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1386 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1387 !PreviousNonComment->ClosesRequiresClause) ||
1388 Current.NestingLevel != 0) &&
1389 PreviousNonComment->isNoneOf(
1390 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1391 TT_LeadingJavaAnnotation) &&
1392 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1395 (!Style.BraceWrapping.BeforeLambdaBody ||
1396 Current.isNot(TT_LambdaLBrace))) {
1397 CurrentState.BreakBeforeParameter =
true;
1402 if (PreviousNonComment &&
1403 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1405 CurrentState.BreakBeforeClosingBrace =
true;
1408 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1409 if (
auto Previous = PreviousNonComment->Previous) {
1411 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1412 }
else if (
Previous->isLoop(Style)) {
1413 CurrentState.BreakBeforeClosingParen =
1414 Style.BreakBeforeCloseBracketLoop;
1415 }
else if (
Previous->is(tok::kw_switch)) {
1416 CurrentState.BreakBeforeClosingParen =
1417 Style.BreakBeforeCloseBracketSwitch;
1419 CurrentState.BreakBeforeClosingParen =
1420 Style.BreakBeforeCloseBracketFunction;
1425 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1426 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1428 if (CurrentState.AvoidBinPacking) {
1433 bool PreviousIsBreakingCtorInitializerColon =
1434 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1436 bool AllowAllConstructorInitializersOnNextLine =
1439 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1440 !PreviousIsBreakingCtorInitializerColon) ||
1441 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1442 State.Line->MustBeDeclaration) ||
1443 (!Style.AllowAllArgumentsOnNextLine &&
1444 !State.Line->MustBeDeclaration) ||
1445 (!AllowAllConstructorInitializersOnNextLine &&
1446 PreviousIsBreakingCtorInitializerColon) ||
1448 CurrentState.BreakBeforeParameter =
true;
1454 if (PreviousIsBreakingCtorInitializerColon &&
1455 AllowAllConstructorInitializersOnNextLine) {
1456 CurrentState.BreakBeforeParameter =
false;
1461 CurrentState.BreakBeforeParameter =
true;
1467ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1468 if (!State.NextToken || !State.NextToken->Previous)
1472 const auto &CurrentState = State.Stack.back();
1474 if (CurrentState.IsCSharpGenericTypeConstraint &&
1475 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1476 return CurrentState.ColonPos + 2;
1481 const auto ContinuationIndent =
1482 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1483 CurrentState.Indent) +
1484 Style.ContinuationIndentWidth;
1485 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1487 if (!NextNonComment)
1488 NextNonComment = &Current;
1491 if (Style.isJava() &&
1492 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1493 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1494 CurrentState.Indent + Style.ContinuationIndentWidth);
1499 if (Style.isVerilog() && PreviousNonComment &&
1500 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1501 return State.FirstIndent;
1505 State.Line->First->is(tok::kw_enum)) {
1506 return IndentationAndAlignment(Style.IndentWidth *
1507 State.Line->First->IndentLevel) +
1511 if (Style.BraceWrapping.BeforeLambdaBody &&
1512 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1514 ? CurrentState.Indent
1515 : State.FirstIndent;
1516 return From + Style.IndentWidth;
1521 if (Style.BraceWrapping.AfterRequiresExpression &&
1522 Current.is(TT_RequiresExpressionLBrace)) {
1523 return CurrentState.NestedBlockIndent;
1526 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1527 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1528 if (Current.NestingLevel == 0 ||
1530 State.NextToken->is(TT_LambdaLBrace))) {
1531 return State.FirstIndent;
1533 return CurrentState.Indent;
1535 if (Current.is(TT_LambdaArrow) &&
1536 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1537 tok::kw_consteval, tok::kw_static,
1538 TT_AttributeRSquare)) {
1539 return ContinuationIndent;
1541 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1542 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1543 State.Stack.size() > 1) {
1544 if (Current.closesBlockOrBlockTypeList(Style))
1545 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1546 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit)) {
1556 if ((State.Stack.size() == 2 &&
1557 Current.MatchingParen->getPreviousNonComment() &&
1558 Current.MatchingParen->getPreviousNonComment()->is(
1560 (State.Stack.size() == 3 &&
1562 return State.FirstIndent;
1564 return State.Stack[State.Stack.size() - 2].LastSpace;
1566 return State.FirstIndent;
1583 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1585 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1586 return State.Stack[State.Stack.size() - 2].LastSpace;
1590 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1591 State.Stack.size() > 1) {
1592 return State.Stack[State.Stack.size() - 2].LastSpace;
1594 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1595 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1596 State.Stack.size() > 1) {
1597 return State.Stack[State.Stack.size() - 2].LastSpace;
1599 if ((Style.BreakBeforeCloseBracketFunction ||
1600 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1601 Style.BreakBeforeCloseBracketSwitch) &&
1602 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1603 return State.Stack[State.Stack.size() - 2].LastSpace;
1605 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1606 State.Stack.size() > 1) {
1607 return State.Stack[State.Stack.size() - 2].LastSpace;
1609 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1610 return State.Stack[State.Stack.size() - 2].LastSpace;
1618 if (Current.is(tok::identifier) && Current.Next &&
1619 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1620 (Current.Next->is(TT_DictLiteral) ||
1621 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1622 return CurrentState.Indent;
1624 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1625 State.StartOfStringLiteral != 0) {
1626 return State.StartOfStringLiteral - 1;
1628 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1629 return State.StartOfStringLiteral;
1630 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1631 return CurrentState.FirstLessLess;
1632 if (NextNonComment->isMemberAccess()) {
1633 if (CurrentState.CallContinuation == 0)
1634 return ContinuationIndent;
1635 return CurrentState.CallContinuation;
1637 if (CurrentState.QuestionColumn != 0 &&
1638 ((NextNonComment->is(tok::colon) &&
1639 NextNonComment->is(TT_ConditionalExpr)) ||
1640 Previous.is(TT_ConditionalExpr))) {
1641 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1642 !NextNonComment->Next->FakeLParens.empty() &&
1644 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1646 !CurrentState.IsWrappedConditional) {
1651 unsigned Indent = CurrentState.Indent.Total;
1653 Indent -= Style.ContinuationIndentWidth;
1654 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1658 return CurrentState.QuestionColumn;
1660 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1661 return CurrentState.VariablePos;
1662 if (Current.is(TT_RequiresClause)) {
1663 if (Style.IndentRequiresClause)
1664 return CurrentState.Indent + Style.IndentWidth;
1665 switch (Style.RequiresClausePosition) {
1669 return CurrentState.Indent;
1674 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1675 TT_InheritanceComma)) {
1676 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1678 if ((PreviousNonComment &&
1679 (PreviousNonComment->ClosesTemplateDeclaration ||
1680 PreviousNonComment->ClosesRequiresClause ||
1681 (PreviousNonComment->is(TT_AttributeMacro) &&
1682 Current.isNot(tok::l_paren) &&
1683 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1684 TT_PointerOrReference)) ||
1685 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1686 TT_FunctionAnnotationRParen,
1688 TT_LeadingJavaAnnotation))) ||
1689 (!Style.IndentWrappedFunctionNames &&
1690 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)) ||
1691 (State.Line->ReturnTypeWrapped && PreviousNonComment &&
1693 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1694 CurrentState.Indent);
1696 if (NextNonComment->is(TT_SelectorName)) {
1697 if (!CurrentState.ObjCSelectorNameFound) {
1698 auto MinIndent = CurrentState.Indent;
1701 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1702 Style.ContinuationIndentWidth);
1713 return MinIndent.addPadding(
1714 std::max(NextNonComment->LongestObjCSelectorName,
1715 NextNonComment->ColumnWidth) -
1716 NextNonComment->ColumnWidth);
1718 if (!CurrentState.AlignColons)
1719 return CurrentState.Indent;
1720 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1721 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1722 return CurrentState.Indent;
1724 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1725 return CurrentState.ColonPos;
1726 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1727 if (CurrentState.StartOfArraySubscripts != 0) {
1728 return CurrentState.StartOfArraySubscripts;
1729 }
else if (Style.isCSharp()) {
1731 return CurrentState.Indent;
1733 return ContinuationIndent;
1738 if (State.Line->InPragmaDirective) {
1739 FormatToken *PragmaType = State.Line->First->Next->Next;
1740 if (PragmaType && PragmaType->TokenText ==
"omp")
1741 return CurrentState.Indent + Style.ContinuationIndentWidth;
1746 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1747 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1748 return CurrentState.Indent;
1751 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1752 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1753 return ContinuationIndent;
1755 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1756 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1757 return ContinuationIndent;
1759 if (NextNonComment->is(TT_CtorInitializerComma))
1760 return CurrentState.Indent;
1761 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1763 return CurrentState.Indent;
1765 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1767 return CurrentState.Indent;
1770 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1771 !Current.isBinaryOperator() &&
1772 Current.isNoneOf(tok::colon, tok::comment)) {
1773 return ContinuationIndent;
1775 if (Current.is(TT_ProtoExtensionLSquare))
1776 return CurrentState.Indent;
1777 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1778 return CurrentState.Indent - Current.Tok.getLength() -
1779 Current.SpacesRequiredBefore;
1781 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1782 CurrentState.UnindentOperator) {
1783 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1784 NextNonComment->SpacesRequiredBefore;
1786 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1787 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1790 return CurrentState.Indent + Style.ContinuationIndentWidth;
1792 return CurrentState.Indent;
1804 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1807unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1808 bool DryRun,
bool Newline) {
1809 assert(State.Stack.size());
1811 auto &CurrentState = State.Stack.back();
1813 if (Current.is(TT_CSharpGenericTypeConstraint))
1814 CurrentState.IsCSharpGenericTypeConstraint =
true;
1815 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1816 CurrentState.NoLineBreakInOperand =
false;
1817 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1818 CurrentState.AvoidBinPacking =
true;
1819 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1820 if (CurrentState.FirstLessLess == 0)
1821 CurrentState.FirstLessLess = State.Column;
1823 CurrentState.LastOperatorWrapped = Newline;
1825 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1826 CurrentState.LastOperatorWrapped = Newline;
1827 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1828 Current.Previous->isNot(TT_ConditionalExpr)) {
1829 CurrentState.LastOperatorWrapped = Newline;
1831 if (Current.is(TT_ArraySubscriptLSquare) &&
1832 CurrentState.StartOfArraySubscripts == 0) {
1833 CurrentState.StartOfArraySubscripts = State.Column;
1837 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1839 if (
Tok.MustBreakBefore)
1843 return Next &&
Next->MustBreakBefore;
1845 if (IsWrappedConditional(Current))
1846 CurrentState.IsWrappedConditional =
true;
1847 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1848 CurrentState.QuestionColumn = State.Column;
1849 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1854 CurrentState.QuestionColumn = State.Column;
1856 if (!Current.opensScope() && !Current.closesScope() &&
1857 Current.isNot(TT_PointerOrReference)) {
1858 State.LowestLevelOnLine =
1859 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1861 if (Current.isMemberAccess())
1862 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1863 if (Current.is(TT_SelectorName))
1864 CurrentState.ObjCSelectorNameFound =
true;
1865 if (Current.is(TT_CtorInitializerColon) &&
1872 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1876 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1878 CurrentState.AvoidBinPacking =
true;
1879 CurrentState.BreakBeforeParameter =
1880 Style.ColumnLimit > 0 &&
1884 CurrentState.BreakBeforeParameter =
false;
1887 if (Current.is(TT_CtorInitializerColon) &&
1889 CurrentState.Indent =
1890 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1891 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1893 CurrentState.AvoidBinPacking =
true;
1895 CurrentState.BreakBeforeParameter =
false;
1897 if (Current.is(TT_InheritanceColon)) {
1898 CurrentState.Indent =
1899 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1901 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1902 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1903 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1904 CurrentState.LastSpace = State.Column;
1905 if (Current.is(TT_RequiresExpression) &&
1907 CurrentState.NestedBlockIndent = State.Column;
1919 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1921 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1922 !CurrentState.HasMultipleNestedBlocks) {
1923 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1924 for (ParenState &PState : llvm::drop_end(State.Stack))
1925 PState.NoLineBreak =
true;
1926 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1928 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1929 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1930 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1931 TT_CtorInitializerColon)))) {
1932 CurrentState.NestedBlockInlined =
1936 moveStatePastFakeLParens(State, Newline);
1937 moveStatePastScopeCloser(State);
1940 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1941 !State.Stack.back().NoLineBreakInOperand;
1942 moveStatePastScopeOpener(State, Newline);
1943 moveStatePastFakeRParens(State);
1945 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1946 State.StartOfStringLiteral = State.Column + 1;
1947 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1948 State.StartOfStringLiteral = State.Column + 1;
1949 }
else if (Current.is(TT_TableGenMultiLineString) &&
1950 State.StartOfStringLiteral == 0) {
1951 State.StartOfStringLiteral = State.Column + 1;
1952 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1953 State.StartOfStringLiteral = State.Column;
1954 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1955 !Current.isStringLiteral()) {
1956 State.StartOfStringLiteral = 0;
1959 State.Column += Current.ColumnWidth;
1960 State.NextToken = State.NextToken->Next;
1965 if (Style.isVerilog() && State.NextToken &&
1966 State.NextToken->MustBreakBefore &&
1967 Keywords.isVerilogEndOfLabel(Current)) {
1968 State.FirstIndent += Style.IndentWidth;
1969 CurrentState.Indent = State.FirstIndent;
1973 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1976 Current.Role->formatFromToken(State,
this, DryRun);
1983 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1988void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1991 if (Current.FakeLParens.empty())
1999 bool SkipFirstExtraIndent =
2002 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
2006 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
2007 const auto &CurrentState = State.Stack.back();
2008 ParenState NewParenState = CurrentState;
2009 NewParenState.Tok =
nullptr;
2010 NewParenState.ContainsLineBreak =
false;
2011 NewParenState.LastOperatorWrapped =
true;
2012 NewParenState.IsChainedConditional =
false;
2013 NewParenState.IsWrappedConditional =
false;
2014 NewParenState.UnindentOperator =
false;
2015 NewParenState.NoLineBreak =
2016 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
2017 NewParenState.Precedence = PrecedenceLevel;
2021 NewParenState.AvoidBinPacking =
false;
2026 if (!Current.isTrailingComment() &&
2030 (!Style.isJava() && PrecedenceLevel > 0)) &&
2031 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
2032 Current.NestingLevel == 0) &&
2033 (!Style.isTableGen() ||
2035 TT_TableGenDAGArgListCommaToBreak)))) {
2036 NewParenState.Indent =
2037 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
2038 IndentationAndAlignment(CurrentState.LastSpace)});
2045 State.Stack.size() > 1) {
2046 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
2047 Style.ContinuationIndentWidth;
2058 NewParenState.UnindentOperator =
true;
2061 NewParenState.AlignedTo =
Previous;
2071 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2073 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2074 NewParenState.StartOfFunctionCall = State.Column;
2084 &PrecedenceLevel == &Current.FakeLParens.back() &&
2085 !CurrentState.IsWrappedConditional) {
2086 NewParenState.IsChainedConditional =
true;
2087 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2090 !Current.isTrailingComment())) {
2091 NewParenState.Indent += Style.ContinuationIndentWidth;
2094 NewParenState.BreakBeforeParameter =
false;
2095 State.Stack.push_back(NewParenState);
2096 SkipFirstExtraIndent =
false;
2100void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2101 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2102 unsigned VariablePos = State.Stack.back().VariablePos;
2103 if (State.Stack.size() == 1) {
2107 State.Stack.pop_back();
2108 State.Stack.back().VariablePos = VariablePos;
2111 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2114 State.Stack.back().LastSpace -= Style.IndentWidth;
2118void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2121 if (!Current.opensScope())
2124 const auto &CurrentState = State.Stack.back();
2127 if (Current.isOneOf(tok::less, tok::l_paren) &&
2128 CurrentState.IsCSharpGenericTypeConstraint) {
2132 if (Current.MatchingParen && Current.is(
BK_Block)) {
2133 moveStateToNewBlock(State, Newline);
2140 const auto *Prev =
Tok->getPreviousNonComment();
2143 return Prev->is(tok::comma);
2144 }(Current.MatchingParen);
2146 IndentationAndAlignment NewIndent = 0;
2147 unsigned LastSpace = CurrentState.LastSpace;
2148 bool AvoidBinPacking;
2149 bool BreakBeforeParameter =
false;
2150 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2151 CurrentState.NestedBlockIndent);
2152 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2154 if (Current.opensBlockOrBlockTypeList(Style)) {
2155 NewIndent = Style.IndentWidth +
2156 std::min(State.Column, CurrentState.NestedBlockIndent);
2157 }
else if (Current.is(tok::l_brace)) {
2158 const auto Width = Style.BracedInitializerIndentWidth;
2159 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2160 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2162 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2164 const FormatToken *NextNonComment = Current.getNextNonComment();
2166 EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() ||
2169 NextNonComment->isOneOf(TT_DesignatedInitializerPeriod,
2170 TT_DesignatedInitializerLSquare));
2171 BreakBeforeParameter = EndsInComma;
2172 if (Current.ParameterCount > 1)
2173 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2175 NewIndent = IndentationAndAlignment(std::max(
2176 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2177 Style.ContinuationIndentWidth;
2179 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2186 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2187 NewIndent = State.Column +
Next->TokenText.size() + 2;
2194 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2195 NewIndent = std::max(NewIndent, CurrentState.Indent);
2196 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2201 bool ObjCBinPackProtocolList =
2207 bool BinPackDeclaration =
2211 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
2213 bool GenericSelection =
2214 Current.getPreviousNonComment() &&
2215 Current.getPreviousNonComment()->is(tok::kw__Generic);
2218 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2219 (Style.isJavaScript() && EndsInComma) ||
2220 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2221 (!State.Line->MustBeDeclaration &&
2223 (Style.ExperimentalAutoDetectBinPacking &&
2227 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2228 Style.ObjCBreakBeforeNestedBlockParam) {
2229 if (Style.ColumnLimit) {
2234 BreakBeforeParameter =
true;
2240 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2241 if (
Tok->MustBreakBefore ||
2242 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2243 BreakBeforeParameter =
true;
2250 if (Style.isJavaScript() && EndsInComma)
2251 BreakBeforeParameter =
true;
2257 Current.Children.empty() &&
2258 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2259 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2260 (Current.is(TT_TemplateOpener) &&
2261 CurrentState.ContainsUnwrappedBuilder));
2262 State.Stack.push_back(
2263 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2264 auto &NewState = State.Stack.back();
2265 NewState.NestedBlockIndent = NestedBlockIndent;
2266 NewState.BreakBeforeParameter = BreakBeforeParameter;
2267 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2269 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2270 Current.is(tok::l_paren)) {
2274 if (next->is(TT_LambdaLSquare)) {
2275 NewState.HasMultipleNestedBlocks =
true;
2282 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2284 Current.Previous->is(tok::at);
2287void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2289 if (!Current.closesScope())
2294 if (State.Stack.size() > 1 &&
2295 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2296 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2297 State.NextToken->is(TT_TemplateCloser) ||
2298 State.NextToken->is(TT_TableGenListCloser) ||
2299 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2300 State.Stack.pop_back();
2303 auto &CurrentState = State.Stack.back();
2315 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2316 Current.MatchingParen->Previous) {
2317 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2318 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2319 CurrentScopeOpener.MatchingParen) {
2320 int NecessarySpaceInLine =
2322 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2323 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2324 Style.ColumnLimit) {
2325 CurrentState.BreakBeforeParameter =
false;
2330 if (Current.is(tok::r_square)) {
2332 const FormatToken *NextNonComment = Current.getNextNonComment();
2333 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2334 CurrentState.StartOfArraySubscripts = 0;
2338void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2340 State.NextToken->is(TT_LambdaLBrace) &&
2341 !State.Line->MightBeFunctionDecl) {
2342 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2343 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2345 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2347 unsigned NewIndent =
2348 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2349 ? Style.ObjCBlockIndentWidth
2350 : Style.IndentWidth);
2357 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2358 State.NextToken->is(TT_LambdaLBrace);
2360 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2361 State.Stack.back().LastSpace,
2362 true, NoLineBreak));
2363 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2364 State.Stack.back().BreakBeforeParameter =
true;
2370 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2371 if (LastNewlinePos == StringRef::npos) {
2372 return StartColumn +
2376 0, TabWidth, Encoding);
2380unsigned ContinuationIndenter::reformatRawStringLiteral(
2382 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2383 unsigned StartColumn = State.Column - Current.ColumnWidth;
2385 StringRef NewDelimiter =
2387 if (NewDelimiter.empty())
2388 NewDelimiter = OldDelimiter;
2391 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2392 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2395 std::string RawText = std::string(
2396 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2397 if (NewDelimiter != OldDelimiter) {
2400 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2401 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2402 NewDelimiter = OldDelimiter;
2405 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2406 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2409 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2420 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2442 unsigned CurrentIndent =
2443 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2444 ? State.Stack.back().NestedBlockIndent
2445 : State.Stack.back().Indent.Total;
2446 unsigned NextStartColumn = ContentStartsOnNewline
2447 ? CurrentIndent + Style.IndentWidth
2458 unsigned LastStartColumn =
2459 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2462 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2463 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2468 return addMultilineToken(Current, State);
2470 if (NewDelimiter != OldDelimiter) {
2473 SourceLocation PrefixDelimiterStart =
2474 Current.Tok.getLocation().getLocWithOffset(2);
2475 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2476 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2479 <<
"Failed to update the prefix delimiter of a raw string: "
2480 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2484 SourceLocation SuffixDelimiterStart =
2485 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2486 1 - OldDelimiter.size());
2487 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2488 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2491 <<
"Failed to update the suffix delimiter of a raw string: "
2492 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2495 SourceLocation OriginLoc =
2496 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2497 for (
const tooling::Replacement &Fix : Fixes.first) {
2498 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2499 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2500 Fix.getLength(), Fix.getReplacementText()));
2502 llvm::errs() <<
"Failed to reformat raw string: "
2503 << llvm::toString(std::move(Err)) <<
"\n";
2508 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2509 State.Column = RawLastLineEndColumn + NewSuffixSize;
2513 unsigned PrefixExcessCharacters =
2514 StartColumn + NewPrefixSize > Style.ColumnLimit
2515 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2518 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2521 for (ParenState &
Paren : State.Stack)
2522 Paren.BreakBeforeParameter =
true;
2524 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2527unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2530 for (ParenState &
Paren : State.Stack)
2531 Paren.BreakBeforeParameter =
true;
2533 unsigned ColumnsUsed = State.Column;
2536 State.Column = Current.LastLineColumnWidth;
2539 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2543unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2545 bool AllowBreak,
bool Newline) {
2546 unsigned Penalty = 0;
2549 auto RawStringStyle = getRawStringStyle(Current, State);
2550 if (RawStringStyle && !Current.Finalized) {
2551 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2553 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2556 Penalty = addMultilineToken(Current, State);
2559 LineState OriginalState = State;
2563 bool Strict =
false;
2566 bool Exceeded =
false;
2567 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2568 Current, State, AllowBreak,
true, Strict);
2572 LineState StrictState = OriginalState;
2573 unsigned StrictPenalty =
2574 breakProtrudingToken(Current, StrictState, AllowBreak,
2577 Strict = StrictPenalty <= Penalty;
2579 Penalty = StrictPenalty;
2580 State = std::move(StrictState);
2586 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2591 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2592 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2601 auto Tok = Current.getPreviousNonComment();
2602 if (!
Tok ||
Tok->isNot(tok::l_paren))
2604 Tok =
Tok->getPreviousNonComment();
2607 if (
Tok->is(TT_TemplateCloser)) {
2608 Tok =
Tok->MatchingParen;
2610 Tok =
Tok->getPreviousNonComment();
2612 if (!
Tok ||
Tok->isNot(tok::identifier))
2614 return Tok->TokenText;
2617std::optional<FormatStyle>
2618ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2619 const LineState &State) {
2620 if (!Current.isStringLiteral())
2621 return std::nullopt;
2624 return std::nullopt;
2626 if (!RawStringStyle && Delimiter->empty()) {
2630 if (!RawStringStyle)
2631 return std::nullopt;
2633 return RawStringStyle;
2636std::unique_ptr<BreakableToken>
2637ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2639 unsigned StartColumn = State.Column - Current.ColumnWidth;
2640 if (Current.isStringLiteral()) {
2643 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2657 if (Current.IsUnterminatedLiteral)
2661 if (State.Stack.back().IsInsideObjCArrayLiteral)
2668 if (Style.isVerilog() && Current.Previous &&
2669 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2672 StringRef
Text = Current.TokenText;
2682 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2685 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2686 Text.ends_with(
"'")) {
2688 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2689 Text.ends_with(
"\"")) {
2691 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2696 return std::make_unique<BreakableStringLiteralUsingOperators>(
2697 Current, QuoteStyle,
2708 if ((
Text.ends_with(Postfix =
"\"") &&
2709 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2710 Text.starts_with(Prefix =
"u\"") ||
2711 Text.starts_with(Prefix =
"U\"") ||
2712 Text.starts_with(Prefix =
"u8\"") ||
2713 Text.starts_with(Prefix =
"L\""))) ||
2714 (
Text.starts_with(Prefix =
"_T(\"") &&
2715 Text.ends_with(Postfix =
"\")"))) {
2716 return std::make_unique<BreakableStringLiteral>(
2718 State.Line->InPPDirective, Encoding, Style);
2720 }
else if (Current.is(TT_BlockComment)) {
2728 return std::make_unique<BreakableBlockComment>(
2729 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2730 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2731 }
else if (Current.is(TT_LineComment) &&
2732 (!Current.Previous ||
2733 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2734 bool RegularComments = [&]() {
2735 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2737 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2743 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2747 return std::make_unique<BreakableLineCommentSection>(
2748 Current, StartColumn,
false, Encoding, Style);
2753std::pair<unsigned, bool>
2754ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2756 bool DryRun,
bool Strict) {
2757 std::unique_ptr<const BreakableToken> Token =
2758 createBreakableToken(Current, State, AllowBreak);
2761 assert(Token->getLineCount() > 0);
2763 if (Current.is(TT_LineComment)) {
2765 ColumnLimit = Style.ColumnLimit;
2767 if (ColumnLimit == 0) {
2770 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2772 if (Current.UnbreakableTailLength >= ColumnLimit)
2776 unsigned StartColumn = State.Column - Current.ColumnWidth;
2777 unsigned NewBreakPenalty = Current.isStringLiteral()
2778 ? Style.PenaltyBreakString
2779 : Style.PenaltyBreakComment;
2782 bool Exceeded =
false;
2784 bool BreakInserted = Token->introducesBreakBeforeToken();
2787 bool NewBreakBefore =
false;
2791 bool Reflow =
false;
2794 unsigned TailOffset = 0;
2796 unsigned ContentStartColumn =
2797 Token->getContentStartColumn(0,
false);
2799 unsigned RemainingTokenColumns =
2800 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2803 Token->adaptStartOfLine(0, Whitespaces);
2805 unsigned ContentIndent = 0;
2806 unsigned Penalty = 0;
2807 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2808 << StartColumn <<
".\n");
2809 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2810 LineIndex != EndIndex; ++LineIndex) {
2811 LLVM_DEBUG(llvm::dbgs()
2812 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2813 NewBreakBefore =
false;
2817 bool TryReflow = Reflow;
2819 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2820 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2821 << (ContentStartColumn + RemainingTokenColumns)
2822 <<
", space: " << ColumnLimit
2823 <<
", reflown prefix: " << ContentStartColumn
2824 <<
", offset in line: " << TailOffset <<
"\n");
2830 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2831 ContentStartColumn, CommentPragmasRegex);
2832 if (
Split.first == StringRef::npos) {
2835 if (LineIndex < EndIndex - 1) {
2838 Penalty += Style.PenaltyExcessCharacter *
2839 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2841 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2844 assert(
Split.first != 0);
2846 if (Token->supportsReflow()) {
2866 unsigned ToSplitColumns = Token->getRangeLength(
2867 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2868 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2871 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2872 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2875 unsigned ToNextSplitColumns = 0;
2876 if (NextSplit.first == StringRef::npos) {
2877 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2878 ContentStartColumn);
2880 ToNextSplitColumns = Token->getRangeLength(
2881 LineIndex, TailOffset,
2882 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2886 ToNextSplitColumns =
2887 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2888 LLVM_DEBUG(llvm::dbgs()
2889 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2890 LLVM_DEBUG(llvm::dbgs()
2891 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2894 bool ContinueOnLine =
2895 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2896 unsigned ExcessCharactersPenalty = 0;
2897 if (!ContinueOnLine && !Strict) {
2900 ExcessCharactersPenalty =
2901 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2902 Style.PenaltyExcessCharacter;
2903 LLVM_DEBUG(llvm::dbgs()
2904 <<
" Penalty excess: " << ExcessCharactersPenalty
2905 <<
"\n break : " << NewBreakPenalty <<
"\n");
2906 if (ExcessCharactersPenalty < NewBreakPenalty) {
2908 ContinueOnLine =
true;
2911 if (ContinueOnLine) {
2912 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2917 Token->compressWhitespace(LineIndex, TailOffset, Split,
2921 ContentStartColumn += ToSplitColumns + 1;
2922 Penalty += ExcessCharactersPenalty;
2924 RemainingTokenColumns = Token->getRemainingLength(
2925 LineIndex, TailOffset, ContentStartColumn);
2929 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2934 ContentIndent = Token->getContentIndent(LineIndex);
2935 LLVM_DEBUG(llvm::dbgs()
2936 <<
" ContentIndent: " << ContentIndent <<
"\n");
2937 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2940 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2941 LineIndex, TailOffset +
Split.first +
Split.second,
2942 ContentStartColumn);
2943 if (NewRemainingTokenColumns == 0) {
2946 ContentStartColumn =
2947 Token->getContentStartColumn(LineIndex,
true);
2948 NewRemainingTokenColumns = Token->getRemainingLength(
2949 LineIndex, TailOffset +
Split.first +
Split.second,
2950 ContentStartColumn);
2956 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2961 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2962 <<
", " <<
Split.second <<
"\n");
2964 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2968 Penalty += NewBreakPenalty;
2970 RemainingTokenColumns = NewRemainingTokenColumns;
2971 BreakInserted =
true;
2972 NewBreakBefore =
true;
2976 if (LineIndex + 1 != EndIndex) {
2977 unsigned NextLineIndex = LineIndex + 1;
2978 if (NewBreakBefore) {
2997 ContentStartColumn += RemainingTokenColumns + 1;
3002 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
3003 LLVM_DEBUG(llvm::dbgs()
3004 <<
" Size of reflown text: " << ContentStartColumn
3005 <<
"\n Potential reflow split: ");
3006 if (SplitBeforeNext.first != StringRef::npos) {
3007 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
3008 << SplitBeforeNext.second <<
"\n");
3009 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
3012 RemainingTokenColumns = Token->getRemainingLength(
3013 NextLineIndex, TailOffset, ContentStartColumn);
3015 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
3016 LLVM_DEBUG(llvm::dbgs()
3017 <<
" Over limit after reflow, need: "
3018 << (ContentStartColumn + RemainingTokenColumns)
3019 <<
", space: " << ColumnLimit
3020 <<
", reflown prefix: " << ContentStartColumn
3021 <<
", offset in line: " << TailOffset <<
"\n");
3027 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
3028 ContentStartColumn, CommentPragmasRegex);
3029 if (
Split.first == StringRef::npos) {
3030 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
3036 unsigned ToSplitColumns = Token->getRangeLength(
3037 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
3038 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
3039 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
3040 << (ContentStartColumn + ToSplitColumns)
3041 <<
", space: " << ColumnLimit);
3042 unsigned ExcessCharactersPenalty =
3043 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
3044 Style.PenaltyExcessCharacter;
3045 if (NewBreakPenalty < ExcessCharactersPenalty)
3051 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3059 ContentStartColumn =
3060 Token->getContentStartColumn(NextLineIndex,
false);
3061 RemainingTokenColumns = Token->getRemainingLength(
3062 NextLineIndex, TailOffset, ContentStartColumn);
3065 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3080 if (NewBreakBefore) {
3081 assert(Penalty >= NewBreakPenalty);
3082 Penalty -= NewBreakPenalty;
3085 Token->reflow(NextLineIndex, Whitespaces);
3091 Token->getSplitAfterLastLine(TailOffset);
3092 if (SplitAfterLastLine.first != StringRef::npos) {
3093 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3097 Penalty += Style.PenaltyExcessCharacter *
3098 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3101 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3104 ContentStartColumn =
3105 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3106 RemainingTokenColumns = Token->getRemainingLength(
3107 Token->getLineCount() - 1,
3108 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3109 ContentStartColumn);
3112 State.Column = ContentStartColumn + RemainingTokenColumns -
3113 Current.UnbreakableTailLength;
3115 if (BreakInserted) {
3117 Token->updateAfterBroken(Whitespaces);
3122 if (Current.isNot(TT_LineComment))
3123 for (ParenState &
Paren : State.Stack)
3124 Paren.BreakBeforeParameter =
true;
3126 if (Current.is(TT_BlockComment))
3127 State.NoContinuation =
true;
3129 State.Stack.back().LastSpace = StartColumn;
3132 Token->updateNextToken(State);
3134 return {Penalty, Exceeded};
3139 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3142bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3144 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3149 if (Current.
TokenText.starts_with(
"R\""))
3153 if (Current.getNextNonComment() &&
3154 Current.getNextNonComment()->isStringLiteral()) {
3157 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3159 Style.ColumnLimit) {
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
Defines and computes precedence levels for binary/ternary operators.
static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
WhitespaceManager class manages whitespace around tokens and their replacements.
__DEVICE__ int max(int __a, int __b)
This class handles loading and caching of source files into memory.
SourceLocation getEnd() const
SourceLocation getBegin() const
Token - This structure provides full information about a lexed token.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
Top level wrappers for InstallAPI frontend operations.
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
bool isReturnTypePrefixSpecifier(const FormatToken &Tok)
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...