[cfe-commits] r171995 - in /cfe/trunk: lib/Format/UnwrappedLineParser.cpp lib/Format/UnwrappedLineParser.h unittests/Format/FormatTest.cpp

Nico Weber nicolasweber at gmx.de
Wed Jan 9 12:25:35 PST 2013


Author: nico
Date: Wed Jan  9 14:25:35 2013
New Revision: 171995

URL: http://llvm.org/viewvc/llvm-project?rev=171995&view=rev
Log:
Formatter: Add support for @interface.

Previously:
@interface Foo + (id)init; @end

Now:
@interface Foo
+ (id)init;
@end

Some tweaking remains, but this is a good first step.


Modified:
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp
    cfe/trunk/lib/Format/UnwrappedLineParser.h
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=171995&r1=171994&r2=171995&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Wed Jan  9 14:25:35 2013
@@ -208,6 +208,8 @@
     case tok::objc_package:
     case tok::objc_private:
       return parseAccessSpecifier();
+    case tok::objc_interface:
+      return parseObjCInterface();
     default:
       break;
     }
@@ -494,6 +496,46 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseObjCInterface() {
+  nextToken();
+  nextToken();  // interface name
+
+  // @interface can be followed by either a base class, or a category.
+  if (FormatTok.Tok.is(tok::colon)) {
+    nextToken();
+    nextToken();  // base class name
+  } else if (FormatTok.Tok.is(tok::l_paren))
+    // 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 instance variables are present, keep the '{' on the first line too.
+  if (FormatTok.Tok.is(tok::l_brace))
+    parseBlock();
+
+  // With instance variables, this puts '}' on its own line.  Without instance
+  // variables, this ends the @interface line.
+  addUnwrappedLine();
+
+  // Read everything up to the @end.
+  do {
+    if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
+      nextToken();
+      addUnwrappedLine();
+      break;
+    }
+
+    parseStructuralElement();
+  } while (!eof());
+}
+
 void UnwrappedLineParser::addUnwrappedLine() {
   if (!RootTokenInitialized)
     return;

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=171995&r1=171994&r2=171995&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Wed Jan  9 14:25:35 2013
@@ -142,6 +142,7 @@
   void parseAccessSpecifier();
   void parseEnum();
   void parseStructOrClass();
+  void parseObjCInterface();
   void addUnwrappedLine();
   bool eof() const;
   void nextToken();

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=171995&r1=171994&r2=171995&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Jan  9 14:25:35 2013
@@ -443,34 +443,6 @@
                "}");
 }
 
-TEST_F(FormatTest, FormatObjCInterface) {
-  verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyGoogleFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
-                     " @public\n"
-                     "  int field1;\n"
-                     " @protected\n"
-                     "  int field2;\n"
-                     " @private\n"
-                     "  int field3;\n"
-                     " @package\n"
-                     "  int field4;\n"
-                     "}\n"
-                     "+ (id)init;\n"
-                     "@end");
-}
-
 TEST_F(FormatTest, StaticInitializers) {
   verifyFormat("static SomeClass SC = { 1, 'a' };");
 
@@ -1180,6 +1152,103 @@
   verifyFormat("int (^Block1) (int, int) = ^(int i, int j)");
 }
 
+TEST_F(FormatTest, FormatObjCInterface) {
+  // FIXME: Handle comments like in "@interface /* wait for it */ Foo", PR14875
+  // FIXME: In google style, it's "+(id) init", not "+ (id)init".
+  verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  // FIXME: In LLVM style, there should be a space before '<' for protocols.
+  verifyGoogleFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
+                     " @public\n"
+                     "  int field1;\n"
+                     " @protected\n"
+                     "  int field2;\n"
+                     " @private\n"
+                     "  int field3;\n"
+                     " @package\n"
+                     "  int field4;\n"
+                     "}\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface Foo\n"
+               "+ (id)init;\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i;\n"
+               "@end");
+
+  verifyFormat("@interface Foo\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar<Baz, Quux>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  // FIXME: there should be a space before '(' for categories.
+  verifyFormat("@interface Foo(HackStuff)\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo()\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo(HackStuff)<MyProtocol>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar<Baz, Quux> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo(HackStuff) {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo() {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo(HackStuff)<MyProtocol> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+}
+
 TEST_F(FormatTest, ObjCAt) {
   verifyFormat("@autoreleasepool");
   verifyFormat("@catch");





More information about the cfe-commits mailing list