Browse Source

Implement `Object.prototype.__defineSetter__` (#2109)

<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel neccesary.
--->

This Pull Request fixes part of https://github.com/boa-dev/boa/issues/2067.

It adds the legacy `Object.prototype.__defineSetter__` function.
pull/2111/head
Ngo Iok Ui (Wu Yu Wei) 3 years ago
parent
commit
0eb771d343
  1. 43
      boa_engine/src/builtins/object/mod.rs

43
boa_engine/src/builtins/object/mod.rs

@ -58,6 +58,7 @@ impl BuiltIn for Object {
.method(Self::value_of, "valueOf", 0) .method(Self::value_of, "valueOf", 0)
.method(Self::is_prototype_of, "isPrototypeOf", 1) .method(Self::is_prototype_of, "isPrototypeOf", 1)
.method(Self::legacy_define_getter, "__defineGetter__", 2) .method(Self::legacy_define_getter, "__defineGetter__", 2)
.method(Self::legacy_define_setter, "__defineSetter__", 2)
.static_method(Self::create, "create", 2) .static_method(Self::create, "create", 2)
.static_method(Self::set_prototype_of, "setPrototypeOf", 2) .static_method(Self::set_prototype_of, "setPrototypeOf", 2)
.static_method(Self::get_prototype_of, "getPrototypeOf", 1) .static_method(Self::get_prototype_of, "getPrototypeOf", 1)
@ -158,6 +159,48 @@ impl Object {
Ok(JsValue::undefined()) Ok(JsValue::undefined())
} }
/// `Object.prototype.__defineSetter__(prop, func)`
///
/// Binds an object's property to a function to be called when an attempt is made to set that property.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-object.prototype.__defineSetter__
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__
pub fn legacy_define_setter(
this: &JsValue,
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let setter = args.get_or_undefined(1);
// 1. Let O be ? ToObject(this value).
let obj = this.to_object(context)?;
// 2. If IsCallable(setter) is false, throw a TypeError exception.
if !setter.is_callable() {
return context
.throw_type_error("Object.prototype.__defineSetter__: Expecting function");
}
// 3. Let desc be PropertyDescriptor { [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: true }.
let desc = PropertyDescriptor::builder()
.set(setter)
.enumerable(true)
.configurable(true);
// 4. Let key be ? ToPropertyKey(P).
let key = args.get_or_undefined(0).to_property_key(context)?;
// 5. Perform ? DefinePropertyOrThrow(O, key, desc).
obj.define_property_or_throw(key, desc, context)?;
// 6. Return undefined.
Ok(JsValue::undefined())
}
/// `Object.create( proto, [propertiesObject] )` /// `Object.create( proto, [propertiesObject] )`
/// ///
/// Creates a new object from the provided prototype. /// Creates a new object from the provided prototype.

Loading…
Cancel
Save