From 3a59b5a15147d68916f7edc0529340cf35c8e836 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 12:06:42 +1100 Subject: [PATCH] better async contextual identifiers --- acorn.js | 50 +++++++------- test/tests-6to5.js | 168 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 24 deletions(-) diff --git a/acorn.js b/acorn.js index 9da6054829..3eae0e4afe 100644 --- a/acorn.js +++ b/acorn.js @@ -2079,15 +2079,6 @@ next(); return parseFunction(node, true, false); } - - function eatAsync() { - if (tokType === _name && tokVal === "async") { - next(); - return true; - } else { - return false; - } - } function parseIfStatement(node) { next(); @@ -2727,23 +2718,28 @@ } else first = false; var prop = startNode(), isGenerator, isAsync; - if (options.ecmaVersion >= 7) { - isAsync = eatAsync(); - if (isAsync && tokType === _star) unexpected(); + if (options.ecmaVersion >= 7 && tokType === _ellipsis) { + prop = parseMaybeUnary(); + prop.type = "SpreadProperty"; + node.properties.push(prop); + continue; } if (options.ecmaVersion >= 6) { prop.method = false; prop.shorthand = false; isGenerator = eat(_star); } - if (options.ecmaVersion >= 7 && tokType === _ellipsis) { - if (isAsync || isGenerator) unexpected(); - prop = parseMaybeUnary(); - prop.type = "SpreadProperty"; - node.properties.push(prop); - continue; + if (options.ecmaVersion >= 7 && !isGenerator && tokType === _name && tokVal === "async") { + var asyncId = parseIdent(); + if (tokType === _colon || tokType === _parenL) { + prop.key = asyncId; + } else { + isAsync = true; + parsePropertyName(prop); + } + } else { + parsePropertyName(prop); } - parsePropertyName(prop); if (eat(_colon)) { prop.value = parseExpression(true); prop.kind = "init"; @@ -2953,12 +2949,18 @@ method['static'] = false; } var isAsync = false; - if (options.ecmaVersion >= 7) { - isAsync = eatAsync(); - if (isAsync && tokType === _star) unexpected(); - } var isGenerator = eat(_star); - parsePropertyName(method); + if (options.ecmaVersion >= 7 && !isGenerator && tokType === _name && tokVal === "async") { + var asyncId = parseIdent(); + if (tokType === _colon || tokType === _parenL) { + method.key = asyncId; + } else { + isAsync = true; + parsePropertyName(method); + } + } else { + parsePropertyName(method); + } if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" && (method.key.name === "get" || method.key.name === "set" || (options.playground && method.key.name === "memo"))) { if (isGenerator || isAsync) unexpected(); diff --git a/test/tests-6to5.js b/test/tests-6to5.js index 757e67762d..87416eca36 100644 --- a/test/tests-6to5.js +++ b/test/tests-6to5.js @@ -1733,6 +1733,174 @@ test('(function() { var async; async = 10 })', { ranges: true }); +test('class Test { async() {} }', { + type: "Program", + start: 0, + end: 25, + body: [{ + type: "ClassDeclaration", + start: 0, + end: 25, + id: { + type: "Identifier", + start: 6, + end: 10, + name: "Test" + }, + superClass: null, + body: { + type: "ClassBody", + start: 11, + end: 25, + body: [{ + type: "MethodDefinition", + start: 13, + end: 23, + static: false, + key: { + type: "Identifier", + start: 13, + end: 18, + name: "async" + }, + kind: "", + value: { + type: "FunctionExpression", + start: 18, + end: 23, + id: null, + params: [], + defaults: [], + rest: null, + generator: false, + async: false, + body: { + type: "BlockStatement", + start: 21, + end: 23, + body: [] + }, + expression: false + } + }] + } + }] +}, { + ecmaVersion: 7 +}); + +test('var obj = { async: "test" };', { + type: "Program", + start: 0, + end: 28, + body: [{ + type: "VariableDeclaration", + start: 0, + end: 28, + declarations: [{ + type: "VariableDeclarator", + start: 4, + end: 27, + id: { + type: "Identifier", + start: 4, + end: 7, + name: "obj" + }, + init: { + type: "ObjectExpression", + start: 10, + end: 27, + properties: [{ + type: "Property", + start: 12, + end: 25, + method: false, + shorthand: false, + key: { + type: "Identifier", + start: 12, + end: 17, + name: "async" + }, + value: { + type: "Literal", + start: 19, + end: 25, + value: "test", + raw: "\"test\"" + }, + kind: "init" + }] + } + }], + kind: "var" + }] +}, { + ecmaVersion: 7 +}); + +test('var obj = { async() {} };', { + type: "Program", + start: 0, + end: 25, + body: [{ + type: "VariableDeclaration", + start: 0, + end: 25, + declarations: [{ + type: "VariableDeclarator", + start: 4, + end: 24, + id: { + type: "Identifier", + start: 4, + end: 7, + name: "obj" + }, + init: { + type: "ObjectExpression", + start: 10, + end: 24, + properties: [{ + type: "Property", + start: 12, + end: 22, + method: true, + shorthand: false, + key: { + type: "Identifier", + start: 12, + end: 17, + name: "async" + }, + kind: "init", + value: { + type: "FunctionExpression", + start: 17, + end: 22, + id: null, + params: [], + defaults: [], + rest: null, + generator: false, + body: { + type: "BlockStatement", + start: 20, + end: 22, + body: [] + }, + expression: false + } + }] + } + }], + kind: "var" + }] +}, { + ecmaVersion: 7 +}); + // ES7: Abstract references test('foo::bar;', {