r294315 - clang-format: [JS] correcly format object literal methods.

Martin Probst via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 7 08:33:13 PST 2017


Author: mprobst
Date: Tue Feb  7 10:33:13 2017
New Revision: 294315

URL: http://llvm.org/viewvc/llvm-project?rev=294315&view=rev
Log:
clang-format: [JS] correcly format object literal methods.

Summary:
In JavaScript, object literals can contain methods:

   var x = {
     a() { return 1; },
   };

Previously, clang-format always parsed nested {} inside a braced list as
further braced lists. Special case this logic for JavaScript to try
parsing as a braced list, but fall back to parsing as a child block.

Reviewers: djasper

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D29656

Modified:
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp
    cfe/trunk/unittests/Format/FormatTestJS.cpp

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=294315&r1=294314&r2=294315&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Tue Feb  7 10:33:13 2017
@@ -2648,6 +2648,7 @@ void TokenAnnotator::printDebugInfo(cons
                  << " T=" << getTokenTypeName(Tok->Type)
                  << " S=" << Tok->SpacesRequiredBefore
                  << " B=" << Tok->BlockParameterCount
+                 << " BK=" << Tok->BlockKind
                  << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
                  << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
                  << " FakeLParens=";

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=294315&r1=294314&r2=294315&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Feb  7 10:33:13 2017
@@ -335,8 +335,11 @@ void UnwrappedLineParser::calculateBrace
     case tok::l_brace:
       if (Style.Language == FormatStyle::LK_JavaScript && PrevTok &&
           PrevTok->is(tok::colon))
-        // In TypeScript's TypeMemberLists, there can be semicolons between the
-        // individual members.
+        // A colon indicates this code is in a type, or a braced list following
+        // a label in an object literal ({a: {b: 1}}).
+        // The code below could be confused by semicolons between the individual
+        // members in a type member list, which would normally trigger BK_Block.
+        // In both cases, this must be parsed as an inline braced init.
         Tok->BlockKind = BK_BracedInit;
       else
         Tok->BlockKind = BK_Unknown;
@@ -1298,6 +1301,12 @@ bool UnwrappedLineParser::parseBracedLis
           continue;
         }
       }
+      if (FormatTok->is(tok::l_brace)) {
+        // Could be a method inside of a braced list `{a() { return 1; }}`.
+        if (tryToParseBracedList())
+          continue;
+        parseChildBlock();
+      }
     }
     switch (FormatTok->Tok.getKind()) {
     case tok::caret:
@@ -1309,12 +1318,6 @@ bool UnwrappedLineParser::parseBracedLis
     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).
-      FormatTok->BlockKind = BK_BracedInit;
-      parseBracedList();
-      break;
     case tok::l_paren:
       parseParens();
       // JavaScript can just have free standing methods and getters/setters in
@@ -1325,6 +1328,12 @@ bool UnwrappedLineParser::parseBracedLis
         break;
       }
       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).
+      FormatTok->BlockKind = BK_BracedInit;
+      parseBracedList();
+      break;
     case tok::r_brace:
       nextToken();
       return !HasError;

Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=294315&r1=294314&r2=294315&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Tue Feb  7 10:33:13 2017
@@ -240,6 +240,18 @@ TEST_F(FormatTestJS, ContainerLiterals)
                "};");
   verifyFormat("var x = {y: (a) => a};");
 
+  // Methods in object literals.
+  verifyFormat("var x = {\n"
+               "  y(a: string): number {\n"
+               "    return a;\n"
+               "  }\n"
+               "};");
+  verifyFormat("var x = {\n"
+               "  y(a: string) {\n"
+               "    return a;\n"
+               "  }\n"
+               "};");
+
   // Computed keys.
   verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};");
   verifyFormat("var x = {\n"




More information about the cfe-commits mailing list