Formatting: Add support for @protocol.

Pull pieces of the @interface code into reusable methods.

llvm-svn: 172001
This commit is contained in:
Nico Weber 2013-01-09 21:15:03 +00:00
parent 5652a8df32
commit 8696a8d9e3
4 changed files with 59 additions and 17 deletions

View File

@ -210,6 +210,8 @@ void UnwrappedLineParser::parseStructuralElement() {
return parseAccessSpecifier();
case tok::objc_interface:
return parseObjCInterface();
case tok::objc_protocol:
return parseObjCProtocol();
default:
break;
}
@ -496,6 +498,25 @@ void UnwrappedLineParser::parseStructOrClass() {
} 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
@ -508,13 +529,8 @@ void UnwrappedLineParser::parseObjCInterface() {
// 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))
@ -524,16 +540,24 @@ void UnwrappedLineParser::parseObjCInterface() {
// 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() {

View File

@ -142,7 +142,10 @@ private:
void parseAccessSpecifier();
void parseEnum();
void parseStructOrClass();
void parseObjCProtocolList();
void parseObjCUntilAtEnd();
void parseObjCInterface();
void parseObjCProtocol();
void addUnwrappedLine();
bool eof() const;
void nextToken();

View File

@ -30,7 +30,7 @@
*/
+ 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>

View File

@ -1249,6 +1249,21 @@ TEST_F(FormatTest, FormatObjCInterface) {
"@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");