Checking argument names clash in strict mode for arrow functions.

Some more testFail message fixes.
This commit is contained in:
Ingvar Stepanyan 2014-07-24 02:51:37 +03:00 committed by Marijn Haverbeke
parent 47c4196d41
commit 2db14fbb08
2 changed files with 57 additions and 50 deletions

View File

@ -1810,7 +1810,6 @@
node.defaults = [];
node.rest = null;
node.generator = false;
node.expression = false;
}
expect(_parenL);
for (;;) {
@ -1828,36 +1827,7 @@
}
}
}
// 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");
}
}
parseFunctionBody(node);
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.params = params;
node.defaults = hasDefaults ? defaults : [];
node.rest = null;
node.body = body;
node.generator = false;
node.expression = isExpression;
parseFunctionBody(node, true);
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
// an array. `close` is the token type that ends the list, and
// `allowEmpty` can be turned on to allow subsequent commas with

View File

@ -15817,33 +15817,33 @@ testFail("((a)) => 42", "Unexpected token (1:7)", {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("\"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("(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", {
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("\"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});