: 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;
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
if (CurrentToken->is(tok::r_paren)) {
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
+
+ if (StartsObjCMethodExpr)
+ objCSelector.markEnd(*CurrentToken);
+
next();
return true;
}
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;
}
"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"
" { 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"
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"
"}");