From 1dc05fcc12d213bc82b4427d63fdec751c1f20ff Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 10 Nov 2022 19:19:53 +0000 Subject: [PATCH] LibIDL: Also handle anonymous union types in resolve_typedef() Even if the type doesn't have a name and won't yield a result when looking for it in interface.typedefs, we still need to look at each of the union's members and resolve those as well, in a similar fashion to how we already recursively resolve the replaced type. This is commonly used in function parameters, for example send() from the XMLHttpRequest interface: send(optional (Document or XMLHttpRequestBodyInit)? body = null) --- Userland/Libraries/LibIDL/IDLParser.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibIDL/IDLParser.cpp b/Userland/Libraries/LibIDL/IDLParser.cpp index 44f803352a..f50b9427aa 100644 --- a/Userland/Libraries/LibIDL/IDLParser.cpp +++ b/Userland/Libraries/LibIDL/IDLParser.cpp @@ -815,6 +815,8 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter consume_whitespace(); } +static void resolve_union_typedefs(Interface& interface, UnionType& union_); + static void resolve_typedef(Interface& interface, NonnullRefPtr& type, HashMap* extended_attributes = {}) { if (is(*type)) { @@ -825,6 +827,12 @@ static void resolve_typedef(Interface& interface, NonnullRefPtr& type, Has return; } + // Resolve anonymous union types until we get named types that can be resolved in the next step. + if (is(*type) && type->name().is_empty()) { + resolve_union_typedefs(interface, type->as_union()); + return; + } + auto it = interface.typedefs.find(type->name()); if (it == interface.typedefs.end()) return; @@ -847,18 +855,23 @@ static void resolve_typedef(Interface& interface, NonnullRefPtr& type, Has // So whatever referenced NestedUnion ends up with the following resolved union: // UnionType(UnionType(A, B), UnionType(C, D)) // Note that flattening unions is handled separately as per the spec. - if (is(*type)) { - auto& union_type = type->as_union(); - auto& member_types = static_cast>&>(union_type.member_types()); - for (auto& member_type : member_types) - resolve_typedef(interface, member_type); - } + if (is(*type)) + resolve_union_typedefs(interface, type->as_union()); } + +static void resolve_union_typedefs(Interface& interface, UnionType& union_) +{ + auto& member_types = static_cast>&>(union_.member_types()); + for (auto& member_type : member_types) + resolve_typedef(interface, member_type); +} + static void resolve_parameters_typedefs(Interface& interface, Vector& parameters) { for (auto& parameter : parameters) resolve_typedef(interface, parameter.type, ¶meter.extended_attributes); } + template void resolve_function_typedefs(Interface& interface, FunctionType& function) {