Pārlūkot izejas kodu

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)
Linus Groh 2 gadi atpakaļ
vecāks
revīzija
1dc05fcc12
1 mainītis faili ar 19 papildinājumiem un 6 dzēšanām
  1. 19 6
      Userland/Libraries/LibIDL/IDLParser.cpp

+ 19 - 6
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>& 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)
 {