[cfe-commits] r172304 - in /cfe/trunk: lib/Format/Format.cpp unittests/Format/FormatTest.cpp
Nico Weber
nicolasweber at gmx.de
Fri Jan 11 22:18:41 PST 2013
Author: nico
Date: Sat Jan 12 00:18:40 2013
New Revision: 172304
URL: http://llvm.org/viewvc/llvm-project?rev=172304&view=rev
Log:
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];
Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=172304&r1=172303&r2=172304&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Sat Jan 12 00:18:40 2013
@@ -39,6 +39,7 @@
TT_ObjCBlockLParen,
TT_ObjCDecl,
TT_ObjCMethodSpecifier,
+ TT_ObjCMethodExpr,
TT_ObjCSelectorStart,
TT_ObjCProperty,
TT_OverloadedOperator,
@@ -613,7 +614,8 @@
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 @@
}
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 @@
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 @@
private:
AnnotatedToken *CurrentToken;
bool KeywordVirtualFound;
+ bool ColonIsObjCMethodExpr;
};
void createAnnotatedTokens(AnnotatedToken &Current) {
@@ -1048,8 +1082,9 @@
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 @@
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 @@
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 @@
// 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 ||
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=172304&r1=172303&r2=172304&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Sat Jan 12 00:18:40 2013
@@ -1468,6 +1468,67 @@
"@end\n");
}
+TEST_F(FormatTest, FormatObjCMethodExpr) {
+ verifyFormat("[foo bar:baz];");
+ verifyFormat("return [foo bar:baz];");
+ verifyFormat("f([foo bar:baz]);");
+ verifyFormat("f(2, [foo bar:baz]);");
+ verifyFormat("f(2, a ? b : c);");
+ verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
+
+ verifyFormat("[foo bar:baz], [foo bar:baz];");
+ verifyFormat("[foo bar:baz] = [foo bar:baz];");
+ verifyFormat("[foo bar:baz] *= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] /= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] %= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] += [foo bar:baz];");
+ verifyFormat("[foo bar:baz] -= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] &= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] |= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
+ verifyFormat("[foo bar:baz] || [foo bar:baz];");
+ verifyFormat("[foo bar:baz] && [foo bar:baz];");
+ verifyFormat("[foo bar:baz] | [foo bar:baz];");
+ verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
+ verifyFormat("[foo bar:baz] & [foo bar:baz];");
+ verifyFormat("[foo bar:baz] == [foo bar:baz];");
+ verifyFormat("[foo bar:baz] != [foo bar:baz];");
+ verifyFormat("[foo bar:baz] >= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] <= [foo bar:baz];");
+ verifyFormat("[foo bar:baz] > [foo bar:baz];");
+ verifyFormat("[foo bar:baz] < [foo bar:baz];");
+ verifyFormat("[foo bar:baz] >> [foo bar:baz];");
+ verifyFormat("[foo bar:baz] << [foo bar:baz];");
+ verifyFormat("[foo bar:baz] - [foo bar:baz];");
+ verifyFormat("[foo bar:baz] + [foo bar:baz];");
+ verifyFormat("[foo bar:baz] * [foo bar:baz];");
+ verifyFormat("[foo bar:baz] / [foo bar:baz];");
+ verifyFormat("[foo bar:baz] % [foo bar:baz];");
+ // Whew!
+
+ verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
+ verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
+ verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
+ verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
+ verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
+
+
+ verifyFormat("arr[[self indexForFoo:a]];");
+ verifyFormat("throw [self errorFor:a];");
+ verifyFormat("@throw [self errorFor:a];");
+
+ // The formatting of this isn't ideal yet. It tests that the formatter doesn't
+ // break after "backing" but before ":", which would be at 80 columns.
+ verifyFormat(
+ "void f() {\n"
+ " if ((self = [super initWithContentRect:contentRect styleMask:\n"
+ " styleMask backing:NSBackingStoreBuffered defer:YES]))");
+
+}
+
TEST_F(FormatTest, ObjCAt) {
verifyFormat("@autoreleasepool");
verifyFormat("@catch");
More information about the cfe-commits
mailing list