Skip to content

Commit

Permalink
Implement AggregateError
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Mar 3, 2022
1 parent fb8c5cf commit 897bee9
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 1 deletion.
114 changes: 114 additions & 0 deletions boa_engine/src/builtins/error/aggregate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//! This module implements the global `AggregateError` object.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma262/#sec-aggregate-error
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError

use crate::{
builtins::{iterable::iterable_to_list, Array, BuiltIn, JsArgs},
context::StandardObjects,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, JsObject, ObjectData,
},
property::{Attribute, PropertyDescriptorBuilder},
Context, JsResult, JsValue,
};
use boa_profiler::Profiler;

use super::Error;

#[derive(Debug, Clone, Copy)]
pub(crate) struct AggregateError;

impl BuiltIn for AggregateError {
const NAME: &'static str = "AggregateError";

const ATTRIBUTE: Attribute = Attribute::WRITABLE
.union(Attribute::NON_ENUMERABLE)
.union(Attribute::CONFIGURABLE);

fn init(context: &mut Context) -> JsValue {
let _timer = Profiler::global().start_event(Self::NAME, "init");

let error_constructor = context.standard_objects().error_object().constructor();
let error_prototype = context.standard_objects().error_object().prototype();

let attribute = Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE;
let aggregate_error_object = ConstructorBuilder::with_standard_object(
context,
Self::constructor,
context.standard_objects().aggregate_error_object().clone(),
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype)
.custom_prototype(error_constructor)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();

aggregate_error_object.into()
}
}

impl AggregateError {
/// The amount of arguments this function object takes.
pub(crate) const LENGTH: usize = 1;

/// Create a new aggregate error object.
pub(crate) fn constructor(
new_target: &JsValue,
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
// 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%AggregateError.prototype%", « [[ErrorData]] »).
let prototype = get_prototype_from_constructor(
new_target,
StandardObjects::aggregate_error_object,
context,
)?;
let o = JsObject::from_proto_and_data(prototype, ObjectData::error());

// 3. If message is not undefined, then
let message = args.get_or_undefined(1);
if !message.is_undefined() {
// a. Let msg be ? ToString(message).
let msg = message.to_string(context)?;

// b. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
o.create_non_enumerable_data_property_or_throw("message", msg, context);
}

// 4. Perform ? InstallErrorCause(O, options).
Error::install_error_cause(&o, args.get_or_undefined(2), context)?;

// 5. Let errorsList be ? IterableToList(errors).
let errors = args.get_or_undefined(0);
let errors_list = iterable_to_list(context, errors, None)?;
// 6. Perform ! DefinePropertyOrThrow(O, "errors",
// PropertyDescriptor {
// [[Configurable]]: true,
// [[Enumerable]]: false,
// [[Writable]]: true,
// [[Value]]: CreateArrayFromList(errorsList)
// }).
o.define_property_or_throw(
"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");

// 5. Return O.
Ok(o.into())
}
}
2 changes: 2 additions & 0 deletions boa_engine/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
};
use boa_profiler::Profiler;

pub(crate) mod aggregate;
pub(crate) mod eval;
pub(crate) mod range;
pub(crate) mod reference;
Expand All @@ -31,6 +32,7 @@ pub(crate) mod uri;
#[cfg(test)]
mod tests;

pub(crate) use self::aggregate::AggregateError;
pub(crate) use self::eval::EvalError;
pub(crate) use self::r#type::TypeError;
pub(crate) use self::range::RangeError;
Expand Down
6 changes: 5 additions & 1 deletion boa_engine/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ pub(crate) use self::{
boolean::Boolean,
dataview::DataView,
date::Date,
error::{Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, UriError},
error::{
AggregateError, Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError,
UriError,
},
function::BuiltInFunctionObject,
global_this::GlobalThis,
infinity::Infinity,
Expand Down Expand Up @@ -163,6 +166,7 @@ pub fn init(context: &mut Context) {
SyntaxError,
EvalError,
UriError,
AggregateError,
Reflect
};

Expand Down
7 changes: 7 additions & 0 deletions boa_engine/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub struct StandardObjects {
syntax_error: StandardConstructor,
eval_error: StandardConstructor,
uri_error: StandardConstructor,
aggregate_error: StandardConstructor,
map: StandardConstructor,
set: StandardConstructor,
typed_array: StandardConstructor,
Expand Down Expand Up @@ -134,6 +135,7 @@ impl Default for StandardObjects {
syntax_error: StandardConstructor::default(),
eval_error: StandardConstructor::default(),
uri_error: StandardConstructor::default(),
aggregate_error: StandardConstructor::default(),
map: StandardConstructor::default(),
set: StandardConstructor::default(),
typed_array: StandardConstructor::default(),
Expand Down Expand Up @@ -250,6 +252,11 @@ impl StandardObjects {
&self.uri_error
}

#[inline]
pub fn aggregate_error_object(&self) -> &StandardConstructor {
&self.aggregate_error
}

#[inline]
pub fn map_object(&self) -> &StandardConstructor {
&self.map
Expand Down

0 comments on commit 897bee9

Please sign in to comment.