Skip to content

Commit 2a2a099

Browse files
authored
Add [ImplicitThis] behaviour (#166)
1 parent 17ba65e commit 2a2a099

File tree

5 files changed

+1150
-676
lines changed

5 files changed

+1150
-676
lines changed

lib/constructs/attribute.js

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,15 @@ class Attribute {
2323

2424
const onInstance = utils.isOnInstance(this.idl, this.interface.idl);
2525

26-
let objName = `this`;
27-
if (onInstance) { // we're in a setup method
28-
objName = `obj`;
29-
}
3026
let brandCheck = `
31-
if (!this || !exports.is(this)) {
27+
if (!exports.is(esValue)) {
3228
throw new TypeError("Illegal invocation");
3329
}
3430
`;
35-
let getterBody = `return utils.tryWrapperForImpl(${objName}[impl]["${this.idl.name}"]);`;
36-
let setterBody = `${objName}[impl]["${this.idl.name}"] = V;`;
31+
let getterBody = `return utils.tryWrapperForImpl(esValue[impl]["${this.idl.name}"]);`;
32+
let setterBody = `esValue[impl]["${this.idl.name}"] = V;`;
3733
if (conversions[this.idl.idlType.idlType]) {
38-
getterBody = `return ${objName}[impl]["${this.idl.name}"];`;
34+
getterBody = `return esValue[impl]["${this.idl.name}"];`;
3935
}
4036

4137
const addMethod = this.static ?
@@ -51,8 +47,8 @@ class Attribute {
5147
throw new Error("Unknown reflector type: " + this.idl.idlType.idlType);
5248
}
5349
const attrName = shouldReflect.rhs && shouldReflect.rhs.value.replace(/_/g, "-") || this.idl.name;
54-
getterBody = reflector[this.idl.idlType.idlType].get(objName, attrName.toLowerCase());
55-
setterBody = reflector[this.idl.idlType.idlType].set(objName, attrName.toLowerCase());
50+
getterBody = reflector[this.idl.idlType.idlType].get("esValue", attrName.toLowerCase());
51+
setterBody = reflector[this.idl.idlType.idlType].set("esValue", attrName.toLowerCase());
5652
}
5753

5854
if (utils.getExtAttr(this.idl.extAttrs, "LenientThis")) {
@@ -71,6 +67,7 @@ class Attribute {
7167
}
7268

7369
addMethod(this.idl.name, [], `
70+
const esValue = this !== null && this !== undefined ? this : globalObject;
7471
${brandCheck}
7572
${getterBody}
7673
`, "get", { configurable });
@@ -95,19 +92,22 @@ class Attribute {
9592
}
9693

9794
addMethod(this.idl.name, ["V"], `
95+
const esValue = this !== null && this !== undefined ? this : globalObject;
9896
${brandCheck}
9997
${idlConversion}
10098
${setterBody}
10199
`, "set", { configurable });
102100
} else if (utils.getExtAttr(this.idl.extAttrs, "PutForwards")) {
103101
addMethod(this.idl.name, ["V"], `
102+
const esValue = this !== null && this !== undefined ? this : globalObject;
104103
${brandCheck}
105104
this.${this.idl.name}.${utils.getExtAttr(this.idl.extAttrs, "PutForwards").rhs.value} = V;
106105
`, "set", { configurable });
107106
} else if (utils.getExtAttr(this.idl.extAttrs, "Replaceable")) {
108107
addMethod(this.idl.name, ["V"], `
108+
const esValue = this !== null && this !== undefined ? this : globalObject;
109109
${brandCheck}
110-
Object.defineProperty(this, "${this.idl.name}", {
110+
Object.defineProperty(esValue, "${this.idl.name}", {
111111
configurable: true,
112112
enumerable: true,
113113
value: V,
@@ -118,10 +118,12 @@ class Attribute {
118118

119119
if (!this.static && this.idl.special === "stringifier") {
120120
addMethod("toString", [], `
121-
if (!this || !exports.is(this)) {
121+
const esValue = this;
122+
if (!exports.is(esValue)) {
122123
throw new TypeError("Illegal invocation");
123124
}
124-
${getterBody};
125+
126+
${getterBody}
125127
`, "regular", { configurable, writable: configurable });
126128
}
127129

lib/constructs/interface.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,12 +1128,12 @@ class Interface {
11281128
const obj = exports.create(globalObject, constructorArgs, privateData);
11291129
return utils.implForWrapper(obj);
11301130
};
1131-
exports._internalSetup = function _internalSetup(obj) {
1131+
exports._internalSetup = function _internalSetup(obj, globalObject) {
11321132
`;
11331133

11341134
if (this.idl.inheritance) {
11351135
this.str += `
1136-
${this.idl.inheritance}._internalSetup(obj);
1136+
${this.idl.inheritance}._internalSetup(obj, globalObject);
11371137
`;
11381138
}
11391139

@@ -1144,7 +1144,7 @@ class Interface {
11441144
exports.setup = function setup(obj, globalObject, constructorArgs = [], privateData = {}) {
11451145
privateData.wrapper = obj;
11461146
1147-
exports._internalSetup(obj);
1147+
exports._internalSetup(obj, globalObject);
11481148
Object.defineProperty(obj, impl, {
11491149
value: new Impl.implementation(globalObject, constructorArgs, privateData),
11501150
configurable: true

lib/constructs/operation.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ class Operation {
6262

6363
if (!this.static) {
6464
str += `
65-
if (!this || !exports.is(this)) {
65+
const esValue = this !== null && this !== undefined ? this : globalObject;
66+
if (!exports.is(esValue)) {
6667
throw new TypeError("Illegal invocation");
6768
}
6869
`;
6970
}
7071

71-
const callOn = this.static ? "Impl.implementation" : "this[impl]";
72+
const callOn = this.static ? "Impl.implementation" : `esValue[impl]`;
7273
// In case of stringifiers, use the named implementation function rather than hardcoded "toString".
7374
// All overloads will have the same name, so pick the first one.
7475
const implFunc = this.idls[0].name || this.name;

0 commit comments

Comments
 (0)