|
@@ -2643,6 +2643,33 @@ static void generate_prototype_or_global_mixin_declarations(IDL::Interface const
|
|
|
)~~~");
|
|
|
}
|
|
|
|
|
|
+ if (interface.set_entry_type.has_value()) {
|
|
|
+ auto setlike_generator = generator.fork();
|
|
|
+
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(get_size);
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(entries);
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(values);
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(for_each);
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(has);
|
|
|
+)~~~");
|
|
|
+ if (!interface.overload_sets.contains("add"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(add);
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ if (!interface.overload_sets.contains("delete"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(delete_);
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ if (!interface.overload_sets.contains("clear"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ JS_DECLARE_NATIVE_FUNCTION(clear);
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
for (auto& attribute : interface.attributes) {
|
|
|
auto attribute_generator = generator.fork();
|
|
|
attribute_generator.set("attribute.name:snakecase", attribute.name.to_snakecase());
|
|
@@ -3172,6 +3199,39 @@ void @class_name@::initialize(JS::Realm& realm)
|
|
|
)~~~");
|
|
|
}
|
|
|
|
|
|
+ // https://webidl.spec.whatwg.org/#js-setlike
|
|
|
+ if (interface.set_entry_type.has_value()) {
|
|
|
+
|
|
|
+ auto setlike_generator = generator.fork();
|
|
|
+
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ define_native_accessor(realm, vm.names.size, get_size, nullptr, JS::Attribute::Enumerable | JS::Attribute::Configurable);
|
|
|
+ define_native_function(realm, vm.names.entries, entries, 0, default_attributes);
|
|
|
+ // NOTE: Keys intentionally returns values for setlike
|
|
|
+ define_native_function(realm, vm.names.keys, values, 0, default_attributes);
|
|
|
+ define_native_function(realm, vm.names.values, values, 0, default_attributes);
|
|
|
+ define_direct_property(vm.well_known_symbol_iterator(), get_without_side_effects(vm.names.values), JS::Attribute::Configurable | JS::Attribute::Writable);
|
|
|
+ define_native_function(realm, vm.names.forEach, for_each, 1, default_attributes);
|
|
|
+ define_native_function(realm, vm.names.has, has, 1, default_attributes);
|
|
|
+)~~~");
|
|
|
+
|
|
|
+ if (!interface.overload_sets.contains("add"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ define_native_function(realm, vm.names.add, add, 1, default_attributes);
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ if (!interface.overload_sets.contains("delete"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ define_native_function(realm, vm.names.delete_, delete_, 1, default_attributes);
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ if (!interface.overload_sets.contains("clear"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+ define_native_function(realm, vm.names.clear, clear, 0, default_attributes);
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (interface.has_unscopable_member) {
|
|
|
generator.append(R"~~~(
|
|
|
define_direct_property(vm.well_known_symbol_unscopables(), unscopable_object, JS::Attribute::Configurable);
|
|
@@ -3771,6 +3831,149 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::values)
|
|
|
}
|
|
|
)~~~");
|
|
|
}
|
|
|
+
|
|
|
+ if (interface.set_entry_type.has_value()) {
|
|
|
+ auto setlike_generator = generator.fork();
|
|
|
+ setlike_generator.set("value_type", interface.set_entry_type.value()->name());
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-size
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::get_size)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::size");
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ return set->set_size();
|
|
|
+}
|
|
|
+
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-entries
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::entries)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::entries");
|
|
|
+ auto& realm = *vm.current_realm();
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ return TRY(throw_dom_exception_if_needed(vm, [&] { return JS::SetIterator::create(realm, *set, Object::PropertyKind::KeyAndValue); }));
|
|
|
+}
|
|
|
+
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-values
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::values)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::values");
|
|
|
+ auto& realm = *vm.current_realm();
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ return TRY(throw_dom_exception_if_needed(vm, [&] { return JS::SetIterator::create(realm, *set, Object::PropertyKind::Value); }));
|
|
|
+}
|
|
|
+
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-forEach
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::for_each)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::for_each");
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ auto callback = vm.argument(0);
|
|
|
+ if (!callback.is_function())
|
|
|
+ return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
|
|
+
|
|
|
+ for (auto& entry : *set) {
|
|
|
+ auto value = entry.key;
|
|
|
+ TRY(call(vm, callback.as_function(), vm.argument(1), value, value, impl));
|
|
|
+ }
|
|
|
+
|
|
|
+ return JS::js_undefined();
|
|
|
+}
|
|
|
+
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-has
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::has)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::has");
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ auto value_arg = vm.argument(0);
|
|
|
+ if (!value_arg.is_object() && !is<@value_type@>(value_arg.as_object())) {
|
|
|
+ return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@value_type@");
|
|
|
+ }
|
|
|
+
|
|
|
+ // FIXME: If value is -0, set value to +0.
|
|
|
+ // What? Which interfaces have a number as their set type?
|
|
|
+
|
|
|
+ return set->set_has(value_arg);
|
|
|
+}
|
|
|
+)~~~");
|
|
|
+
|
|
|
+ if (!interface.overload_sets.contains("add"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-add
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::add)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::add");
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ auto value_arg = vm.argument(0);
|
|
|
+ if (!value_arg.is_object() && !is<@value_type@>(value_arg.as_object())) {
|
|
|
+ return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@value_type@");
|
|
|
+ }
|
|
|
+
|
|
|
+ // FIXME: If value is -0, set value to +0.
|
|
|
+ // What? Which interfaces have a number as their set type?
|
|
|
+
|
|
|
+ set->set_add(value_arg);
|
|
|
+
|
|
|
+ return impl;
|
|
|
+}
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ if (!interface.overload_sets.contains("delete"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-delete
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::delete_)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::delete_");
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ auto value_arg = vm.argument(0);
|
|
|
+ if (!value_arg.is_object() && !is<@value_type@>(value_arg.as_object())) {
|
|
|
+ return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@value_type@");
|
|
|
+ }
|
|
|
+
|
|
|
+ // FIXME: If value is -0, set value to +0.
|
|
|
+ // What? Which interfaces have a number as their set type?
|
|
|
+
|
|
|
+ return set->set_remove(value_arg);
|
|
|
+}
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ if (!interface.overload_sets.contains("clear"sv) && !interface.is_set_readonly) {
|
|
|
+ setlike_generator.append(R"~~~(
|
|
|
+// https://webidl.spec.whatwg.org/#js-set-clear
|
|
|
+JS_DEFINE_NATIVE_FUNCTION(@class_name@::clear)
|
|
|
+{
|
|
|
+ WebIDL::log_trace(vm, "@class_name@::clear");
|
|
|
+ auto* impl = TRY(impl_from(vm));
|
|
|
+
|
|
|
+ JS::NonnullGCPtr<JS::Set> set = impl->set_entries();
|
|
|
+
|
|
|
+ set->set_clear();
|
|
|
+
|
|
|
+ return JS::js_undefined();
|
|
|
+}
|
|
|
+)~~~");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void generate_namespace_header(IDL::Interface const& interface, StringBuilder& builder)
|