Make getAllTypes unwrap IDL record<K, V> types (#37039)

IDL `record` types can themselves contain types that are not described
anywhere else. An example is in
https://github.com/servo/servo/issues/37038, where the `record` contains
a definition of a union. These inner types must be returned from
`getAllTypes`, otherwise we won't generate code for them.

This PR also adds a few type annotations. I can remove them if
requested, but I think they're helpful.

Testing:  Includes a regression test
Fixes: https://github.com/servo/servo/issues/37038

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-05-18 11:30:20 +02:00 committed by GitHub
parent 070a8cf937
commit edea2caec1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 2 deletions

View file

@ -6,6 +6,7 @@
from collections import defaultdict
from itertools import groupby
from typing import Generator, Tuple, Optional, List
import operator
import os
@ -18,7 +19,9 @@ from WebIDL import (
BuiltinTypes,
IDLArgument,
IDLBuiltinType,
IDLCallback,
IDLDefaultDictionaryValue,
IDLDictionary,
IDLEmptySequenceValue,
IDLInterface,
IDLInterfaceMember,
@ -27,12 +30,15 @@ from WebIDL import (
IDLObject,
IDLPromiseType,
IDLType,
IDLTypedef,
IDLTypedefType,
IDLUndefinedValue,
IDLWrapperType,
)
from Configuration import (
Configuration,
Descriptor,
MakeNativeName,
MemberIsLegacyUnforgeable,
getModuleFromObject,
@ -2580,7 +2586,12 @@ class CGCallbackTempRoot(CGGeneric):
CGGeneric.__init__(self, f"{name.replace('<D>', '::<D>')}::new(cx, ${{val}}.get().to_object())")
def getAllTypes(descriptors, dictionaries, callbacks, typedefs):
def getAllTypes(
descriptors: List[Descriptor],
dictionaries: List[IDLDictionary],
callbacks: List[IDLCallback],
typedefs: List[IDLTypedef]
) -> Generator[Tuple[IDLType, Optional[Descriptor]], None, None]:
"""
Generate all the types we're dealing with. For each type, a tuple
containing type, descriptor, dictionary is yielded. The
@ -2588,18 +2599,32 @@ def getAllTypes(descriptors, dictionaries, callbacks, typedefs):
"""
for d in descriptors:
for t in getTypesFromDescriptor(d):
if t.isRecord():
yield (t.inner, d)
yield (t, d)
for dictionary in dictionaries:
for t in getTypesFromDictionary(dictionary):
if t.isRecord():
yield (t.inner, None)
yield (t, None)
for callback in callbacks:
for t in getTypesFromCallback(callback):
if t.isRecord():
yield (t.inner, None)
yield (t, None)
for typedef in typedefs:
if typedef.innerType.isRecord():
yield (typedef.innerType.inner, None)
yield (typedef.innerType, None)
def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
def UnionTypes(
descriptors: List[Descriptor],
dictionaries: List[IDLDictionary],
callbacks: List[IDLCallback],
typedefs: List[IDLTypedef],
config: Configuration
):
"""
Returns a CGList containing CGUnionStructs for every union.
"""

View file

@ -621,3 +621,9 @@ namespace TestNS {
};
typedef Promise<undefined> PromiseUndefined;
// https://github.com/servo/servo/issues/37038
dictionary NotUsedAnyWhereElse {};
dictionary RecordFieldWithUnionInside {
record<USVString, (USVString or NotUsedAnyWhereElse)> recordWithUnionField;
};