Formatter: Initial support for ObjC dictionary literals.
authorNico Weber <nicolasweber@gmx.de>
Sun, 10 Feb 2013 20:35:35 +0000 (20:35 +0000)
committerNico Weber <nicolasweber@gmx.de>
Sun, 10 Feb 2013 20:35:35 +0000 (20:35 +0000)
Before:
  @{
  foo:
    bar
  }
  ;

Now:
  @{ foo : bar };

parseBracedList() already does the right thing from an UnwrappedLineParser
perspective, so check for "@{" in all loops that process constructs that can
contain expressions and call parseBracedList() if found.

llvm-svn: 174840

clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp

index 36307e0..cb95608 100644 (file)
@@ -188,7 +188,8 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
   return Error;
 }
 
-bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels) {
+bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
+                                     unsigned AddLevels) {
   assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
   nextToken();
 
@@ -265,6 +266,10 @@ void UnwrappedLineParser::parseStructuralElement() {
   switch (FormatTok.Tok.getKind()) {
   case tok::at:
     nextToken();
+    if (FormatTok.Tok.is(tok::l_brace)) {
+      parseBracedList();
+      break;
+    }
     switch (FormatTok.Tok.getObjCKeywordID()) {
     case tok::objc_public:
     case tok::objc_protected:
@@ -344,6 +349,11 @@ void UnwrappedLineParser::parseStructuralElement() {
   do {
     ++TokenNumber;
     switch (FormatTok.Tok.getKind()) {
+    case tok::at:
+      nextToken();
+      if (FormatTok.Tok.is(tok::l_brace))
+        parseBracedList();
+      break;
     case tok::kw_enum:
       parseEnum();
       break;
@@ -457,6 +467,11 @@ void UnwrappedLineParser::parseParens() {
       Line->Level -= 1;
       break;
     }
+    case tok::at:
+      nextToken();
+      if (FormatTok.Tok.is(tok::l_brace))
+        parseBracedList();
+      break;
     default:
       nextToken();
       break;
index 4e44f5e..6d434ca 100644 (file)
@@ -2546,9 +2546,21 @@ TEST_F(FormatTest, ObjCLiterals) {
       "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
   verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
 
-  // FIXME: Array and dictionary literals need more work.
   verifyFormat("@{");
-
+  verifyFormat("@{}");
+  verifyFormat("@{ @\"one\" : @1 }");
+  verifyFormat("return @{ @\"one\" : @1 };");
+  verifyFormat("@{ @\"one\" : @1, }");
+  verifyFormat("@{ @\"one\" : @{ @2 : @1 } }");
+  verifyFormat("@{ @\"one\" : @{ @2 : @1 }, }");
+  verifyFormat("@{ 1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2 }");
+  verifyFormat("[self setDict:@{}");
+  verifyFormat("[self setDict:@{ @1 : @2 }");
+  verifyFormat("NSLog(@\"%@\", @{ @1 : @2, @2 : @3 }[@1]);");
+  verifyFormat(
+      "NSDictionary *masses = @{ @\"H\" : @1.0078, @\"He\" : @4.0026 };");
+  
+  // FIXME: Nested and multi-line array and dictionary literals need more work.
 }
 
 TEST_F(FormatTest, ReformatRegionAdjustsIndent) {