Commit e26093f3 authored by keuchel@chromium.org's avatar keuchel@chromium.org

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
parent f35e53ff
......@@ -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();
......
// 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;");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment