Skip to content

Commit

Permalink
Transition Intl types to NativeObject API (#3491)
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 authored Dec 1, 2023
1 parent 9f181ef commit eb2f33e
Show file tree
Hide file tree
Showing 15 changed files with 117 additions and 322 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion boa_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ js = ["dep:web-time"]

[dependencies]
boa_interner.workspace = true
boa_gc = { workspace = true, features = [ "thinvec" ] }
boa_gc = { workspace = true, features = [ "thin-vec", "icu" ] }
boa_profiler.workspace = true
boa_macros.workspace = true
boa_ast.workspace = true
Expand Down
10 changes: 5 additions & 5 deletions boa_engine/src/builtins/intl/collator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ mod options;
pub(crate) use options::*;

#[derive(Debug)]
pub struct Collator {
pub(crate) struct Collator {
locale: Locale,
collation: Value,
numeric: bool,
Expand Down Expand Up @@ -350,7 +350,7 @@ impl BuiltInConstructor for Collator {
let collator = JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::collator(Self {
ObjectData::native_object(Self {
locale,
collation,
numeric,
Expand Down Expand Up @@ -414,7 +414,7 @@ impl Collator {
})?;
let collator_obj = this.clone();
let mut collator = this.borrow_mut();
let collator = collator.as_collator_mut().ok_or_else(|| {
let collator = collator.downcast_mut::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`resolvedOptions` can only be called on a `Collator` object")
})?;
Expand All @@ -436,7 +436,7 @@ impl Collator {
// 2. Assert: Type(collator) is Object and collator has an [[InitializedCollator]] internal slot.
let collator = collator.borrow();
let collator = collator
.as_collator()
.downcast_ref::<Self>()
.expect("checked above that the object was a collator object");

// 3. If x is not provided, let x be undefined.
Expand Down Expand Up @@ -483,7 +483,7 @@ impl Collator {
JsNativeError::typ()
.with_message("`resolvedOptions` can only be called on a `Collator` object")
})?;
let collator = collator.as_collator().ok_or_else(|| {
let collator = collator.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`resolvedOptions` can only be called on a `Collator` object")
})?;
Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/builtins/intl/date_time_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl OptionType for HourCycle {

/// JavaScript `Intl.DateTimeFormat` object.
#[derive(Debug, Clone, Trace, Finalize)]
pub struct DateTimeFormat {
pub(crate) struct DateTimeFormat {
initialized_date_time_format: bool,
locale: JsString,
calendar: JsString,
Expand Down Expand Up @@ -123,7 +123,7 @@ impl BuiltInConstructor for DateTimeFormat {
let date_time_format = JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::date_time_format(Box::new(Self {
ObjectData::native_object(Self {
initialized_date_time_format: true,
locale: js_string!("en-US"),
calendar: js_string!("gregory"),
Expand All @@ -143,7 +143,7 @@ impl BuiltInConstructor for DateTimeFormat {
hour_cycle: js_string!("h24"),
pattern: js_string!("{hour}:{minute}"),
bound_format: js_string!("undefined"),
})),
}),
);

// TODO 3. Perform ? InitializeDateTimeFormat(dateTimeFormat, locales, options).
Expand Down
18 changes: 12 additions & 6 deletions boa_engine/src/builtins/intl/list_format/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fmt::Write;

use boa_gc::{empty_trace, Finalize, Trace};
use boa_profiler::Profiler;
use icu_list::{provider::AndListV1Marker, ListFormatter, ListLength};
use icu_locid::Locale;
Expand Down Expand Up @@ -29,14 +30,19 @@ use super::{
mod options;
pub(crate) use options::*;

#[derive(Debug)]
pub struct ListFormat {
#[derive(Debug, Finalize)]
pub(crate) struct ListFormat {
locale: Locale,
typ: ListFormatType,
style: ListLength,
native: ListFormatter,
}

// SAFETY: `ListFormat` doesn't contain traceable data.
unsafe impl Trace for ListFormat {
empty_trace!();
}

impl Service for ListFormat {
type LangMarker = AndListV1Marker;

Expand Down Expand Up @@ -164,7 +170,7 @@ impl BuiltInConstructor for ListFormat {
let list_format = JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::list_format(Self {
ObjectData::native_object(Self {
locale,
typ,
style,
Expand Down Expand Up @@ -221,7 +227,7 @@ impl ListFormat {
JsNativeError::typ()
.with_message("`format` can only be called on a `ListFormat` object")
})?;
let lf = lf.as_list_format().ok_or_else(|| {
let lf = lf.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`format` can only be called on a `ListFormat` object")
})?;
Expand Down Expand Up @@ -339,7 +345,7 @@ impl ListFormat {
JsNativeError::typ()
.with_message("`formatToParts` can only be called on a `ListFormat` object")
})?;
let lf = lf.as_list_format().ok_or_else(|| {
let lf = lf.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`formatToParts` can only be called on a `ListFormat` object")
})?;
Expand Down Expand Up @@ -413,7 +419,7 @@ impl ListFormat {
JsNativeError::typ()
.with_message("`resolvedOptions` can only be called on a `ListFormat` object")
})?;
let lf = lf.as_list_format().ok_or_else(|| {
let lf = lf.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`resolvedOptions` can only be called on a `ListFormat` object")
})?;
Expand Down
34 changes: 17 additions & 17 deletions boa_engine/src/builtins/intl/locale/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl BuiltInConstructor for Locale {

let mut tag = if let Some(tag) = tag
.as_object()
.and_then(|obj| obj.borrow().as_locale().cloned())
.and_then(|obj| obj.borrow().downcast_ref::<icu_locid::Locale>().cloned())
{
// a. Let tag be tag.[[Locale]].
tag
Expand Down Expand Up @@ -371,7 +371,7 @@ impl BuiltInConstructor for Locale {
let locale = JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::locale(tag),
ObjectData::native_object(tag),
);

// 37. Return locale.
Expand All @@ -398,7 +398,7 @@ impl Locale {
JsNativeError::typ().with_message("`maximize` can only be called on a `Locale` object")
})?;
let mut loc = loc
.as_locale()
.downcast_ref::<icu_locid::Locale>()
.ok_or_else(|| {
JsNativeError::typ()
.with_message("`maximize` can only be called on a `Locale` object")
Expand All @@ -413,7 +413,7 @@ impl Locale {
Ok(JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::locale(loc),
ObjectData::native_object(loc),
)
.into())
}
Expand All @@ -436,7 +436,7 @@ impl Locale {
JsNativeError::typ().with_message("`minimize` can only be called on a `Locale` object")
})?;
let mut loc = loc
.as_locale()
.downcast_ref::<icu_locid::Locale>()
.ok_or_else(|| {
JsNativeError::typ()
.with_message("`minimize` can only be called on a `Locale` object")
Expand All @@ -451,7 +451,7 @@ impl Locale {
Ok(JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
prototype,
ObjectData::locale(loc),
ObjectData::native_object(loc),
)
.into())
}
Expand All @@ -469,7 +469,7 @@ impl Locale {
let loc = this.as_object().map(JsObject::borrow).ok_or_else(|| {
JsNativeError::typ().with_message("`toString` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ().with_message("`toString` can only be called on a `Locale` object")
})?;

Expand All @@ -491,7 +491,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get baseName` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get baseName` can only be called on a `Locale` object")
})?;
Expand All @@ -515,7 +515,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get calendar` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get calendar` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -544,7 +544,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get caseFirst` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get caseFirst` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -573,7 +573,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get collation` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get collation` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -602,7 +602,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get hourCycle` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get hourCycle` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -631,7 +631,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get numeric` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get numeric` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -668,7 +668,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get numberingSystem` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get numberingSystem` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -697,7 +697,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get language` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get language` can only be called on a `Locale` object")
})?;
Expand All @@ -722,7 +722,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get script` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get script` can only be called on a `Locale` object")
})?;
Expand Down Expand Up @@ -752,7 +752,7 @@ impl Locale {
JsNativeError::typ()
.with_message("`get region` can only be called on a `Locale` object")
})?;
let loc = loc.as_locale().ok_or_else(|| {
let loc = loc.downcast_ref::<icu_locid::Locale>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`get region` can only be called on a `Locale` object")
})?;
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/intl/locale/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub(crate) fn canonicalize_locale_list(
let o = if locales.is_string()
|| locales
.as_object()
.map_or(false, |o| o.borrow().is_locale())
.map_or(false, |o| o.borrow().is::<Locale>())
{
// a. Let O be CreateArrayFromList(« locales »).
Array::create_array_from_list([locales.clone()], context)
Expand Down Expand Up @@ -113,7 +113,7 @@ pub(crate) fn canonicalize_locale_list(
// iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
let mut tag = if let Some(tag) = k_value
.as_object()
.and_then(|obj| obj.borrow().as_locale().cloned())
.and_then(|obj| obj.borrow().downcast_ref::<Locale>().cloned())
{
// 1. Let tag be kValue.[[Locale]].
tag
Expand Down
18 changes: 12 additions & 6 deletions boa_engine/src/builtins/intl/plural_rules/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod options;

use boa_gc::{empty_trace, Finalize, Trace};
use boa_macros::utf16;
use boa_profiler::Profiler;
use fixed_decimal::FixedDecimal;
Expand Down Expand Up @@ -34,14 +35,19 @@ use super::{
Service,
};

#[derive(Debug)]
pub struct PluralRules {
#[derive(Debug, Finalize)]
pub(crate) struct PluralRules {
locale: Locale,
native: PluralRulesWithRanges<NativePluralRules>,
rule_type: PluralRuleType,
format_options: DigitFormatOptions,
}

// SAFETY: `PluralRules` doesn't contain any traceable data.
unsafe impl Trace for PluralRules {
empty_trace!();
}

impl Service for PluralRules {
type LangMarker = CardinalV1Marker;

Expand Down Expand Up @@ -164,7 +170,7 @@ impl BuiltInConstructor for PluralRules {
Ok(JsObject::from_proto_and_data_with_shared_shape(
context.root_shape(),
proto,
ObjectData::plural_rules(Self {
ObjectData::native_object(Self {
locale,
native,
rule_type,
Expand Down Expand Up @@ -192,7 +198,7 @@ impl PluralRules {
JsNativeError::typ()
.with_message("`select` can only be called on an `Intl.PluralRules` object")
})?;
let plural_rules = plural_rules.as_plural_rules().ok_or_else(|| {
let plural_rules = plural_rules.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`select` can only be called on an `Intl.PluralRules` object")
})?;
Expand All @@ -219,7 +225,7 @@ impl PluralRules {
JsNativeError::typ()
.with_message("`select_range` can only be called on an `Intl.PluralRules` object")
})?;
let plural_rules = plural_rules.as_plural_rules().ok_or_else(|| {
let plural_rules = plural_rules.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ()
.with_message("`select_range` can only be called on an `Intl.PluralRules` object")
})?;
Expand Down Expand Up @@ -314,7 +320,7 @@ impl PluralRules {
"`resolved_options` can only be called on an `Intl.PluralRules` object",
)
})?;
let plural_rules = plural_rules.as_plural_rules().ok_or_else(|| {
let plural_rules = plural_rules.downcast_ref::<Self>().ok_or_else(|| {
JsNativeError::typ().with_message(
"`resolved_options` can only be called on an `Intl.PluralRules` object",
)
Expand Down
Loading

0 comments on commit eb2f33e

Please sign in to comment.