| const oneCallOfParentConstructor = 1; |
| const twoCallOfParentConstructor = 2; |
| |
| function tryCatch(klass) { |
| let result = false; |
| try { |
| new klass(); |
| } catch(e) { |
| result = e instanceof ReferenceError; |
| } |
| return result; |
| } |
| |
| var testCase = function (actual, expected, message) { |
| if (actual !== expected) { |
| throw message + ". Expected '" + expected + "', but was '" + actual + "'"; |
| } |
| }; |
| |
| let count = 0; |
| class A { |
| constructor() { |
| this.id = 0; |
| count++; |
| } |
| } |
| |
| class B extends A { |
| constructor() { |
| super(); |
| super(); |
| super(); |
| } |
| } |
| |
| testCase(tryCatch(B), true, 'Error: ReferenceError was not raised in case of two or more call super() #1'); |
| testCase(count, twoCallOfParentConstructor, 'Excpected two call of parent constructor #1'); |
| |
| count = 0; |
| class C extends A { |
| constructor() { |
| (()=>super())(); |
| (()=>super())(); |
| (()=>super())(); |
| } |
| } |
| |
| testCase(tryCatch(C), true, 'Error: ReferenceError was not raised in case of two or more call super() in arrrow function #2'); |
| testCase(count, twoCallOfParentConstructor, 'Excpected two call of parent constructor in arrow function #2'); |
| |
| count = 0; |
| class D extends A { |
| constructor() { |
| eval('super()'); |
| eval('super()'); |
| eval('super()'); |
| } |
| } |
| |
| testCase(tryCatch(D), true, 'Error: ReferenceError was not raised in case of two or more call super() in eval #3'); |
| testCase(count, twoCallOfParentConstructor, 'Excpected two call of parent constructor in eval #3'); |
| |
| count = 0; |
| class E extends A { |
| constructor() { |
| (()=>eval('super()'))(); |
| (()=>eval('super()'))(); |
| (()=>eval('super()'))(); |
| } |
| } |
| |
| testCase(tryCatch(E), true, 'Error: ReferenceError was not raised in case of two or more call super() in eval within arrow function #4'); |
| testCase(count, twoCallOfParentConstructor, 'Excpected two call of parent constructor in eval within arrow function #4'); |
| |
| count = 0; |
| class F extends A { |
| constructor() { |
| super(); |
| var arrow = () => 'testValue'; |
| arrow(); |
| } |
| } |
| |
| testCase(tryCatch(F), false, 'Error: ReferenceError was raised but should not be #5'); |
| testCase(count, oneCallOfParentConstructor, 'Excpected two call of parent constructor #5'); |
| |
| count = 0; |
| class G extends A { |
| constructor() { |
| super(); |
| eval('(()=>"abc")()'); |
| } |
| } |
| |
| testCase(tryCatch(G), false, 'Error: ReferenceError was raised but should not be #6'); |
| testCase(count, oneCallOfParentConstructor, 'Excpected two call of parent constructor #6'); |
| |
| count = 0; |
| class H extends A { |
| constructor() { |
| eval('(()=>eval("super()"))()'); |
| try { |
| eval('(()=>eval("super()"))()'); |
| } catch(e) { |
| let result = e instanceof ReferenceError; |
| if (!result) throw new Error('Wrong type error'); |
| } |
| try { |
| eval('(()=>eval("super()"))()'); |
| } catch(e) { |
| let result = e instanceof ReferenceError; |
| if (!result) throw new Error('Wrong type error'); |
| } |
| try { |
| eval('(()=>eval("super()"))()'); |
| } catch(e) { |
| let result = e instanceof ReferenceError; |
| if (!result) throw new Error('Wrong type error'); |
| } |
| } |
| } |
| |
| testCase(tryCatch(H), false, 'Error: ReferenceError was raised but should not be #7'); |
| testCase(count, 4, 'Excpected two call of parent constructor #7'); |
| |
| noInline(B); |
| for (var i = 0; i < 10000; i++) { |
| count = 0; |
| let result = false; |
| try { |
| new B(); |
| } catch(e) { |
| result = e instanceof ReferenceError; |
| } |
| |
| testCase(result, true, ''); |
| testCase(count, 2, ''); |
| } |
| |
| count = 0; |
| class I extends A { |
| constructor() { |
| super(); |
| (()=>super())(); |
| } |
| } |
| |
| testCase(tryCatch(I), true, 'Error: ReferenceError was not raised in case of two or more call super() #8'); |
| testCase(count, 2, 'Excpected two call of parent constructor #8'); |
| |
| count = 0; |
| class J extends A { |
| constructor() { |
| super(); |
| eval('super()'); |
| } |
| } |
| |
| testCase(tryCatch(J), true, 'Error: ReferenceError was not raised in case of two or more call super() #9'); |
| testCase(count, 2, 'Excpected two call of parent constructor #9'); |
| |
| let maxCount = 150000; |
| class K extends A { |
| constructor(i) { |
| if (i % 2 === 0 ) |
| super(); |
| if (i % 2 !== 0 || maxCount === i) |
| super(); |
| } |
| } |
| |
| noInline(K); |
| let result = false; |
| try { |
| count = 0; |
| for (var i = 1; i <= maxCount; i++) { |
| new K(i); |
| } |
| } catch (e) { |
| result = e instanceof ReferenceError; |
| } |
| testCase(result, true, 'Error: ReferenceError was not raised in case of two or more call super() #10'); |
| testCase(count, maxCount + 1, 'Excpected a lot of calls of parent constructor #10'); |