From 9b697af8033201882fa28ea6ad3a5b476291bdd1 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 25 Jul 2014 00:15:58 +0300 Subject: [PATCH] Destructuring assignments. --- acorn.js | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/acorn.js b/acorn.js index 5d622bb1e2..8c9053be95 100644 --- a/acorn.js +++ b/acorn.js @@ -1155,7 +1155,8 @@ // to. function checkLVal(expr) { - if (expr.type !== "Identifier" && expr.type !== "MemberExpression") + if (expr.type !== "Identifier" && expr.type !== "MemberExpression" && + expr.type !== "ObjectPattern" && expr.type !== "ArrayPattern") raise(expr.start, "Assigning to rvalue"); if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name)) raise(expr.start, "Assigning to " + expr.name + " in strict mode"); @@ -1508,8 +1509,8 @@ node.kind = kind; for (;;) { var decl = startNode(); - decl.id = parseIdent(); - if (strict && isStrictBadIdWord(decl.id.name)) + decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent(); + if (strict && decl.id.type === "Identifier" && isStrictBadIdWord(decl.id.name)) raise(decl.id.start, "Binding " + decl.id.name + " in strict mode"); decl.init = eat(_eq) ? parseExpression(true, noIn) : (kind === _const.keyword ? unexpected() : null); node.declarations.push(finishNode(decl, "VariableDeclarator")); @@ -1910,22 +1911,31 @@ // Parse function parameters. function parseFunctionParams(node) { + var defaults = [], hasDefaults = false; + expect(_parenL); for (;;) { if (eat(_parenR)) { break; } else if (options.ecmaVersion >= 6 && eat(_ellipsis)) { - node.rest = parseIdent(); + node.rest = toAssignable(parseExprAtom()); expect(_parenR); break; } else { - node.params.push(parseIdent()); + node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent()); + if (options.ecmaVersion >= 6 && tokVal === '=') { + next(); + hasDefaults = true; + defaults.push(parseExpression(true)); + } if (!eat(_comma)) { expect(_parenR); break; } } } + + if (hasDefaults) node.defaults = defaults; } // Parse function body and check parameters. @@ -2043,4 +2053,28 @@ return finishNode(node, "Identifier"); } + // Convert existing expression atom to assignable pattern + // if possible. + + function toAssignable(node) { + if (options.ecmaVersion >= 6) { + switch (node.type) { + case "Identifier": + break; + + case "ObjectExpression": + node.type = "ObjectPattern"; + break; + + case "ArrayExpression": + node.type = "ArrayPattern"; + break; + + default: + unexpected(node.start); + } + } + return node; + } + });