Skip to content

Emit iterable arguments for ES2015+ #699

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions baselines/dom.iterable.generated.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
/// DOM Iterable APIs
/////////////////////////////

interface AudioParam {
setValueCurveAtTime(values: Iterable<number>, startTime: number, duration: number): AudioParam;
}

interface AudioParamMap extends ReadonlyMap<string, AudioParam> {
}

interface AudioTrackList {
[Symbol.iterator](): IterableIterator<AudioTrack>;
}

interface BaseAudioContext {
createIIRFilter(feedforward: Iterable<number>, feedback: Iterable<number>): IIRFilterNode;
createPeriodicWave(real: Iterable<number>, imag: Iterable<number>, constraints?: PeriodicWaveConstraints): PeriodicWave;
}

interface CSSRuleList {
[Symbol.iterator](): IterableIterator<CSSRule>;
}
Expand All @@ -17,6 +26,14 @@ interface CSSStyleDeclaration {
[Symbol.iterator](): IterableIterator<string>;
}

interface Cache {
addAll(requests: Iterable<RequestInfo>): Promise<void>;
}

interface CanvasPathDrawingStyles {
setLineDash(segments: Iterable<number>): void;
}

interface ClientRectList {
[Symbol.iterator](): IterableIterator<ClientRect>;
}
Expand Down Expand Up @@ -96,6 +113,15 @@ interface Headers {
values(): IterableIterator<string>;
}

interface IDBObjectStore {
/**
* Creates a new index in store with the given name, keyPath and options and returns a new IDBIndex. If the keyPath and options define constraints that cannot be satisfied with the data already in store the upgrade transaction will abort with a "ConstraintError" DOMException.
*
* Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
*/
createIndex(name: string, keyPath: string | Iterable<string>, options?: IDBIndexParameters): IDBIndex;
}

interface MediaKeyStatusMap {
[Symbol.iterator](): IterableIterator<[BufferSource, MediaKeyStatus]>;
entries(): IterableIterator<[BufferSource, MediaKeyStatus]>;
Expand All @@ -115,6 +141,10 @@ interface NamedNodeMap {
[Symbol.iterator](): IterableIterator<Attr>;
}

interface Navigator {
requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: Iterable<MediaKeySystemConfiguration>): Promise<MediaKeySystemAccess>;
}

