aboutsummaryrefslogtreecommitdiff
path: root/lib/Format/Format.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2013-01-12 06:18:40 +0000
committerNico Weber <nicolasweber@gmx.de>2013-01-12 06:18:40 +0000
commitbcfdd263b79c766db9154b009bd831ef83090c83 (patch)
tree24b0b37482c08593683b605e7ab553f7e273fb51 /lib/Format/Format.cpp
parent5e9f91c342f8efffe0423d516997ddbc408c9f53 (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.cpp54
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 ||