1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:48:11 +00:00

LibJS: Use a synthetic constructor if class with parent doesn't have one

We already did this but it called the @@iterator method of
%Array.prototype% visible to the user for example by overriding that
method. This should not be visible so we use a special version of
SuperCall now.
This commit is contained in:
davidot 2022-08-20 17:27:02 +02:00 committed by Linus Groh
parent b79f03182d
commit ae349ec6a8
4 changed files with 100 additions and 4 deletions

View file

@ -449,3 +449,60 @@ test("super outside of derived class fails to parse", () => {
new J();
}).toThrowWithMessage(SyntaxError, "'super' keyword unexpected here");
});
test("When no constructor on deriving class @@iterator of %Array.prototype% is not visibly called", () => {
const oldIterator = Array.prototype[Symbol.iterator];
var calls = 0;
Array.prototype[Symbol.iterator] = function () {
++calls;
expect().fail("Called @@iterator");
};
class Base {
constructor(value1, value2) {
this.value1 = value1;
this.value2 = value2;
}
}
class Derived extends Base {}
const noArgumentsDerived = new Derived();
expect(noArgumentsDerived.value1).toBeUndefined();
expect(noArgumentsDerived.value2).toBeUndefined();
expect(noArgumentsDerived).toBeInstanceOf(Base);
expect(noArgumentsDerived).toBeInstanceOf(Derived);
const singleArgumentDerived = new Derived(1);
expect(singleArgumentDerived.value1).toBe(1);
expect(singleArgumentDerived.value2).toBeUndefined();
const singleArrayArgumentDerived = new Derived([1, 2]);
expect(singleArrayArgumentDerived.value1).toEqual([1, 2]);
expect(singleArrayArgumentDerived.value2).toBeUndefined();
const doubleArgumentDerived = new Derived(1, 2);
expect(doubleArgumentDerived.value1).toBe(1);
expect(doubleArgumentDerived.value2).toBe(2);
expect(calls).toBe(0);
class Derived2 extends Base {
constructor(...args) {
super(...args);
}
}
expect(() => {
new Derived2();
}).toThrowWithMessage(ExpectationError, "Called @@iterator");
expect(calls).toBe(1);
Array.prototype[Symbol.iterator] = oldIterator;
// Now Derived2 is fine again.
expect(new Derived2()).toBeInstanceOf(Derived2);
expect(calls).toBe(1);
});