Switch from Function.{rest,defaults} to AssignmentPattern and RestElement.

Closes #182.
This commit is contained in:
Ingvar Stepanyan 2015-01-23 15:29:37 +02:00
parent 38609ae26d
commit 917de714b1
4 changed files with 1251 additions and 1431 deletions

113
acorn.js
View File

@ -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);
}
}

View File

@ -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");

File diff suppressed because it is too large Load Diff

View File

@ -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: [