use crate::{
builtins::{
iterable::iterable_to_list, Array, BuiltInBuilder, BuiltInConstructor, BuiltInObject,
IntrinsicObject,
},
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData},
property::{Attribute, PropertyDescriptorBuilder},
realm::Realm,
string::utf16,
Context, JsArgs, JsResult, JsValue,
};
use boa_profiler::Profiler;
use super::{Error, ErrorKind};
#[derive(Debug, Clone, Copy)]
pub(crate) struct AggregateError;
impl IntrinsicObject for AggregateError {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");
let attribute = Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE;
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.prototype(realm.intrinsics().constructors().error().constructor())
.inherits(Some(realm.intrinsics().constructors().error().prototype()))
.property(utf16!("name"), Self::NAME, attribute)
.property(utf16!("message"), "", attribute)
.build();
}
fn get(intrinsics: &Intrinsics) -> JsObject {
Self::STANDARD_CONSTRUCTOR(intrinsics.constructors()).constructor()
}
}
impl BuiltInObject for AggregateError {
const NAME: &'static str = "AggregateError";
}
impl BuiltInConstructor for AggregateError {
const LENGTH: usize = 2;
const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor =
StandardConstructors::aggregate_error;
fn constructor(
new_target: &JsValue,
args: &[JsValue],
context: &mut Context<'_>,
) -> JsResult<JsValue> {
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.unwrap_or_else(|| {
context
.intrinsics()
.constructors()
.aggregate_error()
.constructor()
})
.into()
} else {
new_target.clone()
};
let prototype = get_prototype_from_constructor(
new_target,
StandardConstructors::aggregate_error,
context,
)?;
let o = JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::error(ErrorKind::Aggregate),
);
let message = args.get_or_undefined(1);
if !message.is_undefined() {
let msg = message.to_string(context)?;
o.create_non_enumerable_data_property_or_throw(utf16!("message"), msg, context);
}
Error::install_error_cause(&o, args.get_or_undefined(2), context)?;
let errors = args.get_or_undefined(0);
let errors_list = iterable_to_list(context, errors, None)?;
o.define_property_or_throw(
utf16!("errors"),
PropertyDescriptorBuilder::new()
.configurable(true)
.enumerable(false)
.writable(true)
.value(Array::create_array_from_list(errors_list, context))
.build(),
context,
)
.expect("should not fail according to spec");
Ok(o.into())
}
}