diff options
author | Nico Weber <nicolasweber@gmx.de> | 2013-01-12 06:18:40 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2013-01-12 06:18:40 +0000 |
commit | bcfdd263b79c766db9154b009bd831ef83090c83 (patch) | |
tree | 24b0b37482c08593683b605e7ab553f7e273fb51 /lib/Format/Format.cpp | |
parent | 5e9f91c342f8efffe0423d516997ddbc408c9f53 (diff) |
Formatter: Initial support for formatting Objective-C method expressions.
This follows the approach suggested by djasper in PR14911: When a '[' is
seen that's at the start of a line, follows a binary operator, or follows one
of : [ ( return throw, that '[' and its closing ']' are marked as
TT_ObjCMethodExpr and every ':' in that range that isn't part of a ternary
?: is marked as TT_ObjCMethodExpr as well.
Update the layout routines to not output spaces around ':' tokens that are
marked TT_ObjCMethodExpr, and only allow breaking after such tokens, not
before.
Before:
[self adjustButton : closeButton_ ofKind : NSWindowCloseButton];
Now:
[self adjustButton:closeButton_ ofKind:NSWindowCloseButton];
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172304 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/Format.cpp')
-rw-r--r-- | lib/Format/Format.cpp | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index aa534b9ef3..0c486e0be3 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -39,6 +39,7 @@ enum TokenType { TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCMethodSpecifier, + TT_ObjCMethodExpr, TT_ObjCSelectorStart, TT_ObjCProperty, TT_OverloadedOperator, @@ -613,7 +614,8 @@ public: class AnnotatingParser { public: AnnotatingParser(AnnotatedToken &RootToken) - : CurrentToken(&RootToken), KeywordVirtualFound(false) {} + : CurrentToken(&RootToken), KeywordVirtualFound(false), + ColonIsObjCMethodExpr(false) {} bool parseAngle() { while (CurrentToken != NULL) { @@ -651,8 +653,34 @@ public: } bool parseSquare() { + if (!CurrentToken) + return false; + + // A '[' could be an index subscript (after an indentifier or after + // ')' or ']'), or it could be the start of an Objective-C method + // expression. + AnnotatedToken *LSquare = CurrentToken->Parent; + bool StartsObjCMethodExpr = + !LSquare->Parent || LSquare->Parent->is(tok::colon) || + LSquare->Parent->is(tok::l_square) || + LSquare->Parent->is(tok::l_paren) || + LSquare->Parent->is(tok::kw_return) || + LSquare->Parent->is(tok::kw_throw) || + getBinOpPrecedence(LSquare->Parent->FormatTok.Tok.getKind(), + true, true) > prec::Unknown; + + bool ColonWasObjCMethodExpr = ColonIsObjCMethodExpr; + if (StartsObjCMethodExpr) { + ColonIsObjCMethodExpr = true; + LSquare->Type = TT_ObjCMethodExpr; + } + while (CurrentToken != NULL) { if (CurrentToken->is(tok::r_square)) { + if (StartsObjCMethodExpr) { + ColonIsObjCMethodExpr = ColonWasObjCMethodExpr; + CurrentToken->Type = TT_ObjCMethodExpr; + } next(); return true; } @@ -716,6 +744,11 @@ public: if (Tok->Parent == NULL) Tok->Type = TT_ObjCMethodSpecifier; break; + case tok::colon: + // Colons from ?: are handled in parseConditional(). + if (ColonIsObjCMethodExpr) + Tok->Type = TT_ObjCMethodExpr; + break; case tok::l_paren: { bool ParensWereObjCReturnType = Tok->Parent && Tok->Parent->Type == TT_ObjCMethodSpecifier; @@ -841,6 +874,7 @@ public: private: AnnotatedToken *CurrentToken; bool KeywordVirtualFound; + bool ColonIsObjCMethodExpr; }; void createAnnotatedTokens(AnnotatedToken &Current) { @@ -1048,8 +1082,9 @@ private: Style.PointerAndReferenceBindToType; if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; - if (Left.is(tok::l_square) || Right.is(tok::l_square) || - Right.is(tok::r_square)) + if (Left.is(tok::l_square) || Right.is(tok::r_square)) + return false; + if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) return false; if (Left.is(tok::coloncolon) || (Right.is(tok::coloncolon) && @@ -1057,8 +1092,10 @@ private: return false; if (Left.is(tok::period) || Right.is(tok::period)) return false; - if (Left.is(tok::colon) || Right.is(tok::colon)) - return true; + if (Left.is(tok::colon)) + return Left.Type != TT_ObjCMethodExpr; + if (Right.is(tok::colon)) + return Right.Type != TT_ObjCMethodExpr; if (Left.is(tok::l_paren)) return false; if (Right.is(tok::l_paren)) { @@ -1106,7 +1143,8 @@ private: if (Tok.Parent->Type == TT_OverloadedOperator) return false; if (Tok.is(tok::colon)) - return RootToken.isNot(tok::kw_case) && (!Tok.Children.empty()); + return RootToken.isNot(tok::kw_case) && !Tok.Children.empty() && + Tok.Type != TT_ObjCMethodExpr; if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) return false; @@ -1148,6 +1186,10 @@ private: // Don't break at ':' if identifier before it can beak. return false; } + if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr) + return false; + if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) + return true; if (Left.ClosesTemplateDeclaration) return true; if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || |