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) &&
160 Previous.
isNot(tok::question)) ||
162 Previous.
is(TT_ConditionalExpr))) &&
164 !Current.
isOneOf(tok::r_paren, tok::r_brace))
166 if (((Previous.
is(TT_DictLiteral) && Previous.
is(tok::l_brace)) ||
167 (Previous.
is(TT_ArrayInitializerLSquare) &&
173 if (Current.
is(TT_CtorInitializerColon) &&
176 State.
Stack.back().BreakBeforeParameter) &&
180 if (Current.
is(TT_SelectorName) && State.
Stack.back().ObjCSelectorNameFound &&
181 State.
Stack.back().BreakBeforeParameter)
184 unsigned NewLineColumn = getNewLineColumn(State);
187 (State.
Column > NewLineColumn ||
191 if (State.
Column <= NewLineColumn)
197 !Previous.
isOneOf(tok::kw_return, tok::lessless, tok::at) &&
198 !Previous.
isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
199 nextIsMultilineString(State))
219 bool LHSIsBinaryExpr =
223 State.
Stack.back().BreakBeforeParameter)
226 State.
Stack.back().BreakBeforeParameter) {
231 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
232 State.
Stack.back().BreakBeforeParameter &&
233 State.
Stack.back().FirstLessLess == 0)
242 if (Previous.
is(TT_FunctionAnnotationRParen))
244 if (Previous.
is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
245 Current.
isNot(TT_LeadingJavaAnnotation))
250 if ((Current.
is(TT_FunctionDeclarationName) ||
251 (Current.
is(tok::kw_operator) && !Previous.
is(tok::coloncolon))) &&
252 State.
Stack.back().BreakBeforeParameter)
256 (State.
Stack.back().CallContinuation != 0 ||
257 State.
Stack.back().BreakBeforeParameter))
264 Previous.
is(tok::l_brace) && !Current.
isOneOf(tok::r_brace, tok::comment))
267 if (Current.
is(tok::lessless) &&
268 ((Previous.
is(tok::identifier) && Previous.
TokenText ==
"endl") ||
278 unsigned ExtraSpaces) {
281 assert(!State.
Stack.empty());
282 if ((Current.
is(TT_ImplicitStringLiteral) &&
285 tok::pp_not_keyword))) {
293 unsigned StartColumn =
295 assert(EndColumn >= StartColumn);
296 State.
Column += EndColumn - StartColumn;
298 moveStateToNextToken(State, DryRun,
false);
302 unsigned Penalty = 0;
304 Penalty = addTokenOnNewLine(State, DryRun);
306 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
308 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
311 void ContinuationIndenter::addTokenOnCurrentLine(
LineState &
State,
bool DryRun,
312 unsigned ExtraSpaces) {
315 if (Current.
is(tok::equal) &&
317 State.
Stack.back().VariablePos == 0) {
328 State.
Stack.back().LastSpace = State.
Stack.back().VariablePos;
335 Spaces, State.
Column + Spaces);
337 if (Current.
is(TT_SelectorName) &&
338 !State.
Stack.back().ObjCSelectorNameFound) {
341 State.
Stack.back().Indent);
344 State.
Stack.back().AlignColons =
false;
348 State.
Stack.back().ColonPos = FirstColonPos;
355 Previous.
is(tok::l_paren) && State.
Column > getNewLineColumn(State) &&
357 !Previous.
Previous->
isOneOf(tok::kw_for, tok::kw_while, tok::kw_switch)))
358 State.
Stack.back().NoLineBreak =
true;
365 State.
Stack.back().NoLineBreak =
true;
367 State.
Column > getNewLineColumn(State))
368 State.
Stack.back().ContainsUnwrappedBuilder =
true;
371 State.
Stack.back().NoLineBreak =
true;
381 State.
Stack.back().NoLineBreak =
true;
385 if (Current.
isNot(tok::comment) && Previous.
is(tok::l_paren) &&
391 State.
Stack.back().NestedBlockIndent = State.
Column;
392 }
else if (!Current.
isOneOf(tok::comment, tok::caret) &&
393 ((Previous.
is(tok::comma) &&
394 !Previous.
is(TT_OverloadedOperator)) ||
395 (Previous.
is(tok::colon) && Previous.
is(TT_ObjCMethodExpr)))) {
397 }
else if ((Previous.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
398 TT_CtorInitializerColon)) &&
407 }
else if (Previous.
is(TT_InheritanceColon)) {
416 bool HasTrailingCall =
false;
421 if (HasTrailingCall && State.
Stack.size() > 1 &&
422 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0)
427 unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
429 FormatToken &Current = *State.NextToken;
430 const FormatToken &Previous = *State.NextToken->
Previous;
434 unsigned Penalty = 0;
442 if (!State.Stack.back().ContainsLineBreak)
444 State.Stack.back().ContainsLineBreak =
true;
446 Penalty += State.NextToken->SplitPenalty;
451 if (NextNonComment->is(tok::lessless) &&
452 State.Stack.back().FirstLessLess == 0 &&
454 State.Stack.back().BreakBeforeParameter))
457 State.Column = getNewLineColumn(State);
469 Current.NestingLevel != 0 || !PreviousNonComment->is(tok::equal) ||
471 State.Stack.back().NestedBlockIndent = State.Column;
473 if (NextNonComment->isMemberAccess()) {
474 if (State.Stack.back().CallContinuation == 0)
475 State.Stack.back().CallContinuation = State.Column;
476 }
else if (NextNonComment->is(TT_SelectorName)) {
477 if (!State.Stack.back().ObjCSelectorNameFound) {
478 if (NextNonComment->LongestObjCSelectorName == 0) {
479 State.Stack.back().AlignColons =
false;
481 State.Stack.back().ColonPos =
483 ? std::max(State.Stack.back().Indent,
485 : State.Stack.back().Indent) +
486 NextNonComment->LongestObjCSelectorName;
488 }
else if (State.Stack.back().AlignColons &&
489 State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
490 State.Stack.back().ColonPos = State.Column + NextNonComment->ColumnWidth;
492 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
493 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
503 if (State.Stack.size() > 1)
504 State.Stack[State.Stack.size() - 2].LastSpace =
505 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
509 if ((Previous.isOneOf(tok::comma, tok::semi) &&
510 !State.Stack.back().AvoidBinPacking) ||
511 Previous.is(TT_BinaryOperator))
512 State.Stack.back().BreakBeforeParameter =
false;
513 if (Previous.isOneOf(TT_TemplateCloser, TT_JavaAnnotation) &&
514 Current.NestingLevel == 0)
515 State.Stack.back().BreakBeforeParameter =
false;
516 if (NextNonComment->is(tok::question) ||
517 (PreviousNonComment && PreviousNonComment->is(tok::question)))
518 State.Stack.back().BreakBeforeParameter =
true;
519 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
520 State.Stack.back().BreakBeforeParameter =
false;
523 unsigned Newlines = std::max(
526 State.Stack.back().IndentLevel, State.Column,
527 State.Column, State.Line->InPPDirective);
530 if (!Current.isTrailingComment())
531 State.Stack.back().LastSpace = State.Column;
532 State.StartOfLineLevel = Current.NestingLevel;
533 State.LowestLevelOnLine = Current.NestingLevel;
537 bool NestedBlockSpecialCase =
539 Current.is(tok::r_brace) && State.Stack.size() > 1 &&
540 State.Stack[State.Stack.size() - 2].NestedBlockInlined;
541 if (!NestedBlockSpecialCase)
542 for (
unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
543 State.Stack[i].BreakBeforeParameter =
true;
545 if (PreviousNonComment &&
546 !PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
547 (PreviousNonComment->isNot(TT_TemplateCloser) ||
548 Current.NestingLevel != 0) &&
549 !PreviousNonComment->isOneOf(
550 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
551 TT_LeadingJavaAnnotation) &&
552 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope())
553 State.Stack.back().BreakBeforeParameter =
true;
557 if (PreviousNonComment &&
558 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)))
559 State.Stack.back().BreakBeforeClosingBrace =
true;
561 if (State.Stack.back().AvoidBinPacking) {
565 if (!Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
567 State.Line->MustBeDeclaration) ||
568 Previous.is(TT_DictLiteral))
569 State.Stack.back().BreakBeforeParameter =
true;
575 unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
576 if (!State.NextToken || !State.NextToken->Previous)
578 FormatToken &Current = *State.NextToken;
579 const FormatToken &Previous = *Current.Previous;
581 unsigned ContinuationIndent =
582 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
584 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
585 const FormatToken *NextNonComment = Previous.getNextNonComment();
592 return std::max(State.Stack.back().LastSpace,
595 if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind ==
BK_Block)
596 return Current.NestingLevel == 0 ? State.FirstIndent
597 : State.Stack.back().Indent;
598 if (Current.isOneOf(tok::r_brace, tok::r_square) && State.Stack.size() > 1) {
599 if (Current.closesBlockOrBlockTypeList(Style))
600 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
601 if (Current.MatchingParen &&
603 return State.Stack[State.Stack.size() - 2].LastSpace;
604 return State.FirstIndent;
606 if (Current.is(tok::identifier) && Current.Next &&
607 Current.Next->is(TT_DictLiteral))
608 return State.Stack.back().Indent;
609 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
610 return State.StartOfStringLiteral;
611 if (NextNonComment->is(TT_ObjCStringLiteral) &&
612 State.StartOfStringLiteral != 0)
613 return State.StartOfStringLiteral - 1;
614 if (NextNonComment->is(tok::lessless) &&
615 State.Stack.back().FirstLessLess != 0)
616 return State.Stack.back().FirstLessLess;
617 if (NextNonComment->isMemberAccess()) {
618 if (State.Stack.back().CallContinuation == 0)
619 return ContinuationIndent;
620 return State.Stack.back().CallContinuation;
622 if (State.Stack.back().QuestionColumn != 0 &&
623 ((NextNonComment->is(tok::colon) &&
624 NextNonComment->is(TT_ConditionalExpr)) ||
625 Previous.is(TT_ConditionalExpr)))
626 return State.Stack.back().QuestionColumn;
627 if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0)
628 return State.Stack.back().VariablePos;
629 if ((PreviousNonComment &&
630 (PreviousNonComment->ClosesTemplateDeclaration ||
631 PreviousNonComment->isOneOf(
632 TT_AttributeParen, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
633 TT_LeadingJavaAnnotation))) ||
635 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)))
636 return std::max(State.Stack.back().LastSpace, State.Stack.back().Indent);
637 if (NextNonComment->is(TT_SelectorName)) {
638 if (!State.Stack.back().ObjCSelectorNameFound) {
639 if (NextNonComment->LongestObjCSelectorName == 0)
640 return State.Stack.back().Indent;
642 ? std::max(State.Stack.back().Indent,
644 : State.Stack.back().Indent) +
645 NextNonComment->LongestObjCSelectorName -
646 NextNonComment->ColumnWidth;
648 if (!State.Stack.back().AlignColons)
649 return State.Stack.back().Indent;
650 if (State.Stack.back().ColonPos > NextNonComment->ColumnWidth)
651 return State.Stack.back().ColonPos - NextNonComment->ColumnWidth;
652 return State.Stack.back().Indent;
654 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
655 if (State.Stack.back().StartOfArraySubscripts != 0)
656 return State.Stack.back().StartOfArraySubscripts;
657 return ContinuationIndent;
662 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
663 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr))
664 return State.Stack.back().Indent;
666 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
667 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon))
668 return ContinuationIndent;
669 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
670 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))
671 return ContinuationIndent;
672 if (NextNonComment->is(TT_CtorInitializerColon))
674 if (NextNonComment->is(TT_CtorInitializerComma))
675 return State.Stack.back().Indent;
676 if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
677 !Current.isOneOf(tok::colon, tok::comment))
678 return ContinuationIndent;
679 if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment &&
680 PreviousNonComment->isNot(tok::r_brace))
684 return State.Stack.back().Indent;
687 unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
688 bool DryRun,
bool Newline) {
689 assert(State.Stack.size());
690 const FormatToken &Current = *State.NextToken;
692 if (Current.is(TT_InheritanceColon))
693 State.Stack.back().AvoidBinPacking =
true;
694 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
695 if (State.Stack.back().FirstLessLess == 0)
696 State.Stack.back().FirstLessLess = State.Column;
698 State.Stack.back().LastOperatorWrapped = Newline;
700 if ((Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless)) ||
701 Current.is(TT_ConditionalExpr))
702 State.Stack.back().LastOperatorWrapped = Newline;
703 if (Current.is(TT_ArraySubscriptLSquare) &&
704 State.Stack.back().StartOfArraySubscripts == 0)
705 State.Stack.back().StartOfArraySubscripts = State.Column;
707 (Current.getPreviousNonComment() && Current.isNot(tok::colon) &&
708 Current.getPreviousNonComment()->is(tok::question) &&
710 State.Stack.back().QuestionColumn = State.Column;
711 if (!Current.opensScope() && !Current.closesScope())
712 State.LowestLevelOnLine =
713 std::min(State.LowestLevelOnLine, Current.NestingLevel);
714 if (Current.isMemberAccess())
715 State.Stack.back().StartOfFunctionCall =
716 !Current.NextOperator ? 0 : State.Column;
717 if (Current.is(TT_SelectorName)) {
718 State.Stack.back().ObjCSelectorNameFound =
true;
720 State.Stack.back().Indent =
724 if (Current.is(TT_CtorInitializerColon)) {
730 State.Stack.back().Indent =
732 State.Stack.back().NestedBlockIndent = State.Stack.back().Indent;
734 State.Stack.back().AvoidBinPacking =
true;
735 State.Stack.back().BreakBeforeParameter =
false;
737 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
738 State.Stack.back().NestedBlockIndent =
739 State.Column + Current.ColumnWidth + 1;
742 const FormatToken *Previous = Current.getPreviousNonComment();
750 if (Current.isNot(tok::comment) && Previous &&
751 Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
752 !Previous->is(TT_DictLiteral) && State.Stack.size() > 1) {
753 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
754 for (
unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
755 State.Stack[i].NoLineBreak =
true;
756 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
758 if (Previous && (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) ||
759 Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) &&
760 !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
761 State.Stack.back().NestedBlockInlined =
763 (Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1);
766 moveStatePastFakeLParens(State, Newline);
767 moveStatePastScopeOpener(State, Newline);
768 moveStatePastScopeCloser(State);
769 moveStatePastFakeRParens(State);
771 if (Current.isStringLiteral() && State.StartOfStringLiteral == 0)
772 State.StartOfStringLiteral = State.Column;
773 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
774 State.StartOfStringLiteral = State.Column + 1;
775 else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
776 !Current.isStringLiteral())
777 State.StartOfStringLiteral = 0;
779 State.Column += Current.ColumnWidth;
780 State.NextToken = State.NextToken->Next;
781 unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
788 Current.Role->formatFromToken(State,
this, DryRun);
794 if (Previous && Previous->Role)
795 Penalty += Previous->Role->formatAfterToken(State,
this, DryRun);
800 void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
802 const FormatToken &Current = *State.NextToken;
803 const FormatToken *Previous = Current.getPreviousNonComment();
808 bool SkipFirstExtraIndent =
809 (Previous && (Previous->opensScope() ||
810 Previous->isOneOf(tok::semi, tok::kw_return) ||
813 Previous->is(TT_ObjCMethodExpr)));
814 for (SmallVectorImpl<prec::Level>::const_reverse_iterator
815 I = Current.FakeLParens.rbegin(),
816 E = Current.FakeLParens.rend();
818 ParenState NewParenState = State.Stack.back();
819 NewParenState.ContainsLineBreak =
false;
824 if (!Current.isTrailingComment() &&
826 (!Previous || Previous->isNot(tok::kw_return) ||
830 NewParenState.Indent =
831 std::max(std::max(State.Column, NewParenState.Indent),
832 State.Stack.back().LastSpace);
839 Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
841 bool BreakBeforeOperator =
842 Previous->is(tok::lessless) ||
843 (Previous->is(TT_BinaryOperator) &&
845 (Previous->is(TT_ConditionalExpr) &&
847 if ((!Newline && !BreakBeforeOperator) ||
848 (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator))
849 NewParenState.NoLineBreak =
true;
859 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
861 NewParenState.StartOfFunctionCall = State.Column;
869 !Current.isTrailingComment()))
871 if ((Previous && !Previous->opensScope()) || *
I !=
prec::Comma)
872 NewParenState.BreakBeforeParameter =
false;
873 State.Stack.push_back(NewParenState);
874 SkipFirstExtraIndent =
false;
878 void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
879 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
880 unsigned VariablePos = State.Stack.back().VariablePos;
881 if (State.Stack.size() == 1) {
885 State.Stack.pop_back();
886 State.Stack.back().VariablePos = VariablePos;
890 void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
892 const FormatToken &Current = *State.NextToken;
893 if (!Current.opensScope())
896 if (Current.MatchingParen && Current.BlockKind ==
BK_Block) {
897 moveStateToNewBlock(State);
902 unsigned NewIndentLevel = State.Stack.back().IndentLevel;
903 unsigned LastSpace = State.Stack.back().LastSpace;
904 bool AvoidBinPacking;
905 bool BreakBeforeParameter =
false;
906 unsigned NestedBlockIndent = std::max(State.Stack.back().StartOfFunctionCall,
907 State.Stack.back().NestedBlockIndent);
908 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
909 if (Current.opensBlockOrBlockTypeList(Style)) {
910 NewIndent = State.Stack.back().NestedBlockIndent + Style.
IndentWidth;
911 NewIndent = std::min(State.Column + 2, NewIndent);
916 const FormatToken *NextNoComment = Current.getNextNonComment();
917 bool EndsInComma = Current.MatchingParen &&
918 Current.MatchingParen->Previous &&
919 Current.MatchingParen->Previous->is(tok::comma);
921 (Current.is(TT_ArrayInitializerLSquare) && EndsInComma) ||
922 Current.is(TT_DictLiteral) ||
924 (NextNoComment && NextNoComment->is(TT_DesignatedInitializerPeriod));
925 if (Current.ParameterCount > 1)
926 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
929 std::max(State.Stack.back().LastSpace,
930 State.Stack.back().StartOfFunctionCall);
937 if (Current.Tok.getKind() == tok::less &&
938 Current.ParentBracket == tok::l_paren) {
939 NewIndent = std::max(NewIndent, State.Stack.back().Indent);
940 LastSpace = std::max(LastSpace, State.Stack.back().Indent);
948 (!BinPackInconclusiveFunctions &&
950 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen) {
956 BreakBeforeParameter =
true;
960 for (
const FormatToken *Tok = &Current;
964 BreakBeforeParameter =
true;
975 Current.Children.empty() &&
976 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
977 (State.Stack.back().NoLineBreak ||
978 (Current.is(TT_TemplateOpener) &&
979 State.Stack.back().ContainsUnwrappedBuilder));
980 State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace,
981 AvoidBinPacking, NoLineBreak));
982 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
983 State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
984 State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
987 void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
988 const FormatToken &Current = *State.NextToken;
989 if (!Current.closesScope())
994 if (State.Stack.size() > 1 &&
995 (Current.isOneOf(tok::r_paren, tok::r_square) ||
996 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
997 State.NextToken->is(TT_TemplateCloser)))
998 State.Stack.pop_back();
1000 if (Current.is(tok::r_square)) {
1002 const FormatToken *NextNonComment = Current.getNextNonComment();
1003 if (NextNonComment && NextNonComment->isNot(tok::l_square))
1004 State.Stack.back().StartOfArraySubscripts = 0;
1008 void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
1009 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
1011 unsigned NewIndent =
1012 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
1015 State.Stack.push_back(ParenState(
1016 NewIndent, State.Stack.back().IndentLevel + 1,
1017 State.Stack.back().LastSpace,
true,
1019 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
1020 State.Stack.back().BreakBeforeParameter =
true;
1023 unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
1026 for (
unsigned i = 0, e = State.Stack.size(); i != e; ++i)
1027 State.Stack[i].BreakBeforeParameter =
true;
1029 unsigned ColumnsUsed = State.Column;
1032 State.Column = Current.LastLineColumnWidth;
1039 unsigned ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
1044 if (Current.isNot(TT_BlockComment) && Current.IsMultiline)
1045 return addMultilineToken(Current, State);
1048 if (Current.is(TT_ImplicitStringLiteral) ||
1052 if (!Current.isStringLiteral() && !Current.is(tok::comment))
1055 std::unique_ptr<BreakableToken>
Token;
1056 unsigned StartColumn = State.Column - Current.ColumnWidth;
1059 if (Current.isStringLiteral()) {
1075 if (Current.IsUnterminatedLiteral)
1078 StringRef
Text = Current.TokenText;
1081 bool IsNSStringLiteral =
false;
1086 if (Text.startswith(
"\"") && Current.Previous &&
1087 Current.Previous->is(tok::at)) {
1088 IsNSStringLiteral =
true;
1091 if ((Text.endswith(Postfix =
"\"") &&
1092 (IsNSStringLiteral || Text.startswith(Prefix =
"\"") ||
1093 Text.startswith(Prefix =
"u\"") || Text.startswith(Prefix =
"U\"") ||
1094 Text.startswith(Prefix =
"u8\"") ||
1095 Text.startswith(Prefix =
"L\""))) ||
1096 (Text.startswith(Prefix =
"_T(\"") && Text.endswith(Postfix =
"\")"))) {
1097 Token.reset(
new BreakableStringLiteral(
1098 Current, State.Line->Level, StartColumn, Prefix, Postfix,
1099 State.Line->InPPDirective, Encoding, Style));
1103 }
else if (Current.is(TT_BlockComment) && Current.isTrailingComment()) {
1105 CommentPragmasRegex.match(Current.TokenText.substr(2)))
1107 Token.reset(
new BreakableBlockComment(
1108 Current, State.Line->Level, StartColumn, Current.OriginalColumn,
1109 !Current.Previous, State.Line->InPPDirective, Encoding, Style));
1110 }
else if (Current.is(TT_LineComment) &&
1111 (Current.Previous ==
nullptr ||
1112 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
1114 CommentPragmasRegex.match(Current.TokenText.substr(2)))
1116 Token.reset(
new BreakableLineComment(Current, State.Line->Level,
1124 if (Current.UnbreakableTailLength >= ColumnLimit)
1127 unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength;
1128 bool BreakInserted =
false;
1129 unsigned Penalty = 0;
1130 unsigned RemainingTokenColumns = 0;
1131 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
1132 LineIndex != EndIndex; ++LineIndex) {
1134 Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
1135 unsigned TailOffset = 0;
1136 RemainingTokenColumns =
1137 Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
1138 while (RemainingTokenColumns > RemainingSpace) {
1140 Token->getSplit(LineIndex, TailOffset, ColumnLimit);
1141 if (Split.first == StringRef::npos) {
1143 if (LineIndex < EndIndex - 1)
1145 (RemainingTokenColumns - RemainingSpace);
1148 assert(Split.first != 0);
1149 unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
1150 LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
1153 if (RemainingTokenColumns + 1 - Split.second <= RemainingSpace) {
1154 RemainingTokenColumns = 0;
1156 Token->replaceWhitespace(LineIndex, TailOffset, Split, Whitespaces);
1163 if (NewRemainingTokenColumns == RemainingTokenColumns)
1166 assert(NewRemainingTokenColumns < RemainingTokenColumns);
1168 Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
1169 Penalty += Current.SplitPenalty;
1170 unsigned ColumnsUsed =
1171 Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
1172 if (ColumnsUsed > ColumnLimit) {
1175 TailOffset += Split.first + Split.second;
1176 RemainingTokenColumns = NewRemainingTokenColumns;
1177 BreakInserted =
true;
1181 State.Column = RemainingTokenColumns;
1183 if (BreakInserted) {
1187 if (Current.isNot(TT_LineComment)) {
1188 for (
unsigned i = 0, e = State.Stack.size(); i != e; ++i)
1189 State.Stack[i].BreakBeforeParameter =
true;
1195 State.Stack.back().LastSpace = StartColumn;
1205 bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
1212 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.
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()))
detail::InMemoryDirectory::const_iterator E
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
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.