Skip to content

Commit 5226b23

Browse files
authored
feat: implement new async_iterable syntax (#819)
* feat: implement new async_iterable syntax * Update README.md
1 parent 49789ae commit 5226b23

17 files changed

+91
-37
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ For `"Infinity"`:
745745

746746
* `negative`: Boolean indicating whether this is negative Infinity or not.
747747

748-
### `iterable<>`, `async iterable<>`, `maplike<>`, and `setlike<>` declarations
748+
### `iterable<>`, `async_iterable<>`, `maplike<>`, and `setlike<>` declarations
749749

750750
These appear as members of interfaces that look like this:
751751

@@ -755,7 +755,7 @@ These appear as members of interfaces that look like this:
755755
"idlType": /* One or two types */ ,
756756
"readonly": false, // only for maplike and setlike
757757
"async": false, // iterable can be async
758-
"arguments": [], // only for async iterable
758+
"arguments": [], // only for async_iterable
759759
"extAttrs": [],
760760
"parent": { ... }
761761
}
@@ -766,8 +766,8 @@ The fields are as follows:
766766
* `type`: Always one of "iterable", "maplike" or "setlike".
767767
* `idlType`: An array with one or more [IDL Types](#idl-type) representing the declared type arguments.
768768
* `readonly`: `true` if the maplike or setlike is declared as read only.
769-
* `async`: `true` if the type is async iterable.
770-
* `arguments`: An array of arguments if exists, empty otherwise. Currently only `async iterable` supports the syntax.
769+
* `async`: `true` if the type is `async iterable`. Note that it's false for the new `async_iterable`.
770+
* `arguments`: An array of arguments if exists, empty otherwise. Currently only `async_iterable` supports the syntax.
771771
* `extAttrs`: An array of [extended attributes](#extended-attributes).
772772
* `parent`: The container of this type as an Object.
773773

lib/productions/iterable.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { validationError } from "../error.js";
12
import { Base } from "./base.js";
23
import {
34
type_with_extended_attributes,
@@ -23,16 +24,18 @@ export class IterableLike extends Base {
2324
? tokeniser.consume("maplike", "setlike")
2425
: tokens.async
2526
? tokeniser.consume("iterable")
26-
: tokeniser.consume("iterable", "maplike", "setlike");
27+
: tokeniser.consume("iterable", "async_iterable", "maplike", "setlike");
2728
if (!tokens.base) {
2829
tokeniser.unconsume(start_position);
2930
return;
3031
}
3132

3233
const { type } = ret;
3334
const secondTypeRequired = type === "maplike";
34-
const secondTypeAllowed = secondTypeRequired || type === "iterable";
35-
const argumentAllowed = ret.async && type === "iterable";
35+
const secondTypeAllowed =
36+
secondTypeRequired || type === "iterable" || type === "async_iterable";
37+
const argumentAllowed =
38+
type === "async_iterable" || (ret.async && type === "iterable");
3639

3740
tokens.open =
3841
tokeniser.consume("<") ||
@@ -86,6 +89,18 @@ export class IterableLike extends Base {
8689
}
8790

8891
*validate(defs) {
92+
if (this.async && this.type === "iterable") {
93+
const message = "`async iterable` is now changed to `async_iterable`.";
94+
yield validationError(
95+
this.tokens.async,
96+
this,
97+
"obsolete-async-iterable-syntax",
98+
message,
99+
{
100+
autofix: autofixAsyncIterableSyntax(this),
101+
},
102+
);
103+
}
89104
for (const type of this.idlType) {
90105
yield* type.validate(defs);
91106
}
@@ -114,3 +129,18 @@ export class IterableLike extends Base {
114129
);
115130
}
116131
}
132+
133+
/**
134+
* @param {IterableLike} iterableLike
135+
*/
136+
function autofixAsyncIterableSyntax(iterableLike) {
137+
return () => {
138+
const async = iterableLike.tokens.async;
139+
iterableLike.tokens.base = {
140+
...async,
141+
type: "async_iterable",
142+
value: "async_iterable",
143+
};
144+
delete iterableLike.tokens.async;
145+
};
146+
}

lib/tokeniser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ const nonRegexTerminals = [
7272
"NaN",
7373
"ObservableArray",
7474
"Promise",
75+
"async_iterable",
7576
"bigint",
7677
"boolean",
7778
"byte",

test/autofix.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,20 @@ describe("Writer template functions", () => {
360360
`;
361361
expect(autofix(input)).toBe(output);
362362
});
363+
364+
it("should replace `async iterable` to `async_iterable`", () => {
365+
const input = `
366+
[Exposed=Window]
367+
interface AsyncIterable {
368+
async iterable<long, short>;
369+
};
370+
`;
371+
const output = `
372+
[Exposed=Window]
373+
interface AsyncIterable {
374+
async_iterable<long, short>;
375+
};
376+
`;
377+
expect(autofix(input)).toBe(output);
378+
});
363379
});

test/invalid/baseline/argument-dict-default.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
(dict-arg-default) Validation error at line 18 in argument-dict-default.webidl, inside `interface X -> operation z -> argument union`:
1111
undefined z(optional Union union);
1212
^ Optional dictionary arguments must have a default value of `{}`.
13-
(dict-arg-default) Validation error at line 22 in argument-dict-default.webidl, inside `interface X -> iterable -> argument union`:
13+
(dict-arg-default) Validation error at line 22 in argument-dict-default.webidl, inside `interface X -> async_iterable -> argument union`:
1414
DOMString>(optional Union union);
1515
^ Optional dictionary arguments must have a default value of `{}`.

test/invalid/baseline/argument-dict-nullable.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ boolean or Dict)? union = {})
1919
(no-nullable-dict-arg) Validation error at line 17 in argument-dict-nullable.webidl, inside `interface X -> operation r -> argument req`:
2020
undefined r(Required? req);
2121
^ Dictionary arguments cannot be nullable.
22-
(no-nullable-dict-arg) Validation error at line 19 in argument-dict-nullable.webidl, inside `interface X -> iterable -> argument dict`:
22+
(no-nullable-dict-arg) Validation error at line 19 in argument-dict-nullable.webidl, inside `interface X -> async_iterable -> argument dict`:
2323
>(optional Dict? dict);
2424
^ Dictionary arguments cannot be nullable.

test/invalid/baseline/argument-dict-optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@
1313
(dict-arg-optional) Validation error at line 38 in argument-dict-optional.webidl, inside `interface mixin Container -> operation op8 -> argument lastRequired`:
1414
undefined op8(Optional lastRequired, optional DOMString yay
1515
^ Dictionary argument must be optional if it has no required fields
16-
(dict-arg-optional) Validation error at line 44 in argument-dict-optional.webidl, inside `interface ContainerInterface -> iterable -> argument shouldBeOptional`:
16+
(dict-arg-optional) Validation error at line 44 in argument-dict-optional.webidl, inside `interface ContainerInterface -> async_iterable -> argument shouldBeOptional`:
1717
<DOMString>(Optional shouldBeOptional);
1818
^ Dictionary argument must be optional if it has no required fields
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Syntax error at line 3 in async-iterable-readonly.webidl, since `interface AsyncIterable`:
2-
readonly async iterable<long
2+
readonly async_iterable<long,
33
^ Missing return type
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(obsolete-async-iterable-syntax) Validation error at line 3 in async-space-iterable.webidl:
2+
async iterable<long,
3+
^ `async iterable` is now changed to `async_iterable`.

test/invalid/idl/argument-dict-default.webidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ interface X {
1919
undefined z2(optional Union union = {});
2020
undefined r(Required req);
2121

22-
async iterable<DOMString>(optional Union union);
22+
async_iterable<DOMString>(optional Union union);
2323
};

0 commit comments

Comments
 (0)