diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index 0c1439308..449cea7ba 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -4026,6 +4026,7 @@ interface DOMMatrixReadOnly { toJSON(): any; transformPoint(point?: DOMPointInit): DOMPoint; translate(tx?: number, ty?: number, tz?: number): DOMMatrix; + toString(): string; } declare var DOMMatrixReadOnly: { @@ -4034,6 +4035,7 @@ declare var DOMMatrixReadOnly: { fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly; fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly; + toString(): string; }; /** Provides the ability to parse XML or HTML source code from a string into a DOM Document. */ @@ -4191,6 +4193,7 @@ interface DOMTokenList { * Can be set, to change the associated attribute. */ value: string; + toString(): string; /** * Adds all arguments passed, except those already present. * @@ -7071,6 +7074,7 @@ interface HTMLHyperlinkElementUtils { host: string; hostname: string; href: string; + toString(): string; readonly origin: string; password: string; pathname: string; @@ -9924,6 +9928,7 @@ interface Location { * Can be set, to navigate to the given URL. */ href: string; + toString(): string; /** * Returns the Location object's URL's origin. */ @@ -10382,10 +10387,10 @@ declare var MediaKeys: { interface MediaList { readonly length: number; mediaText: string; + toString(): string; appendMedium(medium: string): void; deleteMedium(medium: string): void; item(index: number): string | null; - toString(): number; [index: number]: string; } @@ -12652,6 +12657,7 @@ interface Range extends AbstractRange { setStartAfter(node: Node): void; setStartBefore(node: Node): void; surroundContents(newParent: Node): void; + toString(): string; readonly END_TO_END: number; readonly END_TO_START: number; readonly START_TO_END: number; @@ -12665,6 +12671,7 @@ declare var Range: { readonly END_TO_START: number; readonly START_TO_END: number; readonly START_TO_START: number; + toString(): string; }; interface ReadableByteStreamController { @@ -15036,11 +15043,13 @@ interface Selection { selectAllChildren(node: Node): void; setBaseAndExtent(anchorNode: Node, anchorOffset: number, focusNode: Node, focusOffset: number): void; setPosition(node: Node | null, offset?: number): void; + toString(): string; } declare var Selection: { prototype: Selection; new(): Selection; + toString(): string; }; interface ServiceUIFrameContext { @@ -16045,6 +16054,7 @@ interface URL { host: string; hostname: string; href: string; + toString(): string; readonly origin: string; password: string; pathname: string; @@ -16092,12 +16102,14 @@ interface URLSearchParams { */ set(name: string, value: string): void; sort(): void; + toString(): string; forEach(callbackfn: (value: string, key: string, parent: URLSearchParams) => void, thisArg?: any): void; } declare var URLSearchParams: { prototype: URLSearchParams; new(init?: string[][] | Record | string | URLSearchParams): URLSearchParams; + toString(): string; }; /** This WebVR API interface represents any VR device supported by this API. It includes generic information such as device IDs and descriptions, as well as methods for starting to present a VR scene, retrieving eye parameters and display capabilities, and other important functionality. */ diff --git a/baselines/webworker.generated.d.ts b/baselines/webworker.generated.d.ts index 492e7951a..111b94ad0 100644 --- a/baselines/webworker.generated.d.ts +++ b/baselines/webworker.generated.d.ts @@ -3211,6 +3211,7 @@ interface URL { host: string; hostname: string; href: string; + toString(): string; readonly origin: string; password: string; pathname: string; @@ -3255,12 +3256,14 @@ interface URLSearchParams { */ set(name: string, value: string): void; sort(): void; + toString(): string; forEach(callbackfn: (value: string, key: string, parent: URLSearchParams) => void, thisArg?: any): void; } declare var URLSearchParams: { prototype: URLSearchParams; new(init?: string[][] | Record | string | URLSearchParams): URLSearchParams; + toString(): string; }; interface WEBGL_color_buffer_float { @@ -5389,12 +5392,12 @@ interface WorkerLocation { readonly host: string; readonly hostname: string; readonly href: string; + toString(): string; readonly origin: string; readonly pathname: string; readonly port: string; readonly protocol: string; readonly search: string; - toString(): string; } declare var WorkerLocation: { diff --git a/src/emitter.ts b/src/emitter.ts index 3f4669833..5f23a60d0 100644 --- a/src/emitter.ts +++ b/src/emitter.ts @@ -626,6 +626,10 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) { const readOnlyModifier = p["read-only"] === 1 && prefix === "" ? "readonly " : ""; printer.printLine(`${prefix}${readOnlyModifier}${p.name}${requiredModifier}: ${pType};`); } + + if (p.stringifier) { + printer.printLine("toString(): string;") + } } function emitComments(entity: { comment?: string; deprecated?: 1 }, print: (s: string) => void) { @@ -666,7 +670,16 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) { case "querySelector": return emitQuerySelectorOverloads(m); case "querySelectorAll": return emitQuerySelectorAllOverloads(m); } - emitSignatures(m, prefix, m.name, printLine); + + // ignore toString() provided from browser.webidl.preprocessed.json + // to prevent duplication + if (m.name !== "toString") { + emitSignatures(m, prefix, m.name, printLine); + + if (m.stringifier) { + printLine("toString(): string;") + } + } } function emitSignature(s: Browser.Signature, prefix: string | undefined, name: string | undefined, printLine: (s: string) => void) { @@ -698,6 +711,12 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) { .sort(compareName) .forEach(m => emitMethod(prefix, m, conflictedMembers)); } + if (i["anonymous-methods"]) { + const stringifier = i["anonymous-methods"].method.find(m => m.stringifier); + if (stringifier) { + printer.printLine("toString(): string;"); + } + } // The window interface inherited some methods from "Object", // which need to explicitly exposed diff --git a/src/widlprocess.ts b/src/widlprocess.ts index 9c65a5614..7372dcf9f 100644 --- a/src/widlprocess.ts +++ b/src/widlprocess.ts @@ -145,7 +145,7 @@ function convertInterfaceCommon(i: webidl2.InterfaceType | webidl2.InterfaceMixi properties!.property[member.name] = prop; } } - else if (member.type === "operation" && member.idlType) { + else if (member.type === "operation") { const operation = convertOperation(member, result.exposed); const { method } = result.methods; if (!member.name) { @@ -205,18 +205,23 @@ function getNamedConstructor(extAttrs: webidl2.ExtendedAttribute[], parent: stri } function convertOperation(operation: webidl2.OperationMemberType, inheritedExposure: string | undefined): Browser.AnonymousMethod | Browser.Method { - if (!operation.idlType) { + const isStringifier = operation.special === "stringifier"; + const type = + operation.idlType ? convertIdlType(operation.idlType) : + isStringifier ? { type: "DOMString" } : + undefined; + if (!type) { throw new Error("Unexpected anonymous operation"); } return { name: operation.name || undefined, signature: [{ - ...convertIdlType(operation.idlType), + ...type, param: operation.arguments.map(convertArgument) }], getter: operation.special === "getter" ? 1 : undefined, static: operation.special === "static" ? 1 : undefined, - stringifier: operation.special === "stringifier" ? 1 : undefined, + stringifier: isStringifier ? 1 : undefined, exposed: getExtAttrConcatenated(operation.extAttrs, "Exposed") || inheritedExposure }; } @@ -249,6 +254,7 @@ function convertAttribute(attribute: webidl2.AttributeMemberType, inheritedExpos name: attribute.name, ...convertIdlType(attribute.idlType), static: attribute.special === "static" ? 1 : undefined, + stringifier: attribute.special === "stringifier" ? 1 : undefined, "read-only": attribute.readonly ? 1 : undefined, "event-handler": isEventHandler ? attribute.name.slice(2) : undefined, exposed: getExtAttrConcatenated(attribute.extAttrs, "Exposed") || inheritedExposure