Revision: 8041
Author: [email protected]
Date: Tue May 24 07:02:59 2011
Log: 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
http://code.google.com/p/v8/source/detail?r=8041
Added:
/branches/bleeding_edge/test/preparser/strict-const.js
/branches/bleeding_edge/test/preparser/strict-function-statement.pyt
Modified:
/branches/bleeding_edge/preparser/preparser-process.cc
/branches/bleeding_edge/src/preparser.cc
/branches/bleeding_edge/src/preparser.h
/branches/bleeding_edge/test/preparser/strict-identifiers.pyt
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/preparser/strict-const.js Tue May 24
07:02:59 2011
@@ -0,0 +1,29 @@
+// 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;
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/preparser/strict-function-statement.pyt
Tue May 24 07:02:59 2011
@@ -0,0 +1,99 @@
+# 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() { }
+""")
+
+
+
=======================================
--- /branches/bleeding_edge/preparser/preparser-process.cc Mon May 23
03:53:39 2011
+++ /branches/bleeding_edge/preparser/preparser-process.cc Tue May 24
07:02:59 2011
@@ -242,8 +242,8 @@
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) {
=======================================
--- /branches/bleeding_edge/src/preparser.cc Mon May 23 03:35:30 2011
+++ /branches/bleeding_edge/src/preparser.cc Tue May 24 07:02:59 2011
@@ -242,7 +242,7 @@
ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
*ok = false;
}
- return Statement::Default();
+ return Statement::FunctionDeclaration();
}
@@ -278,7 +278,15 @@
//
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 @@
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 @@
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();
}
=======================================
--- /branches/bleeding_edge/src/preparser.h Thu May 19 02:22:32 2011
+++ /branches/bleeding_edge/src/preparser.h Tue May 24 07:02:59 2011
@@ -239,6 +239,10 @@
static Statement Default() {
return Statement(kUnknownStatement);
}
+
+ static Statement FunctionDeclaration() {
+ return Statement(kFunctionDeclaration);
+ }
// Creates expression statement from expression.
// Preserves being an unparenthesized string literal, possibly
@@ -262,12 +266,17 @@
bool IsUseStrictLiteral() {
return code_ == kUseStrictExpressionStatement;
}
+
+ bool IsFunctionDeclaration() {
+ return code_ == kFunctionDeclaration;
+ }
private:
enum Type {
kUnknownStatement,
kStringLiteralExpressionStatement,
- kUseStrictExpressionStatement
+ kUseStrictExpressionStatement,
+ kFunctionDeclaration
};
explicit Statement(Type code) : code_(code) {}
=======================================
--- /branches/bleeding_edge/test/preparser/strict-identifiers.pyt Mon May
23 03:35:30 2011
+++ /branches/bleeding_edge/test/preparser/strict-identifiers.pyt Tue May
24 07:02:59 2011
@@ -134,6 +134,10 @@
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 @@
$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 @@
$id -= 10;
try {} catch ($id) { }
function $id($id) { }
+ x = {$id: 42};
+ x = {get $id() {}, set $id(value) {}};
""")
# ----------------------------------------------------------------------
@@ -165,6 +173,7 @@
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 @@
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():
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev