Checking argument names clash in strict mode for arrow functions.
Some more testFail message fixes.
This commit is contained in:
parent
47c4196d41
commit
2db14fbb08
79
acorn.js
79
acorn.js
@ -1810,7 +1810,6 @@
|
|||||||
node.defaults = [];
|
node.defaults = [];
|
||||||
node.rest = null;
|
node.rest = null;
|
||||||
node.generator = false;
|
node.generator = false;
|
||||||
node.expression = false;
|
|
||||||
}
|
}
|
||||||
expect(_parenL);
|
expect(_parenL);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -1828,36 +1827,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
parseFunctionBody(node);
|
||||||
// Start a new scope with regard to labels and the `inFunction`
|
|
||||||
// flag (restore them to their old value afterwards).
|
|
||||||
var oldInFunc = inFunction, oldLabels = labels;
|
|
||||||
inFunction = true; labels = [];
|
|
||||||
node.body = parseBlock(true);
|
|
||||||
inFunction = oldInFunc; labels = oldLabels;
|
|
||||||
|
|
||||||
// If this is a strict mode function, verify that argument names
|
|
||||||
// are not repeated, and it does not try to bind the words `eval`
|
|
||||||
// or `arguments`.
|
|
||||||
if (strict || node.body.body.length && isUseStrict(node.body.body[0])) {
|
|
||||||
// Negative indices are used to reuse loop body for node.rest and node.id
|
|
||||||
for (var i = -2, id; i < node.params.length; ++i) {
|
|
||||||
if (i >= 0) {
|
|
||||||
id = node.params[i];
|
|
||||||
} else if (i == -2) {
|
|
||||||
if (node.rest) id = node.rest;
|
|
||||||
else continue;
|
|
||||||
} else {
|
|
||||||
if (node.id) id = node.id;
|
|
||||||
else continue;
|
|
||||||
}
|
|
||||||
if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name))
|
|
||||||
raise(id.start, "Defining '" + id.name + "' in strict mode");
|
|
||||||
if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name)
|
|
||||||
raise(id.start, "Argument name clash in strict mode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
|
return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1885,19 +1855,56 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isExpression = tokType !== _braceL;
|
|
||||||
var body = isExpression ? parseExpression(true) : parseBlock(true);
|
|
||||||
|
|
||||||
node.id = null;
|
node.id = null;
|
||||||
node.params = params;
|
node.params = params;
|
||||||
node.defaults = hasDefaults ? defaults : [];
|
node.defaults = hasDefaults ? defaults : [];
|
||||||
node.rest = null;
|
node.rest = null;
|
||||||
node.body = body;
|
|
||||||
node.generator = false;
|
node.generator = false;
|
||||||
node.expression = isExpression;
|
parseFunctionBody(node, true);
|
||||||
return finishNode(node, "ArrowFunctionExpression");
|
return finishNode(node, "ArrowFunctionExpression");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse function body and check parameters.
|
||||||
|
|
||||||
|
function parseFunctionBody(node, allowExpression) {
|
||||||
|
var isExpression = allowExpression && tokType !== _braceL;
|
||||||
|
|
||||||
|
if (isExpression) {
|
||||||
|
node.body = parseExpression(true);
|
||||||
|
node.expression = true;
|
||||||
|
} else {
|
||||||
|
// Start a new scope with regard to labels and the `inFunction`
|
||||||
|
// flag (restore them to their old value afterwards).
|
||||||
|
var oldInFunc = inFunction, oldLabels = labels;
|
||||||
|
inFunction = true; labels = [];
|
||||||
|
node.body = parseBlock(true);
|
||||||
|
node.expression = false;
|
||||||
|
inFunction = oldInFunc; labels = oldLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a strict mode function, verify that argument names
|
||||||
|
// are not repeated, and it does not try to bind the words `eval`
|
||||||
|
// or `arguments`.
|
||||||
|
if (strict || !isExpression && node.body.body.length && isUseStrict(node.body.body[0])) {
|
||||||
|
// Negative indices are used to reuse loop body for node.rest and node.id
|
||||||
|
for (var i = -2, id; i < node.params.length; ++i) {
|
||||||
|
if (i >= 0) {
|
||||||
|
id = node.params[i];
|
||||||
|
} else if (i == -2) {
|
||||||
|
if (node.rest) id = node.rest;
|
||||||
|
else continue;
|
||||||
|
} else {
|
||||||
|
if (node.id) id = node.id;
|
||||||
|
else continue;
|
||||||
|
}
|
||||||
|
if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name))
|
||||||
|
raise(id.start, "Defining '" + id.name + "' in strict mode");
|
||||||
|
if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name)
|
||||||
|
raise(id.start, "Argument name clash in strict mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parses a comma-separated list of expressions, and returns them as
|
// Parses a comma-separated list of expressions, and returns them as
|
||||||
// an array. `close` is the token type that ends the list, and
|
// an array. `close` is the token type that ends the list, and
|
||||||
// `allowEmpty` can be turned on to allow subsequent commas with
|
// `allowEmpty` can be turned on to allow subsequent commas with
|
||||||
|
|||||||
@ -15817,33 +15817,33 @@ testFail("((a)) => 42", "Unexpected token (1:7)", {ecmaVersion: 6});
|
|||||||
|
|
||||||
testFail("(a, (b)) => 42", "Unexpected token (1:10)", {ecmaVersion: 6});
|
testFail("(a, (b)) => 42", "Unexpected token (1:10)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (eval = 10) => 42", "Unexpected token (1:16)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (eval = 10) => 42", "Assigning to eval in strict mode (1:15)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; eval => 42", "Unexpected token (1:25)", {ecmaVersion: 6});
|
testFail("\"use strict\"; eval => 42", "Defining 'eval' in strict mode (1:14)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; arguments => 42", "Unexpected token (1:30)", {ecmaVersion: 6});
|
testFail("\"use strict\"; arguments => 42", "Defining 'arguments' in strict mode (1:14)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (eval, a) => 42", "Unexpected token (1:30)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (eval, a) => 42", "Defining 'eval' in strict mode (1:15)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (arguments, a) => 42", "Unexpected token (1:35)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (arguments, a) => 42", "Defining 'arguments' in strict mode (1:15)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (eval, a = 10) => 42", "Unexpected token (1:35)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (eval, a = 10) => 42", "Defining 'eval' in strict mode (1:15)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("(a, a) => 42", "Unexpected token (1:7)", {ecmaVersion: 6});
|
testFail("(a, a) => 42", "Unexpected token (1:7)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (a, a) => 42", "Unexpected token (1:21)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (a, a) => 42", "Argument name clash in strict mode (1:18)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (a) => 00", "Unexpected token (1:22)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (a) => 00", "Invalid number (1:21)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("() <= 42", "Unexpected token (1:4)", {ecmaVersion: 6});
|
testFail("() <= 42", "Unexpected token (1:4)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("(10) => 00", "Unexpected token (1:6)", {ecmaVersion: 6});
|
testFail("(10) => 00", "Unexpected token (1:1)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("(10, 20) => 00", "Unexpected token (1:10)", {ecmaVersion: 6});
|
testFail("(10, 20) => 00", "Unexpected token (1:1)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("yield v", "Unexpected token (1:7)", {ecmaVersion: 6});
|
testFail("yield v", "Unexpected token (1:6)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("yield 10", "Unexpected token (1:7)", {ecmaVersion: 6});
|
testFail("yield 10", "Unexpected token (1:6)", {ecmaVersion: 6});
|
||||||
|
|
||||||
test("yield* 10", {
|
test("yield* 10", {
|
||||||
type: "Program",
|
type: "Program",
|
||||||
@ -16126,8 +16126,8 @@ testFail("module \"Universe\" { ; ; ", "Unexpected token (1:27)", {ecmaVersion
|
|||||||
|
|
||||||
testFail("switch (cond) { case 10: let a = 20; ", "Unexpected token (1:37)", {ecmaVersion: 6});
|
testFail("switch (cond) { case 10: let a = 20; ", "Unexpected token (1:37)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; (eval) => 42", "Unexpected token (1:27)", {ecmaVersion: 6});
|
testFail("\"use strict\"; (eval) => 42", "Defining 'eval' in strict mode (1:15)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("(eval) => { \"use strict\"; 42 }", "Unexpected token (1:31)", {ecmaVersion: 6});
|
testFail("(eval) => { \"use strict\"; 42 }", "Defining 'eval' in strict mode (1:1)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("({ get test() { } }) => 42", "Unexpected token (1:21)", {ecmaVersion: 6});
|
testFail("({ get test() { } }) => 42", "Unexpected token (1:21)", {ecmaVersion: 6});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user