From 555c7898c8afa7318e8e8074b84d01d950146b3c Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 22 Jan 2015 18:21:38 +0200 Subject: [PATCH 01/14] Remove Token::{startLoc,endLoc} so they don't appear in next release. --- acorn.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/acorn.js b/acorn.js index 10cac96e47..f4b1534bac 100644 --- a/acorn.js +++ b/acorn.js @@ -200,9 +200,6 @@ if (options.locations) { this.loc = new SourceLocation(); this.loc.end = tokEndLoc; - // TODO: remove in next major release - this.startLoc = tokStartLoc; - this.endLoc = tokEndLoc; } if (options.ranges) this.range = [tokStart, tokEnd]; From 2e55540bbee9475d3249e3442a2a3e640bf16808 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 22 Jan 2015 18:53:45 +0200 Subject: [PATCH 02/14] Fix {start,end}Loc -> loc.{start,end} in acorn_loose; remove forceRegexp. --- acorn_loose.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/acorn_loose.js b/acorn_loose.js index 27e8b65e63..db2883c4bf 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -58,14 +58,12 @@ var lastEnd, token = {start: 0, end: 0}, ahead = []; var curLineStart, nextLineStart, curIndent, lastEndLoc, sourceFile; - function next(forceRegexp) { + function next() { lastEnd = token.end; if (options.locations) - lastEndLoc = token.endLoc; - if (forceRegexp) - ahead.length = 0; + lastEndLoc = token.loc && token.loc.end; - token = ahead.shift() || readToken(forceRegexp); + token = ahead.shift() || readToken(); if (options.onToken) options.onToken(token); @@ -78,10 +76,10 @@ } } - function readToken(forceRegexp) { + function readToken() { for (;;) { try { - var tok = fetchToken(forceRegexp); + var tok = fetchToken(); if (tok.type === tt.dot && input.substr(tok.end, 1) === '.') { tok = fetchToken(); tok.start--; @@ -129,8 +127,8 @@ if (replace === true) replace = {start: pos, end: pos, type: tt.name, value: "✖"}; if (replace) { if (options.locations) { - replace.startLoc = acorn.getLineInfo(input, replace.start); - replace.endLoc = acorn.getLineInfo(input, replace.end); + replace.loc = new SourceLocation(acorn.getLineInfo(input, replace.start)); + replace.loc.end = acorn.getLineInfo(input, replace.end); } return replace; } @@ -212,7 +210,7 @@ Node.prototype = acorn.Node.prototype; function SourceLocation(start) { - this.start = start || token.startLoc || {line: 1, column: 0}; + this.start = start || token.loc.start || {line: 1, column: 0}; this.end = null; if (sourceFile !== null) this.source = sourceFile; } @@ -229,7 +227,7 @@ } function storeCurrentPos() { - return options.locations ? [token.start, token.startLoc] : token.start; + return options.locations ? [token.start, token.loc.start] : token.start; } function startNodeAt(pos) { @@ -313,7 +311,7 @@ node.body = []; while (token.type !== tt.eof) node.body.push(parseStatement()); lastEnd = token.end; - lastEndLoc = token.endLoc; + lastEndLoc = token.loc && token.loc.end; return finishNode(node, "Program"); } @@ -913,7 +911,7 @@ // If there is no closing brace, make the node span to the start // of the next token (this is useful for Tern) lastEnd = token.start; - if (options.locations) lastEndLoc = token.startLoc; + if (options.locations) lastEndLoc = token.loc.start; } if (isClass) { semicolon(); @@ -1168,7 +1166,7 @@ // If there is no closing brace, make the node span to the start // of the next token (this is useful for Tern) lastEnd = token.start; - if (options.locations) lastEndLoc = token.startLoc; + if (options.locations) lastEndLoc = token.loc.start; } return elts; } From 39d752dc6b446380b77c2c2143150455e13cb8c2 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 11:48:39 +0200 Subject: [PATCH 03/14] Make top-level equal to block statement context. Fixes #203. --- acorn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acorn.js b/acorn.js index f4b1534bac..c60c6eac45 100644 --- a/acorn.js +++ b/acorn.js @@ -614,7 +614,7 @@ tokPos = tokLineStart = 0; } tokType = _eof; - tokContext = []; + tokContext = [b_stat]; tokExprAllowed = true; if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') { skipLineComment(2); From e6f1e1027e9a9075b5572a9c495630b8a1d7870a Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 13:17:03 +0200 Subject: [PATCH 04/14] Fix dividing function expression. Fixes #204. --- acorn.js | 29 +++++++++++++++++++++-------- test/tests.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/acorn.js b/acorn.js index c60c6eac45..334b3ff1d8 100644 --- a/acorn.js +++ b/acorn.js @@ -627,18 +627,22 @@ var b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true}, b_tmpl = {token: "${", isExpr: true}; var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true}; - var q_tmpl = {token: "`", isExpr: true}; + var q_tmpl = {token: "`", isExpr: true}, f_expr = {token: "function", isExpr: true}; + + function curTokContext() { + return tokContext[tokContext.length - 1]; + } function braceIsBlock(prevType) { var parent; - if (prevType === _colon && (parent = tokContext[tokContext.length - 1]).token == "{") + if (prevType === _colon && (parent = curTokContext()).token == "{") return !parent.isExpr; if (prevType === _return) return newline.test(input.slice(lastEnd, tokStart)); if (prevType === _else || prevType === _semi || prevType === _eof) return true; if (prevType == _braceL) - return tokContext[tokContext.length - 1] === b_stat; + return curTokContext() === b_stat; return !tokExprAllowed; } @@ -657,8 +661,14 @@ // Update context info if (type === _parenR || type === _braceR) { var out = tokContext.pop(); - tokExprAllowed = !(out && out.isExpr); - preserveSpace = out === b_tmpl; + if (out === b_tmpl) { + preserveSpace = true; + } else if (out === b_stat && curTokContext() === f_expr) { + tokContext.pop(); + tokExprAllowed = false; + } else { + tokExprAllowed = !(out && out.isExpr); + } } else if (type === _braceL) { tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr); tokExprAllowed = true; @@ -673,10 +683,13 @@ // tokExprAllowed stays unchanged } else if (type.keyword && prevType == _dot) { tokExprAllowed = false; - } else if (tokExprAllowed && type == _function) { + } else if (type == _function) { + if (curTokContext() !== b_stat) { + tokContext.push(f_expr); + } tokExprAllowed = false; } else if (type === _backQuote) { - if (tokContext[tokContext.length - 1] === q_tmpl) { + if (curTokContext() === q_tmpl) { tokContext.pop(); } else { tokContext.push(q_tmpl); @@ -939,7 +952,7 @@ if (options.locations) tokStartLoc = curPosition(); if (tokPos >= inputLen) return finishToken(_eof); - if (tokContext[tokContext.length - 1] === q_tmpl) { + if (curTokContext() === q_tmpl) { return readTmplToken(); } diff --git a/test/tests.js b/test/tests.js index 172eb1fb87..dee69bb4a3 100644 --- a/test/tests.js +++ b/test/tests.js @@ -28862,3 +28862,48 @@ test("#!/usr/bin/node\n;", {}, { end: 15 }] }); + +// https://github.com/marijnh/acorn/issues/204 +test("(function () {} / 1)", { + type: "Program", + body: [{ + type: "ExpressionStatement", + expression: { + type: "BinaryExpression", + left: { + type: "FunctionExpression", + id: null, + params: [], + body: { + type: "BlockStatement", + body: [] + } + }, + operator: "/", + right: {type: "Literal", value: 1} + } + }] +}); + +test("function f() {} / 1 /", { + type: "Program", + body: [ + { + type: "FunctionDeclaration", + id: {type: "Identifier", name: "f"}, + params: [], + body: { + type: "BlockStatement", + body: [] + } + }, + { + type: "ExpressionStatement", + expression: { + type: "Literal", + regex: {pattern: " 1 ", flags: ""}, + value: {} + } + } + ] +}); From cb94a0851c5574d9f5380e805cca698c0b0bec83 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 13:50:01 +0200 Subject: [PATCH 05/14] Add regex comparison to test driver. --- test/driver.js | 5 ++++- test/tests-harmony.js | 38 +++++++++++++++++++------------------- test/tests.js | 18 +++++++++--------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/test/driver.js b/test/driver.js index c76b8f91a4..7b7dee853c 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..c0c74b8113 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -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 / } } ] From 38609ae26d6fa071194026d4e15e9bd7d21fea82 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 14:14:02 +0200 Subject: [PATCH 06/14] Closes #205. --- acorn.js | 32 ++++++++++++++++++-------------- acorn_loose.js | 5 +++-- test/tests-harmony.js | 18 +++++++++--------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/acorn.js b/acorn.js index 334b3ff1d8..491a3e2f23 100644 --- a/acorn.js +++ b/acorn.js @@ -1458,6 +1458,7 @@ case "ObjectPattern": case "ArrayPattern": case "AssignmentPattern": + case "RestElement": break; case "ObjectExpression": @@ -1478,6 +1479,7 @@ case "SpreadElement": if (allowSpread) { + node.type = "RestElement"; toAssignable(node.argument, false, checkType); checkSpreadAssign(node.argument); } else { @@ -1502,17 +1504,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. @@ -1530,7 +1534,7 @@ while (!eat(_bracketR)) { first ? first = false : expect(_comma); if (tokType === _ellipsis) { - elts.push(parseSpread(true)); + elts.push(parseRest()); expect(_bracketR); break; } @@ -1648,7 +1652,7 @@ break; case "AssignmentPattern": - case "SpreadElement": + case "RestElement": break; default: @@ -2270,7 +2274,7 @@ first ? first = false : expect(_comma); if (tokType === _ellipsis) { spreadStart = tokStart; - exprList.push(parseSpread(true)); + exprList.push(parseRest()); break; } else { if (tokType === _parenL && !innerParenStart) { @@ -2479,7 +2483,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 db2883c4bf..dca43afc7b 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/tests-harmony.js b/test/tests-harmony.js index c0c74b8113..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} From 917de714b145882aa65d21c121eeeae0e76b4c99 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 15:29:37 +0200 Subject: [PATCH 07/14] Switch from Function.{rest,defaults} to AssignmentPattern and RestElement. Closes #182. --- acorn.js | 113 +- acorn_loose.js | 49 +- test/tests-harmony.js | 2433 ++++++++++++++++++++--------------------- test/tests.js | 87 +- 4 files changed, 1251 insertions(+), 1431 deletions(-) diff --git a/acorn.js b/acorn.js index 491a3e2f23..6cf6a60443 100644 --- a/acorn.js +++ b/acorn.js @@ -1472,9 +1472,7 @@ case "ArrayExpression": node.type = "ArrayPattern"; - for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) { - toAssignable(node.elements[i], i === lastI, checkType); - } + toAssignableList(node.elements, checkType); break; case "SpreadElement": @@ -1502,6 +1500,15 @@ return node; } + // Convert list of expression atoms to binding list. + + function toAssignableList(exprList, checkType) { + for (var i = 0; i < exprList.length; i++) { + toAssignable(exprList[i], i === exprList.length - 1, checkType); + } + return exprList; + } + // Parses spread element. function parseSpread() { @@ -1530,16 +1537,7 @@ case _bracketL: var node = startNode(); next(); - var elts = node.elements = [], first = true; - while (!eat(_bracketR)) { - first ? first = false : expect(_comma); - if (tokType === _ellipsis) { - elts.push(parseRest()); - expect(_bracketR); - break; - } - elts.push(tokType === _comma ? null : parseMaybeDefault()); - } + node.elements = parseAssignableList(_bracketR, true); return finishNode(node, "ArrayPattern"); case _braceL: @@ -1550,6 +1548,20 @@ } } + function parseAssignableList(close, allowEmpty) { + var elts = [], first = true; + while (!eat(close)) { + first ? first = false : expect(_comma); + if (tokType === _ellipsis) { + elts.push(parseRest()); + expect(close); + break; + } + elts.push(allowEmpty && tokType === _comma ? null : parseMaybeDefault()); + } + return elts; + } + // Parses assignment pattern around given atom if possible. function parseMaybeDefault(startPos, left) { @@ -1593,6 +1605,9 @@ if (elem) checkFunctionParam(elem, nameHash); } break; + + case "RestElement": + return checkFunctionParam(param.argument, nameHash); } } @@ -2425,11 +2440,9 @@ function initFunction(node) { node.id = null; - node.params = []; if (options.ecmaVersion >= 6) { - node.defaults = []; - node.rest = null; node.generator = false; + node.expression = false; } } @@ -2444,7 +2457,8 @@ if (isStatement || tokType === _name) { node.id = parseIdent(); } - parseFunctionParams(node); + expect(_parenL); + node.params = parseAssignableList(_parenR, false); parseFunctionBody(node, allowExpressionBody); return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); } @@ -2454,7 +2468,8 @@ function parseMethod(isGenerator) { var node = startNode(); initFunction(node); - parseFunctionParams(node); + expect(_parenL); + node.params = parseAssignableList(_parenR, false); var allowExpressionBody; if (options.ecmaVersion >= 6) { node.generator = isGenerator; @@ -2470,69 +2485,11 @@ function parseArrowExpression(node, params) { initFunction(node); - - var defaults = node.defaults, hasDefaults = false; - - for (var i = 0, lastI = params.length - 1; i <= lastI; i++) { - var param = params[i]; - - if (param.type === "AssignmentExpression" && param.operator === "=") { - hasDefaults = true; - params[i] = param.left; - defaults.push(param.right); - } else { - toAssignable(param, i === lastI, true); - defaults.push(null); - if (param.type === "RestElement") { - params.length--; - node.rest = param.argument; - break; - } - } - } - - node.params = params; - if (!hasDefaults) node.defaults = []; - + node.params = toAssignableList(params, true); parseFunctionBody(node, true); return finishNode(node, "ArrowFunctionExpression"); } - // Parse function parameters. - - function parseFunctionParams(node) { - var defaults = [], hasDefaults = false; - - expect(_parenL); - for (;;) { - if (eat(_parenR)) { - break; - } else if (eat(_ellipsis)) { - node.rest = parseAssignableAtom(); - checkSpreadAssign(node.rest); - expect(_parenR); - defaults.push(null); - break; - } else { - node.params.push(parseAssignableAtom()); - if (options.ecmaVersion >= 6) { - if (eat(_eq)) { - hasDefaults = true; - defaults.push(parseExpression(true)); - } else { - defaults.push(null); - } - } - if (!eat(_comma)) { - expect(_parenR); - break; - } - } - } - - if (hasDefaults) node.defaults = defaults; - } - // Parse function body and check parameters. function parseFunctionBody(node, allowExpression) { @@ -2560,8 +2517,6 @@ checkFunctionParam(node.id, {}); for (var i = 0; i < node.params.length; i++) checkFunctionParam(node.params[i], nameHash); - if (node.rest) - checkFunctionParam(node.rest, nameHash); } } diff --git a/acorn_loose.js b/acorn_loose.js index dca43afc7b..e1ee14fc3c 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -952,8 +952,6 @@ node.id = null; node.params = []; if (options.ecmaVersion >= 6) { - node.defaults = []; - node.rest = null; node.generator = false; node.expression = false; } @@ -969,16 +967,13 @@ node.type = "ObjectPattern"; var props = node.properties; for (var i = 0; i < props.length; i++) { - props[i].value = toAssignable(props[i].value); + toAssignable(props[i].value); } break; case "ArrayExpression": node.type = "ArrayPattern"; - var elms = node.elements; - for (var i = 0; i < elms.length; i++) { - elms[i] = toAssignable(elms[i]); - } + toAssignableList(node.elements); break; case "SpreadElement": @@ -994,33 +989,17 @@ return checkLVal(node); } - function parseFunctionParams(node, params) { - var defaults = [], hasDefaults = false; - - if (!params) { - pushCx(); - params = parseExprList(tt.parenR); - } - for (var i = 0; i < params.length; i++) { - var param = params[i], defValue = null; - if (param.type === "AssignmentExpression") { - defValue = param.right; - param = param.left; - } - param = toAssignable(param); - if (param.type === "RestElement") { - param = param.argument; - if (i === params.length - 1) { - node.rest = param; - continue; - } - } - node.params.push(param); - defaults.push(defValue); - if (defValue) hasDefaults = true; + function toAssignableList(exprList) { + for (var i = 0; i < exprList.length; i++) { + toAssignable(exprList[i]); } + return exprList; + } - if (hasDefaults) node.defaults = defaults; + function parseFunctionParams(params) { + pushCx(); + params = parseExprList(tt.parenR); + return toAssignableList(params); } function parseFunction(node, isStatement) { @@ -1030,7 +1009,7 @@ } if (token.type === tt.name) node.id = parseIdent(); else if (isStatement) node.id = dummyIdent(); - parseFunctionParams(node); + node.params = parseFunctionParams(); node.body = parseBlock(); return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); } @@ -1038,7 +1017,7 @@ function parseMethod(isGenerator) { var node = startNode(); initFunction(node); - parseFunctionParams(node); + node.params = parseFunctionParams(); node.generator = isGenerator || false; node.expression = options.ecmaVersion >= 6 && token.type !== tt.braceL; node.body = node.expression ? parseExpression(true) : parseBlock(); @@ -1047,7 +1026,7 @@ function parseArrowExpression(node, params) { initFunction(node); - parseFunctionParams(node, params); + node.params = toAssignableList(params); node.expression = token.type !== tt.braceL; node.body = node.expression ? parseExpression(true) : parseBlock(); return finishNode(node, "ArrowFunctionExpression"); diff --git a/test/tests-harmony.js b/test/tests-harmony.js index 82eafb146d..9fc9dec59c 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -174,7 +174,6 @@ test("function test() {'use strict'; 0o0; }", { } }, params: [], - defaults: [], body: { type: "BlockStatement", body: [ @@ -216,7 +215,6 @@ test("function test() {'use strict'; 0o0; }", { end: {line: 1, column: 37} } }, - rest: null, generator: false, expression: false, loc: { @@ -331,7 +329,6 @@ test("function test() {'use strict'; 0O0; }", { } }, params: [], - defaults: [], body: { type: "BlockStatement", body: [ @@ -373,7 +370,6 @@ test("function test() {'use strict'; 0O0; }", { end: {line: 1, column: 37} } }, - rest: null, generator: false, expression: false, loc: { @@ -1028,8 +1024,6 @@ test("`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`",{ type: "FunctionExpression", id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -1198,7 +1192,6 @@ test("() => \"test\"", { type: "ArrowFunctionExpression", id: null, params: [], - defaults: [], body: { type: "Literal", value: "test", @@ -1208,7 +1201,6 @@ test("() => \"test\"", { end: {line: 1, column: 12} } }, - rest: null, generator: false, expression: true, loc: { @@ -1246,7 +1238,6 @@ test("e => \"test\"", { end: {line: 1, column: 1} } }], - defaults: [], body: { type: "Literal", value: "test", @@ -1256,7 +1247,6 @@ test("e => \"test\"", { end: {line: 1, column: 11} } }, - rest: null, generator: false, expression: true, loc: { @@ -1294,7 +1284,6 @@ test("(e) => \"test\"", { end: {line: 1, column: 2} } }], - defaults: [], body: { type: "Literal", value: "test", @@ -1304,7 +1293,6 @@ test("(e) => \"test\"", { end: {line: 1, column: 13} } }, - rest: null, generator: false, expression: true, loc: { @@ -1352,7 +1340,6 @@ test("(a, b) => \"test\"", { } } ], - defaults: [], body: { type: "Literal", value: "test", @@ -1362,7 +1349,6 @@ test("(a, b) => \"test\"", { end: {line: 1, column: 16} } }, - rest: null, generator: false, expression: true, loc: { @@ -1400,7 +1386,6 @@ test("e => { 42; }", { end: {line: 1, column: 1} } }], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -1424,7 +1409,6 @@ test("e => { 42; }", { end: {line: 1, column: 12} } }, - rest: null, generator: false, expression: false, loc: { @@ -1462,7 +1446,6 @@ test("e => ({ property: 42 })", { end: {line: 1, column: 1} } }], - defaults: [], body: { type: "ObjectExpression", properties: [{ @@ -1498,7 +1481,6 @@ test("e => ({ property: 42 })", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: true, loc: { @@ -1536,7 +1518,6 @@ test("e => { label: 42 }", { end: {line: 1, column: 1} } }], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -1575,7 +1556,6 @@ test("e => { label: 42 }", { end: {line: 1, column: 18} } }, - rest: null, generator: false, expression: false, loc: { @@ -1623,7 +1603,6 @@ test("(a, b) => { 42; }", { } } ], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -1647,7 +1626,6 @@ test("(a, b) => { 42; }", { end: {line: 1, column: 17} } }, - rest: null, generator: false, expression: false, loc: { @@ -1703,7 +1681,6 @@ test("([a, , b]) => 42", { end: {line: 1, column: 9} } }], - defaults: [], body: { type: "Literal", value: 42, @@ -1713,7 +1690,6 @@ test("([a, , b]) => 42", { end: {line: 1, column: 16} } }, - rest: null, generator: false, expression: true, loc: { @@ -1774,7 +1750,6 @@ test("([a.a]) => 42", { end: {line: 1, column: 6} } }], - defaults: [], body: { type: "Literal", value: 42, @@ -1784,7 +1759,6 @@ test("([a.a]) => 42", { end: {line: 1, column: 13} } }, - rest: null, generator: false, expression: true, loc: { @@ -1815,20 +1789,23 @@ test("(x=1) => x * x", { type: "ArrowFunctionExpression", id: null, params: [{ - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 2} - } - }], - defaults: [{ - type: "Literal", - value: 1, - raw: "1", - loc: { - start: {line: 1, column: 3}, - end: {line: 1, column: 4} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 1}, + end: {line: 1, column: 2} + } + }, + right: { + type: "Literal", + value: 1, + raw: "1", + loc: { + start: {line: 1, column: 3}, + end: {line: 1, column: 4} + } } }], body: { @@ -1855,7 +1832,6 @@ test("(x=1) => x * x", { end: {line: 1, column: 14} } }, - rest: null, generator: false, expression: true, loc: { @@ -1893,7 +1869,6 @@ test("eval => 42", { end: {line: 1, column: 4} } }], - defaults: [], body: { type: "Literal", value: 42, @@ -1903,7 +1878,6 @@ test("eval => 42", { end: {line: 1, column: 10} } }, - rest: null, generator: false, expression: true, loc: { @@ -1941,7 +1915,6 @@ test("arguments => 42", { end: {line: 1, column: 9} } }], - defaults: [], body: { type: "Literal", value: 42, @@ -1951,7 +1924,6 @@ test("arguments => 42", { end: {line: 1, column: 15} } }, - rest: null, generator: false, expression: true, loc: { @@ -1989,7 +1961,6 @@ test("(a) => 00", { end: {line: 1, column: 2} } }], - defaults: [], body: { type: "Literal", value: 0, @@ -1999,7 +1970,6 @@ test("(a) => 00", { end: {line: 1, column: 9} } }, - rest: null, generator: false, expression: true, loc: { @@ -2047,7 +2017,6 @@ test("(eval, a) => 42", { } } ], - defaults: [], body: { type: "Literal", value: 42, @@ -2057,7 +2026,6 @@ test("(eval, a) => 42", { end: {line: 1, column: 15} } }, - rest: null, generator: false, expression: true, loc: { @@ -2088,20 +2056,23 @@ test("(eval = 10) => 42", { type: "ArrowFunctionExpression", id: null, params: [{ - type: "Identifier", - name: "eval", - loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 5} - } - }], - defaults: [{ - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 8}, - end: {line: 1, column: 10} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "eval", + loc: { + start: {line: 1, column: 1}, + end: {line: 1, column: 5} + } + }, + right: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 8}, + end: {line: 1, column: 10} + } } }], body: { @@ -2113,7 +2084,6 @@ test("(eval = 10) => 42", { end: {line: 1, column: 17} } }, - rest: null, generator: false, expression: true, loc: { @@ -2153,23 +2123,23 @@ test("(eval, a = 10) => 42", { } }, { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 7}, - end: {line: 1, column: 8} - } - } - ], - defaults: [ - null, - { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 13} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 7}, + end: {line: 1, column: 8} + } + }, + right: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 13} + } } } ], @@ -2182,7 +2152,6 @@ test("(eval, a = 10) => 42", { end: {line: 1, column: 20} } }, - rest: null, generator: false, expression: true, loc: { @@ -2220,7 +2189,6 @@ test("(x => x)", { end: {line: 1, column: 2} } }], - defaults: [], body: { type: "Identifier", name: "x", @@ -2229,7 +2197,6 @@ test("(x => x)", { end: {line: 1, column: 7} } }, - rest: null, generator: false, expression: true, loc: { @@ -2267,7 +2234,6 @@ test("x => y => 42", { end: {line: 1, column: 1} } }], - defaults: [], body: { type: "ArrowFunctionExpression", id: null, @@ -2279,7 +2245,6 @@ test("x => y => 42", { end: {line: 1, column: 6} } }], - defaults: [], body: { type: "Literal", value: 42, @@ -2289,7 +2254,6 @@ test("x => y => 42", { end: {line: 1, column: 12} } }, - rest: null, generator: false, expression: true, loc: { @@ -2297,7 +2261,6 @@ test("x => y => 42", { end: {line: 1, column: 12} } }, - rest: null, generator: false, expression: true, loc: { @@ -2335,7 +2298,6 @@ test("(x) => ((y, z) => (x, y, z))", { end: {line: 1, column: 2} } }], - defaults: [], body: { type: "ArrowFunctionExpression", id: null, @@ -2357,7 +2319,6 @@ test("(x) => ((y, z) => (x, y, z))", { } } ], - defaults: [], body: { type: "SequenceExpression", expressions: [ @@ -2391,7 +2352,6 @@ test("(x) => ((y, z) => (x, y, z))", { end: {line: 1, column: 26} } }, - rest: null, generator: false, expression: true, loc: { @@ -2399,7 +2359,6 @@ test("(x) => ((y, z) => (x, y, z))", { end: {line: 1, column: 27} } }, - rest: null, generator: false, expression: true, loc: { @@ -2440,7 +2399,6 @@ test("foo(() => {})", { type: "ArrowFunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2449,7 +2407,6 @@ test("foo(() => {})", { end: {line: 1, column: 12} } }, - rest: null, generator: false, expression: false, loc: { @@ -2512,7 +2469,6 @@ test("foo((x, y) => {})", { } } ], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2521,7 +2477,6 @@ test("foo((x, y) => {})", { end: {line: 1, column: 16} } }, - rest: null, generator: false, expression: false, loc: { @@ -2586,8 +2541,6 @@ test("(a, a) => 42", { name: "a" } ], - defaults: [], - rest: null, generator: false, body: { type: "Literal", @@ -2640,7 +2593,6 @@ test("x = { method() { } }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2649,7 +2601,6 @@ test("x = { method() { } }", { end: {line: 1, column: 18} } }, - rest: null, generator: false, expression: false, loc: { @@ -2729,7 +2680,6 @@ test("x = { method(test) { } }", { end: {line: 1, column: 17} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2738,7 +2688,6 @@ test("x = { method(test) { } }", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -2812,7 +2761,6 @@ test("x = { 'method'() { } }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2821,7 +2769,6 @@ test("x = { 'method'() { } }", { end: {line: 1, column: 20} } }, - rest: null, generator: false, expression: false, loc: { @@ -2894,7 +2841,6 @@ test("x = { get() { } }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2903,7 +2849,6 @@ test("x = { get() { } }", { end: {line: 1, column: 15} } }, - rest: null, generator: false, expression: false, loc: { @@ -2976,7 +2921,6 @@ test("x = { set() { } }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -2985,7 +2929,6 @@ test("x = { set() { } }", { end: {line: 1, column: 15} } }, - rest: null, generator: false, expression: false, loc: { @@ -3058,7 +3001,6 @@ test("x = { method() 42 }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "Literal", value: 42, @@ -3068,7 +3010,6 @@ test("x = { method() 42 }", { end: {line: 1, column: 17} } }, - rest: null, generator: false, expression: true, loc: { @@ -3141,7 +3082,6 @@ test("x = { get method() 42 }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "Literal", value: 42, @@ -3151,7 +3091,6 @@ test("x = { get method() 42 }", { end: {line: 1, column: 21} } }, - rest: null, generator: false, expression: true, loc: { @@ -3231,7 +3170,6 @@ test("x = { set method(val) v = val }", { end: {line: 1, column: 20} } }], - defaults: [], body: { type: "AssignmentExpression", operator: "=", @@ -3256,7 +3194,6 @@ test("x = { set method(val) v = val }", { end: {line: 1, column: 29} } }, - rest: null, generator: false, expression: true, loc: { @@ -4834,7 +4771,6 @@ test("export function parse() { }", { } }, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -4843,7 +4779,6 @@ test("export function parse() { }", { end: {line: 1, column: 27} } }, - rest: null, generator: false, expression: false, loc: { @@ -5615,7 +5550,6 @@ test("(function* () { yield v })", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -5646,7 +5580,6 @@ test("(function* () { yield v })", { end: {line: 1, column: 25} } }, - rest: null, generator: true, expression: false, loc: { @@ -5677,7 +5610,6 @@ test("(function* () { yield\nv })", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [ @@ -5718,7 +5650,6 @@ test("(function* () { yield\nv })", { end: {line: 2, column: 3} } }, - rest: null, generator: true, expression: false, loc: { @@ -5749,7 +5680,6 @@ test("(function* () { yield *v })", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -5780,7 +5710,6 @@ test("(function* () { yield *v })", { end: {line: 1, column: 26} } }, - rest: null, generator: true, expression: false, loc: { @@ -5816,7 +5745,6 @@ test("function* test () { yield *v }", { } }, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -5847,7 +5775,6 @@ test("function* test () { yield *v }", { end: {line: 1, column: 30} } }, - rest: null, generator: true, expression: false, loc: { @@ -5895,7 +5822,6 @@ test("var x = { *test () { yield *v } };", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -5926,7 +5852,6 @@ test("var x = { *test () { yield *v } };", { end: {line: 1, column: 31} } }, - rest: null, generator: true, expression: false, loc: { @@ -5982,7 +5907,6 @@ test("function* t() {}", { } }, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -5991,7 +5915,6 @@ test("function* t() {}", { end: {line: 1, column: 16} } }, - rest: null, generator: true, expression: false, loc: { @@ -6017,7 +5940,6 @@ test("(function* () { yield yield 10 })", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -6057,7 +5979,6 @@ test("(function* () { yield yield 10 })", { end: {line: 1, column: 32} } }, - rest: null, generator: true, expression: false, loc: { @@ -6554,7 +6475,6 @@ test("class A {get() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -6563,7 +6483,6 @@ test("class A {get() {}}", { end: {line: 1, column: 17} } }, - rest: null, generator: false, expression: false, loc: { @@ -6628,7 +6547,6 @@ test("class A { static get() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -6637,7 +6555,6 @@ test("class A { static get() {}}", { end: {line: 1, column: 25} } }, - rest: null, generator: false, expression: false, loc: { @@ -6709,7 +6626,6 @@ test("class A extends B {get foo() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -6718,7 +6634,6 @@ test("class A extends B {get foo() {}}", { end: {line: 1, column: 31} } }, - rest: null, generator: false, expression: false, loc: { @@ -6790,7 +6705,6 @@ test("class A extends B { static get foo() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -6799,7 +6713,6 @@ test("class A extends B { static get foo() {}}", { end: {line: 1, column: 39} } }, - rest: null, generator: false, expression: false, loc: { @@ -6871,7 +6784,6 @@ test("class A {set a(v) {}}", { end: {line: 1, column: 16} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -6880,7 +6792,6 @@ test("class A {set a(v) {}}", { end: {line: 1, column: 20} } }, - rest: null, generator: false, expression: false, loc: { @@ -6952,7 +6863,6 @@ test("class A { static set a(v) {}}", { end: {line: 1, column: 24} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -6961,7 +6871,6 @@ test("class A { static set a(v) {}}", { end: {line: 1, column: 28} } }, - rest: null, generator: false, expression: false, loc: { @@ -7033,7 +6942,6 @@ test("class A {set(v) {};}", { end: {line: 1, column: 14} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7042,7 +6950,6 @@ test("class A {set(v) {};}", { end: {line: 1, column: 18} } }, - rest: null, generator: false, expression: false, loc: { @@ -7114,7 +7021,6 @@ test("class A { static set(v) {};}", { end: {line: 1, column: 22} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7123,7 +7029,6 @@ test("class A { static set(v) {};}", { end: {line: 1, column: 26} } }, - rest: null, generator: false, expression: false, loc: { @@ -7195,7 +7100,6 @@ test("class A {*gen(v) { yield v; }}", { end: {line: 1, column: 15} } }], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -7226,7 +7130,6 @@ test("class A {*gen(v) { yield v; }}", { end: {line: 1, column: 29} } }, - rest: null, generator: true, expression: false, loc: { @@ -7298,7 +7201,6 @@ test("class A { static *gen(v) { yield v; }}", { end: {line: 1, column: 23} } }], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -7329,7 +7231,6 @@ test("class A { static *gen(v) { yield v; }}", { end: {line: 1, column: 37} } }, - rest: null, generator: true, expression: false, loc: { @@ -7413,7 +7314,6 @@ test("\"use strict\"; (class A {constructor() { super() }})", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -7444,7 +7344,6 @@ test("\"use strict\"; (class A {constructor() { super() }})", { end: {line: 1, column: 49} } }, - rest: null, generator: false, expression: false, loc: { @@ -7515,7 +7414,6 @@ test("class A {static foo() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7524,7 +7422,6 @@ test("class A {static foo() {}}", { end: {line: 1, column: 24} } }, - rest: null, generator: false, expression: false, loc: { @@ -7590,7 +7487,6 @@ test("class A {foo() {} static bar() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7599,7 +7495,6 @@ test("class A {foo() {} static bar() {}}", { end: {line: 1, column: 17} } }, - rest: null, generator: false, expression: false, loc: { @@ -7629,7 +7524,6 @@ test("class A {foo() {} static bar() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7638,7 +7532,6 @@ test("class A {foo() {} static bar() {}}", { end: {line: 1, column: 33} } }, - rest: null, generator: false, expression: false, loc: { @@ -7723,7 +7616,6 @@ test("\"use strict\"; (class A { static constructor() { super() }})", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -7754,7 +7646,6 @@ test("\"use strict\"; (class A { static constructor() { super() }})", { end: {line: 1, column: 57} } }, - rest: null, generator: false, expression: false, loc: { @@ -7826,7 +7717,6 @@ test("class A { foo() {} bar() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7835,7 +7725,6 @@ test("class A { foo() {} bar() {}}", { end: {line: 1, column: 18} } }, - rest: null, generator: false, expression: false, loc: { @@ -7865,7 +7754,6 @@ test("class A { foo() {} bar() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7874,7 +7762,6 @@ test("class A { foo() {} bar() {}}", { end: {line: 1, column: 27} } }, - rest: null, generator: false, expression: false, loc: { @@ -7941,7 +7828,6 @@ test("class A { get foo() {} set foo(v) {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7950,7 +7836,6 @@ test("class A { get foo() {} set foo(v) {}}", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -7987,7 +7872,6 @@ test("class A { get foo() {} set foo(v) {}}", { end: {line: 1, column: 32} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -7996,7 +7880,6 @@ test("class A { get foo() {} set foo(v) {}}", { end: {line: 1, column: 36} } }, - rest: null, generator: false, expression: false, loc: { @@ -8063,7 +7946,6 @@ test("class A { static get foo() {} get foo() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8072,7 +7954,6 @@ test("class A { static get foo() {} get foo() {}}", { end: {line: 1, column: 29} } }, - rest: null, generator: false, expression: false, loc: { @@ -8102,7 +7983,6 @@ test("class A { static get foo() {} get foo() {}}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8111,7 +7991,6 @@ test("class A { static get foo() {} get foo() {}}", { end: {line: 1, column: 42} } }, - rest: null, generator: false, expression: false, loc: { @@ -8178,7 +8057,6 @@ test("class A { static get foo() {} static get bar() {} }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8187,7 +8065,6 @@ test("class A { static get foo() {} static get bar() {} }", { end: {line: 1, column: 29} } }, - rest: null, generator: false, expression: false, loc: { @@ -8217,7 +8094,6 @@ test("class A { static get foo() {} static get bar() {} }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8226,7 +8102,6 @@ test("class A { static get foo() {} static get bar() {} }", { end: {line: 1, column: 49} } }, - rest: null, generator: false, expression: false, loc: { @@ -8293,7 +8168,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8302,7 +8176,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) end: {line: 1, column: 29} } }, - rest: null, generator: false, expression: false, loc: { @@ -8339,7 +8212,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) end: {line: 1, column: 46} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8348,7 +8220,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) end: {line: 1, column: 50} } }, - rest: null, generator: false, expression: false, loc: { @@ -8378,7 +8249,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8387,7 +8257,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) end: {line: 1, column: 63} } }, - rest: null, generator: false, expression: false, loc: { @@ -8424,7 +8293,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) end: {line: 1, column: 73} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8433,7 +8301,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v) end: {line: 1, column: 77} } }, - rest: null, generator: false, expression: false, loc: { @@ -8522,8 +8389,6 @@ test("class A { static [foo]() {} }", { }, id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -8600,8 +8465,6 @@ test("class A { static get [foo]() {} }", { }, id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -8660,7 +8523,6 @@ test("class A { set foo(v) {} get foo() {} }", { end: {line: 1, column: 19} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8669,7 +8531,6 @@ test("class A { set foo(v) {} get foo() {} }", { end: {line: 1, column: 23} } }, - rest: null, generator: false, expression: false, loc: { @@ -8699,7 +8560,6 @@ test("class A { set foo(v) {} get foo() {} }", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -8708,7 +8568,6 @@ test("class A { set foo(v) {} get foo() {} }", { end: {line: 1, column: 36} } }, - rest: null, generator: false, expression: false, loc: { @@ -8797,8 +8656,6 @@ test("class A { foo() {} get foo() {} }",{ }, id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -8836,8 +8693,6 @@ test("class A { foo() {} get foo() {} }",{ }, id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -9043,7 +8898,6 @@ test("({[x]: function() {}})", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -9052,7 +8906,6 @@ test("({[x]: function() {}})", { end: {line: 1, column: 20} } }, - rest: null, generator: false, expression: false, loc: { @@ -9194,7 +9047,6 @@ test("({get [x]() {}, set [x](v) {}})", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -9203,7 +9055,6 @@ test("({get [x]() {}, set [x](v) {}})", { end: {line: 1, column: 14} } }, - rest: null, generator: false, expression: false, loc: { @@ -9241,7 +9092,6 @@ test("({get [x]() {}, set [x](v) {}})", { end: {line: 1, column: 25} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -9250,7 +9100,6 @@ test("({get [x]() {}, set [x](v) {}})", { end: {line: 1, column: 29} } }, - rest: null, generator: false, expression: false, loc: { @@ -9308,7 +9157,6 @@ test("({[x]() {}})", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [], @@ -9317,7 +9165,6 @@ test("({[x]() {}})", { end: {line: 1, column: 10} } }, - rest: null, generator: false, expression: false, loc: { @@ -9495,7 +9342,6 @@ test("function f({[x]: y}) {}", { end: {line: 1, column: 19} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -9504,7 +9350,6 @@ test("function f({[x]: y}) {}", { end: {line: 1, column: 23} } }, - rest: null, generator: false, expression: false, loc: { @@ -9552,7 +9397,6 @@ test("var x = {*[test]() { yield *v; }}", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -9583,7 +9427,6 @@ test("var x = {*[test]() { yield *v; }}", { end: {line: 1, column: 32} } }, - rest: null, generator: true, expression: false, loc: { @@ -9678,8 +9521,6 @@ test("class A {[x]() {}}", { }, id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -9717,34 +9558,37 @@ test("function f([x] = [1]) {}", { } }, params: [{ - type: "ArrayPattern", - elements: [{ - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ArrayPattern", + elements: [{ + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 12}, + end: {line: 1, column: 13} + } + }], loc: { - start: {line: 1, column: 12}, - end: {line: 1, column: 13} + start: {line: 1, column: 11}, + end: {line: 1, column: 14} } - }], - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 14} - } - }], - defaults: [{ - type: "ArrayExpression", - elements: [{ - type: "Literal", - value: 1, - raw: "1", + }, + right: { + type: "ArrayExpression", + elements: [{ + type: "Literal", + value: 1, + raw: "1", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 19} + } + }], loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 19} + start: {line: 1, column: 17}, + end: {line: 1, column: 20} } - }], - loc: { - start: {line: 1, column: 17}, - end: {line: 1, column: 20} } }], body: { @@ -9755,7 +9599,6 @@ test("function f([x] = [1]) {}", { end: {line: 1, column: 24} } }, - rest: null, generator: false, expression: false, loc: { @@ -9786,72 +9629,75 @@ test("function f({x} = {x: 10}) {}", { } }, params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 12}, + end: {line: 1, column: 13} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 12}, + end: {line: 1, column: 13} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 12}, end: {line: 1, column: 13} } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 12}, - end: {line: 1, column: 13} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 12}, - end: {line: 1, column: 13} + start: {line: 1, column: 11}, + end: {line: 1, column: 14} } - }], - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 14} - } - }], - defaults: [{ - type: "ObjectExpression", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + }, + right: { + type: "ObjectExpression", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 19} + } + }, + value: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 21}, + end: {line: 1, column: 23} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 18}, - end: {line: 1, column: 19} - } - }, - value: { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 21}, end: {line: 1, column: 23} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 23} + start: {line: 1, column: 17}, + end: {line: 1, column: 24} } - }], - loc: { - start: {line: 1, column: 17}, - end: {line: 1, column: 24} } }], body: { @@ -9862,7 +9708,6 @@ test("function f({x} = {x: 10}) {}", { end: {line: 1, column: 28} } }, - rest: null, generator: false, expression: false, loc: { @@ -9899,72 +9744,75 @@ test("f = function({x} = {x: 10}) {}", { type: "FunctionExpression", id: null, params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 14}, + end: {line: 1, column: 15} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 14}, + end: {line: 1, column: 15} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 14}, end: {line: 1, column: 15} } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 14}, - end: {line: 1, column: 15} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 14}, - end: {line: 1, column: 15} + start: {line: 1, column: 13}, + end: {line: 1, column: 16} } - }], - loc: { - start: {line: 1, column: 13}, - end: {line: 1, column: 16} - } - }], - defaults: [{ - type: "ObjectExpression", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + }, + right: { + type: "ObjectExpression", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 20}, + end: {line: 1, column: 21} + } + }, + value: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 23}, + end: {line: 1, column: 25} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 20}, - end: {line: 1, column: 21} - } - }, - value: { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 23}, end: {line: 1, column: 25} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 20}, - end: {line: 1, column: 25} + start: {line: 1, column: 19}, + end: {line: 1, column: 26} } - }], - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 26} } }], body: { @@ -9975,7 +9823,6 @@ test("f = function({x} = {x: 10}) {}", { end: {line: 1, column: 30} } }, - rest: null, generator: false, expression: false, loc: { @@ -10023,72 +9870,75 @@ test("({f: function({x} = {x: 10}) {}})", { type: "FunctionExpression", id: null, params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 15}, + end: {line: 1, column: 16} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 15}, + end: {line: 1, column: 16} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 15}, end: {line: 1, column: 16} } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 15}, - end: {line: 1, column: 16} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 15}, - end: {line: 1, column: 16} + start: {line: 1, column: 14}, + end: {line: 1, column: 17} } - }], - loc: { - start: {line: 1, column: 14}, - end: {line: 1, column: 17} - } - }], - defaults: [{ - type: "ObjectExpression", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + }, + right: { + type: "ObjectExpression", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 21}, + end: {line: 1, column: 22} + } + }, + value: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 24}, + end: {line: 1, column: 26} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 21}, - end: {line: 1, column: 22} - } - }, - value: { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 24}, end: {line: 1, column: 26} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 21}, - end: {line: 1, column: 26} + start: {line: 1, column: 20}, + end: {line: 1, column: 27} } - }], - loc: { - start: {line: 1, column: 20}, - end: {line: 1, column: 27} } }], body: { @@ -10099,7 +9949,6 @@ test("({f: function({x} = {x: 10}) {}})", { end: {line: 1, column: 31} } }, - rest: null, generator: false, expression: false, loc: { @@ -10156,72 +10005,75 @@ test("({f({x} = {x: 10}) {}})", { type: "FunctionExpression", id: null, params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 5}, + end: {line: 1, column: 6} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 5}, + end: {line: 1, column: 6} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 5}, end: {line: 1, column: 6} } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 5}, - end: {line: 1, column: 6} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 5}, - end: {line: 1, column: 6} + start: {line: 1, column: 4}, + end: {line: 1, column: 7} } - }], - loc: { - start: {line: 1, column: 4}, - end: {line: 1, column: 7} - } - }], - defaults: [{ - type: "ObjectExpression", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + }, + right: { + type: "ObjectExpression", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 12} + } + }, + value: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 14}, + end: {line: 1, column: 16} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 11}, - end: {line: 1, column: 12} - } - }, - value: { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 14}, end: {line: 1, column: 16} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 16} + start: {line: 1, column: 10}, + end: {line: 1, column: 17} } - }], - loc: { - start: {line: 1, column: 10}, - end: {line: 1, column: 17} } }], body: { @@ -10232,7 +10084,6 @@ test("({f({x} = {x: 10}) {}})", { end: {line: 1, column: 21} } }, - rest: null, generator: false, expression: false, loc: { @@ -10293,72 +10144,75 @@ test("(class {f({x} = {x: 10}) {}})", { type: "FunctionExpression", id: null, params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 12} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 12} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 11}, end: {line: 1, column: 12} } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 12} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 12} + start: {line: 1, column: 10}, + end: {line: 1, column: 13} } - }], - loc: { - start: {line: 1, column: 10}, - end: {line: 1, column: 13} - } - }], - defaults: [{ - type: "ObjectExpression", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + }, + right: { + type: "ObjectExpression", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 17}, + end: {line: 1, column: 18} + } + }, + value: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 20}, + end: {line: 1, column: 22} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 17}, - end: {line: 1, column: 18} - } - }, - value: { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 20}, end: {line: 1, column: 22} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 17}, - end: {line: 1, column: 22} + start: {line: 1, column: 16}, + end: {line: 1, column: 23} } - }], - loc: { - start: {line: 1, column: 16}, - end: {line: 1, column: 23} } }], body: { @@ -10369,7 +10223,6 @@ test("(class {f({x} = {x: 10}) {}})", { end: {line: 1, column: 27} } }, - rest: null, generator: false, expression: false, loc: { @@ -10417,72 +10270,75 @@ test("(({x} = {x: 10}) => {})", { type: "ArrowFunctionExpression", id: null, params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + type: "AssignmentPattern", + left: { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 3}, + end: {line: 1, column: 4} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 3}, + end: {line: 1, column: 4} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 3}, end: {line: 1, column: 4} } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 3}, - end: {line: 1, column: 4} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 3}, - end: {line: 1, column: 4} + start: {line: 1, column: 2}, + end: {line: 1, column: 5} } - }], - loc: { - start: {line: 1, column: 2}, - end: {line: 1, column: 5} - } - }], - defaults: [{ - type: "ObjectExpression", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "x", + }, + right: { + type: "ObjectExpression", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 9}, + end: {line: 1, column: 10} + } + }, + value: { + type: "Literal", + value: 10, + raw: "10", + loc: { + start: {line: 1, column: 12}, + end: {line: 1, column: 14} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 9}, - end: {line: 1, column: 10} - } - }, - value: { - type: "Literal", - value: 10, - raw: "10", - loc: { - start: {line: 1, column: 12}, end: {line: 1, column: 14} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 9}, - end: {line: 1, column: 14} + start: {line: 1, column: 8}, + end: {line: 1, column: 15} } - }], - loc: { - start: {line: 1, column: 8}, - end: {line: 1, column: 15} } }], body: { @@ -10493,7 +10349,6 @@ test("(({x} = {x: 10}) => {})", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -10535,20 +10390,23 @@ test("x = function(y = 1) {}", { type: "FunctionExpression", id: null, params: [{ - type: "Identifier", - name: "y", - loc: { - start: {line: 1, column: 13}, - end: {line: 1, column: 14} - } - }], - defaults: [{ - type: "Literal", - value: 1, - raw: "1", - loc: { - start: {line: 1, column: 17}, - end: {line: 1, column: 18} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "y", + loc: { + start: {line: 1, column: 13}, + end: {line: 1, column: 14} + } + }, + right: { + type: "Literal", + value: 1, + raw: "1", + loc: { + start: {line: 1, column: 17}, + end: {line: 1, column: 18} + } } }], body: { @@ -10559,7 +10417,6 @@ test("x = function(y = 1) {}", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -10600,20 +10457,23 @@ test("function f(a = 1) {}", { } }, params: [{ - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 12} - } - }], - defaults: [{ - type: "Literal", - value: 1, - raw: "1", - loc: { - start: {line: 1, column: 15}, - end: {line: 1, column: 16} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 12} + } + }, + right: { + type: "Literal", + value: 1, + raw: "1", + loc: { + start: {line: 1, column: 15}, + end: {line: 1, column: 16} + } } }], body: { @@ -10624,7 +10484,6 @@ test("function f(a = 1) {}", { end: {line: 1, column: 20} } }, - rest: null, generator: false, expression: false, loc: { @@ -10673,20 +10532,23 @@ test("x = { f: function(a=1) {} }", { type: "FunctionExpression", id: null, params: [{ - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 19} - } - }], - defaults: [{ - type: "Literal", - value: 1, - raw: "1", - loc: { - start: {line: 1, column: 20}, - end: {line: 1, column: 21} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 19} + } + }, + right: { + type: "Literal", + value: 1, + raw: "1", + loc: { + start: {line: 1, column: 20}, + end: {line: 1, column: 21} + } } }], body: { @@ -10697,7 +10559,6 @@ test("x = { f: function(a=1) {} }", { end: {line: 1, column: 25} } }, - rest: null, generator: false, expression: false, loc: { @@ -10770,20 +10631,23 @@ test("x = { f(a=1) {} }", { type: "FunctionExpression", id: null, params: [{ - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 8}, - end: {line: 1, column: 9} - } - }], - defaults: [{ - type: "Literal", - value: 1, - raw: "1", - loc: { - start: {line: 1, column: 10}, - end: {line: 1, column: 11} + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 8}, + end: {line: 1, column: 9} + } + }, + right: { + type: "Literal", + value: 1, + raw: "1", + loc: { + start: {line: 1, column: 10}, + end: {line: 1, column: 11} + } } }], body: { @@ -10794,7 +10658,6 @@ test("x = { f(a=1) {} }", { end: {line: 1, column: 15} } }, - rest: null, generator: false, expression: false, loc: { @@ -10850,15 +10713,27 @@ test("function f(a, ...b) {}", { end: {line: 1, column: 10} } }, - params: [{ - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 12} + params: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 12} + } + }, + { + type: "RestElement", + argument: { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 17}, + end: {line: 1, column: 18} + } + } } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -10867,14 +10742,6 @@ test("function f(a, ...b) {}", { end: {line: 1, column: 22} } }, - rest: { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 17}, - end: {line: 1, column: 18} - } - }, generator: false, expression: false, loc: { @@ -10931,7 +10798,6 @@ test("function x([ a, b ]){}", { end: {line: 1, column: 19} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -10940,7 +10806,6 @@ test("function x([ a, b ]){}", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -11033,7 +10898,6 @@ test("function x({ a, b }){}", { end: {line: 1, column: 19} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -11042,7 +10906,6 @@ test("function x({ a, b }){}", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -11116,7 +10979,6 @@ test("function x(a, { a }){}", { } } ], - defaults: [], body: { type: "BlockStatement", body: [], @@ -11125,7 +10987,6 @@ test("function x(a, { a }){}", { end: {line: 1, column: 22} } }, - rest: null, generator: false, expression: false, loc: { @@ -11155,8 +11016,34 @@ test("function x(...[ a, b ]){}", { end: {line: 1, column: 10} } }, - params: [], - defaults: [], + params: [{ + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 16}, + end: {line: 1, column: 17} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 19}, + end: {line: 1, column: 20} + } + } + ], + loc: { + start: {line: 1, column: 14}, + end: {line: 1, column: 22} + } + } + }], body: { type: "BlockStatement", body: [], @@ -11165,31 +11052,6 @@ test("function x(...[ a, b ]){}", { end: {line: 1, column: 25} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 16}, - end: {line: 1, column: 17} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 20} - } - } - ], - loc: { - start: {line: 1, column: 14}, - end: {line: 1, column: 22} - } - }, generator: false, expression: false, loc: { @@ -11219,142 +11081,179 @@ test("function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){}", { end: {line: 1, column: 10} } }, - params: [{ - type: "ObjectPattern", - properties: [ - { - type: "Property", - key: { - type: "Identifier", - name: "a", + params: [ + { + type: "ObjectPattern", + properties: [ + { + type: "Property", + key: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 13}, + end: {line: 1, column: 14} + } + }, + value: { + type: "ObjectPattern", + properties: [ + { + type: "Property", + key: { + type: "Identifier", + name: "w", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 19} + } + }, + value: { + type: "Identifier", + name: "w", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 19} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 19} + } + }, + { + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 21}, + end: {line: 1, column: 22} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 21}, + end: {line: 1, column: 22} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, + loc: { + start: {line: 1, column: 21}, + end: {line: 1, column: 22} + } + } + ], + loc: { + start: {line: 1, column: 16}, + end: {line: 1, column: 24} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 13}, - end: {line: 1, column: 14} - } - }, - value: { - type: "ObjectPattern", - properties: [ - { - type: "Property", - key: { - type: "Identifier", - name: "w", - loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 19} - } - }, - value: { - type: "Identifier", - name: "w", - loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 19} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, - loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 19} - } - }, - { - type: "Property", - key: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 21}, - end: {line: 1, column: 22} - } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 21}, - end: {line: 1, column: 22} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, - loc: { - start: {line: 1, column: 21}, - end: {line: 1, column: 22} - } - } - ], - loc: { - start: {line: 1, column: 16}, end: {line: 1, column: 24} } }, - kind: "init", - method: false, - shorthand: false, - computed: false, - loc: { - start: {line: 1, column: 13}, - end: {line: 1, column: 24} - } - }, - { - type: "Property", - key: { - type: "Identifier", - name: "b", + { + type: "Property", + key: { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 26}, + end: {line: 1, column: 27} + } + }, + value: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "y", + loc: { + start: {line: 1, column: 30}, + end: {line: 1, column: 31} + } + }, + { + type: "Identifier", + name: "z", + loc: { + start: {line: 1, column: 33}, + end: {line: 1, column: 34} + } + } + ], + loc: { + start: {line: 1, column: 29}, + end: {line: 1, column: 35} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 26}, - end: {line: 1, column: 27} - } - }, - value: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "y", - loc: { - start: {line: 1, column: 30}, - end: {line: 1, column: 31} - } - }, - { - type: "Identifier", - name: "z", - loc: { - start: {line: 1, column: 33}, - end: {line: 1, column: 34} - } - } - ], - loc: { - start: {line: 1, column: 29}, end: {line: 1, column: 35} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + } + ], + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 37} + } + }, + { + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 43}, + end: {line: 1, column: 44} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 46}, + end: {line: 1, column: 47} + } + }, + { + type: "Identifier", + name: "c", + loc: { + start: {line: 1, column: 49}, + end: {line: 1, column: 50} + } + } + ], loc: { - start: {line: 1, column: 26}, - end: {line: 1, column: 35} + start: {line: 1, column: 42}, + end: {line: 1, column: 51} } } - ], - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 37} } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -11363,39 +11262,6 @@ test("function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){}", { end: {line: 1, column: 54} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 43}, - end: {line: 1, column: 44} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 46}, - end: {line: 1, column: 47} - } - }, - { - type: "Identifier", - name: "c", - loc: { - start: {line: 1, column: 49}, - end: {line: 1, column: 50} - } - } - ], - loc: { - start: {line: 1, column: 42}, - end: {line: 1, column: 51} - } - }, generator: false, expression: false, loc: { @@ -11452,7 +11318,6 @@ test("(function x([ a, b ]){})", { end: {line: 1, column: 20} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -11461,7 +11326,6 @@ test("(function x([ a, b ]){})", { end: {line: 1, column: 23} } }, - rest: null, generator: false, expression: false, loc: { @@ -11561,7 +11425,6 @@ test("(function x({ a, b }){})", { end: {line: 1, column: 20} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -11570,7 +11433,6 @@ test("(function x({ a, b }){})", { end: {line: 1, column: 23} } }, - rest: null, generator: false, expression: false, loc: { @@ -11607,8 +11469,34 @@ test("(function x(...[ a, b ]){})", { end: {line: 1, column: 11} } }, - params: [], - defaults: [], + params: [{ + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 17}, + end: {line: 1, column: 18} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 20}, + end: {line: 1, column: 21} + } + } + ], + loc: { + start: {line: 1, column: 15}, + end: {line: 1, column: 23} + } + } + }], body: { type: "BlockStatement", body: [], @@ -11617,31 +11505,6 @@ test("(function x(...[ a, b ]){})", { end: {line: 1, column: 26} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 17}, - end: {line: 1, column: 18} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 20}, - end: {line: 1, column: 21} - } - } - ], - loc: { - start: {line: 1, column: 15}, - end: {line: 1, column: 23} - } - }, generator: false, expression: false, loc: { @@ -11678,142 +11541,179 @@ test("(function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){})", { end: {line: 1, column: 11} } }, - params: [{ - type: "ObjectPattern", - properties: [ - { - type: "Property", - key: { - type: "Identifier", - name: "a", + params: [ + { + type: "ObjectPattern", + properties: [ + { + type: "Property", + key: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 14}, + end: {line: 1, column: 15} + } + }, + value: { + type: "ObjectPattern", + properties: [ + { + type: "Property", + key: { + type: "Identifier", + name: "w", + loc: { + start: {line: 1, column: 19}, + end: {line: 1, column: 20} + } + }, + value: { + type: "Identifier", + name: "w", + loc: { + start: {line: 1, column: 19}, + end: {line: 1, column: 20} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, + loc: { + start: {line: 1, column: 19}, + end: {line: 1, column: 20} + } + }, + { + type: "Property", + key: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 22}, + end: {line: 1, column: 23} + } + }, + value: { + type: "Identifier", + name: "x", + loc: { + start: {line: 1, column: 22}, + end: {line: 1, column: 23} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, + loc: { + start: {line: 1, column: 22}, + end: {line: 1, column: 23} + } + } + ], + loc: { + start: {line: 1, column: 17}, + end: {line: 1, column: 25} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 14}, - end: {line: 1, column: 15} - } - }, - value: { - type: "ObjectPattern", - properties: [ - { - type: "Property", - key: { - type: "Identifier", - name: "w", - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 20} - } - }, - value: { - type: "Identifier", - name: "w", - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 20} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 20} - } - }, - { - type: "Property", - key: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 22}, - end: {line: 1, column: 23} - } - }, - value: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 22}, - end: {line: 1, column: 23} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, - loc: { - start: {line: 1, column: 22}, - end: {line: 1, column: 23} - } - } - ], - loc: { - start: {line: 1, column: 17}, end: {line: 1, column: 25} } }, - kind: "init", - method: false, - shorthand: false, - computed: false, - loc: { - start: {line: 1, column: 14}, - end: {line: 1, column: 25} - } - }, - { - type: "Property", - key: { - type: "Identifier", - name: "b", + { + type: "Property", + key: { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 27}, + end: {line: 1, column: 28} + } + }, + value: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "y", + loc: { + start: {line: 1, column: 31}, + end: {line: 1, column: 32} + } + }, + { + type: "Identifier", + name: "z", + loc: { + start: {line: 1, column: 34}, + end: {line: 1, column: 35} + } + } + ], + loc: { + start: {line: 1, column: 30}, + end: {line: 1, column: 36} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 27}, - end: {line: 1, column: 28} - } - }, - value: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "y", - loc: { - start: {line: 1, column: 31}, - end: {line: 1, column: 32} - } - }, - { - type: "Identifier", - name: "z", - loc: { - start: {line: 1, column: 34}, - end: {line: 1, column: 35} - } - } - ], - loc: { - start: {line: 1, column: 30}, end: {line: 1, column: 36} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + } + ], + loc: { + start: {line: 1, column: 12}, + end: {line: 1, column: 38} + } + }, + { + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 44}, + end: {line: 1, column: 45} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 47}, + end: {line: 1, column: 48} + } + }, + { + type: "Identifier", + name: "c", + loc: { + start: {line: 1, column: 50}, + end: {line: 1, column: 51} + } + } + ], loc: { - start: {line: 1, column: 27}, - end: {line: 1, column: 36} + start: {line: 1, column: 43}, + end: {line: 1, column: 52} } } - ], - loc: { - start: {line: 1, column: 12}, - end: {line: 1, column: 38} } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -11822,39 +11722,6 @@ test("(function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){})", { end: {line: 1, column: 55} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 44}, - end: {line: 1, column: 45} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 47}, - end: {line: 1, column: 48} - } - }, - { - type: "Identifier", - name: "c", - loc: { - start: {line: 1, column: 50}, - end: {line: 1, column: 51} - } - } - ], - loc: { - start: {line: 1, column: 43}, - end: {line: 1, column: 52} - } - }, generator: false, expression: false, loc: { @@ -11921,7 +11788,6 @@ test("({ x([ a, b ]){} })", { end: {line: 1, column: 13} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -11930,7 +11796,6 @@ test("({ x([ a, b ]){} })", { end: {line: 1, column: 16} } }, - rest: null, generator: false, expression: false, loc: { @@ -11986,8 +11851,34 @@ test("({ x(...[ a, b ]){} })", { value: { type: "FunctionExpression", id: null, - params: [], - defaults: [], + params: [{ + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 10}, + end: {line: 1, column: 11} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 13}, + end: {line: 1, column: 14} + } + } + ], + loc: { + start: {line: 1, column: 8}, + end: {line: 1, column: 16} + } + } + }], body: { type: "BlockStatement", body: [], @@ -11996,31 +11887,6 @@ test("({ x(...[ a, b ]){} })", { end: {line: 1, column: 19} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 10}, - end: {line: 1, column: 11} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 13}, - end: {line: 1, column: 14} - } - } - ], - loc: { - start: {line: 1, column: 8}, - end: {line: 1, column: 16} - } - }, generator: false, expression: false, loc: { @@ -12076,7 +11942,8 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", { value: { type: "FunctionExpression", id: null, - params: [{ + params: [ + { type: "ObjectPattern", properties: [ { @@ -12210,8 +12077,44 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", { start: {line: 1, column: 5}, end: {line: 1, column: 31} } - }], - defaults: [], + }, + { + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 37}, + end: {line: 1, column: 38} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 40}, + end: {line: 1, column: 41} + } + }, + { + type: "Identifier", + name: "c", + loc: { + start: {line: 1, column: 43}, + end: {line: 1, column: 44} + } + } + ], + loc: { + start: {line: 1, column: 36}, + end: {line: 1, column: 45} + } + } + } + ], body: { type: "BlockStatement", body: [], @@ -12220,39 +12123,6 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", { end: {line: 1, column: 48} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 37}, - end: {line: 1, column: 38} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 40}, - end: {line: 1, column: 41} - } - }, - { - type: "Identifier", - name: "c", - loc: { - start: {line: 1, column: 43}, - end: {line: 1, column: 44} - } - } - ], - loc: { - start: {line: 1, column: 36}, - end: {line: 1, column: 45} - } - }, generator: false, expression: false, loc: { @@ -12296,8 +12166,17 @@ test("(...a) => {}", { expression: { type: "ArrowFunctionExpression", id: null, - params: [], - defaults: [], + params: [{ + type: "RestElement", + argument: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 4}, + end: {line: 1, column: 5} + } + } + }], body: { type: "BlockStatement", body: [], @@ -12306,14 +12185,6 @@ test("(...a) => {}", { end: {line: 1, column: 12} } }, - rest: { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 4}, - end: {line: 1, column: 5} - } - }, generator: false, expression: false, loc: { @@ -12343,15 +12214,27 @@ test("(a, ...b) => {}", { expression: { type: "ArrowFunctionExpression", id: null, - params: [{ - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 2} + params: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 1}, + end: {line: 1, column: 2} + } + }, + { + type: "RestElement", + argument: { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 7}, + end: {line: 1, column: 8} + } + } } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -12360,14 +12243,6 @@ test("(a, ...b) => {}", { end: {line: 1, column: 15} } }, - rest: { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 7}, - end: {line: 1, column: 8} - } - }, generator: false, expression: false, loc: { @@ -12431,7 +12306,6 @@ test("({ a }) => {}", { end: {line: 1, column: 6} } }], - defaults: [], body: { type: "BlockStatement", body: [], @@ -12440,7 +12314,6 @@ test("({ a }) => {}", { end: {line: 1, column: 13} } }, - rest: null, generator: false, expression: false, loc: { @@ -12470,41 +12343,53 @@ test("({ a }, ...b) => {}", { expression: { type: "ArrowFunctionExpression", id: null, - params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "a", + params: [ + { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 3}, + end: {line: 1, column: 4} + } + }, + value: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 3}, + end: {line: 1, column: 4} + } + }, + kind: "init", + method: false, + shorthand: true, + computed: false, loc: { start: {line: 1, column: 3}, end: {line: 1, column: 4} } - }, - value: { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 3}, - end: {line: 1, column: 4} - } - }, - kind: "init", - method: false, - shorthand: true, - computed: false, + }], loc: { - start: {line: 1, column: 3}, - end: {line: 1, column: 4} + start: {line: 1, column: 1}, + end: {line: 1, column: 6} + } + }, + { + type: "RestElement", + argument: { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 11}, + end: {line: 1, column: 12} + } } - }], - loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 6} } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -12513,14 +12398,6 @@ test("({ a }, ...b) => {}", { end: {line: 1, column: 19} } }, - rest: { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 11}, - end: {line: 1, column: 12} - } - }, generator: false, expression: false, loc: { @@ -12550,8 +12427,34 @@ test("(...[a, b]) => {}", { expression: { type: "ArrowFunctionExpression", id: null, - params: [], - defaults: [], + params: [{ + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 5}, + end: {line: 1, column: 6} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 8}, + end: {line: 1, column: 9} + } + } + ], + loc: { + start: {line: 1, column: 4}, + end: {line: 1, column: 10} + } + } + }], body: { type: "BlockStatement", body: [], @@ -12560,31 +12463,6 @@ test("(...[a, b]) => {}", { end: {line: 1, column: 17} } }, - rest: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 5}, - end: {line: 1, column: 6} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 8}, - end: {line: 1, column: 9} - } - } - ], - loc: { - start: {line: 1, column: 4}, - end: {line: 1, column: 10} - } - }, generator: false, expression: false, loc: { @@ -12614,15 +12492,34 @@ test("(a, ...[b]) => {}", { expression: { type: "ArrowFunctionExpression", id: null, - params: [{ - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 2} + params: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 1}, + end: {line: 1, column: 2} + } + }, + { + type: "RestElement", + argument: { + type: "ArrayPattern", + elements: [{ + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 8}, + end: {line: 1, column: 9} + } + }], + loc: { + start: {line: 1, column: 7}, + end: {line: 1, column: 10} + } + } } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -12631,21 +12528,6 @@ test("(a, ...[b]) => {}", { end: {line: 1, column: 17} } }, - rest: { - type: "ArrayPattern", - elements: [{ - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 8}, - end: {line: 1, column: 9} - } - }], - loc: { - start: {line: 1, column: 7}, - end: {line: 1, column: 10} - } - }, generator: false, expression: false, loc: { @@ -12675,58 +12557,70 @@ test("({ a: [a, b] }, ...c) => {}", { expression: { type: "ArrowFunctionExpression", id: null, - params: [{ - type: "ObjectPattern", - properties: [{ - type: "Property", - key: { - type: "Identifier", - name: "a", + params: [ + { + type: "ObjectPattern", + properties: [{ + type: "Property", + key: { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 3}, + end: {line: 1, column: 4} + } + }, + value: { + type: "ArrayPattern", + elements: [ + { + type: "Identifier", + name: "a", + loc: { + start: {line: 1, column: 7}, + end: {line: 1, column: 8} + } + }, + { + type: "Identifier", + name: "b", + loc: { + start: {line: 1, column: 10}, + end: {line: 1, column: 11} + } + } + ], + loc: { + start: {line: 1, column: 6}, + end: {line: 1, column: 12} + } + }, + kind: "init", + method: false, + shorthand: false, + computed: false, loc: { start: {line: 1, column: 3}, - end: {line: 1, column: 4} - } - }, - value: { - type: "ArrayPattern", - elements: [ - { - type: "Identifier", - name: "a", - loc: { - start: {line: 1, column: 7}, - end: {line: 1, column: 8} - } - }, - { - type: "Identifier", - name: "b", - loc: { - start: {line: 1, column: 10}, - end: {line: 1, column: 11} - } - } - ], - loc: { - start: {line: 1, column: 6}, end: {line: 1, column: 12} } - }, - kind: "init", - method: false, - shorthand: false, - computed: false, + }], loc: { - start: {line: 1, column: 3}, - end: {line: 1, column: 12} + start: {line: 1, column: 1}, + end: {line: 1, column: 14} + } + }, + { + type: "RestElement", + argument: { + type: "Identifier", + name: "c", + loc: { + start: {line: 1, column: 19}, + end: {line: 1, column: 20} + } } - }], - loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 14} } - }], - defaults: [], + ], body: { type: "BlockStatement", body: [], @@ -12735,14 +12629,6 @@ test("({ a: [a, b] }, ...c) => {}", { end: {line: 1, column: 27} } }, - rest: { - type: "Identifier", - name: "c", - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 20} - } - }, generator: false, expression: false, loc: { @@ -12860,9 +12746,19 @@ test("({ a: b, c }, [d, e], ...f) => {}", { start: {line: 1, column: 14}, end: {line: 1, column: 20} } + }, + { + type: "RestElement", + argument: { + type: "Identifier", + name: "f", + loc: { + start: {line: 1, column: 25}, + end: {line: 1, column: 26} + } + } } ], - defaults: [], body: { type: "BlockStatement", body: [], @@ -12871,14 +12767,6 @@ test("({ a: b, c }, [d, e], ...f) => {}", { end: {line: 1, column: 33} } }, - rest: { - type: "Identifier", - name: "f", - loc: { - start: {line: 1, column: 25}, - end: {line: 1, column: 26} - } - }, generator: false, expression: false, loc: { @@ -13981,7 +13869,6 @@ test("e => yield* 10", { end: {line: 1, column: 1} } }], - defaults: [], body: { type: "BinaryExpression", operator: "*", @@ -14007,7 +13894,6 @@ test("e => yield* 10", { end: {line: 1, column: 14} } }, - rest: null, generator: false, expression: true, loc: { @@ -14041,7 +13927,6 @@ test("(function () { yield* 10 })", { type: "FunctionExpression", id: null, params: [], - defaults: [], body: { type: "BlockStatement", body: [{ @@ -14081,7 +13966,6 @@ test("(function () { yield* 10 })", { end: {line: 1, column: 26} } }, - rest: null, generator: false, expression: false, loc: { @@ -14317,19 +14201,18 @@ test('function normal(x, y = 10) {}', { name: "x" }, { - type: "Identifier", - name: "y" + type: "AssignmentPattern", + left: { + type: "Identifier", + name: "y" + }, + right: { + type: "Literal", + value: 10, + raw: "10" + } } ], - defaults: [ - null, - { - type: "Literal", - value: 10, - raw: "10" - } - ], - rest: null, generator: false, body: { type: "BlockStatement", @@ -14714,8 +14597,6 @@ test("class A { static() {} }", { range: [16, 21], id: null, params: [], - defaults: [], - rest: null, generator: false, body: { type: "BlockStatement", @@ -14764,8 +14645,6 @@ test("class A { *static() {} }", { range: [17, 22], id: null, params: [], - defaults: [], - rest: null, generator: true, body: { type: "BlockStatement", diff --git a/test/tests.js b/test/tests.js index d3beafc5f9..dfbfda0438 100644 --- a/test/tests.js +++ b/test/tests.js @@ -23788,21 +23788,23 @@ test("function hello(...rest) { }", { } } }, - params: [], - rest: { - type: "Identifier", - name: "rest", - loc: { - start: { - line: 1, - column: 18 - }, - end: { - line: 1, - column: 22 + params: [{ + type: "RestElement", + argument: { + type: "Identifier", + name: "rest", + loc: { + start: { + line: 1, + column: 18 + }, + end: { + line: 1, + column: 22 + } } } - }, + }], body: { type: "BlockStatement", body: [], @@ -23877,22 +23879,25 @@ test("function hello(a, ...rest) { }", { column: 16 } } - } - ], - rest: { - type: "Identifier", - name: "rest", - loc: { - start: { - line: 1, - column: 21 - }, - end: { - line: 1, - column: 25 + }, + { + type: "RestElement", + argument: { + type: "Identifier", + name: "rest", + loc: { + start: { + line: 1, + column: 21 + }, + end: { + line: 1, + column: 25 + } + } } } - }, + ], body: { type: "BlockStatement", body: [], @@ -24089,21 +24094,23 @@ test("var hi = function (...r) { sayHi() };", { init: { type: "FunctionExpression", id: null, - params: [], - rest: { - type: "Identifier", - name: "r", - loc: { - start: { - line: 1, - column: 22 - }, - end: { - line: 1, - column: 23 + params: [{ + type: "RestElement", + argument: { + type: "Identifier", + name: "r", + loc: { + start: { + line: 1, + column: 22 + }, + end: { + line: 1, + column: 23 + } } } - }, + }], body: { type: "BlockStatement", body: [ From 2e9180f0417122228e4f84426dba86752ccaa1e9 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 15:33:28 +0200 Subject: [PATCH 08/14] Add ES6 patterns to util/walk.js --- util/walk.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/walk.js b/util/walk.js index da7ca9f7e1..5a09df7ddc 100644 --- a/util/walk.js +++ b/util/walk.js @@ -200,7 +200,7 @@ base.ReturnStatement = base.YieldExpression = function(node, st, c) { if (node.argument) c(node.argument, st, "Expression"); }; - base.ThrowStatement = base.SpreadElement = function(node, st, c) { + base.ThrowStatement = base.SpreadElement = base.RestElement = function(node, st, c) { c(node.argument, st, "Expression"); }; base.TryStatement = function(node, st, c) { @@ -249,13 +249,13 @@ base.Expression = skipThrough; base.ThisExpression = ignore; - base.ArrayExpression = function(node, st, c) { + base.ArrayExpression = base.ArrayPattern = function(node, st, c) { for (var i = 0; i < node.elements.length; ++i) { var elt = node.elements[i]; if (elt) c(elt, st, "Expression"); } }; - base.ObjectExpression = function(node, st, c) { + base.ObjectExpression = base.ObjectPattern = function(node, st, c) { for (var i = 0; i < node.properties.length; ++i) c(node.properties[i], st); }; @@ -267,7 +267,7 @@ base.UnaryExpression = base.UpdateExpression = function(node, st, c) { c(node.argument, st, "Expression"); }; - base.BinaryExpression = base.AssignmentExpression = base.LogicalExpression = function(node, st, c) { + base.BinaryExpression = base.AssignmentExpression = base.AssignmentPattern = base.LogicalExpression = function(node, st, c) { c(node.left, st, "Expression"); c(node.right, st, "Expression"); }; From 08b34933d7608470bbbb62a291fb515e4759e197 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 15:39:49 +0200 Subject: [PATCH 09/14] Added acorn_csp to .gitignore and fixed generation under Windows. --- .gitignore | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7a9d2aa37c..088a673331 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /node_modules /.tern-port +/acorn_csp.js diff --git a/package.json b/package.json index e8d244ea07..63412ab22d 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "url": "http://marijnhaverbeke.nl/acorn/LICENSE"}], "scripts": { "test": "node test/run.js", - "prepublish": "bin/without_eval > acorn_csp.js" + "prepublish": "node bin/without_eval > acorn_csp.js" }, "bin": {"acorn": "./bin/acorn"}, "devDependencies": {"regenerate": "~0.6.2", From 41ad304955d6770f2f226edfdb463b74699628c5 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 21:36:16 +0200 Subject: [PATCH 10/14] Introduce helpers for contextual keywords. --- acorn.js | 48 ++++++++++++++++++++++++++---------------------- acorn_loose.js | 42 +++++++++++++++++------------------------- 2 files changed, 43 insertions(+), 47 deletions(-) diff --git a/acorn.js b/acorn.js index 6cf6a60443..35015ad1aa 100644 --- a/acorn.js +++ b/acorn.js @@ -1414,6 +1414,24 @@ } } + // Tests whether parsed token is a contextual keyword. + + function isContextual(name) { + return tokType === _name && tokVal === name; + } + + // Consumes contextual keyword if possible. + + function eatContextual(name) { + return tokVal === name && eat(_name); + } + + // Asserts that following token is given contextual keyword. + + function expectContextual(name) { + if (!eatContextual(name)) unexpected(); + } + // Test whether a semicolon can be inserted at the current position. function canInsertSemicolon() { @@ -1814,13 +1832,13 @@ next(); parseVar(init, true, varKind); finishNode(init, "VariableDeclaration"); - if ((tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) && init.declarations.length === 1 && + if ((tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) && init.declarations.length === 1 && !(isLet && init.declarations[0].init)) return parseForIn(node, init); return parseFor(node, init); } var init = parseExpression(false, true); - if (tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) { + if (tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) { checkLVal(init); return parseForIn(node, init); } @@ -2631,8 +2649,7 @@ node.declaration = null; node['default'] = false; node.specifiers = parseExportSpecifiers(); - if (tokType === _name && tokVal === "from") { - next(); + if (eatContextual("from")) { node.source = tokType === _string ? parseExprAtom() : unexpected(); } else { if (isBatch) unexpected(); @@ -2663,12 +2680,7 @@ var node = startNode(); node.id = parseIdent(tokType === _default); - if (tokType === _name && tokVal === "as") { - next(); - node.name = parseIdent(true); - } else { - node.name = null; - } + node.name = eatContextual("as") ? parseIdent(true) : null; nodes.push(finishNode(node, "ExportSpecifier")); } } @@ -2686,8 +2698,7 @@ node.kind = ""; } else { node.specifiers = parseImportSpecifiers(); - if (tokType !== _name || tokVal !== "from") unexpected(); - next(); + expectContextual("from"); node.source = tokType === _string ? parseExprAtom() : unexpected(); } semicolon(); @@ -2711,8 +2722,7 @@ if (tokType === _star) { var node = startNode(); next(); - if (tokType !== _name || tokVal !== "as") unexpected(); - next(); + expectContextual("as"); node.name = parseIdent(); checkLVal(node.name, true); nodes.push(finishNode(node, "ImportBatchSpecifier")); @@ -2727,12 +2737,7 @@ var node = startNode(); node.id = parseIdent(true); - if (tokType === _name && tokVal === "as") { - next(); - node.name = parseIdent(); - } else { - node.name = null; - } + node.name = eatContextual("as") ? parseIdent() : null; checkLVal(node.name || node.id, true); node['default'] = false; nodes.push(finishNode(node, "ImportSpecifier")); @@ -2765,8 +2770,7 @@ expect(_parenL); block.left = parseAssignableAtom(); checkLVal(block.left, true); - if (tokType !== _name || tokVal !== "of") unexpected(); - next(); + expectContextual("of"); block.right = parseExpression(); expect(_parenR); node.blocks.push(finishNode(block, "ComprehensionBlock")); diff --git a/acorn_loose.js b/acorn_loose.js index e1ee14fc3c..44b0870cd9 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -271,9 +271,18 @@ } } + function isContextual(name) { + return token.type === tt.name && token.value === name; + } + + function eatContextual(name) { + return token.value === name && eat(tt.name); + } + function canInsertSemicolon() { return (token.type === tt.eof || token.type === tt.braceR || newline.test(input.slice(lastEnd, token.start))); } + function semicolon() { return eat(tt.semi); } @@ -352,13 +361,13 @@ if (token.type === tt.semi) return parseFor(node, null); if (token.type === tt._var || token.type === tt._let) { var init = parseVar(true); - if (init.declarations.length === 1 && (token.type === tt._in || token.type === tt.name && token.value === "of")) { + if (init.declarations.length === 1 && (token.type === tt._in || isContextual("of"))) { return parseForIn(node, init); } return parseFor(node, init); } var init = parseExpression(false, true); - if (token.type === tt._in || token.type === tt.name && token.value === "of") { + if (token.type === tt._in || isContextual("of")) { return parseForIn(node, checkLVal(init)); } return parseFor(node, init); @@ -1080,10 +1089,7 @@ if (token.type === tt.star) { var elt = startNode(); next(); - if (token.type === tt.name && token.value === "as") { - next(); - elt.name = parseIdent(); - } + if (eatContextual("as")) elt.name = parseIdent(); elts.push(finishNode(elt, prefix + "BatchSpecifier")); } else { var indent = curIndent, line = curLineStart, continuedLine = nextLineStart; @@ -1092,22 +1098,13 @@ if (curLineStart > continuedLine) continuedLine = curLineStart; while (!closes(tt.braceR, indent + (curLineStart <= continuedLine ? 1 : 0), line)) { var elt = startNode(); - if (token.type === tt.star) { - next(); - if (token.type === tt.name && token.value === "as") { - next(); - elt.name = parseIdent(); - } + if (eat(tt.star)) { + if (eatContextual("as")) elt.name = parseIdent(); finishNode(elt, prefix + "BatchSpecifier"); } else { - if (token.type === tt.name && token.value === "from") break; + if (isContextual("from")) break; elt.id = parseIdent(); - if (token.type === tt.name && token.value === "as") { - next(); - elt.name = parseIdent(); - } else { - elt.name = null; - } + elt.name = eatContextual("as") ? parseIdent() : null; finishNode(elt, prefix + "Specifier"); } elts.push(elt); @@ -1116,12 +1113,7 @@ eat(tt.braceR); popCx(); } - if (token.type === tt.name && token.value === "from") { - next(); - node.source = parseExprAtom(); - } else { - node.source = null; - } + node.source = eatContextual("from") ? parseExprAtom() : null; } function parseExprList(close, allowEmpty) { From f0569147e6b34b94c60f0bdf2edcd8d092012a5d Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 21:48:33 +0200 Subject: [PATCH 11/14] Avoid extra call and arg in parseExpression for single-expression case. --- acorn.js | 18 +++++++++--------- acorn_loose.js | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/acorn.js b/acorn.js index 35015ad1aa..d7fc369fed 100644 --- a/acorn.js +++ b/acorn.js @@ -1837,7 +1837,7 @@ return parseForIn(node, init); return parseFor(node, init); } - var init = parseExpression(false, true); + var init = parseExpression(true); if (tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) { checkLVal(init); return parseForIn(node, init); @@ -2054,7 +2054,7 @@ var decl = startNode(); decl.id = parseAssignableAtom(); checkLVal(decl.id, true); - decl.init = eat(_eq) ? parseExpression(true, noIn) : (kind === _const.keyword ? unexpected() : null); + decl.init = eat(_eq) ? parseMaybeAssign(noIn) : (kind === _const.keyword ? unexpected() : null); node.declarations.push(finishNode(decl, "VariableDeclarator")); if (!eat(_comma)) break; } @@ -2073,10 +2073,10 @@ // sequences (in argument lists, array literals, or object literals) // or the `in` operator (in for loops initalization expressions). - function parseExpression(noComma, noIn) { + function parseExpression(noIn) { var start = storeCurrentPos(); var expr = parseMaybeAssign(noIn); - if (!noComma && tokType === _comma) { + if (tokType === _comma) { var node = startNodeAt(start); node.expressions = [expr]; while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn)); @@ -2111,9 +2111,9 @@ if (eat(_question)) { var node = startNodeAt(start); node.test = expr; - node.consequent = parseExpression(true); + node.consequent = parseMaybeAssign(); expect(_colon); - node.alternate = parseExpression(true, noIn); + node.alternate = parseMaybeAssign(noIn); return finishNode(node, "ConditionalExpression"); } return expr; @@ -2514,7 +2514,7 @@ var isExpression = allowExpression && tokType !== _braceL; if (isExpression) { - node.body = parseExpression(true); + node.body = parseMaybeAssign(); node.expression = true; } else { // Start a new scope with regard to labels and the `inFunction` @@ -2637,7 +2637,7 @@ } else // export default ...; if (eat(_default)) { - node.declaration = parseExpression(true); + node.declaration = parseMaybeAssign(); node['default'] = true; node.specifiers = null; node.source = null; @@ -2755,7 +2755,7 @@ node.argument = null; } else { node.delegate = eat(_star); - node.argument = parseExpression(true); + node.argument = parseMaybeAssign(); } return finishNode(node, "YieldExpression"); } diff --git a/acorn_loose.js b/acorn_loose.js index 44b0870cd9..297589a498 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -366,7 +366,7 @@ } return parseFor(node, init); } - var init = parseExpression(false, true); + var init = parseExpression(true); if (token.type === tt._in || isContextual("of")) { return parseForIn(node, checkLVal(init)); } @@ -539,7 +539,7 @@ do { var decl = startNode(); decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent(); - decl.init = eat(tt.eq) ? parseExpression(true, noIn) : null; + decl.init = eat(tt.eq) ? parseMaybeAssign(noIn) : null; node.declarations.push(finishNode(decl, "VariableDeclarator")); } while (eat(tt.comma)); if (!node.declarations.length) { @@ -551,10 +551,10 @@ return finishNode(node, "VariableDeclaration"); } - function parseExpression(noComma, noIn) { + function parseExpression(noIn) { var start = storeCurrentPos(); var expr = parseMaybeAssign(noIn); - if (!noComma && token.type === tt.comma) { + if (token.type === tt.comma) { var node = startNodeAt(start); node.expressions = [expr]; while (eat(tt.comma)) node.expressions.push(parseMaybeAssign(noIn)); @@ -592,8 +592,8 @@ if (eat(tt.question)) { var node = startNodeAt(start); node.test = expr; - node.consequent = parseExpression(true); - node.alternate = expect(tt.colon) ? parseExpression(true, noIn) : dummyIdent(); + node.consequent = parseMaybeAssign(); + node.alternate = expect(tt.colon) ? parseMaybeAssign(noIn) : dummyIdent(); return finishNode(node, "ConditionalExpression"); } return expr; @@ -783,7 +783,7 @@ node.argument = null; } else { node.delegate = eat(tt.star); - node.argument = parseExpression(true); + node.argument = parseMaybeAssign(); } return finishNode(node, "YieldExpression"); @@ -871,7 +871,7 @@ isGenerator = eat(tt.star); } parsePropertyName(prop); - if (isDummy(prop.key)) { if (isDummy(parseExpression(true))) next(); eat(tt.comma); continue; } + if (isDummy(prop.key)) { if (isDummy(parseMaybeAssign())) next(); eat(tt.comma); continue; } if (isClass) { if (prop.key.type === "Identifier" && !prop.computed && prop.key.name === "static" && (token.type != tt.parenL && token.type != tt.braceL)) { @@ -884,7 +884,7 @@ } if (!isClass && eat(tt.colon)) { prop.kind = "init"; - prop.value = parseExpression(true); + prop.value = parseMaybeAssign(); } else if (options.ecmaVersion >= 6 && (token.type === tt.parenL || token.type === tt.braceL)) { if (isClass) { prop.kind = ""; @@ -1029,7 +1029,7 @@ node.params = parseFunctionParams(); node.generator = isGenerator || false; node.expression = options.ecmaVersion >= 6 && token.type !== tt.braceL; - node.body = node.expression ? parseExpression(true) : parseBlock(); + node.body = node.expression ? parseMaybeAssign() : parseBlock(); return finishNode(node, "FunctionExpression"); } @@ -1037,7 +1037,7 @@ initFunction(node); node.params = toAssignableList(params); node.expression = token.type !== tt.braceL; - node.body = node.expression ? parseExpression(true) : parseBlock(); + node.body = node.expression ? parseMaybeAssign() : parseBlock(); return finishNode(node, "ArrowFunctionExpression"); } @@ -1124,7 +1124,7 @@ elts.push(allowEmpty ? null : dummyIdent()); continue; } - var elt = parseExpression(true); + var elt = parseMaybeAssign(); if (isDummy(elt)) { if (closes(close, indent, line)) break; next(); From 65d09eac6eeeec5dda2a03db715e881892a9675d Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 23 Jan 2015 23:41:03 +0200 Subject: [PATCH 12/14] Implement shorthand property assignment in ambiguous contexts. Issue #181. --- acorn.js | 138 ++++++++++++++-------- test/tests-harmony.js | 265 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 348 insertions(+), 55 deletions(-) diff --git a/acorn.js b/acorn.js index d7fc369fed..01f7037033 100644 --- a/acorn.js +++ b/acorn.js @@ -1468,7 +1468,7 @@ // Convert existing expression atom to assignable pattern // if possible. - function toAssignable(node, allowSpread, checkType) { + function toAssignable(node) { if (options.ecmaVersion >= 6 && node) { switch (node.type) { case "Identifier": @@ -1476,43 +1476,32 @@ case "ObjectPattern": case "ArrayPattern": case "AssignmentPattern": - case "RestElement": break; case "ObjectExpression": node.type = "ObjectPattern"; for (var i = 0; i < node.properties.length; i++) { var prop = node.properties[i]; - if (prop.kind !== "init") unexpected(prop.key.start); - toAssignable(prop.value, false, checkType); + if (prop.kind !== "init") raise(prop.key.start, "Object pattern can't contain getter or setter"); + toAssignable(prop.value); } break; case "ArrayExpression": node.type = "ArrayPattern"; - toAssignableList(node.elements, checkType); - break; - - case "SpreadElement": - if (allowSpread) { - node.type = "RestElement"; - toAssignable(node.argument, false, checkType); - checkSpreadAssign(node.argument); - } else { - unexpected(node.start); - } + toAssignableList(node.elements); break; case "AssignmentExpression": if (node.operator === "=") { node.type = "AssignmentPattern"; } else { - unexpected(node.left.end); + raise(node.left.end, "Only '=' operator can be used for specifying default value."); } break; default: - if (checkType) unexpected(node.start); + raise(node.start, "Assigning to rvalue"); } } return node; @@ -1520,19 +1509,33 @@ // Convert list of expression atoms to binding list. - function toAssignableList(exprList, checkType) { - for (var i = 0; i < exprList.length; i++) { - toAssignable(exprList[i], i === exprList.length - 1, checkType); + function toAssignableList(exprList) { + if (exprList.length) { + for (var i = 0; i < exprList.length - 1; i++) { + toAssignable(exprList[i]); + } + var last = exprList[exprList.length - 1]; + switch (last.type) { + case "RestElement": + break; + case "SpreadElement": + last.type = "RestElement"; + toAssignable(last.argument); + checkSpreadAssign(last.argument); + break; + default: + toAssignable(last); + } } return exprList; } // Parses spread element. - function parseSpread() { + function parseSpread(refShorthandDefaultPos) { var node = startNode(); next(); - node.argument = parseMaybeAssign(); + node.argument = parseMaybeAssign(refShorthandDefaultPos); return finishNode(node, "SpreadElement"); } @@ -1837,10 +1840,14 @@ return parseForIn(node, init); return parseFor(node, init); } - var init = parseExpression(true); + var refShorthandDefaultPos = {start: 0}; + var init = parseExpression(true, refShorthandDefaultPos); if (tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) { + toAssignable(init); checkLVal(init); return parseForIn(node, init); + } else if (refShorthandDefaultPos.start) { + unexpected(refShorthandDefaultPos.start); } return parseFor(node, init); } @@ -2069,17 +2076,20 @@ // and, *if* the syntactic construct they handle is present, wrap // the AST node that the inner parser gave them in another node. - // Parse a full expression. The arguments are used to forbid comma - // sequences (in argument lists, array literals, or object literals) - // or the `in` operator (in for loops initalization expressions). + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). - function parseExpression(noIn) { + function parseExpression(noIn, refShorthandDefaultPos) { var start = storeCurrentPos(); - var expr = parseMaybeAssign(noIn); + var expr = parseMaybeAssign(noIn, refShorthandDefaultPos); if (tokType === _comma) { var node = startNodeAt(start); node.expressions = [expr]; - while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn)); + while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn, refShorthandDefaultPos)); return finishNode(node, "SequenceExpression"); } return expr; @@ -2088,26 +2098,37 @@ // Parse an assignment expression. This includes applications of // operators like `+=`. - function parseMaybeAssign(noIn) { + function parseMaybeAssign(noIn, refShorthandDefaultPos) { + var failOnShorthandAssign; + if (!refShorthandDefaultPos) { + refShorthandDefaultPos = {start: 0}; + failOnShorthandAssign = true; + } else { + failOnShorthandAssign = false; + } var start = storeCurrentPos(); - var left = parseMaybeConditional(noIn); + var left = parseMaybeConditional(noIn, refShorthandDefaultPos); if (tokType.isAssign) { var node = startNodeAt(start); node.operator = tokVal; node.left = tokType === _eq ? toAssignable(left) : left; + refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly checkLVal(left); next(); node.right = parseMaybeAssign(noIn); return finishNode(node, "AssignmentExpression"); + } else if (failOnShorthandAssign && refShorthandDefaultPos.start) { + unexpected(refShorthandDefaultPos.start); } return left; } // Parse a ternary conditional (`?:`) operator. - function parseMaybeConditional(noIn) { + function parseMaybeConditional(noIn, refShorthandDefaultPos) { var start = storeCurrentPos(); - var expr = parseExprOps(noIn); + var expr = parseExprOps(noIn, refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; if (eat(_question)) { var node = startNodeAt(start); node.test = expr; @@ -2121,9 +2142,11 @@ // Start the precedence parser. - function parseExprOps(noIn) { + function parseExprOps(noIn, refShorthandDefaultPos) { var start = storeCurrentPos(); - return parseExprOp(parseMaybeUnary(), start, -1, noIn); + var expr = parseMaybeUnary(refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; + return parseExprOp(expr, start, -1, noIn); } // Parse binary operators with the operator precedence parsing @@ -2152,13 +2175,14 @@ // Parse unary operators, both prefix and postfix. - function parseMaybeUnary() { + function parseMaybeUnary(refShorthandDefaultPos) { if (tokType.prefix) { var node = startNode(), update = tokType.isUpdate; node.operator = tokVal; node.prefix = true; next(); node.argument = parseMaybeUnary(); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) unexpected(refShorthandDefaultPos.start); if (update) checkLVal(node.argument); else if (strict && node.operator === "delete" && node.argument.type === "Identifier") @@ -2166,7 +2190,8 @@ return finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } var start = storeCurrentPos(); - var expr = parseExprSubscripts(); + var expr = parseExprSubscripts(refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; while (tokType.postfix && !canInsertSemicolon()) { var node = startNodeAt(start); node.operator = tokVal; @@ -2181,9 +2206,11 @@ // Parse call, dot, and `[]`-subscript expressions. - function parseExprSubscripts() { + function parseExprSubscripts(refShorthandDefaultPos) { var start = storeCurrentPos(); - return parseSubscripts(parseExprAtom(), start); + var expr = parseExprAtom(refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; + return parseSubscripts(expr, start); } function parseSubscripts(base, start, noCalls) { @@ -2218,7 +2245,7 @@ // `new`, or an expression wrapped in punctuation like `()`, `[]`, // or `{}`. - function parseExprAtom() { + function parseExprAtom(refShorthandDefaultPos) { switch (tokType) { case _this: var node = startNode(); @@ -2268,11 +2295,11 @@ if (options.ecmaVersion >= 7 && tokType === _for) { return parseComprehension(node, false); } - node.elements = parseExprList(_bracketR, true, true); + node.elements = parseExprList(_bracketR, true, true, refShorthandDefaultPos); return finishNode(node, "ArrayExpression"); case _braceL: - return parseObj(); + return parseObj(false, refShorthandDefaultPos); case _function: var node = startNode(); @@ -2302,7 +2329,8 @@ return parseComprehension(startNodeAt(start), true); } - var innerStart = storeCurrentPos(), exprList = [], first = true, spreadStart, innerParenStart; + var innerStart = storeCurrentPos(), exprList = [], first = true; + var refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart; while (tokType !== _parenR) { first ? first = false : expect(_comma); if (tokType === _ellipsis) { @@ -2313,7 +2341,7 @@ if (tokType === _parenL && !innerParenStart) { innerParenStart = tokStart; } - exprList.push(parseMaybeAssign()); + exprList.push(parseMaybeAssign(false, refShorthandDefaultPos)); } } var innerEnd = storeCurrentPos(); @@ -2326,6 +2354,7 @@ if (!exprList.length) unexpected(lastStart); if (spreadStart) unexpected(spreadStart); + if (refShorthandDefaultPos.start) unexpected(refShorthandDefaultPos.start); if (exprList.length > 1) { val = startNodeAt(innerStart); @@ -2392,7 +2421,7 @@ // Parse an object literal or binding pattern. - function parseObj(isPattern) { + function parseObj(isPattern, refShorthandDefaultPos) { var node = startNode(), first = true, propHash = {}; node.properties = []; next(); @@ -2414,7 +2443,7 @@ } parsePropertyName(prop); if (eat(_colon)) { - prop.value = isPattern ? parseMaybeDefault(start) : parseMaybeAssign(); + prop.value = isPattern ? parseMaybeDefault(start) : parseMaybeAssign(false, refShorthandDefaultPos); prop.kind = "init"; } else if (options.ecmaVersion >= 6 && tokType === _parenL) { if (isPattern) unexpected(); @@ -2430,7 +2459,15 @@ prop.value = parseMethod(false); } else if (options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { prop.kind = "init"; - prop.value = isPattern ? parseMaybeDefault(start, prop.key) : prop.key; + if (isPattern) { + prop.value = parseMaybeDefault(start, prop.key); + } else if (tokType === _eq && refShorthandDefaultPos) { + if (!refShorthandDefaultPos.start) + refShorthandDefaultPos.start = tokStart; + prop.value = parseMaybeDefault(start, prop.key); + } else { + prop.value = prop.key; + } prop.shorthand = true; } else unexpected(); @@ -2583,7 +2620,7 @@ // nothing in between them to be parsed as `null` (which is needed // for array literals). - function parseExprList(close, allowTrailingComma, allowEmpty) { + function parseExprList(close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) { var elts = [], first = true; while (!eat(close)) { if (!first) { @@ -2594,7 +2631,10 @@ if (allowEmpty && tokType === _comma) { elts.push(null); } else { - elts.push(tokType === _ellipsis ? parseSpread() : parseMaybeAssign()); + if (tokType === _ellipsis) + elts.push(parseSpread(refShorthandDefaultPos)); + else + elts.push(parseMaybeAssign(false, refShorthandDefaultPos)); } } return elts; diff --git a/test/tests-harmony.js b/test/tests-harmony.js index 9fc9dec59c..641f18657f 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -13745,7 +13745,7 @@ testFail("[2] = 42", "Assigning to rvalue (1:1)", {ecmaVersion: 6}); testFail("({ obj:20 }) = 42", "Assigning to rvalue (1:7)", {ecmaVersion: 6}); -testFail("( { get x() {} } ) = 0", "Unexpected token (1:8)", {ecmaVersion: 6}); +testFail("( { get x() {} } ) = 0", "Object pattern can't contain getter or setter (1:8)", {ecmaVersion: 6}); testFail("x \n is y", "Unexpected token (2:4)", {ecmaVersion: 6}); @@ -13801,9 +13801,9 @@ testFail("\"use strict\"; (a) => 00", "Invalid number (1:21)", {ecmaVersion: 6}) testFail("() <= 42", "Unexpected token (1:1)", {ecmaVersion: 6}); -testFail("(10) => 00", "Unexpected token (1:1)", {ecmaVersion: 6}); +testFail("(10) => 00", "Assigning to rvalue (1:1)", {ecmaVersion: 6}); -testFail("(10, 20) => 00", "Unexpected token (1:1)", {ecmaVersion: 6}); +testFail("(10, 20) => 00", "Assigning to rvalue (1:1)", {ecmaVersion: 6}); testFail("yield v", "Unexpected token (1:6)", {ecmaVersion: 6}); @@ -14037,7 +14037,7 @@ testFail("\"use strict\"; function x(a, ...[a]){}", "Argument name clash in stri testFail("(...a, b) => {}", "Unexpected token (1:5)", {ecmaVersion: 6}); -testFail("([ 5 ]) => {}", "Unexpected token (1:3)", {ecmaVersion: 6}); +testFail("([ 5 ]) => {}", "Assigning to rvalue (1:3)", {ecmaVersion: 6}); testFail("({ 5 }) => {}", "Unexpected token (1:5)", {ecmaVersion: 6}); @@ -14045,7 +14045,7 @@ testFail("(...[ 5 ]) => {}", "Unexpected token (1:6)", {ecmaVersion: 6}); testFail("[...{ a }] = b", "Unexpected token (1:4)", {ecmaVersion: 6}); -testFail("[...a, b] = c", "Unexpected token (1:1)", {ecmaVersion: 6}); +testFail("[...a, b] = c", "Assigning to rvalue (1:1)", {ecmaVersion: 6}); testFail("({ t(eval) { \"use strict\"; } });", "Defining 'eval' in strict mode (1:5)", {ecmaVersion: 6}); @@ -14120,7 +14120,7 @@ testFail("\"use strict\"; (eval) => 42", "Defining 'eval' in strict mode (1:15)" testFail("(eval) => { \"use strict\"; 42 }", "Defining 'eval' in strict mode (1:1)", {ecmaVersion: 6}); -testFail("({ get test() { } }) => 42", "Unexpected token (1:7)", {ecmaVersion: 6}); +testFail("({ get test() { } }) => 42", "Object pattern can't contain getter or setter (1:7)", {ecmaVersion: 6}); /* Regression tests */ @@ -14509,6 +14509,259 @@ test("var [localVar = defaultValue] = obj", { loose: false }); +test("({x = 0} = obj)", { + type: "Program", + range: [0, 15], + body: [{ + type: "ExpressionStatement", + range: [0, 15], + expression: { + type: "AssignmentExpression", + range: [1, 14], + operator: "=", + left: { + type: "ObjectPattern", + range: [1, 8], + properties: [{ + type: "Property", + range: [2, 7], + method: false, + shorthand: true, + computed: false, + key: { + type: "Identifier", + range: [2, 3], + name: "x" + }, + kind: "init", + value: { + type: "AssignmentPattern", + range: [6, 7], + operator: "=", + left: { + type: "Identifier", + range: [2, 3], + name: "x" + }, + right: { + type: "Literal", + range: [6, 7], + value: 0 + } + } + }] + }, + right: { + type: "Identifier", + range: [11, 14], + name: "obj" + } + } + }] +}, { + ecmaVersion: 6, + ranges: true, + loose: false +}); + +test("({x = 0}) => x", { + type: "Program", + range: [0, 14], + body: [{ + type: "ExpressionStatement", + range: [0, 14], + expression: { + type: "ArrowFunctionExpression", + range: [0, 14], + id: null, + generator: false, + expression: true, + params: [{ + type: "ObjectPattern", + range: [1, 8], + properties: [{ + type: "Property", + range: [2, 7], + method: false, + shorthand: true, + computed: false, + key: { + type: "Identifier", + range: [2, 3], + name: "x" + }, + kind: "init", + value: { + type: "AssignmentPattern", + range: [6, 7], + operator: "=", + left: { + type: "Identifier", + range: [2, 3], + name: "x" + }, + right: { + type: "Literal", + range: [6, 7], + value: 0 + } + } + }] + }], + body: { + type: "Identifier", + range: [13, 14], + name: "x" + } + } + }] +}, { + ecmaVersion: 6, + ranges: true, + loose: false +}); + +test("[a, {b: {c = 1}}] = arr", { + type: "Program", + range: [0, 23], + body: [{ + type: "ExpressionStatement", + range: [0, 23], + expression: { + type: "AssignmentExpression", + range: [0, 23], + operator: "=", + left: { + type: "ArrayPattern", + range: [0, 17], + elements: [ + { + type: "Identifier", + range: [1, 2], + name: "a" + }, + { + type: "ObjectPattern", + range: [4, 16], + properties: [{ + type: "Property", + range: [5, 15], + method: false, + shorthand: false, + computed: false, + key: { + type: "Identifier", + range: [5, 6], + name: "b" + }, + value: { + type: "ObjectPattern", + range: [8, 15], + properties: [{ + type: "Property", + range: [9, 14], + method: false, + shorthand: true, + computed: false, + key: { + type: "Identifier", + range: [9, 10], + name: "c" + }, + kind: "init", + value: { + type: "AssignmentPattern", + range: [13, 14], + operator: "=", + left: { + type: "Identifier", + range: [9, 10], + name: "c" + }, + right: { + type: "Literal", + range: [13, 14], + value: 1 + } + } + }] + }, + kind: "init" + }] + } + ] + }, + right: { + type: "Identifier", + range: [20, 23], + name: "arr" + } + } + }] +}, { + ecmaVersion: 6, + ranges: true, + loose: false +}); + +test("for ({x = 0} in arr);", { + type: "Program", + range: [0, 21], + body: [{ + type: "ForInStatement", + range: [0, 21], + left: { + type: "ObjectPattern", + range: [5, 12], + properties: [{ + type: "Property", + range: [6, 11], + method: false, + shorthand: true, + computed: false, + key: { + type: "Identifier", + range: [6, 7], + name: "x" + }, + kind: "init", + value: { + type: "AssignmentPattern", + range: [10, 11], + operator: "=", + left: { + type: "Identifier", + range: [6, 7], + name: "x" + }, + right: { + type: "Literal", + range: [10, 11], + value: 0 + } + } + }] + }, + right: { + type: "Identifier", + range: [16, 19], + name: "arr" + }, + body: { + type: "EmptyStatement", + range: [20, 21] + } + }] +}, { + ecmaVersion: 6, + ranges: true, + loose: false +}); + +testFail("obj = {x = 0}", "Unexpected token (1:9)", {ecmaVersion: 6}); + +testFail("f({x = 0})", "Unexpected token (1:5)", {ecmaVersion: 6}); + // https://github.com/marijnh/acorn/issues/191 test("try {} catch ({message}) {}", { From cdd444eff12a4e6eb0744606ce12d6b6043133b6 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Sat, 24 Jan 2015 02:24:55 +0200 Subject: [PATCH 13/14] Speed-up reading words, strings and templates. Now identifiers and strings even with escaped chars are read in optimized way by reading entire chunks delimited by escape chars (and not bailing to deopt mode on first one). --- acorn.js | 61 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/acorn.js b/acorn.js index 01f7037033..91284e04ac 100644 --- a/acorn.js +++ b/acorn.js @@ -1119,36 +1119,33 @@ } function readString(quote) { - ++tokPos; - var out = ""; + var out = "", chunkStart = ++tokPos; for (;;) { if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant"); var ch = input.charCodeAt(tokPos); - if (ch === quote) { - ++tokPos; - return finishToken(_string, out); - } + if (ch === quote) break; if (ch === 92) { // '\' + out += input.slice(chunkStart, tokPos); out += readEscapedChar(); + chunkStart = tokPos; } else { + if (isNewLine(ch)) raise(tokStart, "Unterminated string constant"); ++tokPos; - if (isNewLine(ch)) { - raise(tokStart, "Unterminated string constant"); - } - out += String.fromCharCode(ch); // '\' } } + out += input.slice(chunkStart, tokPos++); + return finishToken(_string, out); } // Reads template string tokens. function readTmplToken() { - var out = "", start = tokPos; + var out = "", chunkStart = tokPos; for (;;) { if (tokPos >= inputLen) raise(tokStart, "Unterminated template"); var ch = input.charCodeAt(tokPos); if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${' - if (tokPos === start && tokType === _template) { + if (tokPos === tokStart && tokType === _template) { if (ch === 36) { tokPos += 2; return finishToken(_dollarBraceL); @@ -1157,23 +1154,29 @@ return finishToken(_backQuote); } } + out += input.slice(chunkStart, tokPos); return finishToken(_template, out); } if (ch === 92) { // '\' + out += input.slice(chunkStart, tokPos); out += readEscapedChar(); + chunkStart = tokPos; + } else if (isNewLine(ch)) { + out += input.slice(chunkStart, tokPos); + ++tokPos; + if (ch === 13 && input.charCodeAt(tokPos) === 10) { + ++tokPos; + out += "\n"; + } else { + out += String.fromCharCode(ch); + } + if (options.locations) { + ++tokCurLine; + tokLineStart = tokPos; + } + chunkStart = tokPos; } else { ++tokPos; - if (isNewLine(ch)) { - if (ch === 13 && input.charCodeAt(tokPos) === 10) { - ++tokPos; - ch = 10; - } - if (options.locations) { - ++tokCurLine; - tokLineStart = tokPos; - } - } - out += String.fromCharCode(ch); } } } @@ -1228,20 +1231,19 @@ // Read an identifier, and return it as a string. Sets `containsEsc` // to whether the word contained a '\u' escape. // - // Only builds up the word character-by-character when it actually - // containeds an escape, as a micro-optimization. + // Incrementally adds only escaped chars, adding other chunks as-is + // as a micro-optimization. function readWord1() { containsEsc = false; - var word, first = true, start = tokPos; + var word = "", first = true, chunkStart = tokPos; for (;;) { var ch = input.charCodeAt(tokPos); if (isIdentifierChar(ch)) { - if (containsEsc) word += input.charAt(tokPos); ++tokPos; } else if (ch === 92) { // "\" - if (!containsEsc) word = input.slice(start, tokPos); containsEsc = true; + word += input.slice(chunkStart, tokPos); if (input.charCodeAt(++tokPos) != 117) // "u" raise(tokPos, "Expecting Unicode escape sequence \\uXXXX"); ++tokPos; @@ -1251,12 +1253,13 @@ if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc))) raise(tokPos - 4, "Invalid Unicode escape"); word += escStr; + chunkStart = tokPos; } else { break; } first = false; } - return containsEsc ? word : input.slice(start, tokPos); + return word + input.slice(chunkStart, tokPos); } // Read an identifier or keyword token. Will check for reserved From 5d96bbd781538b14d61bb1259a446317520fc0ba Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Sat, 24 Jan 2015 13:38:14 +0200 Subject: [PATCH 14/14] Simplify & fix rest argument validity checks. --- acorn.js | 23 +++++++++++------------ acorn_loose.js | 3 --- test/tests-harmony.js | 3 +++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/acorn.js b/acorn.js index 91284e04ac..847a6ba67c 100644 --- a/acorn.js +++ b/acorn.js @@ -315,7 +315,7 @@ function initParserState() { lastStart = lastEnd = tokPos; if (options.locations) lastEndLoc = curPosition(); - inFunction = inGenerator = strict = false; + inFunction = inGenerator = false; labels = []; skipSpace(); readToken(); @@ -616,6 +616,7 @@ tokType = _eof; tokContext = [b_stat]; tokExprAllowed = true; + strict = false; if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') { skipLineComment(2); } @@ -1523,8 +1524,10 @@ break; case "SpreadElement": last.type = "RestElement"; - toAssignable(last.argument); - checkSpreadAssign(last.argument); + var arg = last.argument; + toAssignable(arg); + if (arg.type !== "Identifier" && arg.type !== "ArrayPattern") + unexpected(arg.start); break; default: toAssignable(last); @@ -1545,8 +1548,7 @@ function parseRest() { var node = startNode(); next(); - node.argument = parseAssignableAtom(); - checkSpreadAssign(node.argument); + node.argument = tokType === _name || tokType === _bracketL ? parseAssignableAtom() : unexpected(); return finishNode(node, "RestElement"); } @@ -1598,13 +1600,6 @@ return finishNode(node, "AssignmentPattern"); } - // Checks if node can be assignable spread argument. - - function checkSpreadAssign(node) { - if (node.type !== "Identifier" && node.type !== "ArrayPattern") - unexpected(node.start); - } - // Verify that argument names are not repeated, and it does not // try to bind the words `eval` or `arguments`. @@ -1691,7 +1686,11 @@ break; case "AssignmentPattern": + checkLVal(expr.left); + break; + case "RestElement": + checkLVal(expr.argument); break; default: diff --git a/acorn_loose.js b/acorn_loose.js index 297589a498..ab0c6ea709 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -325,9 +325,6 @@ } function parseStatement() { - if (token.type === tt.slash || token.type === tt.assign && token.value === "/=") - next(true); - var starttype = token.type, node = startNode(); switch (starttype) { diff --git a/test/tests-harmony.js b/test/tests-harmony.js index 641f18657f..596e5f7ab0 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -15013,3 +15013,6 @@ testFail("if (1) let x = 10;", "Unexpected token (1:7)", {ecmaVersion: 6}); testFail("for (;;) const x = 10;", "Unexpected token (1:9)", {ecmaVersion: 6}); testFail("while (1) function foo(){}", "Unexpected token (1:10)", {ecmaVersion: 6}); testFail("if (1) ; else class Cls {}", "Unexpected token (1:14)", {ecmaVersion: 6}); + +testFail("'use strict'; [...eval] = arr", "Assigning to eval in strict mode (1:18)", {ecmaVersion: 6}); +testFail("'use strict'; ({eval = defValue} = obj)", "Assigning to eval in strict mode (1:16)", {ecmaVersion: 6});