var testCase = function (actual, expected, message) { if (actual !== expected) { throw message + ". Expected '" + expected + "', but was '" + actual + "'"; } }; function getTarget(name) { return x => new.target; } noInline(getTarget) for (var i=0; i < 1000; i++) { var undefinedTarget = getTarget()(); testCase(undefinedTarget, undefined, "Error: new.target is not lexically binded inside of the arrow function #1.0"); } for (var i = 0; i < 1000; i++) { var newTarget = new getTarget()(); testCase(newTarget, getTarget, "Error: new.target is not lexically binded inside of the arrow function #2.0"); } function getTargetWithBlock(name) { return x => { if (false) return new.target; else return new.target; } } noInline(getTargetWithBlock); for (var i=0; i < 1000; i++) { var undefinedTarget = getTargetWithBlock()(); testCase(undefinedTarget, undefined, "Error: new.target is not lexically binded inside of the arrow function #1.1"); } for (var i = 0; i < 1000; i++) { var newTarget = new getTargetWithBlock()(); testCase(newTarget, getTargetWithBlock, "Error: new.target is not lexically binded inside of the arrow function #2.1"); } var passed = false; var A = class A { constructor() { this.idValue = 123; passed = passed && new.target === B; } }; var B = class B extends A { constructor() { var f = () => { passed = new.target === B; super(); }; f(); } }; for (var i = 0; i < 1000; i++) { passed = false; var b = new B(); testCase(passed, true, "Error: new.target is not lexically binded inside of the arrow function in constructor #3"); } // newTargetLocal - is hidden variable that emited for arrow function var C = class C extends A { constructor(tryToAccessToVarInArrow) { var f = () => { super(); if (tryToAccessToVarInArrow) this.id2 = newTargetLocal; }; f(); if (!tryToAccessToVarInArrow) this.id = newTargetLocal; } }; var tryToCreateClass = function (val) { var result = false; try { new C(val); } catch (e) { result = e instanceof ReferenceError; } return result; }; for (var i = 0; i < 1000; i++) { testCase(tryToCreateClass(true), true, "Error: newTargetLocal should be hided variable"); testCase(tryToCreateClass(false), true, "Error: newTargetLocal should be hided variable"); } function getTargetBlockScope() { if (true) { let someValue = ''; if (true) return x => new.target; } return ()=>value; } for (var i = 0; i < 1000; i++) { var undefinedTarget = getTargetBlockScope()() testCase(undefinedTarget, undefined, "Error: new.target is not lexically binded inside of the arrow function #4"); } class D { getNewTarget() { var arr = () => { if (false) { return new.target; } else { return new.target; } } return arr(); } }; class E extends D { getParentNewTarget() { return super.getNewTarget(); } } var e = new E(); for (var i = 0; i < 1000; i++) { var parentNewTarget = e.getParentNewTarget(); testCase(parentNewTarget, undefined, "Error: new.target is not lexically binded inside of the arrow function #5"); } class F { constructor() { let c; eval('c=(()=>new.target===F)()'); this.result = c; } getNewTargetFromEval() { return eval('(()=>new.target===F)()'); } } var f = new F(); testCase(f.result, true, "Error: new.target is not lexically binded inside of the arrow function #6"); testCase(f.getNewTargetFromEval(), false, "Error: new.target is not lexically binded inside of the arrow function #7"); class G extends A { constructor() { var arr; super(); eval('arr = () => new.target'); this.arrow = arr; } } let g = new G(); testCase(g.arrow(), G, "Error: new.target is not lexically binded inside of the arrow function #8"); class H extends A { constructor() { var arr; super(); eval('arr = () => eval("(() => new.target)()")'); this.arrow = arr; } } let h = new H(); testCase(h.arrow(), H, "Error: new.target is not lexically binded inside of the arrow function #9"); class J extends A { constructor() { super(); this.result = eval('eval("(() => new.target)()")'); } } let j = new J(); testCase(j.result, J, "Error: new.target is not lexically binded inside of the arrow function #10");