function assert(b) { if (!b) throw new Error("Bad"); } function hasSyntaxError(f) { let threw = false; try { f(); } catch(e) { threw = e instanceof SyntaxError; } return threw; } let functions = [ Function, (function*foo(){}).__proto__.constructor, (async function foo(){}).__proto__.constructor, ]; function testError(...args) { for (let f of functions) { assert(hasSyntaxError(() => (f(...args)))); } } function testOK(...args) { for (let f of functions) { assert(!hasSyntaxError(() => (f(...args)))); } } testError("a", "b", "/*", ""); testError("/*", "*/){"); testError("a=super()", "body;"); testError("a=super.foo", "body;"); testError("super();"); testError("super.foo;"); testError("a", "b", "/*", ""); testError("a", "'use strict'; let a;"); testError("/*", "*/"); testError("/*", "*/"); testError("a=20", "'use strict';"); testError("{a}", "'use strict';"); testError("...args", "'use strict';"); testError("...args", "b", ""); testError("//", "b", ""); testOK("/*", "*/", ""); testOK("a", "/*b", "*/", "'use strict'; let b"); testOK("{a}", "return a;"); testOK("a", "...args", ""); testOK(""); testOK("let a"); testOK(undefined); testOK("//"); let str = ""; testOK({toString() { str += "1"; return "a"}}, {toString() { str += "2"; return "b"}}, {toString() { str += "3"; return "body;"}}); let target = ""; for (let i = 0; i < functions.length; ++i) target += "123"; assert(str === target);