Make let/const outside of the extended mode early errors (under harmony flag).
The ES.next drafts require that source code that matches the productions for let and const bindings outside the extended mode trigger early syntax errors. This CL adapts the parser / preparser accordingly under the harmony scoping flag. Summary: * Harmony scoping flag not set: Old semantics allowing const in classic mode with function level scope. Const binding in strict mode and let bindings in classic and strict mode trigger early syntax errors. * Harmony scoping is set: Use new harmony const and let in extended mode and old const in classic mode. This is to preserve compatibility with current web pages that already use non-standard implementations of const. An early syntax error is thrown on const in strict mode and on let in classic and strict mode. This depends on: http://codereview.chromium.org/8562002/ TEST=mjsunit/harmony/block-early-errors.js Review URL: http://codereview.chromium.org/8564001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10079 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f35e53ff50
commit
e26093f3d8
@ -206,6 +206,7 @@ function FormatMessage(message) {
|
||||
"illegal_break", ["Illegal break statement"],
|
||||
"illegal_continue", ["Illegal continue statement"],
|
||||
"illegal_return", ["Illegal return statement"],
|
||||
"illegal_let", ["Illegal let declaration outside extended mode"],
|
||||
"error_loading_debugger", ["Error loading debugger"],
|
||||
"no_input_to_regexp", ["No input to ", "%0"],
|
||||
"invalid_json", ["String '", "%0", "' is not valid JSON"],
|
||||
|
@ -1267,6 +1267,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
||||
return ParseBlock(labels, ok);
|
||||
|
||||
case Token::CONST: // fall through
|
||||
case Token::LET:
|
||||
case Token::VAR:
|
||||
stmt = ParseVariableStatement(kStatement, ok);
|
||||
break;
|
||||
@ -1708,6 +1709,16 @@ Block* Parser::ParseVariableDeclarations(
|
||||
if (peek() == Token::VAR) {
|
||||
Consume(Token::VAR);
|
||||
} else if (peek() == Token::CONST) {
|
||||
// TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
|
||||
//
|
||||
// ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
|
||||
//
|
||||
// * It is a Syntax Error if the code that matches this production is not
|
||||
// contained in extended code.
|
||||
//
|
||||
// However disallowing const in classic mode will break compatibility with
|
||||
// existing pages. Therefore we keep allowing const with the old
|
||||
// non-harmony semantics in classic mode.
|
||||
Consume(Token::CONST);
|
||||
switch (top_scope_->language_mode()) {
|
||||
case CLASSIC_MODE:
|
||||
@ -1733,7 +1744,17 @@ Block* Parser::ParseVariableDeclarations(
|
||||
is_const = true;
|
||||
needs_init = true;
|
||||
} else if (peek() == Token::LET) {
|
||||
ASSERT(top_scope_->is_extended_mode());
|
||||
// ES6 Draft Rev4 section 12.2.1:
|
||||
//
|
||||
// LetDeclaration : let LetBindingList ;
|
||||
//
|
||||
// * It is a Syntax Error if the code that matches this production is not
|
||||
// contained in extended code.
|
||||
if (!is_extended_mode()) {
|
||||
ReportMessage("illegal_let", Vector<const char*>::empty());
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
Consume(Token::LET);
|
||||
if (var_context != kSourceElement &&
|
||||
var_context != kForStatement) {
|
||||
|
@ -227,6 +227,7 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
|
||||
return ParseBlock(ok);
|
||||
|
||||
case i::Token::CONST:
|
||||
case i::Token::LET:
|
||||
case i::Token::VAR:
|
||||
return ParseVariableStatement(kStatement, ok);
|
||||
|
||||
@ -377,6 +378,17 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
if (peek() == i::Token::VAR) {
|
||||
Consume(i::Token::VAR);
|
||||
} else if (peek() == i::Token::CONST) {
|
||||
// TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
|
||||
//
|
||||
// ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
|
||||
//
|
||||
// * It is a Syntax Error if the code that matches this production is not
|
||||
// contained in extended code.
|
||||
//
|
||||
// However disallowing const in classic mode will break compatibility with
|
||||
// existing pages. Therefore we keep allowing const with the old
|
||||
// non-harmony semantics in classic mode.
|
||||
Consume(i::Token::CONST);
|
||||
switch (language_mode()) {
|
||||
case i::CLASSIC_MODE:
|
||||
break;
|
||||
@ -398,9 +410,21 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
require_initializer = true;
|
||||
break;
|
||||
}
|
||||
Consume(i::Token::CONST);
|
||||
} else if (peek() == i::Token::LET) {
|
||||
ASSERT(is_extended_mode());
|
||||
// ES6 Draft Rev4 section 12.2.1:
|
||||
//
|
||||
// LetDeclaration : let LetBindingList ;
|
||||
//
|
||||
// * It is a Syntax Error if the code that matches this production is not
|
||||
// contained in extended code.
|
||||
if (!is_extended_mode()) {
|
||||
i::Scanner::Location location = scanner_->peek_location();
|
||||
ReportMessageAt(location.beg_pos, location.end_pos,
|
||||
"illegal_let", NULL);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
Consume(i::Token::LET);
|
||||
if (var_context != kSourceElement &&
|
||||
var_context != kForStatement) {
|
||||
i::Scanner::Location location = scanner_->peek_location();
|
||||
@ -409,7 +433,6 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
}
|
||||
Consume(i::Token::LET);
|
||||
} else {
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
|
55
test/mjsunit/harmony/block-early-errors.js
Normal file
55
test/mjsunit/harmony/block-early-errors.js
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --harmony-scoping
|
||||
|
||||
function CheckException(e) {
|
||||
var string = e.toString();
|
||||
assertInstanceof(e, SyntaxError);
|
||||
assertTrue(string.indexOf("Illegal let") >= 0);
|
||||
}
|
||||
|
||||
function Check(str) {
|
||||
try {
|
||||
eval("(function () { " + str + " })");
|
||||
assertUnreachable();
|
||||
} catch (e) {
|
||||
CheckException(e);
|
||||
}
|
||||
try {
|
||||
eval("(function () { { " + str + " } })");
|
||||
assertUnreachable();
|
||||
} catch (e) {
|
||||
CheckException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for early syntax errors when using let
|
||||
// declarations outside of extended mode.
|
||||
Check("let x;");
|
||||
Check("let x = 1;");
|
||||
Check("let x, y;");
|
Loading…
Reference in New Issue
Block a user