bug 569464, r=brendan: bad let-expression-statements in strict mode

This commit is contained in:
Dave Herman 2010-09-14 19:53:35 -07:00
Родитель ac9c40ba05
Коммит cdf10ce268
4 изменённых файлов: 53 добавлений и 0 удалений

Просмотреть файл

@ -337,3 +337,4 @@ MSG_DEF(JSMSG_BAD_PARSE_NODE, 254, 0, JSEXN_INTERNALERR, "bad parse node
MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 255, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}")
MSG_DEF(JSMSG_CALLER_IS_STRICT, 256, 0, JSEXN_TYPEERR, "access to strict mode caller function is censored")
MSG_DEF(JSMSG_NEED_DEBUG_MODE, 257, 0, JSEXN_ERR, "function can be called only in debug mode")
MSG_DEF(JSMSG_STRICT_CODE_LET_EXPR_STMT, 258, 0, JSEXN_ERR, "strict mode code may not contain unparenthesized let expression statements")

Просмотреть файл

@ -1808,6 +1808,8 @@ MatchOrInsertSemicolon(JSContext *cx, TokenStream *ts)
if (tt == TOK_ERROR)
return JS_FALSE;
if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
/* Advance the scanner for proper error location reporting. */
ts->getToken(TSF_OPERAND);
ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, JSMSG_SEMI_BEFORE_STMNT);
return JS_FALSE;
}
@ -4567,6 +4569,19 @@ Parser::letBlock(JSBool statement)
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_LET);
if (statement && !tokenStream.matchToken(TOK_LC, TSF_OPERAND)) {
/*
* Strict mode eliminates a grammar ambiguity with unparenthesized
* LetExpressions in an ExpressionStatement. If followed immediately
* by an arguments list, it's ambiguous whether the let expression
* is the callee or the call is inside the let expression body.
*
* See bug 569464.
*/
if (!ReportStrictModeError(context, &tokenStream, tc, pnlet,
JSMSG_STRICT_CODE_LET_EXPR_STMT)) {
return NULL;
}
/*
* If this is really an expression in let statement guise, then we
* need to wrap the TOK_LET node in a TOK_SEMI node so that we pop

Просмотреть файл

@ -34,4 +34,5 @@ script regress-592556-c35.js
script regress-593256.js
script regress-595365-1.js
fails-if(!xulRuntime.shell) script regress-595365-2.js
script regress-569464.js
script regress-596103.js

Просмотреть файл

@ -0,0 +1,36 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributor: Dave Herman
*/
function earlyError(src) {
var threw;
try {
eval(src);
threw = false;
} catch (expected) {
threw = true;
}
assertEq(threw, true);
}
earlyError("'use strict'; let (x) 42;");
earlyError("function f() { 'use strict'; let (x) 42;");
earlyError("'use strict'; function id(x) { return x } let (a=1) a ? f : x++(42);");
earlyError("function id(x) { return x } function f() { 'use strict'; let (a=1) a ? f : x++(42); }");
earlyError("'use strict'; let (x=2, y=3) x=3, y=13");
earlyError("function f() { 'use strict'; let (x=2, y=3) x=3, y=13 }");
x = "global";
(let (x=2, y=3) x=3, y=13);
assertEq(x, "global");
assertEq(y, 13);
// https://bugzilla.mozilla.org/show_bug.cgi?id=569464#c12
g = (let (x=7) x*x for each (x in [1,2,3]));
for (let y in g) {
assertEq(y, 49);
}
reportCompare(0, 0, "In strict mode, let expression statements are disallowed.");