21 #include "llvm/Support/Debug.h"
24 #define DEBUG_TYPE "format-formatter"
51 if (Current.
is(TT_CtorInitializerComma) &&
55 (Previous.
isNot(TT_CtorInitializerComma) ||
65 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
66 Whitespaces(Whitespaces), Encoding(Encoding),
67 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
68 CommentPragmasRegex(Style.CommentPragmas) {}
75 State.
Column = FirstIndent;
88 moveStateToNextToken(State, DryRun,
false);
95 assert(&Previous == Current.
Previous);
97 !(State.
Stack.back().BreakBeforeClosingBrace &&
121 if (Previous.
is(tok::l_brace) && State.
Stack.size() > 1 &&
122 State.
Stack[State.
Stack.size() - 2].NestedBlockInlined &&
123 State.
Stack[State.
Stack.size() - 2].HasMultipleNestedBlocks)
128 if (Current.
is(TT_FunctionDeclarationName) &&
133 return !State.
Stack.back().NoLineBreak;
141 if (State.
Stack.back().BreakBeforeClosingBrace &&
148 Previous.
isNot(tok::question)) ||
150 Previous.
is(TT_ConditionalExpr))) &&
152 !Current.
isOneOf(tok::r_paren, tok::r_brace))
154 if (((Previous.
is(TT_DictLiteral) && Previous.
is(tok::l_brace)) ||
155 Previous.
is(TT_ArrayInitializerLSquare)) &&
160 if (Current.
is(TT_CtorInitializerColon) &&
164 if (Current.
is(TT_SelectorName) && State.
Stack.back().ObjCSelectorNameFound &&
165 State.
Stack.back().BreakBeforeParameter)
168 unsigned NewLineColumn = getNewLineColumn(State);
169 if (State.
Column < NewLineColumn)
175 !Previous.
isOneOf(tok::kw_return, tok::lessless, tok::at) &&
176 !Previous.
isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
177 nextIsMultilineString(State))
197 bool LHSIsBinaryExpr =
201 State.
Stack.back().BreakBeforeParameter)
204 State.
Stack.back().BreakBeforeParameter) {
209 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
210 State.
Stack.back().BreakBeforeParameter &&
211 State.
Stack.back().FirstLessLess == 0)
220 if (Previous.
is(TT_FunctionAnnotationRParen))
222 if (Previous.
is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
223 Current.
isNot(TT_LeadingJavaAnnotation))
228 if (Current.
isOneOf(TT_FunctionDeclarationName, tok::kw_operator) &&
229 State.
Stack.back().BreakBeforeParameter)
233 (State.
Stack.back().CallContinuation != 0 ||
234 State.
Stack.back().BreakBeforeParameter))
241 Previous.
is(tok::l_brace) && !Current.
isOneOf(tok::r_brace, tok::comment))
244 if (Current.
is(tok::lessless) && Previous.
is(tok::identifier) &&
253 unsigned ExtraSpaces) {
256 assert(!State.
Stack.empty());
257 if ((Current.
is(TT_ImplicitStringLiteral) &&
260 tok::pp_not_keyword))) {
268 unsigned StartColumn =
270 assert(EndColumn >= StartColumn);
271 State.
Column += EndColumn - StartColumn;
273 moveStateToNextToken(State, DryRun,
false);
277 unsigned Penalty = 0;
279 Penalty = addTokenOnNewLine(State, DryRun);
281 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
283 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
286 void ContinuationIndenter::addTokenOnCurrentLine(
LineState &
State,
bool DryRun,
287 unsigned ExtraSpaces) {
290 if (Current.
is(tok::equal) &&
292 State.
Stack.back().VariablePos == 0) {
303 State.
Stack.back().LastSpace = State.
Stack.back().VariablePos;
310 Spaces, State.
Column + Spaces);
312 if (Current.
is(TT_SelectorName) &&
313 !State.
Stack.back().ObjCSelectorNameFound) {
315 State.
Stack.back().AlignColons =
false;
318 State.
Stack.back().ColonPos =
320 State.
Stack.back().Indent) +
327 Previous.
isNot(TT_ObjCMethodExpr) &&
331 State.
Stack.back().NoLineBreak =
true;
333 State.
Column > getNewLineColumn(State))
334 State.
Stack.back().ContainsUnwrappedBuilder =
true;
337 State.
Stack.back().NoLineBreak =
true;
347 State.
Stack.back().NoLineBreak =
true;
351 if (Current.
isNot(tok::comment) && Previous.
is(tok::l_paren) &&
357 State.
Stack.back().NestedBlockIndent = State.
Column;
358 }
else if (!Current.
isOneOf(tok::comment, tok::caret) &&
359 (Previous.
is(tok::comma) ||
360 (Previous.
is(tok::colon) && Previous.
is(TT_ObjCMethodExpr)))) {
362 }
else if ((Previous.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
363 TT_CtorInitializerColon)) &&
372 }
else if (Previous.
is(TT_InheritanceColon)) {
381 bool HasTrailingCall =
false;
386 if (HasTrailingCall && State.
Stack.size() > 1 &&
387 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0)
392 unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
394 FormatToken &Current = *State.NextToken;
395 const FormatToken &Previous = *State.NextToken->
Previous;
399 unsigned Penalty = 0;
407 if (!State.Stack.back().ContainsLineBreak)
409 State.Stack.back().ContainsLineBreak =
true;
411 Penalty += State.NextToken->SplitPenalty;
416 if (NextNonComment->is(tok::lessless) &&
417 State.Stack.back().FirstLessLess == 0 &&
419 State.Stack.back().BreakBeforeParameter))
422 State.Column = getNewLineColumn(State);
434 Current.NestingLevel != 0 || !PreviousNonComment->is(tok::equal) ||
436 State.Stack.back().NestedBlockIndent = State.Column;
438 if (NextNonComment->isMemberAccess()) {
439 if (State.Stack.back().CallContinuation == 0)
440 State.Stack.back().CallContinuation = State.Column;
441 }
else if (NextNonComment->is(TT_SelectorName)) {
442 if (!State.Stack.back().ObjCSelectorNameFound) {
443 if (NextNonComment->LongestObjCSelectorName == 0) {
444 State.Stack.back().AlignColons =
false;
446 State.Stack.back().ColonPos =
448 ? std::max(State.Stack.back().Indent,
450 : State.Stack.back().Indent) +
451 NextNonComment->LongestObjCSelectorName;
453 }
else if (State.Stack.back().AlignColons &&
454 State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
455 State.Stack.back().ColonPos = State.Column + NextNonComment->ColumnWidth;
457 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
458 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
468 if (State.Stack.size() > 1)
469 State.Stack[State.Stack.size() - 2].LastSpace =
470 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
474 if ((Previous.isOneOf(tok::comma, tok::semi) &&
475 !State.Stack.back().AvoidBinPacking) ||
476 Previous.is(TT_BinaryOperator))
477 State.Stack.back().BreakBeforeParameter =
false;
478 if (Previous.isOneOf(TT_TemplateCloser, TT_JavaAnnotation) &&
479 Current.NestingLevel == 0)
480 State.Stack.back().BreakBeforeParameter =
false;
481 if (NextNonComment->is(tok::question) ||
482 (PreviousNonComment && PreviousNonComment->is(tok::question)))
483 State.Stack.back().BreakBeforeParameter =
true;
484 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
485 State.Stack.back().BreakBeforeParameter =
false;
488 unsigned Newlines = std::max(
491 State.Stack.back().IndentLevel, State.Column,
492 State.Column, State.Line->InPPDirective);
495 if (!Current.isTrailingComment())
496 State.Stack.back().LastSpace = State.Column;
497 State.StartOfLineLevel = Current.NestingLevel;
498 State.LowestLevelOnLine = Current.NestingLevel;
502 bool NestedBlockSpecialCase =
503 Current.is(tok::r_brace) && State.Stack.size() > 1 &&
504 State.Stack[State.Stack.size() - 2].NestedBlockInlined;
505 if (!NestedBlockSpecialCase)
506 for (
unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
507 State.Stack[i].BreakBeforeParameter =
true;
509 if (PreviousNonComment &&
510 !PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
511 (PreviousNonComment->isNot(TT_TemplateCloser) ||
512 Current.NestingLevel != 0) &&
513 !PreviousNonComment->isOneOf(
514 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
515 TT_LeadingJavaAnnotation) &&
516 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope())
517 State.Stack.back().BreakBeforeParameter =
true;
521 if (PreviousNonComment &&
522 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)))
523 State.Stack.back().BreakBeforeClosingBrace =
true;
525 if (State.Stack.back().AvoidBinPacking) {
529 if (!Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
531 State.Line->MustBeDeclaration) ||
532 Previous.is(TT_DictLiteral))
533 State.Stack.back().BreakBeforeParameter =
true;
539 unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
540 if (!State.NextToken || !State.NextToken->Previous)
542 FormatToken &Current = *State.NextToken;
543 const FormatToken &Previous = *Current.Previous;
545 unsigned ContinuationIndent =
546 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
548 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
549 const FormatToken *NextNonComment = Previous.getNextNonComment();
556 return std::max(State.Stack.back().LastSpace,
559 if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind ==
BK_Block)
560 return Current.NestingLevel == 0 ? State.FirstIndent
561 : State.Stack.back().Indent;
562 if (Current.isOneOf(tok::r_brace, tok::r_square) && State.Stack.size() > 1) {
563 if (Current.closesBlockTypeList(Style))
564 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
565 if (Current.MatchingParen &&
567 return State.Stack[State.Stack.size() - 2].LastSpace;
568 return State.FirstIndent;
570 if (Current.is(tok::identifier) && Current.Next &&
571 Current.Next->is(TT_DictLiteral))
572 return State.Stack.back().Indent;
573 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
574 return State.StartOfStringLiteral;
575 if (NextNonComment->is(TT_ObjCStringLiteral) &&
576 State.StartOfStringLiteral != 0)
577 return State.StartOfStringLiteral - 1;
578 if (NextNonComment->is(tok::lessless) &&
579 State.Stack.back().FirstLessLess != 0)
580 return State.Stack.back().FirstLessLess;
581 if (NextNonComment->isMemberAccess()) {
582 if (State.Stack.back().CallContinuation == 0)
583 return ContinuationIndent;
584 return State.Stack.back().CallContinuation;
586 if (State.Stack.back().QuestionColumn != 0 &&
587 ((NextNonComment->is(tok::colon) &&
588 NextNonComment->is(TT_ConditionalExpr)) ||
589 Previous.is(TT_ConditionalExpr)))
590 return State.Stack.back().QuestionColumn;
591 if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0)
592 return State.Stack.back().VariablePos;
593 if ((PreviousNonComment &&
594 (PreviousNonComment->ClosesTemplateDeclaration ||
595 PreviousNonComment->isOneOf(
596 TT_AttributeParen, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
597 TT_LeadingJavaAnnotation))) ||
599 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)))
600 return std::max(State.Stack.back().LastSpace, State.Stack.back().Indent);
601 if (NextNonComment->is(TT_SelectorName)) {
602 if (!State.Stack.back().ObjCSelectorNameFound) {
603 if (NextNonComment->LongestObjCSelectorName == 0)
604 return State.Stack.back().Indent;
606 ? std::max(State.Stack.back().Indent,
608 : State.Stack.back().Indent) +
609 NextNonComment->LongestObjCSelectorName -
610 NextNonComment->ColumnWidth;
612 if (!State.Stack.back().AlignColons)
613 return State.Stack.back().Indent;
614 if (State.Stack.back().ColonPos > NextNonComment->ColumnWidth)
615 return State.Stack.back().ColonPos - NextNonComment->ColumnWidth;
616 return State.Stack.back().Indent;
618 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
619 if (State.Stack.back().StartOfArraySubscripts != 0)
620 return State.Stack.back().StartOfArraySubscripts;
621 return ContinuationIndent;
626 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
627 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr))
628 return State.Stack.back().Indent;
630 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
631 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon))
632 return ContinuationIndent;
633 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
634 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))
635 return ContinuationIndent;
636 if (NextNonComment->is(TT_CtorInitializerColon))
638 if (NextNonComment->is(TT_CtorInitializerComma))
639 return State.Stack.back().Indent;
640 if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
641 !Current.isOneOf(tok::colon, tok::comment))
642 return ContinuationIndent;
643 if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment &&
644 PreviousNonComment->isNot(tok::r_brace))
648 return State.Stack.back().Indent;
651 unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
652 bool DryRun,
bool Newline) {
653 assert(State.Stack.size());
654 const FormatToken &Current = *State.NextToken;
656 if (Current.is(TT_InheritanceColon))
657 State.Stack.back().AvoidBinPacking =
true;
658 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
659 if (State.Stack.back().FirstLessLess == 0)
660 State.Stack.back().FirstLessLess = State.Column;
662 State.Stack.back().LastOperatorWrapped = Newline;
664 if ((Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless)) ||
665 Current.is(TT_ConditionalExpr))
666 State.Stack.back().LastOperatorWrapped = Newline;
667 if (Current.is(TT_ArraySubscriptLSquare) &&
668 State.Stack.back().StartOfArraySubscripts == 0)
669 State.Stack.back().StartOfArraySubscripts = State.Column;
671 (Current.getPreviousNonComment() && Current.isNot(tok::colon) &&
672 Current.getPreviousNonComment()->is(tok::question) &&
674 State.Stack.back().QuestionColumn = State.Column;
675 if (!Current.opensScope() && !Current.closesScope())
676 State.LowestLevelOnLine =
677 std::min(State.LowestLevelOnLine, Current.NestingLevel);
678 if (Current.isMemberAccess())
679 State.Stack.back().StartOfFunctionCall =
680 Current.LastOperator ? 0 : State.Column;
681 if (Current.is(TT_SelectorName))
682 State.Stack.back().ObjCSelectorNameFound =
true;
683 if (Current.is(TT_CtorInitializerColon)) {
689 State.Stack.back().Indent =
691 State.Stack.back().NestedBlockIndent = State.Stack.back().Indent;
693 State.Stack.back().AvoidBinPacking =
true;
694 State.Stack.back().BreakBeforeParameter =
false;
696 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
697 State.Stack.back().NestedBlockIndent =
698 State.Column + Current.ColumnWidth + 1;
701 const FormatToken *Previous = Current.getPreviousNonComment();
709 if (Current.isNot(tok::comment) && Previous &&
710 Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
711 State.Stack.size() > 1) {
712 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
713 for (
unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
714 State.Stack[i].NoLineBreak =
true;
715 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
717 if (Previous && (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) ||
718 Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) &&
719 !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
720 State.Stack.back().NestedBlockInlined =
722 (Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1);
725 moveStatePastFakeLParens(State, Newline);
726 moveStatePastScopeOpener(State, Newline);
727 moveStatePastScopeCloser(State);
728 moveStatePastFakeRParens(State);
730 if (Current.isStringLiteral() && State.StartOfStringLiteral == 0)
731 State.StartOfStringLiteral = State.Column;
732 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
733 State.StartOfStringLiteral = State.Column + 1;
734 else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
735 !Current.isStringLiteral())
736 State.StartOfStringLiteral = 0;
738 State.Column += Current.ColumnWidth;
739 State.NextToken = State.NextToken->Next;
740 unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
747 Current.Role->formatFromToken(State,
this, DryRun);
753 if (Previous && Previous->Role)
754 Penalty += Previous->Role->formatAfterToken(State,
this, DryRun);
759 void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
761 const FormatToken &Current = *State.NextToken;
762 const FormatToken *Previous = Current.getPreviousNonComment();
767 bool SkipFirstExtraIndent =
768 (Previous && (Previous->opensScope() ||
769 Previous->isOneOf(tok::semi, tok::kw_return) ||
772 Previous->is(TT_ObjCMethodExpr)));
773 for (SmallVectorImpl<prec::Level>::const_reverse_iterator
774 I = Current.FakeLParens.rbegin(),
775 E = Current.FakeLParens.rend();
777 ParenState NewParenState = State.Stack.back();
778 NewParenState.ContainsLineBreak =
false;
783 if (!Current.isTrailingComment() &&
785 (!Previous || Previous->isNot(tok::kw_return) ||
788 Current.NestingLevel == 0))
789 NewParenState.Indent =
790 std::max(std::max(State.Column, NewParenState.Indent),
791 State.Stack.back().LastSpace);
798 Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
800 bool BreakBeforeOperator =
801 Previous->is(tok::lessless) ||
802 (Previous->is(TT_BinaryOperator) &&
804 (Previous->is(TT_ConditionalExpr) &&
806 if ((!Newline && !BreakBeforeOperator) ||
807 (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator))
808 NewParenState.NoLineBreak =
true;
818 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
820 NewParenState.StartOfFunctionCall = State.Column;
828 !Current.isTrailingComment()))
830 if ((Previous && !Previous->opensScope()) || *I >
prec::Comma)
831 NewParenState.BreakBeforeParameter =
false;
832 State.Stack.push_back(NewParenState);
833 SkipFirstExtraIndent =
false;
837 void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
838 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
839 unsigned VariablePos = State.Stack.back().VariablePos;
840 if (State.Stack.size() == 1) {
844 State.Stack.pop_back();
845 State.Stack.back().VariablePos = VariablePos;
849 void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
851 const FormatToken &Current = *State.NextToken;
852 if (!Current.opensScope())
855 if (Current.MatchingParen && Current.BlockKind ==
BK_Block) {
856 moveStateToNewBlock(State);
861 unsigned NewIndentLevel = State.Stack.back().IndentLevel;
862 unsigned LastSpace = State.Stack.back().LastSpace;
863 bool AvoidBinPacking;
864 bool BreakBeforeParameter =
false;
865 unsigned NestedBlockIndent = std::max(State.Stack.back().StartOfFunctionCall,
866 State.Stack.back().NestedBlockIndent);
867 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
868 if (Current.opensBlockTypeList(Style)) {
869 NewIndent = State.Stack.back().NestedBlockIndent + Style.
IndentWidth;
870 NewIndent = std::min(State.Column + 2, NewIndent);
875 const FormatToken *NextNoComment = Current.getNextNonComment();
877 Current.isOneOf(TT_ArrayInitializerLSquare, TT_DictLiteral) ||
879 (NextNoComment && NextNoComment->is(TT_DesignatedInitializerPeriod));
880 if (Current.ParameterCount > 1)
881 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
884 std::max(State.Stack.back().LastSpace,
885 State.Stack.back().StartOfFunctionCall);
892 if (Current.Tok.getKind() == tok::less &&
893 Current.ParentBracket == tok::l_paren) {
894 NewIndent = std::max(NewIndent, State.Stack.back().Indent);
895 LastSpace = std::max(LastSpace, State.Stack.back().Indent);
903 (!BinPackInconclusiveFunctions &&
905 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen) {
911 BreakBeforeParameter =
true;
915 for (
const FormatToken *Tok = &Current;
919 BreakBeforeParameter =
true;
926 bool NoLineBreak = State.Stack.back().NoLineBreak ||
927 (Current.is(TT_TemplateOpener) &&
928 State.Stack.back().ContainsUnwrappedBuilder);
929 State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace,
930 AvoidBinPacking, NoLineBreak));
931 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
932 State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
933 State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
936 void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
937 const FormatToken &Current = *State.NextToken;
938 if (!Current.closesScope())
943 if (State.Stack.size() > 1 &&
944 (Current.isOneOf(tok::r_paren, tok::r_square) ||
945 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
946 State.NextToken->is(TT_TemplateCloser)))
947 State.Stack.pop_back();
949 if (Current.is(tok::r_square)) {
951 const FormatToken *NextNonComment = Current.getNextNonComment();
952 if (NextNonComment && NextNonComment->isNot(tok::l_square))
953 State.Stack.back().StartOfArraySubscripts = 0;
957 void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
958 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
961 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
964 State.Stack.push_back(ParenState(
965 NewIndent, State.Stack.back().IndentLevel + 1,
966 State.Stack.back().LastSpace,
true,
967 State.Stack.back().NoLineBreak));
968 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
969 State.Stack.back().BreakBeforeParameter =
true;
972 unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
975 for (
unsigned i = 0, e = State.Stack.size(); i != e; ++i)
976 State.Stack[i].BreakBeforeParameter =
true;
978 unsigned ColumnsUsed = State.Column;
981 State.Column = Current.LastLineColumnWidth;
988 unsigned ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
993 if (Current.isNot(TT_BlockComment) && Current.IsMultiline)
994 return addMultilineToken(Current, State);
997 if (Current.is(TT_ImplicitStringLiteral) ||
1001 if (!Current.isStringLiteral() && !Current.is(tok::comment))
1004 std::unique_ptr<BreakableToken>
Token;
1005 unsigned StartColumn = State.Column - Current.ColumnWidth;
1008 if (Current.isStringLiteral()) {
1024 if (Current.IsUnterminatedLiteral)
1027 StringRef Text = Current.TokenText;
1030 bool IsNSStringLiteral =
false;
1035 if (Text.startswith(
"\"") && Current.Previous &&
1036 Current.Previous->is(tok::at)) {
1037 IsNSStringLiteral =
true;
1040 if ((Text.endswith(Postfix =
"\"") &&
1041 (IsNSStringLiteral || Text.startswith(Prefix =
"\"") ||
1042 Text.startswith(Prefix =
"u\"") || Text.startswith(Prefix =
"U\"") ||
1043 Text.startswith(Prefix =
"u8\"") ||
1044 Text.startswith(Prefix =
"L\""))) ||
1045 (Text.startswith(Prefix =
"_T(\"") && Text.endswith(Postfix =
"\")"))) {
1046 Token.reset(
new BreakableStringLiteral(
1047 Current, State.Line->Level, StartColumn, Prefix, Postfix,
1048 State.Line->InPPDirective, Encoding, Style));
1052 }
else if (Current.is(TT_BlockComment) && Current.isTrailingComment()) {
1053 if (CommentPragmasRegex.match(Current.TokenText.substr(2)))
1055 Token.reset(
new BreakableBlockComment(
1056 Current, State.Line->Level, StartColumn, Current.OriginalColumn,
1057 !Current.Previous, State.Line->InPPDirective, Encoding, Style));
1058 }
else if (Current.is(TT_LineComment) &&
1059 (Current.Previous ==
nullptr ||
1060 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
1061 if (CommentPragmasRegex.match(Current.TokenText.substr(2)))
1063 Token.reset(
new BreakableLineComment(Current, State.Line->Level,
1071 if (Current.UnbreakableTailLength >= ColumnLimit)
1074 unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength;
1075 bool BreakInserted =
false;
1076 unsigned Penalty = 0;
1077 unsigned RemainingTokenColumns = 0;
1078 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
1079 LineIndex != EndIndex; ++LineIndex) {
1081 Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
1082 unsigned TailOffset = 0;
1083 RemainingTokenColumns =
1084 Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
1085 while (RemainingTokenColumns > RemainingSpace) {
1087 Token->getSplit(LineIndex, TailOffset, ColumnLimit);
1088 if (Split.first == StringRef::npos) {
1090 if (LineIndex < EndIndex - 1)
1092 (RemainingTokenColumns - RemainingSpace);
1095 assert(Split.first != 0);
1096 unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
1097 LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
1100 if (RemainingTokenColumns + 1 - Split.second <= RemainingSpace) {
1101 RemainingTokenColumns = 0;
1103 Token->replaceWhitespace(LineIndex, TailOffset, Split, Whitespaces);
1110 if (NewRemainingTokenColumns == RemainingTokenColumns)
1113 assert(NewRemainingTokenColumns < RemainingTokenColumns);
1115 Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
1116 Penalty += Current.SplitPenalty;
1117 unsigned ColumnsUsed =
1118 Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
1119 if (ColumnsUsed > ColumnLimit) {
1122 TailOffset += Split.first + Split.second;
1123 RemainingTokenColumns = NewRemainingTokenColumns;
1124 BreakInserted =
true;
1128 State.Column = RemainingTokenColumns;
1130 if (BreakInserted) {
1134 if (Current.isNot(TT_LineComment)) {
1135 for (
unsigned i = 0, e = State.Stack.size(); i != e; ++i)
1136 State.Stack[i].BreakBeforeParameter =
true;
1142 State.Stack.back().LastSpace = StartColumn;
1152 bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
1159 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.
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()))
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.