return parseAccessSpecifier();
case tok::objc_interface:
return parseObjCInterface();
+ case tok::objc_protocol:
+ return parseObjCProtocol();
default:
break;
}
} while (!eof());
}
+void UnwrappedLineParser::parseObjCProtocolList() {
+ assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
+ do
+ nextToken();
+ while (!eof() && FormatTok.Tok.isNot(tok::greater));
+ nextToken(); // Skip '>'.
+}
+
+void UnwrappedLineParser::parseObjCUntilAtEnd() {
+ do {
+ if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
+ nextToken();
+ addUnwrappedLine();
+ break;
+ }
+ parseStructuralElement();
+ } while (!eof());
+}
+
void UnwrappedLineParser::parseObjCInterface() {
nextToken();
nextToken(); // interface name
// Skip category, if present.
parseParens();
- // Skip protocol list, if present.
- if (FormatTok.Tok.is(tok::less)) {
- do
- nextToken();
- while (!eof() && FormatTok.Tok.isNot(tok::greater));
- nextToken(); // Skip '>'.
- }
+ if (FormatTok.Tok.is(tok::less))
+ parseObjCProtocolList();
// If instance variables are present, keep the '{' on the first line too.
if (FormatTok.Tok.is(tok::l_brace))
// variables, this ends the @interface line.
addUnwrappedLine();
- // Read everything up to the @end.
- do {
- if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
- nextToken();
- addUnwrappedLine();
- break;
- }
+ parseObjCUntilAtEnd();
+}
- parseStructuralElement();
- } while (!eof());
+void UnwrappedLineParser::parseObjCProtocol() {
+ nextToken();
+ nextToken(); // protocol name
+
+ if (FormatTok.Tok.is(tok::less))
+ parseObjCProtocolList();
+
+ // Check for protocol declaration.
+ if (FormatTok.Tok.is(tok::semi)) {
+ nextToken();
+ return addUnwrappedLine();
+ }
+
+ addUnwrappedLine();
+ parseObjCUntilAtEnd();
}
void UnwrappedLineParser::addUnwrappedLine() {
*/
+ ClassMethodMyProto;
@end
-// CHECK: <Declaration>@protocol MyProto @end</Declaration>
+// CHECK: <Declaration>@protocol MyProto\n@end</Declaration>
// CHECK: <Declaration>- (unsigned int)MethodMyProto:(id)anObject inRange:(unsigned int)range;</Declaration>
// CHECK: <Declaration>@optional\n @property(readwrite, copy, atomic) id PropertyMyProto;</Declaration>
// CHECK: <Declaration>+ (id)ClassMethodMyProto;</Declaration>
"@end");
}
+TEST_F(FormatTest, FormatObjCProtocol) {
+ verifyFormat("@protocol Foo\n"
+ "@property(weak) id delegate;\n"
+ "- (NSUInteger)numberOfThings;\n"
+ "@end");
+
+ // FIXME: In LLVM style, there should be a space before '<' for protocols.
+ verifyFormat("@protocol MyProtocol<NSObject>\n"
+ "- (NSUInteger)numberOfThings;\n"
+ "@end");
+
+ verifyFormat("@protocol Foo;\n"
+ "@protocol Bar;\n");
+}
+
TEST_F(FormatTest, ObjCAt) {
verifyFormat("@autoreleasepool");
verifyFormat("@catch");