mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 18:37:36 +00:00
LibWeb: Don't always assign values to nullable IDL dictionary members
IDL dictionary members are nullable by default (unless marked as `required`) and should not get any value assigned unless one was provided by the userland code that isn't undefined, or if the member has a default value. This is so that we can use Optional<T> in the internal representation and check for "is present" via Optional::has_value().
This commit is contained in:
parent
d38f1fb5b2
commit
b9d626d6b2
1 changed files with 22 additions and 10 deletions
|
@ -631,28 +631,40 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
for (auto& member : current_dictionary->members) {
|
for (auto& member : current_dictionary->members) {
|
||||||
dictionary_generator.set("member_key", member.name);
|
dictionary_generator.set("member_key", member.name);
|
||||||
auto member_js_name = make_input_acceptable_cpp(member.name.to_snakecase());
|
auto member_js_name = make_input_acceptable_cpp(member.name.to_snakecase());
|
||||||
|
auto member_value_name = String::formatted("{}_value", member_js_name);
|
||||||
|
auto member_property_value_name = String::formatted("{}_property_value", member_js_name);
|
||||||
dictionary_generator.set("member_name", member_js_name);
|
dictionary_generator.set("member_name", member_js_name);
|
||||||
|
dictionary_generator.set("member_value_name", member_value_name);
|
||||||
|
dictionary_generator.set("member_property_value_name", member_property_value_name);
|
||||||
dictionary_generator.append(R"~~~(
|
dictionary_generator.append(R"~~~(
|
||||||
JS::Value @member_name@;
|
auto @member_property_value_name@ = JS::js_undefined();
|
||||||
if (@js_name@@js_suffix@.is_nullish()) {
|
if (@js_name@@js_suffix@.is_object())
|
||||||
@member_name@ = JS::js_undefined();
|
@member_property_value_name@ = TRY(@js_name@@js_suffix@.as_object().get("@member_key@"));
|
||||||
} else {
|
|
||||||
@member_name@ = TRY(@js_name@@js_suffix@.as_object().get("@member_key@"));
|
|
||||||
}
|
|
||||||
)~~~");
|
)~~~");
|
||||||
if (member.required) {
|
if (member.required) {
|
||||||
dictionary_generator.append(R"~~~(
|
dictionary_generator.append(R"~~~(
|
||||||
if (@member_name@.is_undefined())
|
if (@member_property_value_name@.is_undefined())
|
||||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::MissingRequiredProperty, "@member_key@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::MissingRequiredProperty, "@member_key@");
|
||||||
|
)~~~");
|
||||||
|
} else if (!member.default_value.has_value()) {
|
||||||
|
// Assume struct member is Optional<T> and _don't_ assign the generated default
|
||||||
|
// value (e.g. first enum member) when the dictionary member is optional (i.e.
|
||||||
|
// no `required` and doesn't have a default value).
|
||||||
|
// This is needed so that "dictionary has member" checks work as expected.
|
||||||
|
dictionary_generator.append(R"~~~(
|
||||||
|
if (!@member_property_value_name@.is_undefined()) {
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto member_value_name = String::formatted("{}_value", member_js_name);
|
generate_to_cpp(dictionary_generator, member, member_property_value_name, "", member_value_name, interface, member.extended_attributes.contains("LegacyNullToEmptyString"), !member.required, member.default_value);
|
||||||
dictionary_generator.set("member_value_name", member_value_name);
|
|
||||||
generate_to_cpp(dictionary_generator, member, member_js_name, "", member_value_name, interface, member.extended_attributes.contains("LegacyNullToEmptyString"), !member.required, member.default_value);
|
|
||||||
dictionary_generator.append(R"~~~(
|
dictionary_generator.append(R"~~~(
|
||||||
@cpp_name@.@member_name@ = @member_value_name@;
|
@cpp_name@.@member_name@ = @member_value_name@;
|
||||||
)~~~");
|
)~~~");
|
||||||
|
if (!member.required && !member.default_value.has_value()) {
|
||||||
|
dictionary_generator.append(R"~~~(
|
||||||
|
}
|
||||||
|
)~~~");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (current_dictionary->parent_name.is_null())
|
if (current_dictionary->parent_name.is_null())
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue