Forbid spread element in sequence expressions.
This commit is contained in:
parent
8f96965d36
commit
3ee9e288a2
38
acorn.js
38
acorn.js
@ -32,8 +32,7 @@
|
|||||||
// The main exported interface (under `self.acorn` when in the
|
// The main exported interface (under `self.acorn` when in the
|
||||||
// browser) is a `parse` function that takes a code string and
|
// browser) is a `parse` function that takes a code string and
|
||||||
// returns an abstract syntax tree as specified by [Mozilla parser
|
// returns an abstract syntax tree as specified by [Mozilla parser
|
||||||
// API][api], with the caveat that the SpiderMonkey-specific syntax
|
// API][api], with the caveat that inline XML is not recognized.
|
||||||
// (`let`, `yield`, inline XML, etc) is not recognized.
|
|
||||||
//
|
//
|
||||||
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
|
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
|
||||||
|
|
||||||
@ -53,7 +52,7 @@
|
|||||||
// `ecmaVersion` indicates the ECMAScript version to parse. Must
|
// `ecmaVersion` indicates the ECMAScript version to parse. Must
|
||||||
// be either 3, or 5, or 6. This influences support for strict
|
// be either 3, or 5, or 6. This influences support for strict
|
||||||
// mode, the set of reserved words, support for getters and
|
// mode, the set of reserved words, support for getters and
|
||||||
// setters and other features. ES6 support is only partial.
|
// setters and other features.
|
||||||
ecmaVersion: 5,
|
ecmaVersion: 5,
|
||||||
// Turn on `strictSemicolons` to prevent the parser from doing
|
// Turn on `strictSemicolons` to prevent the parser from doing
|
||||||
// automatic semicolon insertion.
|
// automatic semicolon insertion.
|
||||||
@ -1784,19 +1783,28 @@
|
|||||||
return finishNode(node, "Literal");
|
return finishNode(node, "Literal");
|
||||||
|
|
||||||
case _parenL:
|
case _parenL:
|
||||||
var node = startNode(), tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val;
|
var node = startNode(), tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val, exprList;
|
||||||
next();
|
next();
|
||||||
var oldParenL = ++metParenL;
|
var oldParenL = ++metParenL;
|
||||||
if (tokType !== _parenR) {
|
if (tokType !== _parenR) {
|
||||||
val = parseExpression();
|
val = parseExpression();
|
||||||
|
exprList = val.type === "SequenceExpression" ? val.expressions : [val];
|
||||||
|
} else {
|
||||||
|
exprList = [];
|
||||||
}
|
}
|
||||||
expect(_parenR);
|
expect(_parenR);
|
||||||
// if '=>' follows '(...)', convert contents to arguments
|
// if '=>' follows '(...)', convert contents to arguments
|
||||||
if (metParenL === oldParenL && eat(_arrow)) {
|
if (metParenL === oldParenL && eat(_arrow)) {
|
||||||
val = parseArrowExpression(node, !val ? [] : val.type === "SequenceExpression" ? val.expressions : [val]);
|
val = parseArrowExpression(node, exprList);
|
||||||
} else {
|
} else {
|
||||||
// forbid '()' before everything but '=>'
|
// forbid '()' before everything but '=>'
|
||||||
if (!val) unexpected(lastStart);
|
if (!val) unexpected(lastStart);
|
||||||
|
// forbid '...' in sequence expressions
|
||||||
|
if (options.ecmaVersion >= 6) {
|
||||||
|
for (var i = 0; i < exprList.length; i++) {
|
||||||
|
if (exprList[i].type === "SpreadElement") unexpected();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val.start = tokStart1;
|
val.start = tokStart1;
|
||||||
val.end = lastEnd;
|
val.end = lastEnd;
|
||||||
@ -2065,7 +2073,7 @@
|
|||||||
params[i] = param.left;
|
params[i] = param.left;
|
||||||
defaults.push(param.right);
|
defaults.push(param.right);
|
||||||
} else {
|
} else {
|
||||||
toAssignable(param, i === lastI);
|
toAssignable(param, i === lastI, true);
|
||||||
defaults.push(null);
|
defaults.push(null);
|
||||||
if (param.type === "SpreadElement") {
|
if (param.type === "SpreadElement") {
|
||||||
params.length--;
|
params.length--;
|
||||||
@ -2092,12 +2100,12 @@
|
|||||||
if (eat(_parenR)) {
|
if (eat(_parenR)) {
|
||||||
break;
|
break;
|
||||||
} else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
|
} else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
|
||||||
node.rest = toAssignable(parseExprAtom());
|
node.rest = toAssignable(parseExprAtom(), false, true);
|
||||||
checkSpreadAssign(node.rest);
|
checkSpreadAssign(node.rest);
|
||||||
expect(_parenR);
|
expect(_parenR);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent());
|
node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom(), false, true) : parseIdent());
|
||||||
if (options.ecmaVersion >= 6 && tokVal === '=') {
|
if (options.ecmaVersion >= 6 && tokVal === '=') {
|
||||||
next();
|
next();
|
||||||
hasDefaults = true;
|
hasDefaults = true;
|
||||||
@ -2249,7 +2257,7 @@
|
|||||||
// Convert existing expression atom to assignable pattern
|
// Convert existing expression atom to assignable pattern
|
||||||
// if possible.
|
// if possible.
|
||||||
|
|
||||||
function toAssignable(node, allowSpread) {
|
function toAssignable(node, allowSpread, checkType) {
|
||||||
if (options.ecmaVersion >= 6 && node) {
|
if (options.ecmaVersion >= 6 && node) {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case "Identifier":
|
case "Identifier":
|
||||||
@ -2261,26 +2269,28 @@
|
|||||||
for (var i = 0; i < node.properties.length; i++) {
|
for (var i = 0; i < node.properties.length; i++) {
|
||||||
var prop = node.properties[i];
|
var prop = node.properties[i];
|
||||||
if (prop.kind !== "init") unexpected(prop.key.start);
|
if (prop.kind !== "init") unexpected(prop.key.start);
|
||||||
toAssignable(prop.value);
|
toAssignable(prop.value, false, checkType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ArrayExpression":
|
case "ArrayExpression":
|
||||||
node.type = "ArrayPattern";
|
node.type = "ArrayPattern";
|
||||||
for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) {
|
for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) {
|
||||||
toAssignable(node.elements[i], i === lastI);
|
toAssignable(node.elements[i], i === lastI, checkType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "SpreadElement":
|
case "SpreadElement":
|
||||||
if (allowSpread) {
|
if (allowSpread) {
|
||||||
toAssignable(node.argument);
|
toAssignable(node.argument, false, checkType);
|
||||||
checkSpreadAssign(node.argument);
|
checkSpreadAssign(node.argument);
|
||||||
break;
|
} else {
|
||||||
|
unexpected(node.start);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unexpected(node.start);
|
if (checkType) unexpected(node.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||||
Copyright (C) 2011 Yusuke Suzuki <utatane.tea@gmail.com>
|
Copyright (C) 2011 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||||
Copyright (C) 2011 Arpad Borsos <arpad.borsos@googlemail.com>
|
Copyright (C) 2011 Arpad Borsos <arpad.borsos@googlemail.com>
|
||||||
|
Copyright (C) 2014 Ingvar Stepanyan <me@rreverser.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@ -14465,9 +14466,9 @@ testFail("\"\\u{FFZ}\"", "Bad character escape sequence (1:0)", {ecmaVersion: 6}
|
|||||||
|
|
||||||
testFail("[v] += ary", "Assigning to rvalue (1:0)", {ecmaVersion: 6});
|
testFail("[v] += ary", "Assigning to rvalue (1:0)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("[2] = 42", "Unexpected token (1:1)", {ecmaVersion: 6});
|
testFail("[2] = 42", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("({ obj:20 }) = 42", "Unexpected token (1:7)", {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", "Unexpected token (1:8)", {ecmaVersion: 6});
|
||||||
|
|
||||||
@ -14860,7 +14861,7 @@ test("[...a, ] = b", {
|
|||||||
locations: true
|
locations: true
|
||||||
});
|
});
|
||||||
|
|
||||||
testFail("if (b,...a, );", "Unexpected token (1:11)", {ecmaVersion: 6});
|
testFail("if (b,...a, );", "Unexpected token (1:12)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("(b, ...a)", "Unexpected token (1:9)", {ecmaVersion: 6});
|
testFail("(b, ...a)", "Unexpected token (1:9)", {ecmaVersion: 6});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user