21 #include "llvm/Support/Debug.h"
24 #define DEBUG_TYPE "format-formatter"
57 if (Current.
is(TT_CtorInitializerComma) &&
61 (Previous.
isNot(TT_CtorInitializerComma) ||
71 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
72 Whitespaces(Whitespaces), Encoding(Encoding),
73 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
74 CommentPragmasRegex(Style.CommentPragmas) {}
81 State.
Column = FirstIndent;
94 moveStateToNextToken(State, DryRun,
false);
101 assert(&Previous == Current.
Previous);
103 !(State.
Stack.back().BreakBeforeClosingBrace &&
127 if (Previous.
is(tok::l_brace) && State.
Stack.size() > 1 &&
128 State.
Stack[State.
Stack.size() - 2].NestedBlockInlined &&
129 State.
Stack[State.
Stack.size() - 2].HasMultipleNestedBlocks)
134 if (Current.
is(TT_FunctionDeclarationName) && State.
Column < 6) {
139 return !State.
Stack.back().NoLineBreak;
147 if (State.
Stack.back().BreakBeforeClosingBrace &&
153 (Previous.
is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
161 Previous.
isNot(tok::question)) ||
163 Previous.
is(TT_ConditionalExpr))) &&
165 !Current.
isOneOf(tok::r_paren, tok::r_brace))
167 if (((Previous.
is(TT_DictLiteral) && Previous.
is(tok::l_brace)) ||
168 (Previous.
is(TT_ArrayInitializerLSquare) &&
174 if (Current.
is(TT_CtorInitializerColon) &&
177 State.
Stack.back().BreakBeforeParameter) &&
181 if (Current.
is(TT_SelectorName) && State.
Stack.back().ObjCSelectorNameFound &&
182 State.
Stack.back().BreakBeforeParameter)
185 unsigned NewLineColumn = getNewLineColumn(State);
188 (State.
Column > NewLineColumn ||
192 if (State.
Column <= NewLineColumn)
198 !Previous.
isOneOf(tok::kw_return, tok::lessless, tok::at) &&
199 !Previous.
isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
200 nextIsMultilineString(State))
220 bool LHSIsBinaryExpr =
224 State.
Stack.back().BreakBeforeParameter)
227 State.
Stack.back().BreakBeforeParameter) {
232 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
233 State.
Stack.back().BreakBeforeParameter &&
234 State.
Stack.back().FirstLessLess == 0)
243 if (Previous.
is(TT_FunctionAnnotationRParen))
245 if (Previous.
is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
246 Current.
isNot(TT_LeadingJavaAnnotation))
251 if ((Current.
is(TT_FunctionDeclarationName) ||
252 (Current.
is(tok::kw_operator) && !Previous.
is(tok::coloncolon))) &&
253 !Previous.
is(tok::kw_template) && State.
Stack.back().BreakBeforeParameter)
257 (State.
Stack.back().CallContinuation != 0 ||
258 State.
Stack.back().BreakBeforeParameter))
265 Previous.
is(tok::l_brace) && !Current.
isOneOf(tok::r_brace, tok::comment))
268 if (Current.
is(tok::lessless) &&
269 ((Previous.
is(tok::identifier) && Previous.
TokenText ==
"endl") ||
279 unsigned ExtraSpaces) {
282 assert(!State.
Stack.empty());
283 if ((Current.
is(TT_ImplicitStringLiteral) &&
286 tok::pp_not_keyword))) {
294 unsigned StartColumn =
296 assert(EndColumn >= StartColumn);
297 State.
Column += EndColumn - StartColumn;
299 moveStateToNextToken(State, DryRun,
false);
303 unsigned Penalty = 0;
305 Penalty = addTokenOnNewLine(State, DryRun);
307 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
309 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
312 void ContinuationIndenter::addTokenOnCurrentLine(
LineState &
State,
bool DryRun,
313 unsigned ExtraSpaces) {
316 if (Current.
is(tok::equal) &&
318 State.
Stack.back().VariablePos == 0) {
329 State.
Stack.back().LastSpace = State.
Stack.back().VariablePos;
336 Spaces, State.
Column + Spaces);
338 if (Current.
is(TT_SelectorName) &&
339 !State.
Stack.back().ObjCSelectorNameFound) {
342 State.
Stack.back().Indent);
345 State.
Stack.back().AlignColons =
false;
349 State.
Stack.back().ColonPos = FirstColonPos;
356 Previous.
isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
357 State.
Column > getNewLineColumn(State) &&
370 State.
Stack.back().NoLineBreak =
true;
377 State.
Stack.back().NoLineBreak =
true;
379 State.
Column > getNewLineColumn(State))
380 State.
Stack.back().ContainsUnwrappedBuilder =
true;
383 State.
Stack.back().NoLineBreak =
true;
393 State.
Stack.back().NoLineBreak =
true;
397 if (Current.
isNot(tok::comment) && Previous.
is(tok::l_paren) &&
403 State.
Stack.back().NestedBlockIndent = State.
Column;
404 }
else if (!Current.
isOneOf(tok::comment, tok::caret) &&
405 ((Previous.
is(tok::comma) &&
406 !Previous.
is(TT_OverloadedOperator)) ||
407 (Previous.
is(tok::colon) && Previous.
is(TT_ObjCMethodExpr)))) {
409 }
else if ((Previous.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
410 TT_CtorInitializerColon)) &&
419 }
else if (Previous.
is(TT_InheritanceColon)) {
428 bool HasTrailingCall =
false;
433 if (HasTrailingCall && State.
Stack.size() > 1 &&
434 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0)
439 unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
441 FormatToken &Current = *State.NextToken;
442 const FormatToken &Previous = *State.NextToken->
Previous;
446 unsigned Penalty = 0;
454 if (!State.Stack.back().ContainsLineBreak)
456 State.Stack.back().ContainsLineBreak =
true;
458 Penalty += State.NextToken->SplitPenalty;
463 if (NextNonComment->is(tok::lessless) &&
464 State.Stack.back().FirstLessLess == 0 &&
466 State.Stack.back().BreakBeforeParameter))
469 State.Column = getNewLineColumn(State);
481 if (!Current.is(TT_LambdaArrow) &&
483 Current.NestingLevel != 0 || !PreviousNonComment ||
484 !PreviousNonComment->is(tok::equal) ||
486 State.Stack.back().NestedBlockIndent = State.Column;
488 if (NextNonComment->isMemberAccess()) {
489 if (State.Stack.back().CallContinuation == 0)
490 State.Stack.back().CallContinuation = State.Column;
491 }
else if (NextNonComment->is(TT_SelectorName)) {
492 if (!State.Stack.back().ObjCSelectorNameFound) {
493 if (NextNonComment->LongestObjCSelectorName == 0) {
494 State.Stack.back().AlignColons =
false;
496 State.Stack.back().ColonPos =
498 ?
std::max(State.Stack.back().Indent,
500 : State.Stack.back().Indent) +
501 NextNonComment->LongestObjCSelectorName;
503 }
else if (State.Stack.back().AlignColons &&
504 State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
505 State.Stack.back().ColonPos = State.Column + NextNonComment->ColumnWidth;
507 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
508 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
518 if (State.Stack.size() > 1)
519 State.Stack[State.Stack.size() - 2].LastSpace =
520 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
524 if ((Previous.isOneOf(tok::comma, tok::semi) &&
525 !State.Stack.back().AvoidBinPacking) ||
526 Previous.is(TT_BinaryOperator))
527 State.Stack.back().BreakBeforeParameter =
false;
528 if (Previous.isOneOf(TT_TemplateCloser, TT_JavaAnnotation) &&
529 Current.NestingLevel == 0)
530 State.Stack.back().BreakBeforeParameter =
false;
531 if (NextNonComment->is(tok::question) ||
532 (PreviousNonComment && PreviousNonComment->is(tok::question)))
533 State.Stack.back().BreakBeforeParameter =
true;
534 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
535 State.Stack.back().BreakBeforeParameter =
false;
541 State.Stack.back().IndentLevel, State.Column,
542 State.Column, State.Line->InPPDirective);
545 if (!Current.isTrailingComment())
546 State.Stack.back().LastSpace = State.Column;
547 if (Current.is(tok::lessless))
551 State.Stack.back().LastSpace += 3;
553 State.StartOfLineLevel = Current.NestingLevel;
554 State.LowestLevelOnLine = Current.NestingLevel;
558 bool NestedBlockSpecialCase =
560 Current.is(tok::r_brace) && State.Stack.size() > 1 &&
561 State.Stack[State.Stack.size() - 2].NestedBlockInlined;
562 if (!NestedBlockSpecialCase)
563 for (
unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
564 State.Stack[i].BreakBeforeParameter =
true;
566 if (PreviousNonComment &&
567 !PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
568 (PreviousNonComment->isNot(TT_TemplateCloser) ||
569 Current.NestingLevel != 0) &&
570 !PreviousNonComment->isOneOf(
571 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
572 TT_LeadingJavaAnnotation) &&
573 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope())
574 State.Stack.back().BreakBeforeParameter =
true;
578 if (PreviousNonComment &&
579 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)))
580 State.Stack.back().BreakBeforeClosingBrace =
true;
582 if (State.Stack.back().AvoidBinPacking) {
586 if (!Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
588 State.Line->MustBeDeclaration) ||
589 Previous.is(TT_DictLiteral))
590 State.Stack.back().BreakBeforeParameter =
true;
596 unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
597 if (!State.NextToken || !State.NextToken->Previous)
599 FormatToken &Current = *State.NextToken;
600 const FormatToken &Previous = *Current.Previous;
602 unsigned ContinuationIndent =
603 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
605 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
606 const FormatToken *NextNonComment = Previous.getNextNonComment();
613 return std::max(State.Stack.back().LastSpace,
616 if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind ==
BK_Block)
617 return Current.NestingLevel == 0 ? State.FirstIndent
618 : State.Stack.back().Indent;
619 if (Current.isOneOf(tok::r_brace, tok::r_square) && State.Stack.size() > 1) {
620 if (Current.closesBlockOrBlockTypeList(Style))
621 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
622 if (Current.MatchingParen &&
624 return State.Stack[State.Stack.size() - 2].LastSpace;
625 return State.FirstIndent;
627 if (Current.is(tok::identifier) && Current.Next &&
628 Current.Next->is(TT_DictLiteral))
629 return State.Stack.back().Indent;
630 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
631 return State.StartOfStringLiteral;
632 if (NextNonComment->is(TT_ObjCStringLiteral) &&
633 State.StartOfStringLiteral != 0)
634 return State.StartOfStringLiteral - 1;
635 if (NextNonComment->is(tok::lessless) &&
636 State.Stack.back().FirstLessLess != 0)
637 return State.Stack.back().FirstLessLess;
638 if (NextNonComment->isMemberAccess()) {
639 if (State.Stack.back().CallContinuation == 0)
640 return ContinuationIndent;
641 return State.Stack.back().CallContinuation;
643 if (State.Stack.back().QuestionColumn != 0 &&
644 ((NextNonComment->is(tok::colon) &&
645 NextNonComment->is(TT_ConditionalExpr)) ||
646 Previous.is(TT_ConditionalExpr)))
647 return State.Stack.back().QuestionColumn;
648 if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0)
649 return State.Stack.back().VariablePos;
650 if ((PreviousNonComment &&
651 (PreviousNonComment->ClosesTemplateDeclaration ||
652 PreviousNonComment->isOneOf(
653 TT_AttributeParen, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
654 TT_LeadingJavaAnnotation))) ||
656 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)))
657 return std::max(State.Stack.back().LastSpace, State.Stack.back().Indent);
658 if (NextNonComment->is(TT_SelectorName)) {
659 if (!State.Stack.back().ObjCSelectorNameFound) {
660 if (NextNonComment->LongestObjCSelectorName == 0)
661 return State.Stack.back().Indent;
663 ?
std::max(State.Stack.back().Indent,
665 : State.Stack.back().Indent) +
666 NextNonComment->LongestObjCSelectorName -
667 NextNonComment->ColumnWidth;
669 if (!State.Stack.back().AlignColons)
670 return State.Stack.back().Indent;
671 if (State.Stack.back().ColonPos > NextNonComment->ColumnWidth)
672 return State.Stack.back().ColonPos - NextNonComment->ColumnWidth;
673 return State.Stack.back().Indent;
675 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
676 if (State.Stack.back().StartOfArraySubscripts != 0)
677 return State.Stack.back().StartOfArraySubscripts;
678 return ContinuationIndent;
683 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
684 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr))
685 return State.Stack.back().Indent;
687 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
688 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon))
689 return ContinuationIndent;
690 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
691 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))
692 return ContinuationIndent;
693 if (NextNonComment->is(TT_CtorInitializerColon))
695 if (NextNonComment->is(TT_CtorInitializerComma))
696 return State.Stack.back().Indent;
697 if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
698 !Current.isOneOf(tok::colon, tok::comment))
699 return ContinuationIndent;
700 if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment &&
701 PreviousNonComment->isNot(tok::r_brace))
705 return State.Stack.back().Indent;
708 unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
709 bool DryRun,
bool Newline) {
710 assert(State.Stack.size());
711 const FormatToken &Current = *State.NextToken;
713 if (Current.is(TT_InheritanceColon))
714 State.Stack.back().AvoidBinPacking =
true;
715 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
716 if (State.Stack.back().FirstLessLess == 0)
717 State.Stack.back().FirstLessLess = State.Column;
719 State.Stack.back().LastOperatorWrapped = Newline;
721 if ((Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless)) ||
722 Current.is(TT_ConditionalExpr))
723 State.Stack.back().LastOperatorWrapped = Newline;
724 if (Current.is(TT_ArraySubscriptLSquare) &&
725 State.Stack.back().StartOfArraySubscripts == 0)
726 State.Stack.back().StartOfArraySubscripts = State.Column;
728 State.Stack.back().QuestionColumn = State.Column;
730 const FormatToken *Previous = Current.Previous;
731 while (Previous && Previous->isTrailingComment())
732 Previous = Previous->Previous;
733 if (Previous && Previous->is(tok::question))
734 State.Stack.back().QuestionColumn = State.Column;
736 if (!Current.opensScope() && !Current.closesScope())
737 State.LowestLevelOnLine =
738 std::min(State.LowestLevelOnLine, Current.NestingLevel);
739 if (Current.isMemberAccess())
740 State.Stack.back().StartOfFunctionCall =
741 !Current.NextOperator ? 0 : State.Column;
742 if (Current.is(TT_SelectorName)) {
743 State.Stack.back().ObjCSelectorNameFound =
true;
745 State.Stack.back().Indent =
749 if (Current.is(TT_CtorInitializerColon)) {
755 State.Stack.back().Indent =
757 State.Stack.back().NestedBlockIndent = State.Stack.back().Indent;
759 State.Stack.back().AvoidBinPacking =
true;
760 State.Stack.back().BreakBeforeParameter =
false;
762 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
763 State.Stack.back().NestedBlockIndent =
764 State.Column + Current.ColumnWidth + 1;
767 const FormatToken *Previous = Current.getPreviousNonComment();
775 if (Current.isNot(tok::comment) && Previous &&
776 Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
777 !Previous->is(TT_DictLiteral) && State.Stack.size() > 1) {
778 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
779 for (
unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
780 State.Stack[i].NoLineBreak =
true;
781 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
783 if (Previous && (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) ||
784 Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) &&
785 !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
786 State.Stack.back().NestedBlockInlined =
788 (Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1);
791 moveStatePastFakeLParens(State, Newline);
792 moveStatePastScopeOpener(State, Newline);
793 moveStatePastScopeCloser(State);
794 moveStatePastFakeRParens(State);
796 if (Current.isStringLiteral() && State.StartOfStringLiteral == 0)
797 State.StartOfStringLiteral = State.Column;
798 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
799 State.StartOfStringLiteral = State.Column + 1;
800 else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
801 !Current.isStringLiteral())
802 State.StartOfStringLiteral = 0;
804 State.Column += Current.ColumnWidth;
805 State.NextToken = State.NextToken->Next;
806 unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
813 Current.Role->formatFromToken(State,
this, DryRun);
819 if (Previous && Previous->Role)
820 Penalty += Previous->Role->formatAfterToken(State,
this, DryRun);
825 void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
827 const FormatToken &Current = *State.NextToken;
828 const FormatToken *Previous = Current.getPreviousNonComment();
833 bool SkipFirstExtraIndent =
834 (Previous && (Previous->opensScope() ||
835 Previous->isOneOf(tok::semi, tok::kw_return) ||
838 Previous->is(TT_ObjCMethodExpr)));
839 for (SmallVectorImpl<prec::Level>::const_reverse_iterator
840 I = Current.FakeLParens.rbegin(),
841 E = Current.FakeLParens.rend();
843 ParenState NewParenState = State.Stack.back();
844 NewParenState.ContainsLineBreak =
false;
849 if (!Current.isTrailingComment() &&
851 (!Previous || Previous->isNot(tok::kw_return) ||
855 NewParenState.Indent =
857 State.Stack.back().LastSpace);
864 Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
866 bool BreakBeforeOperator =
867 Previous->is(tok::lessless) ||
868 (Previous->is(TT_BinaryOperator) &&
870 (Previous->is(TT_ConditionalExpr) &&
872 if ((!Newline && !BreakBeforeOperator) ||
873 (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator))
874 NewParenState.NoLineBreak =
true;
884 NewParenState.LastSpace =
std::max(NewParenState.LastSpace, State.Column);
887 NewParenState.StartOfFunctionCall = State.Column;
895 !Current.isTrailingComment()))
897 if ((Previous && !Previous->opensScope()) || *
I !=
prec::Comma)
898 NewParenState.BreakBeforeParameter =
false;
899 State.Stack.push_back(NewParenState);
900 SkipFirstExtraIndent =
false;
904 void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
905 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
906 unsigned VariablePos = State.Stack.back().VariablePos;
907 if (State.Stack.size() == 1) {
911 State.Stack.pop_back();
912 State.Stack.back().VariablePos = VariablePos;
916 void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
918 const FormatToken &Current = *State.NextToken;
919 if (!Current.opensScope())
922 if (Current.MatchingParen && Current.BlockKind ==
BK_Block) {
923 moveStateToNewBlock(State);
928 unsigned NewIndentLevel = State.Stack.back().IndentLevel;
929 unsigned LastSpace = State.Stack.back().LastSpace;
930 bool AvoidBinPacking;
931 bool BreakBeforeParameter =
false;
932 unsigned NestedBlockIndent =
std::max(State.Stack.back().StartOfFunctionCall,
933 State.Stack.back().NestedBlockIndent);
934 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
935 if (Current.opensBlockOrBlockTypeList(Style)) {
936 NewIndent = State.Stack.back().NestedBlockIndent + Style.
IndentWidth;
937 NewIndent =
std::min(State.Column + 2, NewIndent);
942 const FormatToken *NextNoComment = Current.getNextNonComment();
943 bool EndsInComma = Current.MatchingParen &&
944 Current.MatchingParen->Previous &&
945 Current.MatchingParen->Previous->is(tok::comma);
947 (Current.is(TT_ArrayInitializerLSquare) && EndsInComma) ||
948 Current.is(TT_DictLiteral) ||
950 (NextNoComment && NextNoComment->is(TT_DesignatedInitializerPeriod));
951 if (Current.ParameterCount > 1)
952 NestedBlockIndent =
std::max(NestedBlockIndent, State.Column + 1);
955 std::max(State.Stack.back().LastSpace,
956 State.Stack.back().StartOfFunctionCall);
963 if (Current.Tok.getKind() == tok::less &&
964 Current.ParentBracket == tok::l_paren) {
965 NewIndent =
std::max(NewIndent, State.Stack.back().Indent);
966 LastSpace =
std::max(LastSpace, State.Stack.back().Indent);
974 (!BinPackInconclusiveFunctions &&
976 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen) {
982 BreakBeforeParameter =
true;
986 for (
const FormatToken *Tok = &Current;
990 BreakBeforeParameter =
true;
1001 Current.Children.empty() &&
1002 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
1003 (State.Stack.back().NoLineBreak ||
1004 (Current.is(TT_TemplateOpener) &&
1005 State.Stack.back().ContainsUnwrappedBuilder));
1006 State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace,
1007 AvoidBinPacking, NoLineBreak));
1008 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
1009 State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
1010 State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
1013 void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
1014 const FormatToken &Current = *State.NextToken;
1015 if (!Current.closesScope())
1020 if (State.Stack.size() > 1 &&
1021 (Current.isOneOf(tok::r_paren, tok::r_square) ||
1022 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
1023 State.NextToken->is(TT_TemplateCloser)))
1024 State.Stack.pop_back();
1026 if (Current.is(tok::r_square)) {
1028 const FormatToken *NextNonComment = Current.getNextNonComment();
1029 if (NextNonComment && NextNonComment->isNot(tok::l_square))
1030 State.Stack.back().StartOfArraySubscripts = 0;
1034 void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
1035 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
1037 unsigned NewIndent =
1038 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
1041 State.Stack.push_back(ParenState(
1042 NewIndent, State.Stack.back().IndentLevel + 1,
1043 State.Stack.back().LastSpace,
true,
1045 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
1046 State.Stack.back().BreakBeforeParameter =
true;
1049 unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
1051 if (!Current.IsMultiline)
1055 for (
unsigned i = 0, e = State.Stack.size(); i != e; ++i)
1056 State.Stack[i].BreakBeforeParameter =
true;
1058 unsigned ColumnsUsed = State.Column;
1061 State.Column = Current.LastLineColumnWidth;
1068 unsigned ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
1073 if (Current.isNot(TT_BlockComment) && Current.IsMultiline)
1074 return addMultilineToken(Current, State);
1077 if (Current.is(TT_ImplicitStringLiteral) ||
1081 if (!Current.isStringLiteral() && !Current.is(tok::comment))
1084 std::unique_ptr<BreakableToken>
Token;
1085 unsigned StartColumn = State.Column - Current.ColumnWidth;
1088 if (Current.isStringLiteral()) {
1105 if (Current.IsUnterminatedLiteral)
1108 StringRef
Text = Current.TokenText;
1111 bool IsNSStringLiteral =
false;
1116 if (Text.startswith(
"\"") && Current.Previous &&
1117 Current.Previous->is(tok::at)) {
1118 IsNSStringLiteral =
true;
1121 if ((Text.endswith(Postfix =
"\"") &&
1122 (IsNSStringLiteral || Text.startswith(Prefix =
"\"") ||
1123 Text.startswith(Prefix =
"u\"") || Text.startswith(Prefix =
"U\"") ||
1124 Text.startswith(Prefix =
"u8\"") ||
1125 Text.startswith(Prefix =
"L\""))) ||
1126 (Text.startswith(Prefix =
"_T(\"") && Text.endswith(Postfix =
"\")"))) {
1127 Token.reset(
new BreakableStringLiteral(
1128 Current, State.Line->Level, StartColumn, Prefix, Postfix,
1129 State.Line->InPPDirective, Encoding, Style));
1133 }
else if (Current.is(TT_BlockComment)) {
1135 CommentPragmasRegex.match(Current.TokenText.substr(2)))
1136 return addMultilineToken(Current, State);
1137 Token.reset(
new BreakableBlockComment(
1138 Current, State.Line->Level, StartColumn, Current.OriginalColumn,
1139 !Current.Previous, State.Line->InPPDirective, Encoding, Style));
1140 }
else if (Current.is(TT_LineComment) &&
1141 (Current.Previous ==
nullptr ||
1142 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
1144 CommentPragmasRegex.match(Current.TokenText.substr(2)))
1146 Token.reset(
new BreakableLineComment(Current, State.Line->Level,
1154 if (Current.UnbreakableTailLength >= ColumnLimit)
1157 unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength;
1158 bool BreakInserted =
false;
1159 unsigned Penalty = 0;
1160 unsigned RemainingTokenColumns = 0;
1161 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
1162 LineIndex != EndIndex; ++LineIndex) {
1164 Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
1165 unsigned TailOffset = 0;
1166 RemainingTokenColumns =
1167 Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
1168 while (RemainingTokenColumns > RemainingSpace) {
1170 Token->getSplit(LineIndex, TailOffset, ColumnLimit);
1171 if (Split.first == StringRef::npos) {
1173 if (LineIndex < EndIndex - 1)
1175 (RemainingTokenColumns - RemainingSpace);
1178 assert(Split.first != 0);
1179 unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
1180 LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
1183 if (RemainingTokenColumns + 1 - Split.second <= RemainingSpace) {
1184 RemainingTokenColumns = 0;
1186 Token->replaceWhitespace(LineIndex, TailOffset, Split, Whitespaces);
1193 if (NewRemainingTokenColumns == RemainingTokenColumns)
1196 assert(NewRemainingTokenColumns < RemainingTokenColumns);
1198 Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
1199 Penalty += Current.SplitPenalty;
1200 unsigned ColumnsUsed =
1201 Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
1202 if (ColumnsUsed > ColumnLimit) {
1205 TailOffset += Split.first + Split.second;
1206 RemainingTokenColumns = NewRemainingTokenColumns;
1207 BreakInserted =
true;
1211 State.Column = RemainingTokenColumns;
1213 if (BreakInserted) {
1217 if (Current.isNot(TT_LineComment)) {
1218 for (
unsigned i = 0, e = State.Stack.size(); i != e; ++i)
1219 State.Stack[i].BreakBeforeParameter =
true;
1225 State.Stack.back().LastSpace = StartColumn;
1235 bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
1242 if (Current.
TokenText.startswith(
"R\""))
SourceLocation getEnd() const
Defines the SourceManager interface.
Declares BreakableToken, BreakableStringLiteral, and BreakableBlockComment classes, that contain token type-specific logic to break long lines in tokens.
detail::InMemoryDirectory::const_iterator I
WhitespaceManager class manages whitespace around tokens and their replacements.
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
Defines and computes precedence levels for binary/ternary operators.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
SourceLocation getBegin() const
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
const AdditionalKeywords & Keywords
detail::InMemoryDirectory::const_iterator E
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
This file implements an indenter that manages the indentation of continuations.
This class handles loading and caching of source files into memory.
IdentifierInfo * getIdentifierInfo() const
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.