From 775c12f60fe5919f3c9bacadd4a4f355dcc575c5 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Fri, 21 Oct 2022 00:42:27 +0200 Subject: [PATCH] LibIDL: Resolve typedefs in UnionType members recursively --- Userland/Libraries/LibIDL/IDLParser.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibIDL/IDLParser.cpp b/Userland/Libraries/LibIDL/IDLParser.cpp index 531bf764cf..75b27a8afc 100644 --- a/Userland/Libraries/LibIDL/IDLParser.cpp +++ b/Userland/Libraries/LibIDL/IDLParser.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2021, Andreas Kling - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * Copyright (c) 2021, Luke Wilde * Copyright (c) 2022, Ali Mohammad Pur * @@ -835,6 +835,24 @@ static void resolve_typedef(Interface& interface, NonnullRefPtr& type, Has return; for (auto& attribute : it->value.extended_attributes) extended_attributes->set(attribute.key, attribute.value); + + // Recursively resolve typedefs in unions after we resolved the type itself - e.g. for this: + // typedef (A or B) Union1; + // typedef (C or D) Union2; + // typedef (Union1 or Union2) NestedUnion; + // We run: + // - resolve_typedef(NestedUnion) -> NestedUnion gets replaced by UnionType(Union1, Union2) + // - resolve_typedef(Union1) -> Union1 gets replaced by UnionType(A, B) + // - resolve_typedef(Union2) -> Union2 gets replaced by UnionType(C, D) + // 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 = static_ptr_cast(type); + auto& member_types = static_cast>&>(union_type->member_types()); + for (auto& member_type : member_types) + resolve_typedef(interface, member_type); + } } static void resolve_parameters_typedefs(Interface& interface, Vector& parameters) {