Skip to content

Commit

Permalink
Try/catch instead
Browse files Browse the repository at this point in the history
  • Loading branch information
domenic committed Apr 26, 2020
1 parent 945e516 commit 6c4bea9
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 69 deletions.
10 changes: 5 additions & 5 deletions lib/constructs/attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class Attribute {
${brandCheck}
${getterBody}
${promiseHandlingAfter}
`, { type: "get" }, { configurable });
`, "get", { configurable });

if (!this.idl.readonly) {
if (async) {
Expand Down Expand Up @@ -103,13 +103,13 @@ class Attribute {
${brandCheck}
${idlConversion}
${setterBody}
`, { type: "set" }, { configurable });
`, "set", { configurable });
} else if (utils.getExtAttr(this.idl.extAttrs, "PutForwards")) {
addMethod(this.idl.name, ["V"], `
const esValue = this !== null && this !== undefined ? this : globalObject;
${brandCheck}
this.${this.idl.name}.${utils.getExtAttr(this.idl.extAttrs, "PutForwards").rhs.value} = V;
`, { type: "set" }, { configurable });
`, "set", { configurable });
} else if (utils.getExtAttr(this.idl.extAttrs, "Replaceable")) {
addMethod(this.idl.name, ["V"], `
const esValue = this !== null && this !== undefined ? this : globalObject;
Expand All @@ -120,7 +120,7 @@ class Attribute {
value: V,
writable: true
});
`, { type: "set" }, { configurable });
`, "set", { configurable });
}

if (!this.static && this.idl.special === "stringifier") {
Expand All @@ -131,7 +131,7 @@ class Attribute {
}
${getterBody}
`, { type: "regular" }, { configurable, writable: configurable });
`, "regular", { configurable, writable: configurable });
}

return { requires };
Expand Down
28 changes: 14 additions & 14 deletions lib/constructs/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class Interface {

// whence is either "instance" or "prototype"
// type is either "regular", "get", or "set"
addMethod(whence, propName, args, body, { type = "regular", async = false } = {}, {
addMethod(whence, propName, args, body, type = "regular", {
configurable = true,
enumerable = typeof propName === "string",
writable = type === "regular" ? true : undefined
Expand All @@ -150,11 +150,11 @@ class Interface {
}

const descriptor = { configurable, enumerable, writable };
this._outputMethods.set(propName, { whence, type, args, body, descriptor, async });
this._outputMethods.set(propName, { whence, type, args, body, descriptor });
}

// type is either "regular", "get", or "set"
addStaticMethod(propName, args, body, { type = "regular", async = false } = {}, {
addStaticMethod(propName, args, body, type = "regular", {
configurable = true,
enumerable = typeof propName === "string",
writable = type === "regular" ? true : undefined
Expand All @@ -178,7 +178,7 @@ class Interface {
}

const descriptor = { configurable, enumerable, writable };
this._outputStaticMethods.set(propName, { type, args, body, descriptor, async });
this._outputStaticMethods.set(propName, { type, args, body, descriptor });
}

// whence is either "instance" or "prototype"
Expand Down Expand Up @@ -1317,40 +1317,40 @@ class Interface {
}

generateOffInstanceMethods() {
const addOne = (name, args, body, { isAsync, isStatic }) => {
const addOne = (name, args, body) => {
this.str += `
${isStatic ? "static " : ""}${isAsync ? "async " : ""}${name}(${formatArgs(args)}) {${body}}
${name}(${formatArgs(args)}) {${body}}
`;
};

for (const [name, { whence, type, args, body, async }] of this._outputMethods) {
for (const [name, { whence, type, args, body }] of this._outputMethods) {
if (whence !== "prototype") {
continue;
}

const propName = utils.stringifyPropertyKey(name);
if (type === "regular") {
addOne(propName, args, body, { isAsync: async });
addOne(propName, args, body);
} else {
if (body[0] !== undefined) {
addOne(`get ${propName}`, [], body[0], { isAsync: async });
addOne(`get ${propName}`, [], body[0]);
}
if (body[1] !== undefined) {
addOne(`set ${propName}`, args, body[1], { isAsync: async });
addOne(`set ${propName}`, args, body[1]);
}
}
}

for (const [name, { type, args, body, async }] of this._outputStaticMethods) {
for (const [name, { type, args, body }] of this._outputStaticMethods) {
const propName = utils.stringifyPropertyKey(name);
if (type === "regular") {
addOne(`${propName}`, args, body, { isAsync: async, isStatic: true });
addOne(`static ${propName}`, args, body);
} else {
if (body[0] !== undefined) {
addOne(`get ${propName}`, [], body[0], { isAsync: async, isStatic: true });
addOne(`static get ${propName}`, [], body[0]);
}
if (body[1] !== undefined) {
addOne(`set ${propName}`, args, body[0], { isAsync: async, isStatic: true });
addOne(`static set ${propName}`, args, body[0]);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions lib/constructs/operation.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ class Operation {
}

isAsync() {
// As of the time of this writing, the current spec does not disallow such overloads, but the intention is to do so:
// https://github.com/heycam/webidl/pull/776
const firstAsync = this.idls[0].idlType.generic === "Promise";
for (const overload of this.idls.slice(1)) {
const isAsync = overload.idlType.generic === "Promise";
if (isAsync !== firstAsync) {
throw new Error(
`Overloading between Promise and non-Promise return types is not yet implemented: operation ` +
`Overloading between Promise and non-Promise return types is not allowed: operation ` +
`"${this.name}" on ${this.interface.name}`
);
}
Expand Down Expand Up @@ -63,6 +65,8 @@ class Operation {

const onInstance = this.isOnInstance();
const async = this.isAsync();
const promiseHandlingBefore = async ? `try {` : ``;
const promiseHandlingAfter = async ? `} catch (e) { return Promise.reject(e); }` : ``;

const type = this.static ? "static operation" : "regular operation";
const overloads = Overloads.getEffectiveOverloads(type, this.name, 0, this.interface);
Expand Down Expand Up @@ -113,16 +117,18 @@ class Operation {
}
str += invocation;

str = promiseHandlingBefore + str + promiseHandlingAfter;

if (this.static) {
this.interface.addStaticMethod(this.name, argNames, str, { async });
this.interface.addStaticMethod(this.name, argNames, str);
} else {
const forgeable = !utils.getExtAttr(this.idls[0].extAttrs, "Unforgeable");
this.interface.addMethod(
onInstance ? "instance" : "prototype",
this.name,
argNames,
str,
{ type: "regular", async },
"regular",
{ configurable: forgeable, writable: forgeable }
);
}
Expand Down
Loading

0 comments on commit 6c4bea9

Please sign in to comment.