interface NodeList {
[Symbol.iterator](): IterableIterator<Node>;
/**
Expand Down Expand Up @@ -155,6 +185,10 @@ interface PluginArray {
[Symbol.iterator](): IterableIterator<Plugin>;
}

interface RTCRtpTransceiver {
setCodecPreferences(codecs: Iterable<RTCRtpCodecCapability>): void;
}

interface RTCStatsReport extends ReadonlyMap<string, any> {
}

Expand Down Expand Up @@ -222,6 +256,36 @@ interface URLSearchParams {
values(): IterableIterator<string>;
}

interface VRDisplay {
requestPresent(layers: Iterable<VRLayer>): Promise<void>;
}

interface VideoTrackList {
[Symbol.iterator](): IterableIterator<VideoTrack>;
}

interface WEBGL_draw_buffers {
drawBuffersWEBGL(buffers: Iterable<GLenum>): void;
}

interface WebAuthentication {
makeCredential(accountInformation: Account, cryptoParameters: Iterable<ScopedCredentialParameters>, attestationChallenge: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer | null, options?: ScopedCredentialOptions): Promise<ScopedCredentialInfo>;
}

interface WebGLRenderingContextBase {
uniform1fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;
uniform2fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;
uniform3fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;
uniform4fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;
uniform1iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;
uniform2iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;
uniform3iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;
uniform4iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;
uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;
uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;
uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;
vertexAttrib1fv(index: GLuint, values: Iterable<GLfloat>): void;
vertexAttrib2fv(index: GLuint, values: Iterable<GLfloat>): void;
vertexAttrib3fv(index: GLuint, values: Iterable<GLfloat>): void;
vertexAttrib4fv(index: GLuint, values: Iterable<GLfloat>): void;
}
58 changes: 52 additions & 6 deletions src/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) {
}

function convertDomTypeToTsTypeSimple(objDomType: string): string {
if (objDomType === "sequence" && flavor === Flavor.ES6Iterators) {
return "Iterable";
}
if (baseTypeConversionMap.has(objDomType)) {
return baseTypeConversionMap.get(objDomType)!;
}
Expand Down Expand Up @@ -689,7 +692,7 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) {

/// Emit the properties and methods of a given interface
function emitMembers(prefix: string, emitScope: EmitScope, i: Browser.Interface) {
const conflictedMembers = extendConflictsBaseTypes[i.name] ? extendConflictsBaseTypes[i.name].memberNames : new Set();
const conflictedMembers = extendConflictsBaseTypes[i.name] ? extendConflictsBaseTypes[i.name].memberNames : new Set<string>();
emitProperties(prefix, emitScope, i);
const methodPrefix = prefix.startsWith("declare var") ? "declare function " : "";
emitMethods(methodPrefix, emitScope, i, conflictedMembers);
Expand Down Expand Up @@ -1194,8 +1197,8 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) {
});
}

function getIteratorExtends(iterator: Browser.Iterator | undefined, subtypes: string[]) {
if (!iterator) {
function getIteratorExtends(iterator?: Browser.Iterator, subtypes?: string[]) {
if (!iterator || !subtypes) {
return "";
}
const base = iterator.kind === "maplike" ? `Map<${subtypes[0]}, ${subtypes[1]}>` :
Expand All @@ -1207,17 +1210,60 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) {
return `extends ${result} `;
}

function hasSequenceArgument(s: Browser.Signature) {
function typeIncludesSequence(type: string | Browser.Typed[]): boolean {
if (Array.isArray(type)) {
return type.some(t => typeIncludesSequence(t.type))
}
return type === "sequence" || !!sequenceTypedefMap[type];
}
return !!s.param && s.param.some(p => typeIncludesSequence(p.type));
}

function replaceTypedefsInSignatures(signatures: Browser.Signature[]): Browser.Signature[] {
return signatures.map(s => {
const params = s.param!.map(p => {
const typedef = typeof p.type === "string" ? sequenceTypedefMap[p.type] : undefined;
if (!typedef) {
return p;
}
return { ...p, type: typedef.type };
})
return { ...s, param: params };
});
}

const sequenceTypedefs = !webidl.typedefs ? [] :
webidl.typedefs.typedef
.filter(typedef => Array.isArray(typedef.type))
.map(typedef => ({ ...typedef, type: (typedef.type as Browser.Typed[]).filter(t => t.type === "sequence") }))
.filter(typedef => typedef.type.length)
const sequenceTypedefMap = arrayToMap(sequenceTypedefs, t => t["new-type"], t => t);

const subtypes = getIteratorSubtypes();
if (subtypes) {
const methodsWithSequence: Browser.Method[] =
mapToArray(i.methods ? i.methods.method : {})
.filter(m => m.signature && !m["override-signatures"])
.map(m => ({
...m,
signature: replaceTypedefsInSignatures(m.signature.filter(hasSequenceArgument))
}))
.filter(m => m.signature.length)
.sort();

if (subtypes || methodsWithSequence.length) {
const iteratorExtends = getIteratorExtends(i.iterator, subtypes);
const name = extendConflictsBaseTypes[i.name] ? `${i.name}Base` : i.name;
printer.printLine("");
printer.printLine(`interface ${name} ${iteratorExtends}{`);
printer.increaseIndent();
if (!iteratorExtends) {

methodsWithSequence.forEach(m => emitMethod("", m, new Set()));

if (subtypes && !iteratorExtends) {
printer.printLine(`[Symbol.iterator](): IterableIterator<${stringifySingleOrTupleTypes(subtypes)}>;`);
}
if (i.iterator && i.iterator.kind === "iterable") {
if (i.iterator && i.iterator.kind === "iterable" && subtypes) {
emitIterableDeclarationMethods(i, subtypes);
}
printer.decreaseIndent();
Expand Down
2 changes: 1 addition & 1 deletion src/widlprocess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ function convertOperation(operation: webidl2.OperationMemberType, inheritedExpos
throw new Error("Unexpected anonymous operation");
}
return {
name: operation.name,
name: operation.name || undefined,
signature: [{
...convertIdlType(operation.idlType),
param: operation.arguments.map(convertArgument)
Expand Down