// Warning should be shown for unreachable statement after return (bug 1151931). function testWarn(code, lineNumber, columnNumber) { enableLastWarning(); eval(code); var warning = getLastWarning(); assertEq(warning !== null, true, "warning should be caught for " + code); assertEq(warning.name, "Warning"); assertEq(warning.lineNumber, lineNumber); assertEq(warning.columnNumber, columnNumber); clearLastWarning(); Reflect.parse(code); warning = getLastWarning(); assertEq(warning !== null, true, "warning should be caught for " + code); assertEq(warning.name, "Warning"); // Warning generated by Reflect.parse has line/column number for Reflect.parse // itself, not parsed code. disableLastWarning(); } function testPass(code) { enableLastWarning(); eval(code); var warning = getLastWarning(); assertEq(warning, null, "warning should not be caught for " + code); clearLastWarning(); Reflect.parse(code); warning = getLastWarning(); assertEq(warning, null, "warning should not be caught for " + code); disableLastWarning(); } testPass(` function f() { return ( 1 + 2 ); } `); // unary expression testWarn(` function f() { var i = 0; return ++i; } `, 5, 4); testWarn(` function f() { var i = 0; return --i; } `, 5, 4); // array testWarn(` function f() { return [1, 2, 3]; } `, 4, 4); // block (object) testWarn(` function f() { return {x: 10}; } `, 4, 4); testWarn(` function f() { return { method() { f(); } }; } `, 4, 2); // expression in paren testWarn(` function f() { return (1 + 2); } `, 4, 4); // name testWarn(` function f() { return f; } `, 4, 4); // binary expression testWarn(` function f() { return 1 + 2; } `, 4, 4); testWarn(` function f() { return .1 + .2; } `, 4, 4); // string testWarn(` function f() { return "foo"; } `, 4, 4); testWarn(` function f() { return "use struct"; } `, 4, 4); testWarn(` function f() { return 'foo'; } `, 4, 4); // template string testWarn(` function f() { return \`foo\${1 + 2}\`; } `, 4, 4); testWarn(` function f() { return \`foo\`; } `, 4, 4); // RegExp testWarn(` function f() { return /foo/; } `, 4, 4); // boolean testWarn(` function f() { return true; } `, 4, 4); testWarn(` function f() { return false; } `, 4, 4); // null testWarn(` function f() { return null; } `, 4, 4); // this testWarn(` function f() { return this; } `, 4, 4); // new testWarn(` function f() { return new Array(); } `, 4, 4); // delete testWarn(` function f() { var a = {x: 10}; return delete a.x; } `, 5, 4); // yield testWarn(` function* f() { return yield 1; } `, 4, 4); // class testWarn(` function f() { return class A { constructor() {} }; } `, 4, 4); // unary expression testWarn(` function f() { return +1; } `, 4, 4); testWarn(` function f() { return -1; } `, 4, 4); testWarn(` function f() { return !1; } `, 4, 4); testWarn(` function f() { return ~1; } `, 4, 4); // eof testPass(` var f = new Function("return\\n"); `); // empty statement testPass(` function f() { return; ; // empty statement } `); // end of block testPass(` function f() { { return } } `); // function (hosted) testPass(` function f() { g(); return function g() {} } `); // if testWarn(` function f() { return if (true) 1 + 2; } `, 4, 2); // else testPass(` function f() { if (true) return else 1 + 2; } `); // switch testWarn(` function f() { return switch (1) { case 1: break; } } `, 4, 2); // return in switch testWarn(` function f() { switch (1) { case 1: return; 1 + 2; break; } } `, 6, 6); // break in switch testPass(` function f() { switch (1) { case 1: return; break; } } `); // case testPass(` function f() { switch (1) { case 0: return case 1: break; } } `); // default testPass(` function f() { switch (1) { case 0: return default: break; } } `); // while testWarn(` function f() { return while (false) 1 + 2; } `, 4, 2); testPass(` function f() { do return while (false); } `); // do testWarn(` function f() { return do { 1 + 2; } while (false); } `, 4, 2); // for testWarn(` function f() { return for (;;) { break; } } `, 4, 2); // break in for testPass(` function f() { for (;;) { return break; } } `, 5, 4); // continue testWarn(` function f() { for (;;) { return continue; } } `, 5, 4); // var (hosted) testPass(` function f() { return var a = 1; } `); // const testWarn(` function f() { return const a = 1; } `, 4, 2); // with testWarn(` function f() { return with ({}) { 1; } } `, 4, 2); // return testWarn(` function f() { return return; } `, 4, 2); // try testWarn(` function f() { return try { } catch (e) { } } `, 4, 2); // throw testPass(` function f() { return throw 1; } `); // debugger testWarn(` function f() { return debugger; } `, 4, 2); // let testWarn(` function f() { return let a = 1; } `, 4, 2); // skip hoisted testWarn(` function f() { return var a = 0; (1 + 2); } `, 5, 2); testWarn(` function f() { return function f() {} var a = 0; (1 + 2); } `, 6, 2);