]> granicus.if.org Git - clang/commitdiff
Implement parsing of blocks (^{ ... }) in the unwrapped line parser.
authorManuel Klimek <klimek@google.com>
Wed, 4 Sep 2013 13:25:30 +0000 (13:25 +0000)
committerManuel Klimek <klimek@google.com>
Wed, 4 Sep 2013 13:25:30 +0000 (13:25 +0000)
This patch makes sure we produce the right number of unwrapped lines,
a follow-up patch will make the whitespace formatting consistent.

Before:
 void f() {
   int i = {[operation setCompletionBlock : ^{ [self onOperationDone];
 }]
 }
 ;
 }

After:
 void f() {
   int i = {[operation setCompletionBlock : ^{
     [self onOperationDone];
   }] };
 }

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189932 91177308-0d34-0410-b5e6-96231b3b80d8

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

index f58ee823032d6b47c62fb91225c5e66d0d1c311c..c780fdb566da3c48482a96e570b1cb205d9c313a 100644 (file)
@@ -346,6 +346,20 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel) {
   Line->Level = InitialLevel;
 }
 
+void UnwrappedLineParser::parseChildBlock() {
+  FormatTok->BlockKind = BK_Block;
+  nextToken();
+  {
+    ScopedLineState LineState(*this);
+    ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
+                                            /*MustBeDeclaration=*/false);
+    Line->Level += 1;
+    parseLevel(/*HasOpeningBrace=*/true);
+    Line->Level -= 1;
+  }
+  nextToken();
+}
+
 void UnwrappedLineParser::parsePPDirective() {
   assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
   ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
@@ -591,6 +605,12 @@ void UnwrappedLineParser::parseStructuralElement() {
     case tok::l_paren:
       parseParens();
       break;
+    case tok::caret:
+      nextToken();
+      if (FormatTok->is(tok::l_brace)) {
+        parseChildBlock();
+      }
+      break;
     case tok::l_brace:
       if (!tryToParseBracedList()) {
         // A block outside of parentheses must be the last part of a
@@ -674,17 +694,7 @@ void UnwrappedLineParser::tryToParseLambda() {
         break;
     }
   }
-  FormatTok->BlockKind = BK_Block;
-  nextToken();
-  {
-    ScopedLineState LineState(*this);
-    ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
-                                            /*MustBeDeclaration=*/false);
-    Line->Level += 1;
-    parseLevel(/*HasOpeningBrace=*/true);
-    Line->Level -= 1;
-  }
-  nextToken();
+  parseChildBlock();
 }
 
 bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
@@ -741,9 +751,15 @@ void UnwrappedLineParser::parseBracedList() {
     // here, otherwise our bail-out scenarios below break. The better solution
     // might be to just implement a more or less complete expression parser.
     switch (FormatTok->Tok.getKind()) {
-      case tok::l_square:
-        tryToParseLambda();
-        break;
+    case tok::caret:
+      nextToken();
+      if (FormatTok->is(tok::l_brace)) {
+        parseChildBlock();
+      }
+      break;
+    case tok::l_square:
+      tryToParseLambda();
+      break;
     case tok::l_brace:
       // Assume there are no blocks inside a braced init list apart
       // from the ones we explicitly parse out (like lambdas).
index 4660b1dbac255f9139ac4fbecf18f8ff8c6571b1..5c59da3bebc39945e5f5e74d2d9a01564550f0b0 100644 (file)
@@ -66,6 +66,7 @@ private:
   void parseFile();
   void parseLevel(bool HasOpeningBrace);
   void parseBlock(bool MustBeDeclaration, bool AddLevel = true);
+  void parseChildBlock();
   void parsePPDirective();
   void parsePPDefine();
   void parsePPIf();
index d2b2dfd99b3e00c9afb027d0cf24d4b1b2b36b33..32226fc501e3a4f12a8c69d08fee3e27f74d90f6 100644 (file)
@@ -6311,5 +6311,16 @@ TEST_F(FormatTest, FormatsLambdas) {
       "}\n");
 }
 
+TEST_F(FormatTest, FormatsBlocks) {
+  // FIXME: Make whitespace formatting consistent. Ask a ObjC dev how
+  // it would ideally look.
+  verifyFormat("[operation setCompletionBlock:^{\n"
+               "  [self onOperationDone];\n"
+               "}];\n");
+  verifyFormat("int i = {[operation setCompletionBlock : ^{\n"
+               "  [self onOperationDone];\n"
+               "}] };\n");
+}
+
 } // end namespace tooling
 } // end namespace clang