From 1a066f3c42ddb1432467dff178cd46360dd94e59 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 25 Mar 2024 15:20:19 +0100 Subject: [PATCH 1/3] Add support for parsing `async iterable` type --- test.py | 2 ++ widlparser/productions.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 2bd8b22..6301c45 100755 --- a/test.py +++ b/test.py @@ -214,6 +214,8 @@ def test_difference(input, output): typedef foo [ ] [ ] barTypes; typedef sequence sequins; typedef sequence? sequinses; +typedef async iterable asynciterables; +typedef async iterable? asynciterableses; typedef object obj; typedef (short or [Extended] double) union; typedef (short or sequence < DOMString [ ] ? [ ] > ? or DOMString[]?[] or unsigned long long or unrestricted double) craziness; diff --git a/widlparser/productions.py b/widlparser/productions.py index 30826b5..bd80458 100644 --- a/widlparser/productions.py +++ b/widlparser/productions.py @@ -931,7 +931,8 @@ class NonAnyType(ComplexProduction): Syntax: PrimitiveType [TypeSuffix] | "ByteString" [TypeSuffix] | "DOMString" [TypeSuffix] | "USVString" TypeSuffix | Identifier [TypeSuffix] | "sequence" "<" TypeWithExtendedAttributes ">" [Null] - | "object" [TypeSuffix] | "Error" TypeSuffix | "Promise" "<" Type ">" [Null] | BufferRelatedType [Null] + | "async" "iterable" "<" TypeWithExtendedAttributes ">" [Null] | "object" [TypeSuffix] | "Error" TypeSuffix + | "Promise" "<" Type ">" [Null] | BufferRelatedType [Null] | "FrozenArray" "<" TypeWithExtendedAttributes ">" [Null] | "ObservableArray" "<" TypeWithExtendedAttributes ">" [Null] | "record" "<" StringType "," TypeWithExtendedAttributes ">" """ @@ -945,6 +946,7 @@ class NonAnyType(ComplexProduction): type: (PrimitiveType | TypeIdentifier | TypeWithExtendedAttributes | Type | Symbol) type_name: (str | None) sequence: (Symbol | None) + async_iterable: (tuple[Symbol, Symbol] | None) promise: (Symbol | None) record: (Symbol | None) _open_type: (Symbol | None) @@ -968,6 +970,13 @@ def peek(cls, tokens: Tokenizer) -> bool: if (Symbol.peek(tokens, '>')): Symbol.peek(tokens, '?') return tokens.pop_position(True) + elif (token and token.is_symbol('async')): + if (Symbol.peek(tokens, 'iterable')): + if (Symbol.peek(tokens, '<')): + if (TypeWithExtendedAttributes.peek(tokens)): + if (Symbol.peek(tokens, '>')): + Symbol.peek(tokens, '?') + return tokens.pop_position(True) elif (token and token.is_symbol('Promise')): if (Symbol.peek(tokens, '<')): if (Type.peek(tokens)): @@ -990,6 +999,7 @@ def peek(cls, tokens: Tokenizer) -> bool: def __init__(self, tokens: Tokenizer, parent: ComplexProduction) -> None: super().__init__(tokens, parent) self.sequence = None + self.async_iterable = None self.promise = None self.record = None self._open_type = None @@ -1013,6 +1023,12 @@ def __init__(self, tokens: Tokenizer, parent: ComplexProduction) -> None: self.type = TypeWithExtendedAttributes(tokens, self) self._close_type = Symbol(tokens, '>', False) self.null = Symbol(tokens, '?', False) if (Symbol.peek(tokens, '?')) else None + elif (token.is_symbol('async')): + self.async_iterable = (Symbol(tokens), Symbol(tokens)) + self._open_type = Symbol(tokens, '<') + self.type = TypeWithExtendedAttributes(tokens, self) + self._close_type = Symbol(tokens, '>', False) + self.null = Symbol(tokens, '?', False) if (Symbol.peek(tokens, '?')) else None elif (token.is_symbol('Promise')): self.promise = Symbol(tokens, 'Promise') self._open_type = Symbol(tokens, '<') @@ -1043,6 +1059,9 @@ def _str(self) -> str: if (self.sequence): output = str(self.sequence) + str(self._open_type) + str(self.type) + str(self._close_type) return output + (str(self.null) if (self.null) else '') + if (self.async_iterable): + output = str(self.async_iterable[0]) + str(self.async_iterable[1]) + str(self._open_type) + str(self.type) + str(self._close_type) + return output + (str(self.null) if (self.null) else '') if (self.promise): output = str(self.promise) + str(self._open_type) + str(self.type) + str(self._close_type) return output + (str(self.null) if (self.null) else '') @@ -1062,6 +1081,14 @@ def _define_markup(self, generator: MarkupGenerator) -> Production: generator.add_text(self._close_type) generator.add_text(self.null) return self + if (self.async_iterable): + self.async_iterable[0].define_markup(generator) + self.async_iterable[1].define_markup(generator) + generator.add_text(self._open_type) + self.type.define_markup(generator) + generator.add_text(self._close_type) + generator.add_text(self.null) + return self if (self.promise): self.promise.define_markup(generator) generator.add_text(self._open_type) From 402e876f2531f2b3871cb9cf20ce9eb12586894c Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Tue, 26 Mar 2024 14:16:05 +0100 Subject: [PATCH 2/3] fix --- widlparser/productions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widlparser/productions.py b/widlparser/productions.py index bd80458..362c6be 100644 --- a/widlparser/productions.py +++ b/widlparser/productions.py @@ -1085,7 +1085,7 @@ def _define_markup(self, generator: MarkupGenerator) -> Production: self.async_iterable[0].define_markup(generator) self.async_iterable[1].define_markup(generator) generator.add_text(self._open_type) - self.type.define_markup(generator) + generator.add_type(self.type) generator.add_text(self._close_type) generator.add_text(self.null) return self From b3c8e3ab010f7d18becc012d7ae96c272b042338 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Tue, 26 Mar 2024 14:20:00 +0100 Subject: [PATCH 3/3] lint + test --- test-expected.txt | 23 ++++++++++++++++++++++- test.py | 8 ++++++-- widlparser/productions.py | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/test-expected.txt b/test-expected.txt index 5166e82..ea186e6 100644 --- a/test-expected.txt +++ b/test-expected.txt @@ -198,6 +198,12 @@ interface BigNumbers { const bigint biiig = 42; }; +typedef async iterable asynciterables; +typedef async iterable? asynciterableses; +interface Concat { + Promise concat(async iterable iter); +}; + <<< IDL SYNTAX ERROR LINE: 3 - skipped: "serializer" @@ -434,6 +440,11 @@ IDL SYNTAX ERROR LINE: 189 - skipped: "readonly setlike" [Interface: [name: BigNumbers] [members: [Member: [Const: [ConstType: [PrimitiveType: bigint]][name: biiig] = [value: 42]]] ]] +[Typedef: [TypeWithExtendedAttributes: [SingleType: [NonAnyType: [TypeWithExtendedAttributes: [SingleType: [NonAnyType: DOMString[TypeSuffix: [array] ]]]]]]] [name: asynciterables]] +[Typedef: [TypeWithExtendedAttributes: [SingleType: [NonAnyType: [TypeWithExtendedAttributes: [SingleType: [NonAnyType: DOMString[TypeSuffix: [array] ]]]][null]]]] [name: asynciterableses]] +[Interface: [name: Concat] [members: + [Member: [Operation: [Type: [SingleType: [NonAnyType: [Promise] [Type: [SingleType: [NonAnyType: DOMString]]]]]] [OperationRest: [name: [OperationName: concat]] [ArgumentList: [Argument: [type: async iterable ] [name: [ArgumentName: iter]]]]]]] +]] ] MARKED UP: dictionary CSSFontFaceLoadEventInit : EventInit { sequence<CSSFontFaceRule> fontfaces = [ ]; }; @@ -635,7 +646,13 @@ typedef short shorttype = error this is; const

bigint

biiig = 42;
}; -Complexity: 151 +typedef async iterable<DOMString[]> asynciterables; +typedef async iterable<DOMString[]>? asynciterableses; +interface Concat { + Promise<DOMString> concat(async iterable<DOMString> iter); +}; + +Complexity: 155 dictionary: CSSFontFaceLoadEventInit dict-member: fontfaces (fontfaces) interface: Simple @@ -793,6 +810,10 @@ interface: Underscores method: includes(value) (includes) interface: BigNumbers const: biiig (biiig) +typedef: asynciterables +typedef: asynciterableses +interface: Concat + method: concat(iter) (concat) FIND: callMe/round Foo/method(x, y, inf, ...fooArg)/y diff --git a/test.py b/test.py index 6301c45..efc842a 100755 --- a/test.py +++ b/test.py @@ -214,8 +214,6 @@ def test_difference(input, output): typedef foo [ ] [ ] barTypes; typedef sequence sequins; typedef sequence? sequinses; -typedef async iterable asynciterables; -typedef async iterable? asynciterableses; typedef object obj; typedef (short or [Extended] double) union; typedef (short or sequence < DOMString [ ] ? [ ] > ? or DOMString[]?[] or unsigned long long or unrestricted double) craziness; @@ -345,6 +343,12 @@ def test_difference(input, output): interface BigNumbers { const bigint biiig = 42; }; + +typedef async iterable asynciterables; +typedef async iterable? asynciterableses; +interface Concat { + Promise concat(async iterable iter); +}; """ # idl = idl.replace(' ', ' ') print("IDL >>>\n" + idl + "\n<<<") diff --git a/widlparser/productions.py b/widlparser/productions.py index 362c6be..4a438b1 100644 --- a/widlparser/productions.py +++ b/widlparser/productions.py @@ -1085,7 +1085,7 @@ def _define_markup(self, generator: MarkupGenerator) -> Production: self.async_iterable[0].define_markup(generator) self.async_iterable[1].define_markup(generator) generator.add_text(self._open_type) - generator.add_type(self.type) + generator.add_type(self.type) generator.add_text(self._close_type) generator.add_text(self.null) return self