1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:17:35 +00:00

LibWeb: Add support for wrapping arbitrary values to WrapperGenerator

This patch essentially just splits the non return-specific logic from
generate_return_statement (i.e. the wrapping of the cpp value into
a javascript one) into a separate function generate_wrap_statement that
can be used to wrap any cpp value during wrapper generation.
This commit is contained in:
Idan Horowitz 2021-09-28 00:54:20 +03:00 committed by Andreas Kling
parent a11f7868a4
commit 2fab43ba5d

View file

@ -970,73 +970,83 @@ static void generate_arguments(SourceGenerator& generator, Vector<IDL::Parameter
arguments_builder.join(", ", parameter_names); arguments_builder.join(", ", parameter_names);
} }
static void generate_return_statement(SourceGenerator& generator, IDL::Type const& return_type) static void generate_wrap_statement(SourceGenerator& generator, String const& value, IDL::Type const& type, StringView const& result_expression)
{ {
auto scoped_generator = generator.fork(); auto scoped_generator = generator.fork();
scoped_generator.set("return_type", return_type.name); scoped_generator.set("value", value);
scoped_generator.set("type", type.name);
scoped_generator.set("result_expression", result_expression);
if (return_type.name == "undefined") { if (type.name == "undefined") {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return JS::js_undefined(); @result_expression@ JS::js_undefined();
)~~~"); )~~~");
return; return;
} }
if (return_type.nullable) { if (type.nullable) {
if (return_type.is_string()) { if (type.is_string()) {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
if (retval.is_null()) if (@value@.is_null()) {
return JS::js_null(); @result_expression@ JS::js_null();
} else {
)~~~"); )~~~");
} else { } else {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
if (!retval) if (!@value@) {
return JS::js_null(); @result_expression@ JS::js_null();
} else {
)~~~"); )~~~");
} }
} }
if (return_type.is_string()) { if (type.is_string()) {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return JS::js_string(vm, retval); @result_expression@ JS::js_string(vm, @value@);
)~~~"); )~~~");
} else if (return_type.name == "ArrayFromVector") { } else if (type.name == "ArrayFromVector") {
// FIXME: Remove this fake type hack once it's no longer needed. // FIXME: Remove this fake type hack once it's no longer needed.
// Basically once we have NodeList we can throw this out. // Basically once we have NodeList we can throw this out.
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
auto* new_array = JS::Array::create(global_object, 0); auto* new_array = JS::Array::create(global_object, 0);
for (auto& element : retval) for (auto& element : @value@)
new_array->indexed_properties().append(wrap(global_object, element)); new_array->indexed_properties().append(wrap(global_object, element));
return new_array; @result_expression@ new_array;
)~~~"); )~~~");
} else if (return_type.name == "boolean" || return_type.name == "double") { } else if (type.name == "boolean" || type.name == "double") {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return JS::Value(retval); @result_expression@ JS::Value(@value@);
)~~~"); )~~~");
} else if (return_type.name == "short" || return_type.name == "unsigned short" || return_type.name == "long" || return_type.name == "unsigned long") { } else if (type.name == "short" || type.name == "unsigned short" || type.name == "long" || type.name == "unsigned long") {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return JS::Value((i32)retval); @result_expression@ JS::Value((i32)@value@);
)~~~"); )~~~");
} else if (return_type.name == "Uint8ClampedArray" || return_type.name == "any") { } else if (type.name == "Uint8ClampedArray" || type.name == "any") {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return retval; @result_expression@ @value@;
)~~~"); )~~~");
} else if (return_type.name == "EventHandler") { } else if (type.name == "EventHandler") {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
if (retval.callback.is_null()) if (@value@.callback.is_null())
return JS::js_null(); @result_expression@ JS::js_null();
else
return retval.callback.cell(); @result_expression@ @value@.callback.cell();
)~~~"); )~~~");
} else if (return_type.name == "Location") { } else if (type.name == "Location") {
// Location is special cased as it is already a JS::Object. // Location is special cased as it is already a JS::Object.
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return JS::Value(retval); @result_expression@ JS::Value(@value@);
)~~~"); )~~~");
} else { } else {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
return wrap(global_object, const_cast<@return_type@&>(*retval)); @result_expression@ wrap(global_object, const_cast<@type@&>(*@value@));
)~~~");
}
if (type.nullable) {
scoped_generator.append(R"~~~(
}
)~~~"); )~~~");
} }
} }
@ -1046,6 +1056,11 @@ enum class StaticFunction {
Yes, Yes,
}; };
static void generate_return_statement(SourceGenerator& generator, IDL::Type const& return_type)
{
return generate_wrap_statement(generator, "retval", return_type, "return"sv);
}
static void generate_function(SourceGenerator& generator, IDL::Function const& function, StaticFunction is_static_function, String const& class_name, String const& interface_fully_qualified_name) static void generate_function(SourceGenerator& generator, IDL::Function const& function, StaticFunction is_static_function, String const& class_name, String const& interface_fully_qualified_name)
{ {
auto function_generator = generator.fork(); auto function_generator = generator.fork();