@@ -135,7 +135,7 @@ function isEventHandler(p: Browser.Property) {
135135export function emitWebIdl (
136136 webidl : Browser . WebIdl ,
137137 global : string ,
138- iterator : boolean
138+ iterator : "" | "sync" | "async"
139139) : string {
140140 // Global print target
141141 const printer = createTextWriter ( "\n" ) ;
@@ -225,7 +225,14 @@ export function emitWebIdl(
225225 getParentsWithConstant
226226 ) ;
227227
228- return iterator ? emitES6DomIterators ( ) : emit ( ) ;
228+ switch ( iterator ) {
229+ case "sync" :
230+ return emitES6DomIterators ( ) ;
231+ case "async" :
232+ return emitES2018DomAsyncIterators ( ) ;
233+ default :
234+ return emit ( ) ;
235+ }
229236
230237 function getTagNameToElementNameMap ( ) {
231238 const htmlResult : Record < string , string > = { } ;
@@ -402,7 +409,7 @@ export function emitWebIdl(
402409 }
403410
404411 function convertDomTypeToTsTypeSimple ( objDomType : string ) : string {
405- if ( objDomType === "sequence" && iterator ) {
412+ if ( objDomType === "sequence" && iterator !== "" ) {
406413 return "Iterable" ;
407414 }
408415 if ( baseTypeConversionMap . has ( objDomType ) ) {
@@ -1012,7 +1019,7 @@ export function emitWebIdl(
10121019
10131020 // Emit forEach for iterators
10141021 function emitIteratorForEach ( i : Browser . Interface ) {
1015- if ( ! i . iterator ) {
1022+ if ( ! i . iterator || i . iterator . async ) {
10161023 return ;
10171024 }
10181025 const subtype = i . iterator . type . map ( convertDomTypeToTsType ) ;
@@ -1521,8 +1528,15 @@ export function emitWebIdl(
15211528 return printer . getResult ( ) ;
15221529 }
15231530
1531+ function stringifySingleOrTupleTypes ( types : string [ ] ) {
1532+ if ( types . length === 1 ) {
1533+ return types [ 0 ] ;
1534+ }
1535+ return `[${ types . join ( ", " ) } ]` ;
1536+ }
1537+
15241538 function emitIterator ( i : Browser . Interface ) {
1525- // https://heycam.github.io/webidl /#dfn-indexed-property-getter
1539+ // https://webidl.spec.whatwg.org /#dfn-indexed-property-getter
15261540 const isIndexedPropertyGetter = ( m : Browser . AnonymousMethod ) =>
15271541 m . getter &&
15281542 m . signature [ 0 ] ?. param ?. length === 1 &&
@@ -1541,7 +1555,7 @@ export function emitWebIdl(
15411555 }
15421556
15431557 function getIteratorSubtypes ( ) {
1544- if ( i . iterator ) {
1558+ if ( i . iterator && ! i . iterator . async ) {
15451559 if ( i . iterator . type . length === 1 ) {
15461560 return [ convertDomTypeToTsType ( i . iterator . type [ 0 ] ) ] ;
15471561 }
@@ -1559,13 +1573,6 @@ export function emitWebIdl(
15591573 }
15601574 }
15611575
1562- function stringifySingleOrTupleTypes ( types : string [ ] ) {
1563- if ( types . length === 1 ) {
1564- return types [ 0 ] ;
1565- }
1566- return `[${ types . join ( ", " ) } ]` ;
1567- }
1568-
15691576 function emitIterableDeclarationMethods (
15701577 i : Browser . Interface ,
15711578 subtypes : string [ ]
@@ -1678,31 +1685,112 @@ export function emitWebIdl(
16781685 . filter ( ( m ) => m . signature . length )
16791686 . sort ( compareName ) ;
16801687
1681- if ( subtypes || methodsWithSequence . length ) {
1682- const iteratorExtends = getIteratorExtends ( i . iterator , subtypes ) ;
1683- const name = getNameWithTypeParameter (
1684- i . typeParameters ,
1685- extendConflictsBaseTypes [ i . name ] ? `${ i . name } Base` : i . name
1686- ) ;
1687- printer . printLine ( "" ) ;
1688- printer . printLine ( `interface ${ name } ${ iteratorExtends } {` ) ;
1689- printer . increaseIndent ( ) ;
1688+ if ( ! subtypes && ! methodsWithSequence . length ) {
1689+ return ;
1690+ }
16901691
1691- methodsWithSequence . forEach ( ( m ) => emitMethod ( "" , m , new Set ( ) ) ) ;
1692+ const iteratorExtends = getIteratorExtends ( i . iterator , subtypes ) ;
1693+ const name = getNameWithTypeParameter (
1694+ i . typeParameters ,
1695+ extendConflictsBaseTypes [ i . name ] ? `${ i . name } Base` : i . name
1696+ ) ;
1697+ printer . printLine ( "" ) ;
1698+ printer . printLine ( `interface ${ name } ${ iteratorExtends } {` ) ;
1699+ printer . increaseIndent ( ) ;
16921700
1693- if ( subtypes && ! iteratorExtends ) {
1694- printer . printLine (
1695- `[Symbol.iterator](): IterableIterator<${ stringifySingleOrTupleTypes (
1696- subtypes
1697- ) } >;`
1698- ) ;
1701+ methodsWithSequence . forEach ( ( m ) => emitMethod ( "" , m , new Set ( ) ) ) ;
1702+
1703+ if ( subtypes && ! iteratorExtends ) {
1704+ printer . printLine (
1705+ `[Symbol.iterator](): IterableIterator<${ stringifySingleOrTupleTypes (
1706+ subtypes
1707+ ) } >;`
1708+ ) ;
1709+ }
1710+ if ( i . iterator ?. kind === "iterable" && subtypes ) {
1711+ emitIterableDeclarationMethods ( i , subtypes ) ;
1712+ }
1713+ printer . decreaseIndent ( ) ;
1714+ printer . printLine ( "}" ) ;
1715+ }
1716+
1717+ function emitAsyncIterator ( i : Browser . Interface ) {
1718+ function getAsyncIteratorSubtypes ( ) {
1719+ if ( i . iterator && i . iterator . kind === "iterable" && i . iterator . async ) {
1720+ if ( i . iterator . type . length === 1 ) {
1721+ return [ convertDomTypeToTsType ( i . iterator . type [ 0 ] ) ] ;
1722+ }
1723+ return i . iterator . type . map ( convertDomTypeToTsType ) ;
16991724 }
1700- if ( i . iterator ?. kind === "iterable" && subtypes ) {
1701- emitIterableDeclarationMethods ( i , subtypes ) ;
1725+ }
1726+
1727+ function emitAsyncIterableDeclarationMethods (
1728+ i : Browser . Interface ,
1729+ subtypes : string [ ] ,
1730+ paramsString : string
1731+ ) {
1732+ let methods ;
1733+ if ( subtypes . length === 1 ) {
1734+ // https://webidl.spec.whatwg.org/#value-asynchronously-iterable-declaration
1735+ const [ valueType ] = subtypes ;
1736+ methods = [
1737+ {
1738+ name : "values" ,
1739+ definition : `AsyncIterableIterator<${ valueType } >` ,
1740+ } ,
1741+ ] ;
1742+ } else {
1743+ // https://webidl.spec.whatwg.org/#pair-asynchronously-iterable-declaration
1744+ const [ keyType , valueType ] = subtypes ;
1745+ methods = [
1746+ {
1747+ name : "entries" ,
1748+ definition : `AsyncIterableIterator<[${ keyType } , ${ valueType } ]>` ,
1749+ } ,
1750+ {
1751+ name : "keys" ,
1752+ definition : `AsyncIterableIterator<${ keyType } >` ,
1753+ } ,
1754+ {
1755+ name : "values" ,
1756+ definition : `AsyncIterableIterator<${ valueType } >` ,
1757+ } ,
1758+ ] ;
17021759 }
1703- printer . decreaseIndent ( ) ;
1704- printer . printLine ( "}" ) ;
1760+
1761+ const comments = i . iterator ! . comments ?. comment ;
1762+
1763+ methods . forEach ( ( m ) => {
1764+ emitComments ( { comment : comments ?. [ m . name ] } , printer . printLine ) ;
1765+ printer . printLine ( `${ m . name } (${ paramsString } ): ${ m . definition } ;` ) ;
1766+ } ) ;
1767+ }
1768+
1769+ const subtypes = getAsyncIteratorSubtypes ( ) ;
1770+ if ( ! subtypes ) {
1771+ return ;
17051772 }
1773+
1774+ const name = getNameWithTypeParameter (
1775+ i . typeParameters ,
1776+ extendConflictsBaseTypes [ i . name ] ? `${ i . name } Base` : i . name
1777+ ) ;
1778+ const paramsString = i . iterator ! . param
1779+ ? paramsToString ( i . iterator ! . param )
1780+ : "" ;
1781+ printer . printLine ( "" ) ;
1782+ printer . printLine ( `interface ${ name } {` ) ;
1783+ printer . increaseIndent ( ) ;
1784+
1785+ printer . printLine (
1786+ `[Symbol.asyncIterator](${ paramsString } ): AsyncIterableIterator<${ stringifySingleOrTupleTypes (
1787+ subtypes
1788+ ) } >;`
1789+ ) ;
1790+ emitAsyncIterableDeclarationMethods ( i , subtypes , paramsString ) ;
1791+
1792+ printer . decreaseIndent ( ) ;
1793+ printer . printLine ( "}" ) ;
17061794 }
17071795
17081796 function emitES6DomIterators ( ) {
@@ -1715,4 +1803,15 @@ export function emitWebIdl(
17151803
17161804 return printer . getResult ( ) ;
17171805 }
1806+
1807+ function emitES2018DomAsyncIterators ( ) {
1808+ printer . reset ( ) ;
1809+ printer . printLine ( "/////////////////////////////" ) ;
1810+ printer . printLine ( `/// ${ global } Async Iterable APIs` ) ;
1811+ printer . printLine ( "/////////////////////////////" ) ;
1812+
1813+ allInterfaces . sort ( compareName ) . forEach ( emitAsyncIterator ) ;
1814+
1815+ return printer . getResult ( ) ;
1816+ }
17181817}
0 commit comments