v8/test/mjsunit/strong/undefined.js
conradw 3d5717a71b [strong] Implement static restrictions on binding 'undefined' in arrow functions
Implements the strong mode proposal's static restrictions on the use of the
identifier 'undefined', for arrow functions. Assumes these restrictions are
intended to be identical to the restrictions on the use of 'eval and 'arguments'
in strict mode. In addition, Location variables inconsistantly named (e.g.
dupe_error_loc vs dupe_loc) are now consistently named the shorter way.

Baseline: https://codereview.chromium.org/1070633002

BUG=v8:3956
LOG=N

Review URL: https://codereview.chromium.org/1060883004

Cr-Commit-Position: refs/heads/master@{#27756}
2015-04-10 18:27:05 +00:00

201 lines
7.1 KiB
JavaScript

// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --strong-mode --harmony-sloppy --harmony-arrow-functions
// Repurposing the strict mode 'eval' and 'arguments' tests to test for correct
// behaviour of 'undefined' as an identifier in strong mode.
"use strict";
function CheckStrongMode(code) {
let strictContexts = [
["'use strict';", ""],
["function outer() { 'use strict';", "}"],
["function outer() { 'use strict'; function inner() {", "}}"],
["class C { m() {", "} }"]
]
let strongContexts = [
["'use strong';", ""],
["function outer() { 'use strong';", "}"],
["function outer() { 'use strong'; function inner() {", "}}"],
["class C { m() { 'use strong';", "} }"]
]
for (let context of strictContexts) {
assertThrows(context[0] + code + context[1] + "; throw new TypeError();",
TypeError);
}
for (let context of strongContexts) {
assertThrows(context[0] + code + context[1], SyntaxError);
}
}
// Binding 'undefined'
CheckStrongMode("var undefined;");
CheckStrongMode("let undefined;");
CheckStrongMode("var undefined = 0;");
CheckStrongMode("let undefined = 0;");
CheckStrongMode("const undefined = 0;");
CheckStrongMode("var x, y = 0, undefined;");
CheckStrongMode("let x, y = 0, undefined;");
// Function identifier is 'undefined'
// Function declaration
CheckStrongMode("function undefined() {}");
assertThrows("function undefined() {'use strong';}", SyntaxError);
// Generator function
CheckStrongMode("function* undefined() {}");
assertThrows("function* undefined() {'use strong';}", SyntaxError);
// Function expression
CheckStrongMode("(function undefined() {});");
assertThrows("(function undefined() {'use strong';});", SyntaxError);
CheckStrongMode("{foo: (function undefined(){})};");
assertThrows("{foo: (function undefined(){'use strong';})};", SyntaxError);
//Generator function expression
CheckStrongMode("(function* undefined() {})");
assertThrows("(function* undefined() {'use strong';})", SyntaxError);
CheckStrongMode("{foo: (function* undefined(){})};");
assertThrows("{foo: (function* undefined(){'use strong';})};", SyntaxError);
// Function parameter named 'undefined'
// Function declaration
CheckStrongMode("function foo(a, b, undefined, c, d) {}");
assertThrows("function foo(a, b, undefined, c, d) {'use strong';}",
SyntaxError);
// Generator function declaration
CheckStrongMode("function* foo(a, b, undefined, c, d) {}");
assertThrows("function* foo(a, b, undefined, c, d) {'use strong';}",
SyntaxError);
// Function expression
CheckStrongMode("(function foo(a, b, undefined, c, d) {});");
assertThrows("(function foo(a, b, undefined, c, d) {'use strong';})",
SyntaxError);
CheckStrongMode("{foo: (function foo(a, b, undefined, c, d) {})};");
assertThrows("{foo: (function foo(a, b, undefined, c, d) {'use strong';})};",
SyntaxError);
// Generator function expression
CheckStrongMode("(function* foo(a, b, undefined, c, d) {});");
assertThrows("(function* foo(a, b, undefined, c, d) {'use strong';})",
SyntaxError);
CheckStrongMode("{foo: (function* foo(a, b, undefined, c, d) {})};");
assertThrows("{foo: (function* foo(a, b, undefined, c, d) {'use strong';})};",
SyntaxError);
// Method parameter named 'undefined'
// Class method
CheckStrongMode("class C { foo(a, b, undefined, c, d) {} }");
assertThrows("class C { foo(a, b, undefined, c, d) {'use strong';} }",
SyntaxError);
//Class generator method
CheckStrongMode("class C { *foo(a, b, undefined, c, d) {} }");
assertThrows("class C { *foo(a, b, undefined, c, d) {'use strong';} }",
SyntaxError);
//Object literal method
CheckStrongMode("({ foo(a, b, undefined, c, d) {} });");
assertThrows("({ foo(a, b, undefined, c, d) {'use strong';} });", SyntaxError);
//Object literal generator method
CheckStrongMode("({ *foo(a, b, undefined, c, d) {} });");
assertThrows("({ *foo(a, b, undefined, c, d) {'use strong';} });", SyntaxError);
// Class declaration named 'undefined'
CheckStrongMode("class undefined {}");
assertThrows("class undefined {'use strong'}", SyntaxError);
// Class expression named 'undefined'
CheckStrongMode("(class undefined {});");
assertThrows("(class undefined {'use strong'});", SyntaxError);
// Binding/assigning to 'undefined' in for
CheckStrongMode("for(undefined = 0;false;);");
CheckStrongMode("for(var undefined = 0;false;);");
CheckStrongMode("for(let undefined = 0;false;);");
CheckStrongMode("for(const undefined = 0;false;);");
// Binding/assigning to 'undefined' in for-in
CheckStrongMode("for(undefined in {});");
CheckStrongMode("for(var undefined in {});");
CheckStrongMode("for(let undefined in {});");
CheckStrongMode("for(const undefined in {});");
// Binding/assigning to 'undefined' in for-of
CheckStrongMode("for(undefined of []);");
CheckStrongMode("for(var undefined of []);");
CheckStrongMode("for(let undefined of []);");
CheckStrongMode("for(const undefined of []);");
// Property accessor parameter named 'undefined'.
CheckStrongMode("let o = { set foo(undefined) {} }");
assertThrows("let o = { set foo(undefined) {'use strong';} }", SyntaxError);
// catch(undefined)
CheckStrongMode("try {} catch(undefined) {};");
// Assignment to undefined
CheckStrongMode("undefined = 0;");
CheckStrongMode("print(undefined = 0);");
CheckStrongMode("let x = undefined = 0;");
// Compound assignment to undefined
CheckStrongMode("undefined *= 0;");
CheckStrongMode("undefined /= 0;");
CheckStrongMode("print(undefined %= 0);");
CheckStrongMode("let x = undefined += 0;");
CheckStrongMode("let x = undefined -= 0;");
CheckStrongMode("undefined <<= 0;");
CheckStrongMode("undefined >>= 0;");
CheckStrongMode("print(undefined >>>= 0);");
CheckStrongMode("print(undefined &= 0);");
CheckStrongMode("let x = undefined ^= 0;");
CheckStrongMode("let x = undefined |= 0;");
// Postfix increment with undefined
CheckStrongMode("undefined++;");
CheckStrongMode("print(undefined++);");
CheckStrongMode("let x = undefined++;");
// Postfix decrement with undefined
CheckStrongMode("undefined--;");
CheckStrongMode("print(undefined--);");
CheckStrongMode("let x = undefined--;");
// Prefix increment with undefined
CheckStrongMode("++undefined;");
CheckStrongMode("print(++undefined);");
CheckStrongMode("let x = ++undefined;");
// Prefix decrement with undefined
CheckStrongMode("--undefined;");
CheckStrongMode("print(--undefined);");
CheckStrongMode("let x = --undefined;");
// Function constructor: 'undefined' parameter name
assertDoesNotThrow(function() {
Function("undefined", "");
});
assertThrows(function() {
Function("undefined", "'use strong';");
}, SyntaxError);
// Arrow functions with undefined parameters
CheckStrongMode("(undefined => {return});");
assertThrows("(undefined => {'use strong';});");
CheckStrongMode("((undefined, b, c) => {return});");
assertThrows("((undefined, b, c) => {'use strong';});");
CheckStrongMode("((a, undefined, c) => {return});");
assertThrows("((a, undefined, c) => {'use strong';});");
CheckStrongMode("((a, b, undefined) => {return});");
assertThrows("((a, b, undefined) => {'use strong';});");