LibWeb/Bindings: Generate undefined in a union as 'Empty'

This can only ever be undefined, and no other JS value, so it makes
sense to use undefined to represent this case.
This commit is contained in:
Shannon Booth 2025-01-12 22:50:03 +13:00 committed by Tim Ledbetter
commit dfdcfc8e88
Notes: github-actions[bot] 2025-01-12 18:40:27 +00:00
5 changed files with 13 additions and 7 deletions

View file

@ -326,7 +326,7 @@ JS::ThrowCompletionOr<void> CustomElementRegistry::define(String const& name, We
}
// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get
Variant<GC::Root<WebIDL::CallbackType>, JS::Value> CustomElementRegistry::get(String const& name) const
Variant<GC::Root<WebIDL::CallbackType>, Empty> CustomElementRegistry::get(String const& name) const
{
// 1. If this's custom element definition set contains an item with name name, then return that item's constructor.
auto existing_definition_iterator = m_custom_element_definitions.find_if([&name](auto const& definition) {
@ -337,7 +337,7 @@ Variant<GC::Root<WebIDL::CallbackType>, JS::Value> CustomElementRegistry::get(St
return GC::make_root((*existing_definition_iterator)->constructor());
// 2. Return undefined.
return JS::js_undefined();
return Empty {};
}
// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-getname

View file

@ -25,7 +25,7 @@ public:
virtual ~CustomElementRegistry() override;
JS::ThrowCompletionOr<void> define(String const& name, WebIDL::CallbackType* constructor, ElementDefinitionOptions options);
Variant<GC::Root<WebIDL::CallbackType>, JS::Value> get(String const& name) const;
Variant<GC::Root<WebIDL::CallbackType>, Empty> get(String const& name) const;
Optional<String> get_name(GC::Root<WebIDL::CallbackType> const& constructor) const;
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> when_defined(String const& name);
void upgrade(GC::Ref<DOM::Node> root) const;

View file

@ -1199,12 +1199,12 @@ WebIDL::ExceptionOr<void> Window::post_message(JS::Value message, String const&
}
// https://dom.spec.whatwg.org/#dom-window-event
Variant<GC::Root<DOM::Event>, JS::Value> Window::event() const
Variant<GC::Root<DOM::Event>, Empty> Window::event() const
{
// The event getter steps are to return thiss current event.
if (auto* current_event = this->current_event())
return make_root(const_cast<DOM::Event&>(*current_event));
return JS::js_undefined();
return Empty {};
}
// https://w3c.github.io/csswg-drafts/cssom/#dom-window-getcomputedstyle

View file

@ -196,7 +196,7 @@ public:
WebIDL::ExceptionOr<void> post_message(JS::Value message, String const&, Vector<GC::Root<JS::Object>> const&);
WebIDL::ExceptionOr<void> post_message(JS::Value message, WindowPostMessageOptions const&);
Variant<GC::Root<DOM::Event>, JS::Value> event() const;
Variant<GC::Root<DOM::Event>, Empty> event() const;
[[nodiscard]] GC::Ref<CSS::CSSStyleDeclaration> get_computed_style(DOM::Element&, Optional<String> const& pseudo_element) const;

View file

@ -231,9 +231,15 @@ CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface)
if (type.name() == "long" && !type.is_nullable())
return { .name = "WebIDL::Long", .sequence_storage_type = SequenceStorageType::Vector };
if (type.name() == "any" || type.name() == "undefined")
if (type.name() == "any")
return { .name = "JS::Value", .sequence_storage_type = SequenceStorageType::RootVector };
// NOTE: undefined is a somewhat special case that may be used in a union to represent the javascript 'undefined' (and
// only ever js_undefined). Therefore, we say that the type is Empty here, so that a union of (T, undefined) is
// generated as Variant<T, Empty>, which is then returned in the Variant's visit as undefined if it is Empty.
if (type.name() == "undefined")
return { .name = "Empty", .sequence_storage_type = SequenceStorageType::RootVector };
if (type.name() == "object")
return { .name = "GC::Root<JS::Object>", .sequence_storage_type = SequenceStorageType::Vector };