LibWeb/IDL: Implement returning union types from IDL functions
This commit is contained in:
parent
698062b831
commit
98f354cec4
Notes:
sideshowbarker
2024-07-17 16:23:06 +09:00
Author: https://github.com/Lubrsi Commit: https://github.com/SerenityOS/serenity/commit/98f354cec4 Pull-request: https://github.com/SerenityOS/serenity/pull/14184 Reviewed-by: https://github.com/Quaker762 ✅ Reviewed-by: https://github.com/gmta ✅ Reviewed-by: https://github.com/linusg ✅ Reviewed-by: https://github.com/sunverwerth
1 changed files with 49 additions and 3 deletions
|
@ -1300,7 +1300,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
|
|||
return;
|
||||
}
|
||||
|
||||
if (type.nullable) {
|
||||
if (type.nullable && !is<UnionType>(type)) {
|
||||
if (type.is_string()) {
|
||||
scoped_generator.append(R"~~~(
|
||||
if (@value@.is_null()) {
|
||||
|
@ -1365,7 +1365,53 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
|
|||
@result_expression@ @value@;
|
||||
)~~~");
|
||||
} else if (is<IDL::UnionType>(type)) {
|
||||
TODO();
|
||||
auto& union_type = verify_cast<IDL::UnionType>(type);
|
||||
auto union_types = union_type.flattened_member_types();
|
||||
auto union_generator = scoped_generator.fork();
|
||||
|
||||
union_generator.append(R"~~~(
|
||||
@result_expression@ @value@.visit(
|
||||
)~~~");
|
||||
|
||||
for (size_t current_union_type_index = 0; current_union_type_index < union_types.size(); ++current_union_type_index) {
|
||||
auto& current_union_type = union_types.at(current_union_type_index);
|
||||
auto cpp_type = IDL::idl_type_name_to_cpp_type(current_union_type, interface);
|
||||
union_generator.set("current_type", cpp_type.name);
|
||||
union_generator.append(R"~~~(
|
||||
[&vm, &global_object](@current_type@ const& visited_union_value@recursion_depth@) -> JS::Value {
|
||||
// These may be unused.
|
||||
(void)vm;
|
||||
(void)global_object;
|
||||
)~~~");
|
||||
|
||||
// NOTE: While we are using const&, the underlying type for wrappable types in unions is (Nonnull)RefPtr, which are not references.
|
||||
generate_wrap_statement(union_generator, String::formatted("visited_union_value{}", recursion_depth), current_union_type, interface, "return"sv, WrappingReference::No, recursion_depth + 1);
|
||||
|
||||
// End of current visit lambda.
|
||||
// The last lambda cannot have a trailing comma on the closing brace, unless the type is nullable, where an extra lambda will be generated for the Empty case.
|
||||
if (current_union_type_index != union_types.size() - 1 || type.nullable) {
|
||||
union_generator.append(R"~~~(
|
||||
},
|
||||
)~~~");
|
||||
} else {
|
||||
union_generator.append(R"~~~(
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
}
|
||||
|
||||
if (type.nullable) {
|
||||
union_generator.append(R"~~~(
|
||||
[](Empty) -> JS::Value {
|
||||
return JS::js_null();
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
||||
// End of visit.
|
||||
union_generator.append(R"~~~(
|
||||
);
|
||||
)~~~");
|
||||
} else if (interface.enumerations.contains(type.name)) {
|
||||
scoped_generator.append(R"~~~(
|
||||
@result_expression@ JS::js_string(global_object.heap(), Bindings::idl_enum_to_string(@value@));
|
||||
|
@ -1404,7 +1450,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
|
|||
}
|
||||
}
|
||||
|
||||
if (type.nullable) {
|
||||
if (type.nullable && !is<UnionType>(type)) {
|
||||
scoped_generator.append(R"~~~(
|
||||
}
|
||||
)~~~");
|
||||
|
|
Loading…
Add table
Reference in a new issue