22 #include "llvm/Support/Debug.h" 24 #define DEBUG_TYPE "format-indenter" 39 const std::vector<ParenState> &Stack) {
82 int MatchingStackIndex = Stack.size() - 1;
88 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != LBrace)
90 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
99 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
124 if (Current.
is(TT_CtorInitializerComma) &&
130 ((Previous.
isNot(TT_CtorInitializerComma) ||
133 (Previous.
isNot(TT_InheritanceComma) ||
139 if (LessTok.
isNot(tok::less))
151 if (TokenText.size() < 5
152 || !TokenText.startswith(
"R\"") || !TokenText.endswith(
"\""))
158 size_t LParenPos = TokenText.substr(0, 19).find_first_of(
'(');
159 if (LParenPos == StringRef::npos)
161 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);
164 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
165 if (TokenText[RParenPos] !=
')')
167 if (!TokenText.substr(RParenPos + 1).startswith(Delimiter))
178 if (Format.Language == Language)
179 return StringRef(Format.CanonicalDelimiter);
189 if (!LanguageStyle) {
192 RawStringFormat.Language, &PredefinedStyle)) {
194 PredefinedStyle.
Language = RawStringFormat.Language;
196 LanguageStyle = PredefinedStyle;
198 LanguageStyle->ColumnLimit = CodeStyle.
ColumnLimit;
199 for (StringRef Delimiter : RawStringFormat.Delimiters) {
202 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions) {
218 StringRef EnclosingFunction)
const {
230 bool BinPackInconclusiveFunctions)
231 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
232 Whitespaces(Whitespaces), Encoding(Encoding),
233 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
234 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
237 unsigned FirstStartColumn,
243 State.
Column = FirstStartColumn;
245 State.
Column = FirstIndent;
268 State.
Stack.back().AvoidBinPacking =
true;
269 State.
Stack.back().BreakBeforeParameter =
true;
270 State.
Stack.back().AlignColons =
false;
274 moveStateToNextToken(State, DryRun,
false);
281 assert(&Previous == Current.
Previous);
306 if (Previous.
is(tok::l_brace) && State.
Stack.size() > 1 &&
307 State.
Stack[State.
Stack.size() - 2].NestedBlockInlined &&
308 State.
Stack[State.
Stack.size() - 2].HasMultipleNestedBlocks)
313 if (Current.
is(TT_FunctionDeclarationName) && State.
Column < 6) {
320 if (!Current.
isOneOf(TT_BinaryOperator, tok::comma) &&
321 State.
Stack.back().NoLineBreakInOperand)
324 if (Previous.
is(tok::l_square) && Previous.
is(TT_ObjCMethodExpr))
327 return !State.
Stack.back().NoLineBreak;
335 if (State.
Stack.back().BreakBeforeClosingBrace &&
342 Current.
startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
346 (Previous.
is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
354 Previous.
isNot(tok::question)) ||
356 Previous.
is(TT_ConditionalExpr))) &&
358 !Current.
isOneOf(tok::r_paren, tok::r_brace))
360 if (((Previous.
is(TT_DictLiteral) && Previous.
is(tok::l_brace)) ||
361 (Previous.
is(TT_ArrayInitializerLSquare) &&
369 const FormatToken &BreakConstructorInitializersToken =
373 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
376 State.
Stack.back().BreakBeforeParameter) &&
382 if (Current.
is(TT_ObjCMethodExpr) && !Previous.
is(TT_SelectorName) &&
385 if (Current.
is(TT_SelectorName) && !Previous.
is(tok::at) &&
386 State.
Stack.back().ObjCSelectorNameFound &&
387 State.
Stack.back().BreakBeforeParameter)
390 unsigned NewLineColumn = getNewLineColumn(State);
393 (State.
Column > NewLineColumn ||
398 (State.
Stack.back().CallContinuation != 0 ||
399 State.
Stack.back().BreakBeforeParameter) &&
405 !(State.
Column <= NewLineColumn &&
408 State.
Column <= NewLineColumn))
417 if (State.
Column <= NewLineColumn)
423 !Previous.
isOneOf(tok::kw_return, tok::lessless, tok::at) &&
424 !Previous.
isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
425 nextIsMultilineString(State))
446 bool LHSIsBinaryExpr =
450 State.
Stack.back().BreakBeforeParameter)
453 State.
Stack.back().BreakBeforeParameter) {
458 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
459 State.
Stack.back().BreakBeforeParameter &&
460 State.
Stack.back().FirstLessLess == 0)
469 if (Previous.
is(TT_FunctionAnnotationRParen))
471 if (Previous.
is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
472 Current.
isNot(TT_LeadingJavaAnnotation))
477 if ((Current.
is(TT_FunctionDeclarationName) ||
478 (Current.
is(tok::kw_operator) && !Previous.
is(tok::coloncolon))) &&
479 !Previous.
is(tok::kw_template) && State.
Stack.back().BreakBeforeParameter)
486 Previous.
is(tok::l_brace) && !Current.
isOneOf(tok::r_brace, tok::comment))
489 if (Current.
is(tok::lessless) &&
490 ((Previous.
is(tok::identifier) && Previous.
TokenText ==
"endl") ||
506 unsigned ExtraSpaces) {
509 assert(!State.
Stack.empty());
512 if ((Current.
is(TT_ImplicitStringLiteral) &&
515 tok::pp_not_keyword))) {
523 unsigned StartColumn =
525 assert(EndColumn >= StartColumn);
526 State.
Column += EndColumn - StartColumn;
528 moveStateToNextToken(State, DryRun,
false);
532 unsigned Penalty = 0;
534 Penalty = addTokenOnNewLine(State, DryRun);
536 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
538 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
541 void ContinuationIndenter::addTokenOnCurrentLine(
LineState &
State,
bool DryRun,
542 unsigned ExtraSpaces) {
545 if (Current.
is(tok::equal) &&
547 State.
Stack.back().VariablePos == 0) {
558 State.
Stack.back().LastSpace = State.
Stack.back().VariablePos;
564 int PPColumnCorrection = 0;
576 PPColumnCorrection = -1;
581 State.
Column + Spaces + PPColumnCorrection);
586 Current.
is(TT_InheritanceColon))
587 State.
Stack.back().NoLineBreak =
true;
589 Previous.
is(TT_InheritanceColon))
590 State.
Stack.back().NoLineBreak =
true;
592 if (Current.
is(TT_SelectorName) &&
593 !State.
Stack.back().ObjCSelectorNameFound) {
596 State.
Stack.back().Indent);
599 State.
Stack.back().AlignColons =
false;
603 State.
Stack.back().ColonPos = FirstColonPos;
610 Previous.
isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
611 State.
Column > getNewLineColumn(State) &&
613 tok::kw_for, tok::kw_while, tok::kw_switch)) &&
623 State.
Stack.back().NoLineBreak =
true;
624 if (Previous.
is(TT_TemplateString) && Previous.
opensScope())
625 State.
Stack.back().NoLineBreak =
true;
632 State.
Stack.back().NoLineBreak =
true;
634 State.
Column > getNewLineColumn(State))
635 State.
Stack.back().ContainsUnwrappedBuilder =
true;
638 State.
Stack.back().NoLineBreak =
true;
648 State.
Stack.back().NoLineBreak =
true;
655 if (!Current.
is(tok::comment) && P &&
656 (P->
isOneOf(TT_BinaryOperator, tok::comma) ||
657 (P->
is(TT_ConditionalExpr) && P->
is(tok::colon))) &&
658 !P->
isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
662 bool BreakBeforeOperator =
664 (P->
is(TT_BinaryOperator) &&
670 bool HasTwoOperands =
672 if ((!BreakBeforeOperator && !(HasTwoOperands && Style.
AlignOperands)) ||
673 (!State.
Stack.back().LastOperatorWrapped && BreakBeforeOperator))
674 State.
Stack.back().NoLineBreakInOperand =
true;
678 if (Current.
isNot(tok::comment) && Previous.
is(tok::l_paren) &&
685 State.
Stack.back().NestedBlockIndent = State.
Column;
686 }
else if (!Current.
isOneOf(tok::comment, tok::caret) &&
687 ((Previous.
is(tok::comma) &&
688 !Previous.
is(TT_OverloadedOperator)) ||
689 (Previous.
is(tok::colon) && Previous.
is(TT_ObjCMethodExpr)))) {
691 }
else if (Previous.
is(TT_CtorInitializerColon) &&
696 }
else if ((Previous.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
697 TT_CtorInitializerColon)) &&
707 }
else if (Previous.
is(TT_InheritanceColon)) {
716 bool HasTrailingCall =
false;
721 if (HasTrailingCall && State.
Stack.size() > 1 &&
722 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0)
727 unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
734 unsigned Penalty = 0;
739 NextNonComment = &Current;
742 if (!State.
Stack.back().ContainsLineBreak)
744 State.
Stack.back().ContainsLineBreak =
true;
751 if (NextNonComment->
is(tok::lessless) &&
752 State.
Stack.back().FirstLessLess == 0 &&
754 State.
Stack.back().BreakBeforeParameter))
757 State.
Column = getNewLineColumn(State);
769 if (!Current.
is(TT_LambdaArrow) &&
772 !PreviousNonComment->
is(tok::equal) ||
774 State.
Stack.back().NestedBlockIndent = State.
Column;
777 if (State.
Stack.back().CallContinuation == 0)
778 State.
Stack.back().CallContinuation = State.
Column;
779 }
else if (NextNonComment->
is(TT_SelectorName)) {
780 if (!State.
Stack.back().ObjCSelectorNameFound) {
782 State.
Stack.back().AlignColons =
false;
784 State.
Stack.back().ColonPos =
788 : State.
Stack.back().Indent) +
792 }
else if (State.
Stack.back().AlignColons &&
796 }
else if (PreviousNonComment && PreviousNonComment->
is(tok::colon) &&
797 PreviousNonComment->
isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
807 if (State.
Stack.size() > 1)
808 State.
Stack[State.
Stack.size() - 2].LastSpace =
813 if ((PreviousNonComment &&
814 PreviousNonComment->
isOneOf(tok::comma, tok::semi) &&
815 !State.
Stack.back().AvoidBinPacking) ||
816 Previous.
is(TT_BinaryOperator))
817 State.
Stack.back().BreakBeforeParameter =
false;
818 if (PreviousNonComment &&
819 PreviousNonComment->
isOneOf(TT_TemplateCloser, TT_JavaAnnotation) &&
821 State.
Stack.back().BreakBeforeParameter =
false;
822 if (NextNonComment->
is(tok::question) ||
823 (PreviousNonComment && PreviousNonComment->
is(tok::question)))
824 State.
Stack.back().BreakBeforeParameter =
true;
826 State.
Stack.back().BreakBeforeParameter =
false;
837 MaxEmptyLinesToKeep = 1;
841 bool ContinuePPDirective =
844 ContinuePPDirective);
849 if (Current.
is(tok::lessless))
853 State.
Stack.back().LastSpace += 3;
860 bool NestedBlockSpecialCase =
861 !Style.
isCpp() && Current.
is(tok::r_brace) && State.
Stack.size() > 1 &&
862 State.
Stack[State.
Stack.size() - 2].NestedBlockInlined;
863 if (!NestedBlockSpecialCase)
864 for (
unsigned i = 0, e = State.
Stack.size() - 1; i != e; ++i)
865 State.
Stack[i].BreakBeforeParameter =
true;
867 if (PreviousNonComment &&
868 !PreviousNonComment->
isOneOf(tok::comma, tok::colon, tok::semi) &&
869 (PreviousNonComment->
isNot(TT_TemplateCloser) ||
872 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
873 TT_LeadingJavaAnnotation) &&
875 State.
Stack.back().BreakBeforeParameter =
true;
879 if (PreviousNonComment &&
880 (PreviousNonComment->
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
882 State.
Stack.back().BreakBeforeClosingBrace =
true;
884 if (State.
Stack.back().AvoidBinPacking) {
888 if (!Previous.
isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
891 Previous.
is(TT_DictLiteral))
892 State.
Stack.back().BreakBeforeParameter =
true;
898 unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
904 unsigned ContinuationIndent =
910 NextNonComment = &Current;
920 : State.
Stack.back().Indent;
921 if ((Current.
isOneOf(tok::r_brace, tok::r_square) ||
922 (Current.
is(tok::greater) &&
925 State.
Stack.size() > 1) {
927 return State.
Stack[State.
Stack.size() - 2].NestedBlockIndent;
930 return State.
Stack[State.
Stack.size() - 2].LastSpace;
943 if (Current.
is(tok::r_paren) && State.
Stack.size() > 1 &&
945 return State.
Stack[State.
Stack.size() - 2].LastSpace;
946 if (NextNonComment->
is(TT_TemplateString) && NextNonComment->
closesScope())
947 return State.
Stack[State.
Stack.size() - 2].LastSpace;
948 if (Current.
is(tok::identifier) && Current.
Next &&
949 (Current.
Next->
is(TT_DictLiteral) ||
953 return State.
Stack.back().Indent;
954 if (NextNonComment->
is(TT_ObjCStringLiteral) &&
959 if (NextNonComment->
is(tok::lessless) &&
960 State.
Stack.back().FirstLessLess != 0)
961 return State.
Stack.back().FirstLessLess;
963 if (State.
Stack.back().CallContinuation == 0)
964 return ContinuationIndent;
965 return State.
Stack.back().CallContinuation;
967 if (State.
Stack.back().QuestionColumn != 0 &&
968 ((NextNonComment->
is(tok::colon) &&
969 NextNonComment->
is(TT_ConditionalExpr)) ||
970 Previous.
is(TT_ConditionalExpr)))
971 return State.
Stack.back().QuestionColumn;
972 if (Previous.
is(tok::comma) && State.
Stack.back().VariablePos != 0)
973 return State.
Stack.back().VariablePos;
974 if ((PreviousNonComment &&
975 (PreviousNonComment->ClosesTemplateDeclaration ||
976 PreviousNonComment->isOneOf(
977 TT_AttributeParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
978 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
980 NextNonComment->
isOneOf(tok::kw_operator, TT_FunctionDeclarationName)))
982 if (NextNonComment->
is(TT_SelectorName)) {
983 if (!State.
Stack.back().ObjCSelectorNameFound) {
984 unsigned MinIndent = State.
Stack.back().Indent;
1002 if (!State.
Stack.back().AlignColons)
1003 return State.
Stack.back().Indent;
1006 return State.
Stack.back().Indent;
1008 if (NextNonComment->
is(tok::colon) && NextNonComment->
is(TT_ObjCMethodExpr))
1009 return State.
Stack.back().ColonPos;
1010 if (NextNonComment->
is(TT_ArraySubscriptLSquare)) {
1011 if (State.
Stack.back().StartOfArraySubscripts != 0)
1012 return State.
Stack.back().StartOfArraySubscripts;
1013 return ContinuationIndent;
1018 if (NextNonComment->
is(tok::identifier) && NextNonComment->
FakeRParens == 0 &&
1019 NextNonComment->
Next && NextNonComment->
Next->
is(TT_ObjCMethodExpr))
1020 return State.
Stack.back().Indent;
1022 if (NextNonComment->
isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1023 Previous.
isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon))
1024 return ContinuationIndent;
1025 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1026 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))
1027 return ContinuationIndent;
1028 if (NextNonComment->
is(TT_CtorInitializerComma))
1029 return State.
Stack.back().Indent;
1030 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1032 return State.
Stack.back().Indent;
1033 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1035 return State.
Stack.back().Indent;
1036 if (NextNonComment->
isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1037 TT_InheritanceComma))
1040 !Current.
isOneOf(tok::colon, tok::comment))
1041 return ContinuationIndent;
1042 if (Current.
is(TT_ProtoExtensionLSquare))
1043 return State.
Stack.back().Indent;
1044 if (State.
Stack.back().Indent == State.
FirstIndent && PreviousNonComment &&
1045 PreviousNonComment->isNot(tok::r_brace))
1049 return State.
Stack.back().Indent;
1052 unsigned ContinuationIndenter::moveStateToNextToken(
LineState &State,
1053 bool DryRun,
bool Newline) {
1054 assert(State.
Stack.size());
1057 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1058 State.
Stack.back().NoLineBreakInOperand =
false;
1059 if (Current.is(TT_InheritanceColon))
1060 State.
Stack.back().AvoidBinPacking =
true;
1061 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1062 if (State.
Stack.back().FirstLessLess == 0)
1065 State.
Stack.back().LastOperatorWrapped = Newline;
1067 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1068 State.
Stack.back().LastOperatorWrapped = Newline;
1069 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1070 !Current.Previous->is(TT_ConditionalExpr))
1071 State.
Stack.back().LastOperatorWrapped = Newline;
1072 if (Current.is(TT_ArraySubscriptLSquare) &&
1073 State.
Stack.back().StartOfArraySubscripts == 0)
1074 State.
Stack.back().StartOfArraySubscripts = State.
Column;
1081 if (Previous && Previous->
is(tok::question))
1084 if (!Current.opensScope() && !Current.closesScope() &&
1085 !Current.is(TT_PointerOrReference))
1088 if (Current.isMemberAccess())
1089 State.
Stack.back().StartOfFunctionCall =
1090 !Current.NextOperator ? 0 : State.
Column;
1091 if (Current.is(TT_SelectorName))
1092 State.
Stack.back().ObjCSelectorNameFound =
true;
1093 if (Current.is(TT_CtorInitializerColon) &&
1100 State.
Stack.back().Indent =
1105 State.
Stack.back().NestedBlockIndent = State.
Stack.back().Indent;
1107 State.
Stack.back().AvoidBinPacking =
true;
1108 State.
Stack.back().BreakBeforeParameter =
false;
1110 if (Current.is(TT_CtorInitializerColon) &&
1112 State.
Stack.back().Indent =
1114 State.
Stack.back().NestedBlockIndent = State.
Stack.back().Indent;
1116 State.
Stack.back().AvoidBinPacking =
true;
1118 if (Current.is(TT_InheritanceColon))
1119 State.
Stack.back().Indent =
1121 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1122 State.
Stack.back().NestedBlockIndent =
1123 State.
Column + Current.ColumnWidth + 1;
1124 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1136 if (Current.isNot(tok::comment) && Previous &&
1137 Previous->
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
1138 !Previous->
is(TT_DictLiteral) && State.
Stack.size() > 1 &&
1139 !State.
Stack.back().HasMultipleNestedBlocks) {
1140 if (State.
Stack[State.
Stack.size() - 2].NestedBlockInlined && Newline)
1141 for (
unsigned i = 0, e = State.
Stack.size() - 1; i != e; ++i)
1142 State.
Stack[i].NoLineBreak =
true;
1143 State.
Stack[State.
Stack.size() - 2].NestedBlockInlined =
false;
1146 (Previous->
isOneOf(tok::l_paren, tok::comma, tok::colon) ||
1147 Previous->
isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) &&
1148 !Previous->
isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
1149 State.
Stack.back().NestedBlockInlined =
1154 moveStatePastFakeLParens(State, Newline);
1155 moveStatePastScopeCloser(State);
1156 bool AllowBreak = !State.
Stack.back().NoLineBreak &&
1157 !State.
Stack.back().NoLineBreakInOperand;
1158 moveStatePastScopeOpener(State, Newline);
1159 moveStatePastFakeRParens(State);
1165 else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1166 !Current.isStringLiteral())
1169 State.
Column += Current.ColumnWidth;
1173 handleEndOfLine(Current, State, DryRun, AllowBreak);
1176 Current.Role->formatFromToken(State,
this, DryRun);
1182 if (Previous && Previous->
Role)
1183 Penalty += Previous->
Role->formatAfterToken(State,
this, DryRun);
1188 void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1196 bool SkipFirstExtraIndent =
1198 Previous->
isOneOf(tok::semi, tok::kw_return) ||
1201 Previous->
is(TT_ObjCMethodExpr)));
1207 NewParenState.
Tok =
nullptr;
1222 (!Previous || Previous->
isNot(tok::kw_return) ||
1228 State.
Stack.back().LastSpace);
1252 State.
Stack.push_back(NewParenState);
1253 SkipFirstExtraIndent =
false;
1257 void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
1259 unsigned VariablePos = State.
Stack.back().VariablePos;
1260 if (State.
Stack.size() == 1) {
1264 State.
Stack.pop_back();
1265 State.
Stack.back().VariablePos = VariablePos;
1269 void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
1276 moveStateToNewBlock(State);
1281 unsigned LastSpace = State.
Stack.back().LastSpace;
1282 bool AvoidBinPacking;
1283 bool BreakBeforeParameter =
false;
1284 unsigned NestedBlockIndent =
std::max(State.
Stack.back().StartOfFunctionCall,
1285 State.
Stack.back().NestedBlockIndent);
1286 if (Current.
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1298 AvoidBinPacking = EndsInComma || Current.
is(TT_DictLiteral) ||
1303 NextNoComment->
isOneOf(TT_DesignatedInitializerPeriod,
1304 TT_DesignatedInitializerLSquare));
1305 BreakBeforeParameter = EndsInComma;
1307 NestedBlockIndent =
std::max(NestedBlockIndent, State.
Column + 1);
1311 State.
Stack.back().StartOfFunctionCall);
1329 bool ObjCBinPackProtocolList =
1334 bool BinPackDeclaration =
1344 (!BinPackInconclusiveFunctions &&
1353 BreakBeforeParameter =
true;
1361 BreakBeforeParameter =
true;
1369 BreakBeforeParameter =
true;
1376 !Current.
isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
1377 (State.
Stack.back().NoLineBreak ||
1378 State.
Stack.back().NoLineBreakInOperand ||
1379 (Current.
is(TT_TemplateOpener) &&
1380 State.
Stack.back().ContainsUnwrappedBuilder));
1381 State.
Stack.push_back(
1382 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
1383 State.
Stack.back().NestedBlockIndent = NestedBlockIndent;
1384 State.
Stack.back().BreakBeforeParameter = BreakBeforeParameter;
1386 State.
Stack.back().IsInsideObjCArrayLiteral =
1387 Current.
is(TT_ArrayInitializerLSquare) && Current.
Previous &&
1391 void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
1398 if (State.
Stack.size() > 1 &&
1399 (Current.
isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
1402 (Current.
is(tok::greater) && Current.
is(TT_DictLiteral))))
1403 State.
Stack.pop_back();
1418 if (CurrentScopeOpener.
is(TT_ObjCMethodExpr) &&
1420 int NecessarySpaceInLine =
1425 State.
Stack.back().BreakBeforeParameter =
false;
1429 if (Current.
is(tok::r_square)) {
1432 if (NextNonComment && NextNonComment->
isNot(tok::l_square))
1433 State.
Stack.back().StartOfArraySubscripts = 0;
1437 void ContinuationIndenter::moveStateToNewBlock(
LineState &State) {
1438 unsigned NestedBlockIndent = State.
Stack.back().NestedBlockIndent;
1440 unsigned NewIndent =
1441 NestedBlockIndent + (State.
NextToken->
is(TT_ObjCBlockLBrace)
1445 State.
Stack.back().LastSpace,
1448 State.
Stack.back().NestedBlockIndent = NestedBlockIndent;
1449 State.
Stack.back().BreakBeforeParameter =
true;
1455 size_t LastNewlinePos = Text.find_last_of(
"\n");
1456 if (LastNewlinePos == StringRef::npos) {
1457 return StartColumn +
1461 0, TabWidth, Encoding);
1465 unsigned ContinuationIndenter::reformatRawStringLiteral(
1470 StringRef NewDelimiter =
1472 if (NewDelimiter.empty() || OldDelimiter.empty())
1473 NewDelimiter = OldDelimiter;
1476 unsigned OldPrefixSize = 3 + OldDelimiter.size();
1477 unsigned OldSuffixSize = 2 + OldDelimiter.size();
1480 std::string RawText =
1481 Current.
TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize);
1482 if (NewDelimiter != OldDelimiter) {
1485 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").
str();
1486 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
1487 NewDelimiter = OldDelimiter;
1490 unsigned NewPrefixSize = 3 + NewDelimiter.size();
1491 unsigned NewSuffixSize = 2 + NewDelimiter.size();
1494 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
1505 bool ContentStartsOnNewline = Current.
TokenText[OldPrefixSize] ==
'\n';
1519 unsigned CurrentIndent = (Current.
Next && Current.
Next->
is(tok::r_paren))
1520 ? State.
Stack.back().NestedBlockIndent
1521 : State.
Stack.back().Indent;
1522 unsigned NextStartColumn = ContentStartsOnNewline
1535 ? FirstStartColumn - NewPrefixSize
1540 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
1546 return addMultilineToken(Current, State);
1549 if (NewDelimiter != OldDelimiter) {
1555 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
1558 <<
"Failed to update the prefix delimiter of a raw string: " 1565 1 - OldDelimiter.size());
1567 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
1570 <<
"Failed to update the suffix delimiter of a raw string: " 1581 llvm::errs() <<
"Failed to reformat raw string: " 1587 *NewCode, FirstStartColumn, Style.
TabWidth, Encoding);
1588 State.
Column = RawLastLineEndColumn + NewSuffixSize;
1592 unsigned PrefixExcessCharacters =
1594 StartColumn + NewPrefixSize - Style.
ColumnLimit : 0;
1596 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
1599 for (
unsigned i = 0, e = State.
Stack.size(); i != e; ++i)
1600 State.
Stack[i].BreakBeforeParameter =
true;
1605 unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
1608 for (
unsigned i = 0, e = State.
Stack.size(); i != e; ++i)
1609 State.
Stack[i].BreakBeforeParameter =
true;
1611 unsigned ColumnsUsed = State.
Column;
1621 unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
1624 unsigned Penalty = 0;
1627 auto RawStringStyle = getRawStringStyle(Current, State);
1628 if (RawStringStyle && !Current.
Finalized) {
1629 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun);
1633 Penalty = addMultilineToken(Current, State);
1640 bool Strict =
false;
1643 bool Exceeded =
false;
1644 std::tie(Penalty, Exceeded) = breakProtrudingToken(
1645 Current, State, AllowBreak,
true, Strict);
1650 unsigned StrictPenalty =
1651 breakProtrudingToken(Current, StrictState, AllowBreak,
1654 Strict = StrictPenalty <= Penalty;
1656 Penalty = StrictPenalty;
1657 State = StrictState;
1663 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
1679 if (!
Tok || !
Tok->
is(tok::l_paren))
1684 if (
Tok->
is(TT_TemplateCloser)) {
1689 if (!
Tok || !
Tok->
is(tok::identifier))
1695 ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
1703 if (!RawStringStyle && Delimiter->empty())
1706 if (!RawStringStyle)
1709 return RawStringStyle;
1712 std::unique_ptr<BreakableToken> ContinuationIndenter::createBreakableToken(
1737 if (State.
Stack.back().IsInsideObjCArrayLiteral) {
1748 if ((Text.endswith(Postfix =
"\"") &&
1749 (Text.startswith(Prefix =
"@\"") || Text.startswith(Prefix =
"\"") ||
1750 Text.startswith(Prefix =
"u\"") || Text.startswith(Prefix =
"U\"") ||
1751 Text.startswith(Prefix =
"u8\"") ||
1752 Text.startswith(Prefix =
"L\""))) ||
1753 (Text.startswith(Prefix =
"_T(\"") && Text.endswith(Postfix =
"\")"))) {
1761 return llvm::make_unique<BreakableStringLiteral>(
1762 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
1765 }
else if (Current.
is(TT_BlockComment)) {
1773 return llvm::make_unique<BreakableBlockComment>(
1776 }
else if (Current.
is(TT_LineComment) &&
1780 CommentPragmasRegex.match(Current.
TokenText.substr(2)) ||
1783 return llvm::make_unique<BreakableLineCommentSection>(
1785 false, Encoding, Style);
1790 std::pair<unsigned, bool>
1791 ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
1793 bool DryRun,
bool Strict) {
1794 std::unique_ptr<const BreakableToken>
Token =
1795 createBreakableToken(Current, State, AllowBreak);
1798 assert(Token->getLineCount() > 0);
1800 if (Current.
is(TT_LineComment)) {
1814 bool Exceeded =
false;
1816 bool BreakInserted = Token->introducesBreakBeforeToken();
1819 bool NewBreakBefore =
false;
1823 bool Reflow =
false;
1826 unsigned TailOffset = 0;
1828 unsigned ContentStartColumn =
1829 Token->getContentStartColumn(0,
false);
1831 unsigned RemainingTokenColumns =
1832 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
1835 Token->adaptStartOfLine(0, Whitespaces);
1837 unsigned ContentIndent = 0;
1838 unsigned Penalty = 0;
1839 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column " 1840 << StartColumn <<
".\n");
1841 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
1842 LineIndex != EndIndex; ++LineIndex) {
1843 LLVM_DEBUG(llvm::dbgs()
1844 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
1845 NewBreakBefore =
false;
1849 bool TryReflow = Reflow;
1851 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
1852 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: " 1853 << (ContentStartColumn + RemainingTokenColumns)
1854 <<
", space: " << ColumnLimit
1855 <<
", reflown prefix: " << ContentStartColumn
1856 <<
", offset in line: " << TailOffset <<
"\n");
1861 BreakableToken::Split
Split =
1862 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
1863 ContentStartColumn, CommentPragmasRegex);
1864 if (Split.first == StringRef::npos) {
1867 if (LineIndex < EndIndex - 1)
1871 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
1872 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
1875 assert(Split.first != 0);
1877 if (Token->supportsReflow()) {
1897 unsigned ToSplitColumns = Token->getRangeLength(
1898 LineIndex, TailOffset, Split.first, ContentStartColumn);
1899 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
1901 BreakableToken::Split NextSplit = Token->getSplit(
1902 LineIndex, TailOffset + Split.first + Split.second, ColumnLimit,
1903 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
1906 unsigned ToNextSplitColumns = 0;
1907 if (NextSplit.first == StringRef::npos) {
1908 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
1909 ContentStartColumn);
1911 ToNextSplitColumns = Token->getRangeLength(
1912 LineIndex, TailOffset,
1913 Split.first + Split.second + NextSplit.first, ContentStartColumn);
1917 ToNextSplitColumns =
1918 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
1919 LLVM_DEBUG(llvm::dbgs()
1920 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
1921 LLVM_DEBUG(llvm::dbgs()
1922 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
1925 bool ContinueOnLine =
1926 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
1927 unsigned ExcessCharactersPenalty = 0;
1928 if (!ContinueOnLine && !Strict) {
1931 ExcessCharactersPenalty =
1932 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
1934 LLVM_DEBUG(llvm::dbgs()
1935 <<
" Penalty excess: " << ExcessCharactersPenalty
1936 <<
"\n break : " << NewBreakPenalty <<
"\n");
1937 if (ExcessCharactersPenalty < NewBreakPenalty) {
1939 ContinueOnLine =
true;
1942 if (ContinueOnLine) {
1943 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
1948 Token->compressWhitespace(LineIndex, TailOffset, Split,
1951 ContentStartColumn += ToSplitColumns + 1;
1952 Penalty += ExcessCharactersPenalty;
1953 TailOffset += Split.first + Split.second;
1954 RemainingTokenColumns = Token->getRemainingLength(
1955 LineIndex, TailOffset, ContentStartColumn);
1959 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
1964 ContentIndent = Token->getContentIndent(LineIndex);
1965 LLVM_DEBUG(llvm::dbgs()
1966 <<
" ContentIndent: " << ContentIndent <<
"\n");
1967 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
1970 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
1971 LineIndex, TailOffset + Split.first + Split.second,
1972 ContentStartColumn);
1973 if (NewRemainingTokenColumns == 0) {
1976 ContentStartColumn =
1977 Token->getContentStartColumn(LineIndex,
true);
1978 NewRemainingTokenColumns = Token->getRemainingLength(
1979 LineIndex, TailOffset + Split.first + Split.second,
1980 ContentStartColumn);
1986 if (NewRemainingTokenColumns == RemainingTokenColumns) {
1990 assert(NewRemainingTokenColumns < RemainingTokenColumns);
1992 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset + Split.first
1993 <<
", " << Split.second <<
"\n");
1995 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
1998 Penalty += NewBreakPenalty;
1999 TailOffset += Split.first + Split.second;
2000 RemainingTokenColumns = NewRemainingTokenColumns;
2001 BreakInserted =
true;
2002 NewBreakBefore =
true;
2006 if (LineIndex + 1 != EndIndex) {
2007 unsigned NextLineIndex = LineIndex + 1;
2026 ContentStartColumn += RemainingTokenColumns + 1;
2030 BreakableToken::Split SplitBeforeNext =
2031 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2032 LLVM_DEBUG(llvm::dbgs()
2033 <<
" Size of reflown text: " << ContentStartColumn
2034 <<
"\n Potential reflow split: ");
2035 if (SplitBeforeNext.first != StringRef::npos) {
2036 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", " 2037 << SplitBeforeNext.second <<
"\n");
2038 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2041 RemainingTokenColumns = Token->getRemainingLength(
2042 NextLineIndex, TailOffset, ContentStartColumn);
2044 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2045 LLVM_DEBUG(llvm::dbgs()
2046 <<
" Over limit after reflow, need: " 2047 << (ContentStartColumn + RemainingTokenColumns)
2048 <<
", space: " << ColumnLimit
2049 <<
", reflown prefix: " << ContentStartColumn
2050 <<
", offset in line: " << TailOffset <<
"\n");
2055 BreakableToken::Split
Split =
2056 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2057 ContentStartColumn, CommentPragmasRegex);
2058 if (Split.first == StringRef::npos) {
2059 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2065 unsigned ToSplitColumns = Token->getRangeLength(
2066 NextLineIndex, TailOffset, Split.first, ContentStartColumn);
2067 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2068 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: " 2069 << (ContentStartColumn + ToSplitColumns)
2070 <<
", space: " << ColumnLimit);
2071 unsigned ExcessCharactersPenalty =
2072 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2074 if (NewBreakPenalty < ExcessCharactersPenalty) {
2081 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2089 ContentStartColumn =
2090 Token->getContentStartColumn(NextLineIndex,
false);
2091 RemainingTokenColumns = Token->getRemainingLength(
2092 NextLineIndex, TailOffset, ContentStartColumn);
2095 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2110 if (NewBreakBefore) {
2111 assert(Penalty >= NewBreakPenalty);
2112 Penalty -= NewBreakPenalty;
2115 Token->reflow(NextLineIndex, Whitespaces);
2120 BreakableToken::Split SplitAfterLastLine =
2121 Token->getSplitAfterLastLine(TailOffset);
2122 if (SplitAfterLastLine.first != StringRef::npos) {
2123 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2128 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2131 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2133 ContentStartColumn =
2134 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2135 RemainingTokenColumns = Token->getRemainingLength(
2136 Token->getLineCount() - 1,
2137 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2138 ContentStartColumn);
2141 State.
Column = ContentStartColumn + RemainingTokenColumns -
2144 if (BreakInserted) {
2148 if (Current.
isNot(TT_LineComment)) {
2149 for (
unsigned i = 0, e = State.
Stack.size(); i != e; ++i)
2150 State.
Stack[i].BreakBeforeParameter =
true;
2153 if (Current.
is(TT_BlockComment))
2156 State.
Stack.back().LastSpace = StartColumn;
2159 Token->updateNextToken(State);
2161 return {Penalty, Exceeded};
2169 bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2176 if (Current.
TokenText.startswith(
"R\""))
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
Defines the SourceManager interface.
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Token - This structure provides full information about a lexed token.
WhitespaceManager class manages whitespace around tokens and their replacements.
const AnnotatedLine * Line
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines and computes precedence levels for binary/ternary operators.
SourceLocation getEnd() const
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() const
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Dataflow Directional Tag Classes.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
__DEVICE__ int max(int __a, int __b)
__DEVICE__ int min(int __a, int __b)
This file implements an indenter that manages the indentation of continuations.
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.