// 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';});");