Bug 1358246: Report syntax error for stray "async" keyword in object literal property name. r=shu
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 28 Apr 2017 16:34:16 +0200
changeset 355564 de04eca510ed09012bd46b1bf3625fb5107d9dfe
parent 355563 7f3a44bd3ef991186ac60484e2154677b5f9074b
child 355565 2282846d3ef2ab8216e8535d531f30c1110f3cd0
push id89694
push userarchaeopteryx@coole-files.de
push dateFri, 28 Apr 2017 14:35:25 +0000
treeherdermozilla-inbound@de04eca510ed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1358246
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1358246: Report syntax error for stray "async" keyword in object literal property name. r=shu
js/src/frontend/Parser.cpp
js/src/tests/ecma_2017/AsyncFunctions/async-property-name-error.js
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -9621,30 +9621,45 @@ Parser<ParseHandler, CharT>::propertyNam
         propAtom.set(DoubleToAtom(context, tokenStream.currentToken().number()));
         if (!propAtom.get())
             return null();
         propName = newNumber(tokenStream.currentToken());
         if (!propName)
             return null();
         break;
 
+      case TOK_STRING: {
+        propAtom.set(tokenStream.currentToken().atom());
+        uint32_t index;
+        if (propAtom->isIndex(&index)) {
+            propName = handler.newNumber(index, NoDecimal, pos());
+            if (!propName)
+                return null();
+            break;
+        }
+        propName = stringLiteral();
+        if (!propName)
+            return null();
+        break;
+      }
+
       case TOK_LB:
         propName = computedPropertyName(yieldHandling, maybeDecl, propList);
         if (!propName)
             return null();
         break;
 
       default: {
         if (!TokenKindIsPossibleIdentifierName(ltok)) {
             error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
             return null();
         }
 
         propAtom.set(tokenStream.currentName());
-        // Do not look for accessor syntax on generators
+        // Do not look for accessor syntax on generator or async methods.
         if (isGenerator || isAsync || !(ltok == TOK_GET || ltok == TOK_SET)) {
             propName = handler.newObjectLiteralPropertyName(propAtom, pos());
             if (!propName)
                 return null();
             break;
         }
 
         *propType = ltok == TOK_GET ? PropertyType::Getter : PropertyType::Setter;
@@ -9689,50 +9704,35 @@ Parser<ParseHandler, CharT>::propertyNam
         }
 
         // Not an accessor property after all.
         propName = handler.newObjectLiteralPropertyName(propAtom.get(), pos());
         if (!propName)
             return null();
         break;
       }
-
-      case TOK_STRING: {
-        propAtom.set(tokenStream.currentToken().atom());
-        uint32_t index;
-        if (propAtom->isIndex(&index)) {
-            propName = handler.newNumber(index, NoDecimal, pos());
-            if (!propName)
-                return null();
-            break;
-        }
-        propName = stringLiteral();
-        if (!propName)
-            return null();
-        break;
-      }
     }
 
     TokenKind tt;
     if (!tokenStream.getToken(&tt))
         return null();
 
     if (tt == TOK_COLON) {
-        if (isGenerator) {
+        if (isGenerator || isAsync) {
             error(JSMSG_BAD_PROP_ID);
             return null();
         }
         *propType = PropertyType::Normal;
         return propName;
     }
 
     if (TokenKindIsPossibleIdentifierName(ltok) &&
         (tt == TOK_COMMA || tt == TOK_RC || tt == TOK_ASSIGN))
     {
-        if (isGenerator) {
+        if (isGenerator || isAsync) {
             error(JSMSG_BAD_PROP_ID);
             return null();
         }
         tokenStream.ungetToken();
         *propType = tt == TOK_ASSIGN ?
                           PropertyType::CoverInitializedName :
                           PropertyType::Shorthand;
         return propName;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2017/AsyncFunctions/async-property-name-error.js
@@ -0,0 +1,21 @@
+function assertSyntaxError(code) {
+    assertThrowsInstanceOf(() => { Function(code); }, SyntaxError, "Function:" + code);
+    assertThrowsInstanceOf(() => { eval(code); }, SyntaxError, "eval:" + code);
+    var ieval = eval;
+    assertThrowsInstanceOf(() => { ieval(code); }, SyntaxError, "indirect eval:" + code);
+}
+
+assertSyntaxError(`({async async: 0})`);
+assertSyntaxError(`({async async})`);
+assertSyntaxError(`({async async, })`);
+assertSyntaxError(`({async async = 0} = {})`);
+
+for (let decl of ["var", "let", "const"]) {
+    assertSyntaxError(`${decl} {async async: a} = {}`);
+    assertSyntaxError(`${decl} {async async} = {}`);
+    assertSyntaxError(`${decl} {async async, } = {}`);
+    assertSyntaxError(`${decl} {async async = 0} = {}`);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);