diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 74adebe88d..67ca928a1a 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -499,9 +499,8 @@ private: State.Stack.back().FirstLessLess != 0) { State.Column = State.Stack.back().FirstLessLess; } else if (State.ParenLevel != 0 && - (Previous.is(tok::equal) || Previous.is(tok::coloncolon) || - Current.is(tok::period) || Current.is(tok::arrow) || - Current.is(tok::question))) { + (Previous.isOneOf(tok::equal, tok::coloncolon) || + Current.isOneOf(tok::period, tok::arrow, tok::question))) { // Indent and extra 4 spaces after if we know the current expression is // continued. Don't do that on the top level, as we already indent 4 // there. @@ -534,7 +533,7 @@ private: if (Current.is(tok::question)) State.Stack.back().BreakBeforeParameter = true; - if ((Previous.is(tok::comma) || Previous.is(tok::semi)) && + if (Previous.isOneOf(tok::comma, tok::semi) && !State.Stack.back().AvoidBinPacking) State.Stack.back().BreakBeforeParameter = false; @@ -562,7 +561,7 @@ private: for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) { State.Stack[i].BreakBeforeParameter = true; } - if (Current.is(tok::period) || Current.is(tok::arrow)) + if (Current.isOneOf(tok::period, tok::arrow)) State.Stack.back().BreakBeforeParameter = true; // If we break after {, we should also break before the corresponding }. @@ -600,7 +599,7 @@ private: } if (Current.Type != TT_LineComment && - (Previous.is(tok::l_paren) || Previous.is(tok::l_brace) || + (Previous.isOneOf(tok::l_paren, tok::l_brace) || State.NextToken->Parent->Type == TT_TemplateOpener)) State.Stack.back().Indent = State.Column + Spaces; if (Previous.is(tok::comma) && !isTrailingComment(Current)) @@ -622,8 +621,7 @@ private: else if (Previous.Type == TT_InheritanceColon) State.Stack.back().Indent = State.Column; else if (Previous.ParameterCount > 1 && - (Previous.is(tok::l_paren) || Previous.is(tok::l_square) || - Previous.is(tok::l_brace) || + (Previous.isOneOf(tok::l_paren, tok::l_square, tok::l_brace) || Previous.Type == TT_TemplateOpener)) // If this function has multiple parameters, indent nested calls from // the start of the first parameter. @@ -645,7 +643,7 @@ private: State.Stack.back().FirstLessLess = State.Column; if (Current.is(tok::question)) State.Stack.back().QuestionColumn = State.Column; - if ((Current.is(tok::period) || Current.is(tok::arrow)) && + if (Current.isOneOf(tok::period, tok::arrow) && Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0) State.Stack.back().StartOfFunctionCall = Current.LastInChainOfCalls ? 0 : State.Column; @@ -665,8 +663,7 @@ private: // If we encounter an opening (, [, { or <, we add a level to our stacks to // prepare for the following tokens. - if (Current.is(tok::l_paren) || Current.is(tok::l_square) || - Current.is(tok::l_brace) || + if (Current.isOneOf(tok::l_paren, tok::l_square, tok::l_brace) || State.NextToken->Type == TT_TemplateOpener) { unsigned NewIndent; bool AvoidBinPacking; @@ -695,7 +692,7 @@ private: // If we encounter a closing ), ], } or >, we can remove a level from our // stacks. - if (Current.is(tok::r_paren) || Current.is(tok::r_square) || + if (Current.isOneOf(tok::r_paren, tok::r_square) || (Current.is(tok::r_brace) && State.NextToken != &RootToken) || State.NextToken->Type == TT_TemplateCloser) { State.Stack.pop_back(); @@ -985,8 +982,7 @@ private: if (State.NextToken->Parent->is(tok::semi) && State.LineContainsContinuedForLoopSection) return true; - if ((State.NextToken->Parent->is(tok::comma) || - State.NextToken->Parent->is(tok::semi) || + if ((State.NextToken->Parent->isOneOf(tok::comma, tok::semi) || State.NextToken->is(tok::question) || State.NextToken->Type == TT_ConditionalExpr) && State.Stack.back().BreakBeforeParameter && @@ -1126,6 +1122,88 @@ public: virtual ~Formatter() {} + tooling::Replacements format() { + LexerBasedFormatTokenSource Tokens(Lex, SourceMgr); + UnwrappedLineParser Parser(Diag, Style, Tokens, *this); + StructuralError = Parser.parse(); + unsigned PreviousEndOfLineColumn = 0; + TokenAnnotator Annotator(Style, SourceMgr, Lex, + Tokens.getIdentTable().get("in")); + for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { + Annotator.annotate(AnnotatedLines[i]); + } + deriveLocalStyle(); + for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { + Annotator.calculateFormattingInformation(AnnotatedLines[i]); + } + std::vector IndentForLevel; + bool PreviousLineWasTouched = false; + for (std::vector::iterator I = AnnotatedLines.begin(), + E = AnnotatedLines.end(); + I != E; ++I) { + const AnnotatedLine &TheLine = *I; + const FormatToken &FirstTok = TheLine.First.FormatTok; + int Offset = getIndentOffset(TheLine.First); + while (IndentForLevel.size() <= TheLine.Level) + IndentForLevel.push_back(-1); + IndentForLevel.resize(TheLine.Level + 1); + bool WasMoved = + PreviousLineWasTouched && FirstTok.NewlinesBefore == 0; + if (TheLine.First.is(tok::eof)) { + if (PreviousLineWasTouched) { + unsigned NewLines = std::min(FirstTok.NewlinesBefore, 1u); + Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0, + /*WhitespaceStartColumn*/ 0, Style); + } + } else if (TheLine.Type != LT_Invalid && + (WasMoved || touchesLine(TheLine))) { + unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level); + unsigned Indent = LevelIndent; + if (static_cast(Indent) + Offset >= 0) + Indent += Offset; + if (!FirstTok.WhiteSpaceStart.isValid() || StructuralError) { + Indent = LevelIndent = SourceMgr.getSpellingColumnNumber( + FirstTok.Tok.getLocation()) - 1; + } else { + formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective, + PreviousEndOfLineColumn); + } + tryFitMultipleLinesInOne(Indent, I, E); + UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent, + TheLine.First, Whitespaces, + StructuralError); + PreviousEndOfLineColumn = + Formatter.format(I + 1 != E ? &*(I + 1) : NULL); + IndentForLevel[TheLine.Level] = LevelIndent; + PreviousLineWasTouched = true; + } else { + if (FirstTok.NewlinesBefore > 0 || FirstTok.IsFirst) { + unsigned Indent = + SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1; + unsigned LevelIndent = Indent; + if (static_cast(LevelIndent) - Offset >= 0) + LevelIndent -= Offset; + IndentForLevel[TheLine.Level] = LevelIndent; + + // Remove trailing whitespace of the previous line if it was touched. + if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) + formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective, + PreviousEndOfLineColumn); + } + // If we did not reformat this unwrapped line, the column at the end of + // the last token is unchanged - thus, we can calculate the end of the + // last token. + SourceLocation LastLoc = TheLine.Last->FormatTok.Tok.getLocation(); + PreviousEndOfLineColumn = + SourceMgr.getSpellingColumnNumber(LastLoc) + + Lex.MeasureTokenLength(LastLoc, SourceMgr, Lex.getLangOpts()) - 1; + PreviousLineWasTouched = false; + } + } + return Whitespaces.generateReplacements(); + } + +private: void deriveLocalStyle() { unsigned CountBoundToVariable = 0; unsigned CountBoundToType = 0; @@ -1163,91 +1241,6 @@ public: } } - tooling::Replacements format() { - LexerBasedFormatTokenSource Tokens(Lex, SourceMgr); - UnwrappedLineParser Parser(Diag, Style, Tokens, *this); - StructuralError = Parser.parse(); - unsigned PreviousEndOfLineColumn = 0; - TokenAnnotator Annotator(Style, SourceMgr, Lex, - Tokens.getIdentTable().get("in")); - for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { - Annotator.annotate(AnnotatedLines[i]); - } - deriveLocalStyle(); - for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { - Annotator.calculateFormattingInformation(AnnotatedLines[i]); - } - std::vector IndentForLevel; - bool PreviousLineWasTouched = false; - for (std::vector::iterator I = AnnotatedLines.begin(), - E = AnnotatedLines.end(); - I != E; ++I) { - const AnnotatedLine &TheLine = *I; - int Offset = getIndentOffset(TheLine.First); - while (IndentForLevel.size() <= TheLine.Level) - IndentForLevel.push_back(-1); - IndentForLevel.resize(TheLine.Level + 1); - bool WasMoved = - PreviousLineWasTouched && TheLine.First.FormatTok.NewlinesBefore == 0; - if (TheLine.First.is(tok::eof)) { - if (PreviousLineWasTouched) { - unsigned NewLines = - std::min(TheLine.First.FormatTok.NewlinesBefore, 1u); - Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0, - /*WhitespaceStartColumn*/ 0, Style); - } - } else if (TheLine.Type != LT_Invalid && - (WasMoved || touchesLine(TheLine))) { - unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level); - unsigned Indent = LevelIndent; - if (static_cast(Indent) + Offset >= 0) - Indent += Offset; - if (!TheLine.First.FormatTok.WhiteSpaceStart.isValid() || - StructuralError) { - Indent = LevelIndent = SourceMgr.getSpellingColumnNumber( - TheLine.First.FormatTok.Tok.getLocation()) - 1; - } else { - formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective, - PreviousEndOfLineColumn); - } - tryFitMultipleLinesInOne(Indent, I, E); - UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent, - TheLine.First, Whitespaces, - StructuralError); - PreviousEndOfLineColumn = - Formatter.format(I + 1 != E ? &*(I + 1) : NULL); - IndentForLevel[TheLine.Level] = LevelIndent; - PreviousLineWasTouched = true; - } else { - if (TheLine.First.FormatTok.NewlinesBefore > 0 || - TheLine.First.FormatTok.IsFirst) { - unsigned Indent = SourceMgr.getSpellingColumnNumber( - TheLine.First.FormatTok.Tok.getLocation()) - 1; - unsigned LevelIndent = Indent; - if (static_cast(LevelIndent) - Offset >= 0) - LevelIndent -= Offset; - IndentForLevel[TheLine.Level] = LevelIndent; - - // Remove trailing whitespace of the previous line if it was touched. - if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) - formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective, - PreviousEndOfLineColumn); - } - // If we did not reformat this unwrapped line, the column at the end of - // the last token is unchanged - thus, we can calculate the end of the - // last token. - PreviousEndOfLineColumn = - SourceMgr.getSpellingColumnNumber( - TheLine.Last->FormatTok.Tok.getLocation()) + - Lex.MeasureTokenLength(TheLine.Last->FormatTok.Tok.getLocation(), - SourceMgr, Lex.getLangOpts()) - 1; - PreviousLineWasTouched = false; - } - } - return Whitespaces.generateReplacements(); - } - -private: /// \brief Get the indent of \p Level from \p IndentForLevel. /// /// \p IndentForLevel must contain the indent for the level \c l @@ -1267,8 +1260,7 @@ private: /// characters to the left from their level. int getIndentOffset(const AnnotatedToken &RootToken) { bool IsAccessModifier = false; - if (RootToken.is(tok::kw_public) || RootToken.is(tok::kw_protected) || - RootToken.is(tok::kw_private)) + if (RootToken.isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private)) IsAccessModifier = true; else if (RootToken.is(tok::at) && !RootToken.Children.empty() && (RootToken.Children[0].isObjCAtKeyword(tok::objc_public) || @@ -1361,15 +1353,11 @@ private: // we're not in a control flow statement and the last token is an opening // brace. AnnotatedLine &Line = *I; - bool AllowedTokens = - Line.First.isNot(tok::kw_if) && Line.First.isNot(tok::kw_while) && - Line.First.isNot(tok::kw_do) && Line.First.isNot(tok::r_brace) && - Line.First.isNot(tok::kw_else) && Line.First.isNot(tok::kw_try) && - Line.First.isNot(tok::kw_catch) && Line.First.isNot(tok::kw_for) && - // This gets rid of all ObjC @ keywords and methods. - Line.First.isNot(tok::at) && Line.First.isNot(tok::minus) && - Line.First.isNot(tok::plus); - if (!AllowedTokens) + if (Line.First.isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace, + tok::kw_else, tok::kw_try, tok::kw_catch, + tok::kw_for, + // This gets rid of all ObjC @ keywords and methods. + tok::at, tok::minus, tok::plus)) return; AnnotatedToken *Tok = &(I + 1)->First; @@ -1391,7 +1379,7 @@ private: if ((I + 1)->Last->Type == TT_LineComment || Tok->MustBreakBefore) return; do { - if (Tok->is(tok::l_brace) || Tok->is(tok::r_brace)) + if (Tok->isOneOf(tok::l_brace, tok::r_brace)) return; Tok = Tok->Children.empty() ? NULL : &Tok->Children.back(); } while (Tok != NULL); diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 72edc76d77..ac127160d1 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -71,6 +71,16 @@ static const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) { return NextToken; } +static bool closesScope(const AnnotatedToken &Tok) { + return Tok.isOneOf(tok::r_paren, tok::r_brace, tok::r_square) || + Tok.Type == TT_TemplateCloser; +} + +static bool opensScope(const AnnotatedToken &Tok) { + return Tok.isOneOf(tok::l_paren, tok::l_brace, tok::l_square) || + Tok.Type == TT_TemplateOpener; +} + /// \brief A parser that gathers additional information about tokens. /// /// The \c TokenAnnotator tries to match parenthesis and square brakets and @@ -100,11 +110,9 @@ private: next(); return true; } - if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) || - CurrentToken->is(tok::r_brace)) - return false; - if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) || - CurrentToken->is(tok::question) || CurrentToken->is(tok::colon)) + if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace, + tok::pipepipe, tok::ampamp, tok::question, + tok::colon)) return false; updateParameterCount(Left, CurrentToken); if (!consumeToken()) @@ -149,7 +157,7 @@ private: AnnotatedToken &Prev = *CurrentToken->Parent; AnnotatedToken &Next = CurrentToken->Children[0]; if (Prev.Parent->is(tok::identifier) && - (Prev.is(tok::star) || Prev.is(tok::amp) || Prev.is(tok::ampamp)) && + Prev.isOneOf(tok::star, tok::amp, tok::ampamp) && CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) { Prev.Type = TT_BinaryOperator; LookForDecls = false; @@ -171,7 +179,7 @@ private: next(); return true; } - if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace)) + if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) return false; updateParameterCount(Left, CurrentToken); if (!consumeToken()) @@ -191,10 +199,10 @@ private: AnnotatedToken *Parent = getPreviousToken(*Left); bool StartsObjCMethodExpr = Contexts.back().CanBeExpression && - (!Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) || - Parent->is(tok::l_paren) || Parent->is(tok::kw_return) || - Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) || - Parent->Type == TT_ObjCForIn || Parent->Type == TT_CastRParen || + (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, + tok::kw_return, tok::kw_throw) || + isUnaryOperator(*Parent) || Parent->Type == TT_ObjCForIn || + Parent->Type == TT_CastRParen || getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) > prec::Unknown); ScopedContextCreator ContextCreator(*this, 10); @@ -235,7 +243,7 @@ private: next(); return true; } - if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace)) + if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace)) return false; updateParameterCount(Left, CurrentToken); if (!consumeToken()) @@ -257,7 +265,7 @@ private: next(); return true; } - if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square)) + if (CurrentToken->isOneOf(tok::r_paren, tok::r_square)) return false; updateParameterCount(Left, CurrentToken); if (!consumeToken()) @@ -380,7 +388,7 @@ private: break; case tok::kw_operator: while (CurrentToken && CurrentToken->isNot(tok::l_paren)) { - if (CurrentToken->is(tok::star) || CurrentToken->is(tok::amp)) + if (CurrentToken->isOneOf(tok::star, tok::amp)) CurrentToken->Type = TT_PointerOrReference; consumeToken(); } @@ -472,7 +480,7 @@ public: while (CurrentToken != NULL) { if (CurrentToken->is(tok::kw_virtual)) KeywordVirtualFound = true; - if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow)) { + if (CurrentToken->isOneOf(tok::period, tok::arrow)) { ++PeriodsAndArrows; LastPeriodOrArrow = CurrentToken; } @@ -560,18 +568,17 @@ private: if (Previous->is(tok::r_square)) Previous = Previous->MatchingParen; if (Previous->Type == TT_BinaryOperator && - (Previous->is(tok::star) || Previous->is(tok::amp))) { + Previous->isOneOf(tok::star, tok::amp)) { Previous->Type = TT_PointerOrReference; } } - } else if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) || + } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) || (Current.is(tok::l_paren) && !Line.MustBeDeclaration && (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) { Contexts.back().IsExpression = true; - } else if (Current.is(tok::r_paren) || Current.is(tok::greater) || - Current.is(tok::comma)) { + } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { for (AnnotatedToken *Previous = Current.Parent; - Previous && (Previous->is(tok::star) || Previous->is(tok::amp)); + Previous && Previous->isOneOf(tok::star, tok::amp); Previous = Previous->Parent) Previous->Type = TT_PointerOrReference; } else if (Current.Parent && @@ -589,14 +596,12 @@ private: Current.Parent->Type == TT_PointerOrReference || Current.Parent->Type == TT_TemplateCloser)) { Current.Type = TT_StartOfName; - } else if (Current.is(tok::star) || Current.is(tok::amp) || - Current.is(tok::ampamp)) { + } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) { Current.Type = determineStarAmpUsage(Current, Contexts.back().IsExpression); - } else if (Current.is(tok::minus) || Current.is(tok::plus) || - Current.is(tok::caret)) { + } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { Current.Type = determinePlusMinusCaretUsage(Current); - } else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) { + } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { Current.Type = determineIncrementUsage(Current); } else if (Current.is(tok::exclaim)) { Current.Type = TT_UnaryOperator; @@ -614,9 +619,8 @@ private: Current.Parent->Type == TT_PointerOrReference || Current.Parent->Type == TT_TemplateCloser; bool ParensCouldEndDecl = - !Current.Children.empty() && (Current.Children[0].is(tok::equal) || - Current.Children[0].is(tok::semi) || - Current.Children[0].is(tok::l_brace)); + !Current.Children.empty() && + Current.Children[0].isOneOf(tok::equal, tok::semi, tok::l_brace); if (ParensNotExpr && !ParensCouldEndDecl && Contexts.back().IsExpression) // FIXME: We need to get smarter and understand more cases of casts. @@ -652,20 +656,20 @@ private: if (PrevToken->is(tok::l_paren) && !IsExpression) return TT_PointerOrReference; - if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) || - PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) || - PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) || - PrevToken->is(tok::equal) || PrevToken->Type == TT_BinaryOperator || + if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, + tok::comma, tok::kw_return, tok::colon, + tok::equal) || + PrevToken->Type == TT_BinaryOperator || PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) return TT_UnaryOperator; if (NextToken->is(tok::l_square)) return TT_PointerOrReference; - if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) || - PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() || - isUnaryOperator(*NextToken) || NextToken->is(tok::l_paren) || - NextToken->is(tok::l_square)) + if (PrevToken->FormatTok.Tok.isLiteral() || + PrevToken->isOneOf(tok::r_paren, tok::r_square) || + NextToken->FormatTok.Tok.isLiteral() || isUnaryOperator(*NextToken) || + NextToken->isOneOf(tok::l_paren, tok::l_square)) return TT_BinaryOperator; // It is very unlikely that we are going to find a pointer or reference type @@ -682,11 +686,9 @@ private: return TT_UnaryOperator; // Use heuristics to recognize unary operators. - if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) || - PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) || - PrevToken->is(tok::question) || PrevToken->is(tok::colon) || - PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) || - PrevToken->is(tok::at) || PrevToken->is(tok::l_brace)) + if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square, + tok::question, tok::colon, tok::kw_return, + tok::kw_case, tok::at, tok::l_brace)) return TT_UnaryOperator; // There can't be two consecutive binary operators. @@ -702,8 +704,7 @@ private: const AnnotatedToken *PrevToken = getPreviousToken(Tok); if (PrevToken == NULL) return TT_UnaryOperator; - if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) || - PrevToken->is(tok::identifier)) + if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) return TT_TrailingUnaryOperator; return TT_UnaryOperator; @@ -798,16 +799,6 @@ private: Current = Current->Children.empty() ? NULL : &Current->Children[0]; } - bool closesScope(const AnnotatedToken &Tok) { - return Current->is(tok::r_paren) || Current->Type == TT_TemplateCloser || - Current->is(tok::r_brace) || Current->is(tok::r_square); - } - - bool opensScope(const AnnotatedToken &Tok) { - return Current->is(tok::l_paren) || Current->Type == TT_TemplateOpener || - Current->is(tok::l_brace) || Current->is(tok::l_square); - } - AnnotatedToken *Current; }; @@ -901,11 +892,11 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, Left.Type == TT_InheritanceColon) return 2; - if (Right.is(tok::arrow) || Right.is(tok::period)) { + if (Right.isOneOf(tok::arrow, tok::period)) { if (Line.Type == LT_BuilderTypeCall) return 5; - if ((Left.is(tok::r_paren) || Left.is(tok::r_square)) && - Left.MatchingParen && Left.MatchingParen->ParameterCount > 0) + if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen && + Left.MatchingParen->ParameterCount > 0) return 20; // Should be smaller than breaking at a nested comma. return 150; } @@ -926,8 +917,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) return 20; - if (Left.is(tok::l_paren) || Left.is(tok::l_square) || - Left.is(tok::l_brace) || Left.Type == TT_TemplateOpener) + if (opensScope(Left)) return 20; if (Right.is(tok::lessless)) { @@ -955,9 +945,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, const AnnotatedToken &Right) { if (Right.is(tok::hashhash)) return Left.is(tok::hash); - if (Left.is(tok::hashhash) || Left.is(tok::hash)) + if (Left.isOneOf(tok::hashhash, tok::hash)) return Right.is(tok::hash); - if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma)) + if (Right.isOneOf(tok::r_paren, tok::semi, tok::comma)) return false; if (Right.is(tok::less) && (Left.is(tok::kw_template) || @@ -965,20 +955,18 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return true; if (Left.is(tok::arrow) || Right.is(tok::arrow)) return false; - if (Left.is(tok::exclaim) || Left.is(tok::tilde)) + if (Left.isOneOf(tok::exclaim, tok::tilde)) return false; if (Left.is(tok::at) && - (Right.is(tok::identifier) || Right.is(tok::string_literal) || - Right.is(tok::char_constant) || Right.is(tok::numeric_constant) || - Right.is(tok::l_paren) || Right.is(tok::l_brace) || - Right.is(tok::kw_true) || Right.is(tok::kw_false))) + Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant, + tok::numeric_constant, tok::l_paren, tok::l_brace, + tok::kw_true, tok::kw_false)) return false; if (Left.is(tok::coloncolon)) return false; if (Right.is(tok::coloncolon)) - return Left.isNot(tok::identifier) && Left.isNot(tok::greater) && - Left.isNot(tok::l_paren); - if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less)) + return !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren); + if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) return false; if (Right.Type == TT_PointerOrReference) return Left.FormatTok.Tok.isLiteral() || @@ -1004,11 +992,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.is(tok::l_paren)) return false; if (Right.is(tok::l_paren)) { - return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) || - Left.is(tok::kw_for) || Left.is(tok::kw_while) || - Left.is(tok::kw_switch) || Left.is(tok::kw_return) || - Left.is(tok::kw_catch) || Left.is(tok::kw_new) || - Left.is(tok::kw_delete); + return Line.Type == LT_ObjCDecl || + Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, + tok::kw_return, tok::kw_catch, tok::kw_new, + tok::kw_delete); } if (Left.is(tok::at) && Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword) @@ -1045,9 +1032,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Tok.Type == TT_OverloadedOperatorLParen) return false; if (Tok.is(tok::colon)) - return Line.First.isNot(tok::kw_case) && - Line.First.isNot(tok::kw_default) && !Tok.Children.empty() && - Tok.Type != TT_ObjCMethodExpr; + return !Line.First.isOneOf(tok::kw_case, tok::kw_default) && + !Tok.Children.empty() && Tok.Type != TT_ObjCMethodExpr; if (Tok.is(tok::l_paren) && !Tok.Children.empty() && Tok.Children[0].Type == TT_PointerOrReference && !Tok.Children[0].Children.empty() && @@ -1056,8 +1042,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) return false; if (Tok.Type == TT_UnaryOperator) - return Tok.Parent->isNot(tok::l_paren) && - Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) && + return !Tok.Parent->isOneOf(tok::l_paren, tok::l_square, tok::at) && (Tok.Parent->isNot(tok::colon) || Tok.Parent->Type != TT_ObjCMethodExpr); if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) { @@ -1103,7 +1088,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || - Left.is(tok::question) || Left.is(tok::kw_operator)) + Left.isOneOf(tok::question, tok::kw_operator)) return false; if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) return false; @@ -1120,25 +1105,22 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // unless it is follow by ';', '{' or '='. if (Left.is(tok::kw_const) && Left.Parent != NULL && Left.Parent->is(tok::r_paren)) - return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) && - Right.isNot(tok::equal); + return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal); // We only break before r_brace if there was a corresponding break before // the l_brace, which is tracked by BreakBeforeClosingBrace. if (Right.is(tok::r_brace)) return false; - if (Right.is(tok::r_paren) || Right.is(tok::greater)) + if (Right.isOneOf(tok::r_paren, tok::greater)) return false; if (Left.is(tok::identifier) && Right.is(tok::string_literal)) return true; return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) || - Left.is(tok::comma) || Right.is(tok::lessless) || - Right.is(tok::arrow) || Right.is(tok::period) || - Right.is(tok::colon) || Left.is(tok::coloncolon) || - Left.is(tok::semi) || Left.is(tok::l_brace) || + Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace) || + Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) || (Left.is(tok::r_paren) && Left.Type != TT_CastRParen && - (Right.is(tok::identifier) || Right.is(tok::kw___attribute))) || + Right.isOneOf(tok::identifier, tok::kw___attribute)) || (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || (Left.is(tok::l_square) && !Right.is(tok::r_square)); } diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h index b79ee97da8..2b938363d5 100644 --- a/lib/Format/TokenAnnotator.h +++ b/lib/Format/TokenAnnotator.h @@ -79,6 +79,27 @@ public: } bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); } + + bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { + return is(K1) || is(K2); + } + + bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const { + return is(K1) || is(K2) || is(K3); + } + + bool isOneOf( + tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3, + tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS, + tok::TokenKind K6 = tok::NUM_TOKENS, tok::TokenKind K7 = tok::NUM_TOKENS, + tok::TokenKind K8 = tok::NUM_TOKENS, tok::TokenKind K9 = tok::NUM_TOKENS, + tok::TokenKind K10 = tok::NUM_TOKENS, + tok::TokenKind K11 = tok::NUM_TOKENS, + tok::TokenKind K12 = tok::NUM_TOKENS) const { + return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) || + is(K8) || is(K9) || is(K10) || is(K11) || is(K12); + } + bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); } bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {