зеркало из https://github.com/mozilla/pjs.git
Disallow for-in initializers that use let (bug 617288, r=brendan).
This commit is contained in:
Родитель
74c6a2a4ed
Коммит
465388a7f4
|
@ -347,3 +347,5 @@ MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured
|
|||
MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object")
|
||||
MSG_DEF(JSMSG_NON_NATIVE_SCOPE, 266, 0, JSEXN_TYPEERR, "non-native scope object")
|
||||
MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function")
|
||||
MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer")
|
||||
|
||||
|
|
|
@ -5133,10 +5133,9 @@ Parser::forStatement()
|
|||
pn1->pn_xflags |= PNX_FORINVAR;
|
||||
|
||||
/*
|
||||
* Rewrite 'for (<decl> x = i in o)' where <decl> is 'let',
|
||||
* 'var', or 'const' to hoist the initializer or the entire
|
||||
* decl out of the loop head. TOK_VAR is the type for both
|
||||
* 'var' and 'const'.
|
||||
* Rewrite 'for (<decl> x = i in o)' where <decl> is 'var' or
|
||||
* 'const' to hoist the initializer or the entire decl out of
|
||||
* the loop head. TOK_VAR is the type for both 'var' and 'const'.
|
||||
*/
|
||||
pn2 = pn1->pn_head;
|
||||
if ((pn2->pn_type == TOK_NAME && pn2->maybeExpr())
|
||||
|
@ -5144,76 +5143,52 @@ Parser::forStatement()
|
|||
|| pn2->pn_type == TOK_ASSIGN
|
||||
#endif
|
||||
) {
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
if (tt == TOK_LET) {
|
||||
reportErrorNumber(pn2, JSREPORT_ERROR, JSMSG_INVALID_FOR_IN_INIT);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* JS_HAS_BLOCK_SCOPE */
|
||||
|
||||
pnseq = ListNode::create(tc);
|
||||
if (!pnseq)
|
||||
return NULL;
|
||||
pnseq->pn_type = TOK_SEQ;
|
||||
pnseq->pn_pos.begin = pn->pn_pos.begin;
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
if (tt == TOK_LET) {
|
||||
/*
|
||||
* Hoist just the 'i' from 'for (let x = i in o)' to
|
||||
* before the loop, glued together via pnseq.
|
||||
*/
|
||||
JSParseNode *pn3 = UnaryNode::create(tc);
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
pn3->pn_type = TOK_SEMI;
|
||||
pn3->pn_op = JSOP_NOP;
|
||||
JSParseNode *pn4;
|
||||
dflag = PND_INITIALIZED;
|
||||
|
||||
/*
|
||||
* All of 'var x = i' is hoisted above 'for (x in o)',
|
||||
* so clear PNX_FORINVAR.
|
||||
*
|
||||
* Request JSOP_POP here since the var is for a simple
|
||||
* name (it is not a destructuring binding's left-hand
|
||||
* side) and it has an initializer.
|
||||
*/
|
||||
pn1->pn_xflags &= ~PNX_FORINVAR;
|
||||
pn1->pn_xflags |= PNX_POPVAR;
|
||||
pnseq->initList(pn1);
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
if (pn2->pn_type == TOK_ASSIGN) {
|
||||
pn4 = pn2->pn_right;
|
||||
pn2 = pn1->pn_head = pn2->pn_left;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
pn4 = pn2->pn_expr;
|
||||
pn2->pn_expr = NULL;
|
||||
}
|
||||
if (!RebindLets(pn4, tc))
|
||||
if (pn2->pn_type == TOK_ASSIGN) {
|
||||
pn1 = CloneParseTree(pn2->pn_left, tc);
|
||||
if (!pn1)
|
||||
return NULL;
|
||||
pn3->pn_pos = pn4->pn_pos;
|
||||
pn3->pn_kid = pn4;
|
||||
pnseq->initList(pn3);
|
||||
} else
|
||||
#endif /* JS_HAS_BLOCK_SCOPE */
|
||||
{
|
||||
dflag = PND_INITIALIZED;
|
||||
|
||||
/*
|
||||
* All of 'var x = i' is hoisted above 'for (x in o)',
|
||||
* so clear PNX_FORINVAR.
|
||||
*
|
||||
* Request JSOP_POP here since the var is for a simple
|
||||
* name (it is not a destructuring binding's left-hand
|
||||
* side) and it has an initializer.
|
||||
*/
|
||||
pn1->pn_xflags &= ~PNX_FORINVAR;
|
||||
pn1->pn_xflags |= PNX_POPVAR;
|
||||
pnseq->initList(pn1);
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
if (pn2->pn_type == TOK_ASSIGN) {
|
||||
pn1 = CloneParseTree(pn2->pn_left, tc);
|
||||
if (!pn1)
|
||||
return NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
JS_ASSERT(pn2->pn_type == TOK_NAME);
|
||||
pn1 = NameNode::create(pn2->pn_atom, tc);
|
||||
if (!pn1)
|
||||
return NULL;
|
||||
pn1->pn_type = TOK_NAME;
|
||||
pn1->pn_op = JSOP_NAME;
|
||||
pn1->pn_pos = pn2->pn_pos;
|
||||
if (pn2->pn_defn)
|
||||
LinkUseToDef(pn1, (JSDefinition *) pn2, tc);
|
||||
}
|
||||
pn2 = pn1;
|
||||
{
|
||||
JS_ASSERT(pn2->pn_type == TOK_NAME);
|
||||
pn1 = NameNode::create(pn2->pn_atom, tc);
|
||||
if (!pn1)
|
||||
return NULL;
|
||||
pn1->pn_type = TOK_NAME;
|
||||
pn1->pn_op = JSOP_NAME;
|
||||
pn1->pn_pos = pn2->pn_pos;
|
||||
if (pn2->pn_defn)
|
||||
LinkUseToDef(pn1, (JSDefinition *) pn2, tc);
|
||||
}
|
||||
pn2 = pn1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
url-prefix ../../jsreftest.html?test=js1_7/decompilation/
|
||||
skip script regress-346642-01.js # obsolete test
|
||||
script regress-348904.js
|
||||
script regress-349493.js
|
||||
script regress-349499.js
|
||||
skip script regress-349602.js # obsolete test
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is JavaScript Engine testing utilities.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Jesse Ruderman
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 348904;
|
||||
var summary = 'decompilation for "let" in lvalue part of for..in';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f = function () { for (let i = 3 in {}); }
|
||||
actual = f + '';
|
||||
expect = 'function () {\n for (let i in {}) {\n }\n}';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
var f = function () { for (let i = (y = 4) in {}); }
|
||||
actual = f + '';
|
||||
expect = 'function () {\n y = 4;\n for (let i in {}) {\n }\n}';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -160,11 +160,6 @@ function test()
|
|||
actual = f + '';
|
||||
compareSource(expect, actual, summary + ': 21');
|
||||
|
||||
f = (function() { for ( let [a,b]=[c,d] in [3]) { } })
|
||||
expect = 'function() { [c, d]; for ( let [a,b] in [3]) { } }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary + ': 22');
|
||||
|
||||
f = function () { while(1) [a] = [b]; }
|
||||
expect = 'function () { while(true) {[a] = [b];} } ';
|
||||
actual = f + '';
|
||||
|
|
|
@ -85,16 +85,6 @@ function test()
|
|||
|
||||
(function(q){return q;} for each (\u3056 in []))
|
||||
|
||||
// =====
|
||||
|
||||
try
|
||||
{
|
||||
for(let x = <{x}/> in <y/>) x2;
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
// =====
|
||||
|
||||
for(
|
||||
|
|
|
@ -54,15 +54,6 @@ function test()
|
|||
|
||||
// ------- Comment #98 From Gary Kwong [:nth10sd]
|
||||
|
||||
try
|
||||
{
|
||||
for(let [x] = (x) in []) {}
|
||||
// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
uneval(function(){(Number(0) for each (NaN in []) for each (x4 in this))});
|
||||
// Assertion failure: pos == 0, at ../jsopcode.cpp:2963
|
||||
|
||||
|
|
|
@ -74,10 +74,6 @@ function test()
|
|||
// =====
|
||||
function this ({x}) { function x(){} }
|
||||
|
||||
// Assertion failure: cg->stackDepth == stackDepth, at ../jsemit.cpp:3664
|
||||
// =====
|
||||
for(let x = [ "" for (y in /x/g ) if (x)] in (""));
|
||||
|
||||
// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818
|
||||
// =====
|
||||
(function(){const x = 0, y = delete x;})()
|
||||
|
|
|
@ -598,13 +598,9 @@ assertError("for each (const [x,y,z] in foo);", SyntaxError);
|
|||
// destructuring in for-in and for-each-in loop heads with initializers
|
||||
|
||||
assertStmt("for (var {a:x,b:y,c:z} = 22 in foo);", forInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (let {a:x,b:y,c:z} = 22 in foo);", forInStmt(letDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (var [x,y,z] = 22 in foo);", forInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (let [x,y,z] = 22 in foo);", forInStmt(letDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (var {a:x,b:y,c:z} = 22 in foo);", forEachInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (let {a:x,b:y,c:z} = 22 in foo);", forEachInStmt(letDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (var [x,y,z] = 22 in foo);", forEachInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (let [x,y,z] = 22 in foo);", forEachInStmt(letDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertError("for (x = 22 in foo);", SyntaxError);
|
||||
assertError("for ({a:x,b:y,c:z} = 22 in foo);", SyntaxError);
|
||||
assertError("for ([x,y,z] = 22 in foo);", SyntaxError);
|
||||
|
|
|
@ -964,7 +964,6 @@ js1_7/block/regress-352907.js
|
|||
js1_7/block/regress-376410.js
|
||||
js1_7/block/regress-396900.js
|
||||
js1_7/block/regress-411279.js
|
||||
js1_7/decompilation/regress-348904.js
|
||||
js1_7/decompilation/regress-349493.js
|
||||
js1_7/decompilation/regress-349499.js
|
||||
js1_7/decompilation/regress-349633.js
|
||||
|
|
Загрузка…
Ссылка в новой задаче