blob: 218547a192f2dd02553a28504ba4ada4100527a1 [file] [log] [blame]
// 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
// 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';});");