From 1abe6ea5b8961a0fc14c2e0bdbd7451f643ca065 Mon Sep 17 00:00:00 2001 From: Nico Weber <nicolasweber@gmx.de> Date: Wed, 9 Jan 2013 21:15:03 +0000 Subject: [PATCH] Formatting: Add support for @protocol. Pull pieces of the @interface code into reusable methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172001 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/UnwrappedLineParser.cpp | 56 +++++++++++++++++++++--------- lib/Format/UnwrappedLineParser.h | 3 ++ test/Index/comment-objc-decls.m | 2 +- unittests/Format/FormatTest.cpp | 15 ++++++++ 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 131d982906..688937c1e6 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -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() { diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 28ef235190..303afc2d98 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -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(); diff --git a/test/Index/comment-objc-decls.m b/test/Index/comment-objc-decls.m index 4b9a4bcaba..4c9f878c35 100644 --- a/test/Index/comment-objc-decls.m +++ b/test/Index/comment-objc-decls.m @@ -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> diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 4decf94c76..e06544a95f 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -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"); -- 2.40.0