1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 21:58:12 +00:00

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)
This commit is contained in:
Linus Groh 2022-11-10 19:19:53 +00:00
parent d9cb7b6dc7
commit 1dc05fcc12

View file

@ -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>& type, HashMap<String, String>* extended_attributes = {})
{
if (is<ParameterizedType>(*type)) {
@ -825,6 +827,12 @@ static void resolve_typedef(Interface& interface, NonnullRefPtr<Type>& type, Has
return;
}
// Resolve anonymous union types until we get named types that can be resolved in the next step.
if (is<UnionType>(*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>& 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<UnionType>(*type)) {
auto& union_type = type->as_union();
auto& member_types = static_cast<Vector<NonnullRefPtr<Type>>&>(union_type.member_types());
for (auto& member_type : member_types)
resolve_typedef(interface, member_type);
}
if (is<UnionType>(*type))
resolve_union_typedefs(interface, type->as_union());
}
static void resolve_union_typedefs(Interface& interface, UnionType& union_)
{
auto& member_types = static_cast<Vector<NonnullRefPtr<Type>>&>(union_.member_types());
for (auto& member_type : member_types)
resolve_typedef(interface, member_type);
}
static void resolve_parameters_typedefs(Interface& interface, Vector<Parameter>& parameters)
{
for (auto& parameter : parameters)
resolve_typedef(interface, parameter.type, &parameter.extended_attributes);
}
template<typename FunctionType>
void resolve_function_typedefs(Interface& interface, FunctionType& function)
{