diff --git a/acorn.js b/acorn.js index b3ee37430f..e55cfa1121 100644 --- a/acorn.js +++ b/acorn.js @@ -2292,6 +2292,7 @@ case "ObjectPattern": case "ArrayPattern": case "AssignmentPattern": + case "RestElement": break; case "ObjectExpression": @@ -2312,6 +2313,7 @@ case "SpreadElement": if (allowSpread) { + node.type = "RestElement"; toAssignable(node.argument, false, checkType); checkSpreadAssign(node.argument); } else { @@ -2336,17 +2338,19 @@ // Parses spread element. - function parseSpread(isBinding) { - var spread = startNode(); + function parseSpread() { + var node = startNode(); next(); - if (isBinding) { - var arg = parseAssignableAtom(); - checkSpreadAssign(arg); - spread.argument = arg; - } else { - spread.argument = parseMaybeAssign(); - } - return finishNode(spread, "SpreadElement"); + node.argument = parseMaybeAssign(); + return finishNode(node, "SpreadElement"); + } + + function parseRest() { + var node = startNode(); + next(); + node.argument = parseAssignableAtom(); + checkSpreadAssign(node.argument); + return finishNode(node, "RestElement"); } // Parses lvalue (assignable) atom. @@ -2364,7 +2368,7 @@ while (!eat(_bracketR)) { first ? first = false : expect(_comma); if (tokType === _ellipsis) { - elts.push(parseSpread(true)); + elts.push(parseRest()); expect(_bracketR); break; } @@ -2486,8 +2490,8 @@ case "SpreadProperty": case "AssignmentPattern": - case "SpreadElement": case "VirtualPropertyExpression": + case "RestElement": break; default: @@ -3234,7 +3238,7 @@ first ? first = false : expect(_comma); if (tokType === _ellipsis) { spreadStart = tokStart; - exprList.push(parseSpread(true)); + exprList.push(parseRest()); break; } else { if (tokType === _parenL && !innerParenStart) { @@ -3471,7 +3475,7 @@ } else { toAssignable(param, i === lastI, true); defaults.push(null); - if (param.type === "SpreadElement") { + if (param.type === "RestElement") { params.length--; node.rest = param.argument; break; diff --git a/acorn_loose.js b/acorn_loose.js index 74da050698..5a148aa39f 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -297,7 +297,7 @@ case "MemberExpression": case "ObjectPattern": case "ArrayPattern": - case "SpreadElement": + case "RestElement": case "AssignmentPattern": return expr; @@ -982,6 +982,7 @@ break; case "SpreadElement": + node.type = "RestElement"; node.argument = toAssignable(node.argument); break; @@ -1007,7 +1008,7 @@ param = param.left; } param = toAssignable(param); - if (param.type === "SpreadElement") { + if (param.type === "RestElement") { param = param.argument; if (i === params.length - 1) { node.rest = param; diff --git a/test/driver.js b/test/driver.js index 37f36dcb99..4146cc2548 100644 --- a/test/driver.js +++ b/test/driver.js @@ -66,7 +66,7 @@ } }; - function ppJSON(v) { return JSON.stringify(v, null, 2); } + function ppJSON(v) { return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); } function addPath(str, pt) { if (str.charAt(str.length-1) == ")") return str.slice(0, str.length-1) + "/" + pt + ")"; @@ -76,6 +76,9 @@ var misMatch = exports.misMatch = function(exp, act) { if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) { if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act); + } else if (exp instanceof RegExp || act instanceof RegExp) { + var left = ppJSON(exp), right = ppJSON(act); + if (left !== right) return left + " !== " + right; } else if (exp.splice) { if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act); if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length; diff --git a/test/tests-harmony.js b/test/tests-harmony.js index 07bf912d01..82eafb146d 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -12913,7 +12913,7 @@ test("[...a] = b", { left: { type: "ArrayPattern", elements: [{ - type: "SpreadElement", + type: "RestElement", argument: { type: "Identifier", name: "a", @@ -12979,7 +12979,7 @@ test("[a, ...b] = c", { } }, { - type: "SpreadElement", + type: "RestElement", argument: { type: "Identifier", name: "b", @@ -13101,7 +13101,7 @@ test("[{ a, b }, ...c] = d", { } }, { - type: "SpreadElement", + type: "RestElement", argument: { type: "Identifier", name: "c", @@ -13168,7 +13168,7 @@ test("[a, ...[b, c]] = d", { } }, { - type: "SpreadElement", + type: "RestElement", argument: { type: "ArrayPattern", elements: [ @@ -13242,7 +13242,7 @@ test("var [...a] = b", { id: { type: "ArrayPattern", elements: [{ - type: "SpreadElement", + type: "RestElement", argument: { type: "Identifier", name: "a", @@ -13308,7 +13308,7 @@ test("var [a, ...b] = c", { } }, { - type: "SpreadElement", + type: "RestElement", argument: { type: "Identifier", name: "b", @@ -13430,7 +13430,7 @@ test("var [{ a, b }, ...c] = d", { } }, { - type: "SpreadElement", + type: "RestElement", argument: { type: "Identifier", name: "c", @@ -13497,7 +13497,7 @@ test("var [a, ...[b, c]] = d", { } }, { - type: "SpreadElement", + type: "RestElement", argument: { type: "ArrayPattern", elements: [ @@ -14195,7 +14195,7 @@ test("[...a, ] = b", { end: {line: 1, column: 8} }, elements: [{ - type: "SpreadElement", + type: "RestElement", loc: { start: {line: 1, column: 1}, end: {line: 1, column: 5} @@ -14783,47 +14783,47 @@ test("class A { *static() {} }", { locations: true }); -test("`${/\d/.exec('1')[0]}`", { +test("`${/\\d/.exec('1')[0]}`", { "type": "Program", "start": 0, - "end": 21, + "end": 22, "body": [ { "type": "ExpressionStatement", "start": 0, - "end": 21, + "end": 22, "expression": { "type": "TemplateLiteral", "start": 0, - "end": 21, + "end": 22, "expressions": [ { "type": "MemberExpression", "start": 3, - "end": 19, + "end": 20, "object": { "type": "CallExpression", "start": 3, - "end": 16, + "end": 17, "callee": { "type": "MemberExpression", "start": 3, - "end": 11, + "end": 12, "object": { "type": "Literal", "start": 3, - "end": 6, + "end": 7, "regex": { - "pattern": "d", + "pattern": "\\d", "flags": "" }, - "value": {}, - "raw": "/d/" + "value": /\d/, + "raw": "/\\d/" }, "property": { "type": "Identifier", - "start": 7, - "end": 11, + "start": 8, + "end": 12, "name": "exec" }, "computed": false @@ -14831,8 +14831,8 @@ test("`${/\d/.exec('1')[0]}`", { "arguments": [ { "type": "Literal", - "start": 12, - "end": 15, + "start": 13, + "end": 16, "value": "1", "raw": "'1'" } @@ -14840,8 +14840,8 @@ test("`${/\d/.exec('1')[0]}`", { }, "property": { "type": "Literal", - "start": 17, - "end": 18, + "start": 18, + "end": 19, "value": 0, "raw": "0" }, @@ -14861,8 +14861,8 @@ test("`${/\d/.exec('1')[0]}`", { }, { "type": "TemplateElement", - "start": 20, - "end": 20, + "start": 21, + "end": 21, "value": { "raw": "", "cooked": "" diff --git a/test/tests.js b/test/tests.js index dee69bb4a3..d3beafc5f9 100644 --- a/test/tests.js +++ b/test/tests.js @@ -169,7 +169,7 @@ test("/[a-z]/g", { type: "ExpressionStatement", expression: { type: "Literal", - value: /[a-z]/, + value: /[a-z]/g, regex: { pattern: "[a-z]", flags: "g" @@ -7331,7 +7331,7 @@ test("var x = /[a-z]/i", { }, init: { type: "Literal", - value: {}, + value: /[a-z]/i, loc: { start: { line: 1, @@ -7404,7 +7404,7 @@ test("var x = /[x-z]/i", { }, init: { type: "Literal", - value: {}, + value: /[x-z]/i, loc: { start: { line: 1, @@ -7477,7 +7477,7 @@ test("var x = /[a-c]/i", { }, init: { type: "Literal", - value: {}, + value: /[a-c]/i, loc: { start: { line: 1, @@ -7550,7 +7550,7 @@ test("var x = /[P QR]/i", { }, init: { type: "Literal", - value: {}, + value: /[P QR]/i, loc: { start: { line: 1, @@ -7623,7 +7623,7 @@ test("var x = /foo\\/bar/", { }, init: { type: "Literal", - value: {}, + value: /foo\/bar/, loc: { start: { line: 1, @@ -7696,7 +7696,7 @@ test("var x = /=([^=\\s])+/g", { }, init: { type: "Literal", - value: {}, + value: /=([^=\s])+/g, loc: { start: { line: 1, @@ -7769,7 +7769,7 @@ test("var x = /[P QR]/\\u0067", { }, init: { type: "Literal", - value: {}, + value: /[P QR]/g, loc: { start: { line: 1, @@ -28902,7 +28902,7 @@ test("function f() {} / 1 /", { expression: { type: "Literal", regex: {pattern: " 1 ", flags: ""}, - value: {} + value: / 1 / } } ]