@@ -4293,28 +4293,55 @@ An [=interface=] can be declared to be asynchronously iterable by using an
4293
4293
(matching <emu-nt><a href="#prod-AsyncIterable">AsyncIterable</a></emu-nt>) in the body of the
4294
4294
[=interface=].
4295
4295
4296
- <pre highlight="webidl" class="syntax">
4296
+ <!-- TODO: add highlight="webidl" after idlparser gets updated -->
4297
+ <pre class="syntax">
4297
4298
interface interface_identifier {
4299
+ async iterable<value_type>;
4300
+ async iterable<value_type>(/* arguments... */);
4298
4301
async iterable<key_type, value_type>;
4302
+ async iterable<key_type, value_type>(/* arguments... */);
4299
4303
};
4300
4304
</pre>
4301
4305
4302
4306
Objects that [=implement=] an [=interface=] that is declared to be asynchronously iterable support
4303
4307
being iterated over asynchronously to obtain a sequence of values.
4304
4308
4305
- Note: In the ECMAScript language binding, an interface that is asynchronously iterable will have
4306
- <code class="idl">entries</code>, <code class="idl">keys</code>, <code class="idl">values</code>,
4307
- and {{@@asyncIterator}} properties on its [=interface prototype object=].
4309
+ If a single type parameter is given, then the interface has a
4310
+ <dfn export>value asynchronously iterable declaration</dfn> and asynchronously provides values of the
4311
+ specified type. If two type parameters are given, then the interface has a
4312
+ <dfn export>pair asynchronously iterable declaration</dfn> and asynchronously provides
4313
+ [=value pairs=] with the given types.
4314
+
4315
+ If given, an [=asynchronously iterable declaration=]'s arguments (matching
4316
+ <emu-nt><a href="#prod-ArgumentList">ArgumentList</a></emu-nt>) must all be [=optional arguments=].
4317
+
4318
+ <div class="note">
4319
+ In the ECMAScript language binding, an interface that is asynchronously iterable will have
4320
+ {{@@asyncIterator}} and <code class="idl">values</code> properties on its
4321
+ [=interface prototype object=]. If the interface has a
4322
+ [=pair asynchronously iterable declaration=], it will additionally have
4323
+ <code class="idl">entries</code> and <code class="idl">keys</code> properties. All of these
4324
+ methods can be passed optional arguments, which correspond to the argument list in the
4325
+ [=asynchronously iterable declaration=], and are processed by the
4326
+ [=asynchronous iterator initialization steps=], if any exist.
4327
+
4328
+ With this in mind, the requirement that all arguments be optional ensures that, in the
4329
+ ECMAScript binding, <code>for</code>-<code>await</code>-<code>of</code> can work directly on
4330
+ instances of the interface, since <code>for</code>-<code>await</code>-<code>of</code> calls the
4331
+ {{@@asyncIterator}} method with no arguments.
4332
+ </div>
4308
4333
4309
4334
Prose accompanying an [=interface=] with an [=asynchronously iterable declaration=] must define a
4310
4335
<dfn id="dfn-get-the-next-iteration-result" export>get the next iteration result</dfn> algorithm.
4311
4336
This algorithm receives the instance of the [=interface=] that is being iterated, as well as the
4312
4337
async iterator itself (which can be useful for storing state).
4313
4338
It must return a {{Promise}} that either rejects, resolves with undefined to signal the end of the
4314
- iteration, or resolves with a tuple containing two elements :
4339
+ iteration, or resolves with one of the following :
4315
4340
4316
- 1. a value of the first type given in the declaration;
4317
- 1. a value of the second type given in the declaration.
4341
+ : for [=value asynchronously iterable declarations=]:
4342
+ :: a value of the type given in the declaration;
4343
+ : for [=pair asynchronously iterable declarations=]:
4344
+ :: a tuple containing a value of the first type given in the declaration, and a value of the second type given in the declaration.
4318
4345
4319
4346
The prose may also define an <dfn export>asynchronous iterator return</dfn> algorithm. This
4320
4347
algorithm receives the instance of the [=interface=] that is being iterated, the async iterator
@@ -4333,8 +4360,8 @@ but if you are creating an API that needs such capabilities, please
4333
4360
<a href="https://github.com/heycam/webidl/issues/new?title=Enhancement%20request%20for%20Async%20Iterables">file an issue</a>.
4334
4361
4335
4362
The prose may also define <dfn export>asynchronous iterator initialization steps</dfn>. These
4336
- receive the instance of the [=interface=] being iterated, as well as the newly-created
4337
- iterator object .
4363
+ receive the instance of the [=interface=] being iterated, the newly-created iterator object, and a
4364
+ [=list=] of IDL values representing the arguments passed, if any .
4338
4365
4339
4366
[=Interfaces=] with an [=asynchronously iterable declaration=] must not have any
4340
4367
[=interface members=] named "<code>entries</code>", "<code>keys</code>", or "<code>values</code>",
@@ -4443,7 +4470,13 @@ When they are, the effect will be as you would expect.
4443
4470
4444
4471
<pre class="grammar" id="prod-AsyncIterable">
4445
4472
AsyncIterable :
4446
- "async" "iterable" "<" TypeWithExtendedAttributes "," TypeWithExtendedAttributes ">" ";"
4473
+ "async" "iterable" "<" TypeWithExtendedAttributes OptionalType ">" OptionalArgumentList ";"
4474
+ </pre>
4475
+
4476
+ <pre class="grammar" id="prod-OptionalArgumentList">
4477
+ OptionalArgumentList :
4478
+ "(" ArgumentList ")"
4479
+ ε
4447
4480
</pre>
4448
4481
4449
4482
@@ -12290,75 +12323,113 @@ and the string "<code> Iterator</code>".
12290
12323
To <dfn>define the asynchronous iteration methods</dfn> of [=interface=] |definition| on
12291
12324
|target|, given [=Realm=] |realm|, run the following steps:
12292
12325
12293
- 1. If |definition| does not have an an [=asynchronously iterable declaration=], then return.
12326
+ 1. If |definition| does not have an an [=asynchronously iterable declaration=] (of either
12327
+ sort), then return.
12294
12328
1. Assert: |definition| does not have an [=indexed property getter=] or an
12295
12329
[=iterable declaration=].
12296
- 1. Define the {{@@asyncIterator}} and <code class="idl">entries</code> methods:
12297
- 1. Let |steps| be the following series of steps:
12330
+ 1. If |definition| has a [=pair asynchronously iterable declaration=], then define the
12331
+ {{@@asyncIterator}} and <code class="idl">entries</code> methods:
12332
+ 1. Let |steps| be the following series of steps, given function argument values |args|:
12298
12333
1. Let |esValue| be [=?=] [$ToObject$](<emu-val>this</emu-val> value).
12299
12334
1. If |esValue| [=is a platform object=], then [=perform a security check=], passing
12300
12335
|esValue|, "<code>@@asyncIterator</code>", and "<code>method</code>".
12301
12336
1. If |esValue| does not [=implement=] |definition|, then [=ECMAScript/throw=] a
12302
12337
{{ECMAScript/TypeError}}.
12303
12338
1. Let |idlObject| be the IDL [=interface type=] value that represents a reference to
12304
12339
|esValue|.
12340
+ 1. Let |idlArgs| be the result of
12341
+ [=converting arguments for an asynchronous iterator method=] given |args|.
12305
12342
1. Let |iterator| be a newly created [=default asynchronous iterator object=] for
12306
12343
|definition| with |idlObject| as its
12307
12344
[=default asynchronous iterator object/target=], "<code>key+value</code>" as its
12308
12345
[=default asynchronous iterator object/kind=], and
12309
12346
[=default asynchronous iterator object/is finished=] set to false.
12310
12347
1. Run the [=asynchronous iterator initialization steps=] for |definition| with
12311
- |idlObject| and |iterator |, if any such steps exist.
12348
+ |idlObject|, |iterator|, and |idlArgs |, if any such steps exist.
12312
12349
1. Return |iterator|.
12313
12350
1. Let |F| be [=!=] [$CreateBuiltinFunction$](|steps|, « », |realm|).
12314
12351
1. Perform [=!=] [$SetFunctionName$](|F|, "<code>entries</code>").
12315
12352
1. Perform [=!=] [$SetFunctionLength$](|F|, 0).
12316
12353
1. Perform [=!=] [$CreateMethodProperty$](|target|, {{@@asyncIterator}}, |F|).
12317
12354
1. Perform [=!=] [$CreateDataProperty$](|target|, "<code>entries</code>", |F|).
12318
- 1. Define the <code class="idl">keys</code> method:
12319
- 1. Let |steps| be the following series of steps:
12355
+ 1. If |definition| has a [=pair asynchronously iterable declaration=], then define the
12356
+ <code class="idl">keys</code> method:
12357
+ 1. Let |steps| be the following series of steps, given function argument values |args|:
12320
12358
1. Let |esValue| be [=?=] [$ToObject$](<emu-val>this</emu-val> value).
12321
12359
1. If |esValue| [=is a platform object=], then [=perform a security check=], passing
12322
12360
|esValue|, "<code>keys</code>", and "<code>method</code>".
12323
12361
1. If |esValue| does not [=implement=] |definition|, then [=ECMAScript/throw=] a
12324
12362
{{ECMAScript/TypeError}}.
12325
12363
1. Let |idlObject| be the IDL [=interface type=] value that represents a reference to
12326
12364
|esValue|.
12365
+ 1. Let |idlArgs| be the result of
12366
+ [=converting arguments for an asynchronous iterator method=] given |args|.
12327
12367
1. Let |iterator| be a newly created [=default asynchronous iterator object=] for
12328
12368
|definition| with |idlObject| as its
12329
12369
[=default asynchronous iterator object/target=], "<code>key</code>" as its
12330
12370
[=default asynchronous iterator object/kind=], and
12331
12371
[=default asynchronous iterator object/is finished=] set to false.
12332
12372
1. Run the [=asynchronous iterator initialization steps=] for |definition| with
12333
- |idlObject| and |iterator |, if any such steps exist.
12373
+ |idlObject|, |iterator|, and |idlArgs |, if any such steps exist.
12334
12374
1. Return |iterator|.
12335
12375
1. Let |F| be [=!=] [$CreateBuiltinFunction$](|steps|, « », |realm|).
12336
12376
1. Perform [=!=] [$SetFunctionName$](|F|, "<code>keys</code>").
12337
12377
1. Perform [=!=] [$SetFunctionLength$](|F|, 0).
12338
12378
1. Perform [=!=] [$CreateDataProperty$](|target|, "<code>keys</code>", |F|).
12339
- 1. Define the <code class="idl">values</code> method :
12340
- 1. Let |steps| be the following series of steps:
12379
+ 1. Define the <code class="idl">values</code>, and possibly {{@@asyncIterator}}, methods :
12380
+ 1. Let |steps| be the following series of steps, given function argument values |args| :
12341
12381
1. Let |esValue| be [=?=] [$ToObject$](<emu-val>this</emu-val> value).
12342
12382
1. If |esValue| [=is a platform object=], then [=perform a security check=], passing
12343
12383
|esValue|, "<code>values</code>", and "<code>method</code>".
12344
12384
1. If |esValue| does not [=implement=] |definition|, then [=ECMAScript/throw=] a
12345
12385
{{ECMAScript/TypeError}}.
12346
12386
1. Let |idlObject| be the IDL [=interface type=] value that represents a reference to
12347
12387
|esValue|.
12388
+ 1. Let |idlArgs| be the result of
12389
+ [=converting arguments for an asynchronous iterator method=] given |args|.
12348
12390
1. Let |iterator| be a newly created [=default asynchronous iterator object=] for
12349
12391
|definition| with |idlObject| as its
12350
12392
[=default asynchronous iterator object/target=], "<code>value</code>" as its
12351
12393
[=default asynchronous iterator object/kind=], and
12352
12394
[=default asynchronous iterator object/is finished=] set to false.
12353
12395
1. Run the [=asynchronous iterator initialization steps=] for |definition| with
12354
- |idlObject| and |iterator |, if any such steps exist.
12396
+ |idlObject|, |iterator|, and |idlArgs |, if any such steps exist.
12355
12397
1. Return |iterator|.
12356
12398
1. Let |F| be [=!=] [$CreateBuiltinFunction$](|steps|, « », |realm|).
12357
12399
1. Perform [=!=] [$SetFunctionName$](|F|, "<code>values</code>").
12358
12400
1. Perform [=!=] [$SetFunctionLength$](|F|, 0).
12359
12401
1. Perform [=!=] [$CreateDataProperty$](|target|, "<code>values</code>", |F|).
12402
+ 1. If |definition| has a [=value asynchronously iterable declaration=], then perform [=!=]
12403
+ [$CreateMethodProperty$](|target|, {{@@asyncIterator}}, |F|).
12360
12404
</div>
12361
12405
12406
+ <div algorithm>
12407
+ To <dfn lt="converting arguments for an asynchronous iterator method">convert arguments for an asynchronous iterator method</dfn>,
12408
+ given an [=interface=] |definition| that has an [=asynchronously iterable declaration=] and a
12409
+ [=list=] of ECMAScript values |args|:
12410
+
12411
+ 1. Let |idlArgs| be an empty list.
12412
+ 1. Let |argCount| be the number of arguments of |definition|'s
12413
+ [=asynchronously iterable declaration=], or 0 if the [=asynchronously iterable declaration=]
12414
+ does not have an argument list.
12415
+ 1. Let |i| be 0.
12416
+ 1. While |i| < |argCount|:
12417
+ 1. If |i| ≥ |args|'s [=list/size=], or if |args|[|i|] is <emu-val>undefined</emu-val>,
12418
+ then:
12419
+ 1. If the argument to the [=asynchronously iterable declaration=] at index |i| is
12420
+ declared with a [=optional argument/default value=], then [=list/append=] that
12421
+ default value to |idlArgs|.
12422
+ 1. Otherwise, [=list/append=] to |idlArgs| the special value "missing".
12423
+ 1. Otherwise, [=list/append=] to |idlArgs| the result of
12424
+ [=converted to an IDL value|converting=] |args|[|i|] to the IDL type given in the
12425
+ [=asynchronously iterable declaration=]'s argument list at index |i|.
12426
+ 1. Set |i| to |i| + 1.
12427
+ 1. Return |idlArgs|.
12428
+
12429
+ <p class="note">This is essentially a hyper-specialization of the
12430
+ [=overload resolution algorithm=] for the case where no overloads are allowed and all arguments
12431
+ are optional.</p>
12432
+ </div>
12362
12433
12363
12434
<h5 id="es-default-asynchronous-iterator-object">Default asynchronous iterator objects</h5>
12364
12435
@@ -12444,8 +12515,14 @@ The \[[Prototype]] [=internal slot=] of an [=asynchronous iterator prototype obj
12444
12515
1. Set |object|'s [=default asynchronous iterator object/is finished=] to true.
12445
12516
1. Return [=!=] [$CreateIterResultObject$](<emu-val>undefined</emu-val>,
12446
12517
<emu-val>true</emu-val>).
12447
- 1. Otherwise:
12518
+ 1. Otherwise, if |interface| has a [=pair asynchronously iterable declaration=]:
12519
+ 1. Assert: |next| is a [=value pair=].
12448
12520
1. Return the [=iterator result=] for |next| and |kind|.
12521
+ 1. Otherwise:
12522
+ 1. Assert: |interface| has a [=value asynchronously iterable declaration=].
12523
+ 1. Assert: |next| is a value of the type that appears in the declaration.
12524
+ 1. Let |value| be |next|, [=converted to an ECMAScript value=].
12525
+ 1. Return [=!=] [$CreateIterResultObject$](|value|, <emu-val>false</emu-val>).
12449
12526
1. Let |onFulfilled| be [=!=] [$CreateBuiltinFunction$](|fulfillSteps|, « »).
12450
12527
1. Perform [=!=] [$PerformPromiseThen$](|nextPromise|, |onFulfilled|,
12451
12528
<emu-val>undefined</emu-val>, |nextPromiseCapability|).
0 commit comments