Formatter: The contents of @selector() should be formatted as a selector.
Before: @selector(foo: )
Now: @selector(foo:)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172781 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index d1c3a4f..4b994e3 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -747,6 +747,25 @@
: CurrentToken(&RootToken), KeywordVirtualFound(false),
ColonIsObjCMethodExpr(false) {}
+ /// \brief A helper class to manage AnnotatingParser::ColonIsObjCMethodExpr.
+ struct ObjCSelectorRAII {
+ AnnotatingParser &P;
+ bool ColonWasObjCMethodExpr;
+
+ ObjCSelectorRAII(AnnotatingParser &P)
+ : P(P), ColonWasObjCMethodExpr(P.ColonIsObjCMethodExpr) {}
+
+ ~ObjCSelectorRAII() { P.ColonIsObjCMethodExpr = ColonWasObjCMethodExpr; }
+
+ void markStart(AnnotatedToken &Left) {
+ P.ColonIsObjCMethodExpr = true;
+ Left.Type = TT_ObjCMethodExpr;
+ }
+
+ void markEnd(AnnotatedToken &Right) { Right.Type = TT_ObjCMethodExpr; }
+ };
+
+
bool parseAngle() {
if (CurrentToken == NULL)
return false;
@@ -774,9 +793,23 @@
bool parseParens(bool LookForDecls = false) {
if (CurrentToken == NULL)
return false;
+ bool StartsObjCMethodExpr = false;
AnnotatedToken *Left = CurrentToken->Parent;
- if (CurrentToken->is(tok::caret))
+ if (CurrentToken->is(tok::caret)) {
+ // ^( starts a block.
Left->Type = TT_ObjCBlockLParen;
+ } else if (AnnotatedToken *MaybeSel = Left->Parent) {
+ // @selector( starts a selector.
+ if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent &&
+ MaybeSel->Parent->is(tok::at)) {
+ StartsObjCMethodExpr = true;
+ }
+ }
+
+ ObjCSelectorRAII objCSelector(*this);
+ if (StartsObjCMethodExpr)
+ objCSelector.markStart(*Left);
+
while (CurrentToken != NULL) {
// LookForDecls is set when "if (" has been seen. Check for
// 'identifier' '*' 'identifier' followed by not '=' -- this
@@ -796,6 +829,10 @@
if (CurrentToken->is(tok::r_paren)) {
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
+
+ if (StartsObjCMethodExpr)
+ objCSelector.markEnd(*CurrentToken);
+
next();
return true;
}
@@ -824,18 +861,14 @@
getBinOpPrecedence(LSquare->Parent->FormatTok.Tok.getKind(),
true, true) > prec::Unknown;
- bool ColonWasObjCMethodExpr = ColonIsObjCMethodExpr;
- if (StartsObjCMethodExpr) {
- ColonIsObjCMethodExpr = true;
- LSquare->Type = TT_ObjCMethodExpr;
- }
+ ObjCSelectorRAII objCSelector(*this);
+ if (StartsObjCMethodExpr)
+ objCSelector.markStart(*LSquare);
while (CurrentToken != NULL) {
if (CurrentToken->is(tok::r_square)) {
- if (StartsObjCMethodExpr) {
- ColonIsObjCMethodExpr = ColonWasObjCMethodExpr;
- CurrentToken->Type = TT_ObjCMethodExpr;
- }
+ if (StartsObjCMethodExpr)
+ objCSelector.markEnd(*CurrentToken);
next();
return true;
}
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 7b57e85..a762068 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -533,7 +533,7 @@
"static A x = { { { init1, init2, init3, init4 },\n"
" { init1, init2, init3, init4 } } };");
- // FIXME: Fix this in general an verify that it works in LLVM style again.
+ // FIXME: Fix this in general and verify that it works in LLVM style again.
verifyGoogleFormat(
"somes Status::global_reps[3] = {\n"
" { kGlobalRef, OK_CODE, NULL, NULL, NULL },\n"
@@ -545,7 +545,7 @@
" { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop"
" } };");
- // FIXME: We might at some point want to handle this similar to parameters
+ // FIXME: We might at some point want to handle this similar to parameter
// lists, where we have an option to put each on a single line.
verifyFormat("struct {\n"
" unsigned bit;\n"
@@ -1869,7 +1869,7 @@
verifyFormat("@dynamic textColor;");
//verifyFormat("char *buf1 = @encode(int **);");
verifyFormat("Protocol *proto = @protocol(p1);");
- //verifyFormat("SEL s = @selector(foo:);");
+ verifyFormat("SEL s = @selector(foo:);");
verifyFormat("@synchronized(self) {\n"
" f();\n"
"}");