Skip to content

Commit 2d1eca8

Browse files
feat: add support for parsing async_sequence<T> type (#775)
* feat: add support for parsing `async iterable<T>` type * it can be return type of operations * Update to async_sequence * Update README.md * revert the unconsume caused by LL(1) violation * revert usages of `async` * remove async_sequence return The grammar isn't wrong but it's not valid. It's covered in invalid/idl instead. * update validation message --------- Co-authored-by: Kagami Sascha Rosylight <[email protected]>
1 parent 5226b23 commit 2d1eca8

14 files changed

+200
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ properties:
186186
* `sourceName`: the source name you passed to `parse()`.
187187
* `level`: `"error"` by default, can be `"warning"` for some validations for e.g. potential future deprecations.
188188
* `ruleName`: Only for validations. Currently the followings are supported:
189+
* `async-iterable-idl-to-js`: `async_iterable` types cannot be returned from the IDL to JS.
189190
* `attr-invalid-type`: Attributes cannot have sequences, records, nor dictionaries.
190191
* `dict-arg-default`: Optional dictionary type arguments must have a default value of `{}`.
191192
* `dict-arg-optional`: Dictionary type arguments must be optional if the type does not include a required field.
@@ -236,7 +237,7 @@ attached to a field called `idlType`:
236237
Where the fields are as follows:
237238

238239
* `type`: String indicating where this type is used. Can be `null` if not applicable.
239-
* `generic`: String indicating the generic type (e.g. "Promise", "sequence").
240+
* `generic`: String indicating the generic type (e.g. "Promise", "sequence", "async_sequence").
240241
* `idlType`: String indicating the type name, or array of subtypes if the type is
241242
generic or a union.
242243
* `nullable`: `true` if the type is nullable.

lib/productions/attribute.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ export class Attribute extends Base {
7575
yield* this.extAttrs.validate(defs);
7676
yield* this.idlType.validate(defs);
7777

78-
if (["sequence", "record"].includes(this.idlType.generic)) {
78+
if (
79+
["async_sequence", "sequence", "record"].includes(this.idlType.generic)
80+
) {
7981
const message = `Attributes cannot accept ${this.idlType.generic} types.`;
8082
yield validationError(
8183
this.tokens.name,

lib/productions/callback.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
unescape,
66
autoParenter,
77
} from "./helpers.js";
8+
import { validationError } from "../error.js";
89

910
export class CallbackFunction extends Base {
1011
/**
@@ -44,6 +45,18 @@ export class CallbackFunction extends Base {
4445

4546
*validate(defs) {
4647
yield* this.extAttrs.validate(defs);
48+
for (const arg of this.arguments) {
49+
yield* arg.validate(defs);
50+
if (arg.idlType.generic === "async_sequence") {
51+
const message = `async_sequence types cannot be returned as a callback argument.`;
52+
yield validationError(
53+
arg.tokens.name,
54+
arg,
55+
"async-sequence-idl-to-js",
56+
message,
57+
);
58+
}
59+
}
4760
yield* this.idlType.validate(defs);
4861
}
4962

lib/productions/operation.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ export class Operation extends Base {
6868
yield validationError(this.tokens.open, this, "incomplete-op", message);
6969
}
7070
if (this.idlType) {
71+
if (this.idlType.generic === "async_sequence") {
72+
const message = `async_sequence types cannot be returned by an operation.`;
73+
yield validationError(
74+
this.idlType.tokens.base,
75+
this,
76+
"async-sequence-idl-to-js",
77+
message,
78+
);
79+
}
7180
yield* this.idlType.validate(defs);
7281
}
7382
for (const argument of this.arguments) {

lib/productions/type.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function generic_type(tokeniser, typeName) {
2020
"FrozenArray",
2121
"ObservableArray",
2222
"Promise",
23+
"async_sequence",
2324
"sequence",
2425
"record",
2526
);
@@ -42,6 +43,7 @@ function generic_type(tokeniser, typeName) {
4243
ret.subtype.push(subtype);
4344
break;
4445
}
46+
case "async_sequence":
4547
case "sequence":
4648
case "FrozenArray":
4749
case "ObservableArray": {

lib/tokeniser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ const nonRegexTerminals = [
7373
"ObservableArray",
7474
"Promise",
7575
"async_iterable",
76+
"async_sequence",
7677
"bigint",
7778
"boolean",
7879
"byte",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Syntax error at line 3 in async-sequence-const.webidl, since `interface AsyncSequence`:
2+
const async_sequence<long, short
3+
^ Const lacks a type
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(attr-invalid-type) Validation error at line 3 in async-sequence-idl-to-js.webidl, inside `interface asyncIterableAsAttribute -> attribute invalid`:
2+
attribute async_sequence<short> invalid;
3+
^ Attributes cannot accept async_sequence types.
4+
(async-sequence-idl-to-js) Validation error at line 5 in async-sequence-idl-to-js.webidl, inside `interface asyncIterableAsAttribute -> operation invalidOp`:
5+
async_sequence<DOMString> invalidOp
6+
^ async_sequence types cannot be returned by an operation.
7+
(async-sequence-idl-to-js) Validation error at line 8 in async-sequence-idl-to-js.webidl, inside `callback DoSomething -> argument bool`:
8+
(async_sequence<DOMString> bool);
9+
^ async_sequence types cannot be returned as a callback argument.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Syntax error at line 3 in async-sequence-two-params.webidl, since `interface AsyncSequence`:
2+
async_sequence<long, short> foo(
3+
^ Missing closing bracket after async_sequence
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[Exposed=Window]
2+
interface AsyncSequence {
3+
const async_sequence<long, short> ASYNC_SEQUENCE = 0;
4+
};

0 commit comments

Comments
 (0)