Commit b97da904 authored by lrn@chromium.org's avatar lrn@chromium.org

Add tests for function statements in strict mode.

Small fixes.
Added test for const declaration in strict mode.

TEST=preparser/strict-function-statement

Review URL: http://codereview.chromium.org/6990056

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8041 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6f775f2f
......@@ -242,8 +242,8 @@ void CheckException(v8::PreParserData* data,
if (expects->type != NULL) {
const char* actual_message = reader.message();
if (strcmp(expects->type, actual_message)) {
fail(data, "Wrong error message. Expected <%s>, found <%s>\n",
expects->type, actual_message);
fail(data, "Wrong error message. Expected <%s>, found <%s> at %d..%d\n",
expects->type, actual_message, reader.beg_pos(), reader.end_pos());
}
}
if (expects->beg_pos >= 0) {
......
......@@ -242,7 +242,7 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
*ok = false;
}
return Statement::Default();
return Statement::FunctionDeclaration();
}
......@@ -278,7 +278,15 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
//
Expect(i::Token::LBRACE, CHECK_OK);
while (peek() != i::Token::RBRACE) {
ParseStatement(CHECK_OK);
i::Scanner::Location start_location = scanner_->peek_location();
Statement statement = ParseStatement(CHECK_OK);
i::Scanner::Location end_location = scanner_->location();
if (strict_mode() && statement.IsFunctionDeclaration()) {
ReportMessageAt(start_location.beg_pos, end_location.end_pos,
"strict_function", NULL);
*ok = false;
return Statement::Default();
}
}
Expect(i::Token::RBRACE, ok);
return Statement::Default();
......@@ -357,7 +365,14 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
if (peek() == i::Token::COLON && expr.IsRawIdentifier()) {
if (!strict_mode() || !expr.AsIdentifier().IsFutureReserved()) {
Consume(i::Token::COLON);
ParseStatement(ok);
i::Scanner::Location start_location = scanner_->peek_location();
Statement statement = ParseStatement(CHECK_OK);
if (strict_mode() && statement.IsFunctionDeclaration()) {
i::Scanner::Location end_location = scanner_->location();
ReportMessageAt(start_location.beg_pos, end_location.end_pos,
"strict_function", NULL);
*ok = false;
}
return Statement::Default();
}
}
......@@ -486,7 +501,15 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
Expect(i::Token::DEFAULT, CHECK_OK);
Expect(i::Token::COLON, CHECK_OK);
} else {
ParseStatement(CHECK_OK);
i::Scanner::Location start_location = scanner_->peek_location();
Statement statement = ParseStatement(CHECK_OK);
if (strict_mode() && statement.IsFunctionDeclaration()) {
i::Scanner::Location end_location = scanner_->location();
ReportMessageAt(start_location.beg_pos, end_location.end_pos,
"strict_function", NULL);
*ok = false;
return Statement::Default();
}
}
token = peek();
}
......
......@@ -240,6 +240,10 @@ class PreParser {
return Statement(kUnknownStatement);
}
static Statement FunctionDeclaration() {
return Statement(kFunctionDeclaration);
}
// Creates expression statement from expression.
// Preserves being an unparenthesized string literal, possibly
// "use strict".
......@@ -263,11 +267,16 @@ class PreParser {
return code_ == kUseStrictExpressionStatement;
}
bool IsFunctionDeclaration() {
return code_ == kFunctionDeclaration;
}
private:
enum Type {
kUnknownStatement,
kStringLiteralExpressionStatement,
kUseStrictExpressionStatement
kUseStrictExpressionStatement,
kFunctionDeclaration
};
explicit Statement(Type code) : code_(code) {}
......
// 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.
"use strict";
const x = 42;
\ No newline at end of file
# 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.
# In strict mode, function declarations may only appear as source elements.
# A template that performs the same strict-mode test in different
# scopes (global scope, function scope, and nested function scope).
def StrictTest(name, source):
Test(name, '"use strict";\n' + source, "strict_function")
Test(name + '-infunc',
'function foo() {\n "use strict";\n' + source +'\n}\n',
"strict_function")
Test(name + '-infunc2',
'function foo() {\n "use strict";\n function bar() {\n' +
source +'\n }\n}\n',
"strict_function")
# Not testing with-scope, since with is not allowed in strict mode at all.
StrictTest("block", """
{ function foo() { } }
""")
StrictTest("try-w-catch", """
try { function foo() { } } catch (e) { }
""")
StrictTest("try-w-finally", """
try { function foo() { } } finally { }
""")
StrictTest("catch", """
try { } catch (e) { function foo() { } }
""")
StrictTest("finally", """
try { } finally { function foo() { } }
""")
StrictTest("for", """
for (;;) { function foo() { } }
""")
StrictTest("while", """
while (true) { function foo() { } }
""")
StrictTest("do", """
do { function foo() { } } while (true);
""")
StrictTest("then", """
if (true) { function foo() { } }
""")
StrictTest("then-w-else", """
if (true) { function foo() { } } else { }
""")
StrictTest("else", """
if (true) { } else { function foo() { } }
""")
StrictTest("switch-case", """
switch (true) { case true: function foo() { } }
""")
StrictTest("labeled", """
label: function foo() { }
""")
......@@ -134,6 +134,10 @@ read_var = StrictTemplate("read-reserved-$id", """
var x = $id;
""")
setter_arg = StrictTemplate("setter-param-$id", """
var x = {set foo($id) { }};
""")
non_strict_use = Template("nonstrict-$id", """
var $id = 42;
$id++;
......@@ -144,6 +148,8 @@ non_strict_use = Template("nonstrict-$id", """
$id -= 10;
try {} catch ($id) { }
function $id($id) { }
var x = {$id: 42};
x = {get $id() {}, set $id(value) {}};
function foo() { "use strict;" }
var $id = 42;
$id++;
......@@ -154,6 +160,8 @@ non_strict_use = Template("nonstrict-$id", """
$id -= 10;
try {} catch ($id) { }
function $id($id) { }
x = {$id: 42};
x = {get $id() {}, set $id(value) {}};
""")
# ----------------------------------------------------------------------
......@@ -165,6 +173,7 @@ for id in ["eval", "arguments"]:
arg_name_nested({"id": id}, "strict_param_name")
func_name_own({"id": id}, "strict_function_name")
func_name_nested({"id": id}, "strict_function_name")
setter_arg({"id": id}, "strict_param_name")
for op in assign_ops.keys():
assign_var({"id": id, "op":op, "opname": assign_ops[op]},
"strict_lhs_assignment")
......@@ -184,6 +193,7 @@ for reserved_word in reserved_words + strict_reserved_words:
if (reserved_word == "const"): message = "unexpected_token"
arg_name_own({"id":reserved_word}, message)
arg_name_nested({"id":reserved_word}, message)
setter_arg({"id": reserved_word}, message)
func_name_own({"id":reserved_word}, message)
func_name_nested({"id":reserved_word}, message)
for op in assign_ops.keys():
......
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