From ad302410a0a78e899c05e54bd62f7c247c5a8110 Mon Sep 17 00:00:00 2001 From: nekevss Date: Thu, 21 Dec 2023 18:06:10 -0500 Subject: [PATCH] TemporalCalendar trace & general cleanup --- .../src/builtins/temporal/calendar/mod.rs | 52 +++++++++---------- .../src/builtins/temporal/calendar/object.rs | 3 +- .../builtins/temporal/zoned_date_time/mod.rs | 2 +- core/temporal/src/components/calendar.rs | 5 +- core/temporal/src/components/zoneddatetime.rs | 5 +- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/core/engine/src/builtins/temporal/calendar/mod.rs b/core/engine/src/builtins/temporal/calendar/mod.rs index 3c4e5e80ec4..c8618cd6b2d 100644 --- a/core/engine/src/builtins/temporal/calendar/mod.rs +++ b/core/engine/src/builtins/temporal/calendar/mod.rs @@ -21,7 +21,7 @@ use crate::{ string::{common::StaticJsStrings, utf16}, Context, JsArgs, JsData, JsNativeError, JsObject, JsResult, JsString, JsSymbol, JsValue, }; -use boa_gc::{Finalize, Trace}; +use boa_gc::{Finalize, Trace, custom_trace}; use boa_profiler::Profiler; use boa_temporal::{ components::calendar::{ @@ -38,15 +38,22 @@ pub(crate) use object::JsCustomCalendar; #[cfg(test)] mod tests; - /// The `Temporal.Calendar` object. -#[derive(Debug, Trace, Finalize, JsData)] -// SAFETY: `Calendar` doesn't contain traceable types. -#[boa_gc(unsafe_empty_trace)] +#[derive(Debug, Finalize, JsData)] pub struct Calendar { slot: CalendarSlot, } +unsafe impl Trace for Calendar { + custom_trace!(this, mark, { + match &this.slot { + CalendarSlot::Protocol(custom) => mark(custom), + // SAFETY: CalendarSlot::Builtin does not contain any JsValues for the gc to trace. + CalendarSlot::Builtin(_) => {} + } + }); +} + impl Calendar { pub(crate) fn new(slot: CalendarSlot) -> Self { Self { slot } @@ -1051,25 +1058,17 @@ pub(crate) fn to_temporal_calendar_slot_value( if let Some(calendar) = extract_from_temporal_type( calendar_like, |d| Ok(Some(d.inner.calendar().clone())), - |_dt| { - Err(JsNativeError::range() - .with_message("Not yet implemented.") - .into()) + |dt| { + Ok(Some(dt.inner.calendar().clone())) }, - |_ym| { - Err(JsNativeError::range() - .with_message("Not yet implemented.") - .into()) + |ym| { + Ok(Some(ym.inner.calendar().clone())) }, - |_md| { - Err(JsNativeError::range() - .with_message("Not yet implemented.") - .into()) + |md| { + Ok(Some(md.inner.calendar().clone())) }, - |_zdt| { - Err(JsNativeError::range() - .with_message("Not yet implemented.") - .into()) + |zdt| { + Ok(Some(zdt.inner.calendar().clone())) }, )? { return Ok(calendar); @@ -1084,23 +1083,22 @@ pub(crate) fn to_temporal_calendar_slot_value( } // Types: Box <- UserCalendar - let protocol = JsCustomCalendar::new(calendar_like); + let custom = JsCustomCalendar::new(calendar_like); // c. Return temporalCalendarLike. - return Ok(CalendarSlot::Protocol(protocol)); + return Ok(CalendarSlot::Protocol(custom)); } // 3. If temporalCalendarLike is not a String, throw a TypeError exception. - if !calendar_like.is_string() { + let JsValue::String(calendar_id) = calendar_like else { return Err(JsNativeError::typ() .with_message("temporalCalendarLike is not a string.") .into()); - } + }; - // TODO: 4-6 // 4. Let identifier be ? ParseTemporalCalendarString(temporalCalendarLike). // 5. If IsBuiltinCalendar(identifier) is false, throw a RangeError exception. // 6. Return the ASCII-lowercase of identifier. - Ok(CalendarSlot::default()) + Ok(CalendarSlot::::from_str(&calendar_id.to_std_string_escaped())?) } fn object_implements_calendar_protocol(calendar_like: &JsObject, context: &mut Context) -> bool { diff --git a/core/engine/src/builtins/temporal/calendar/object.rs b/core/engine/src/builtins/temporal/calendar/object.rs index 03dca4eb5ad..1ea24e905a4 100644 --- a/core/engine/src/builtins/temporal/calendar/object.rs +++ b/core/engine/src/builtins/temporal/calendar/object.rs @@ -22,6 +22,7 @@ use boa_temporal::{ options::ArithmeticOverflow, TemporalError, TemporalFields, TemporalResult, TinyAsciiStr, }; +use boa_gc::{Finalize, Trace}; use num_traits::ToPrimitive; use plain_date::PlainDate; use plain_month_day::PlainMonthDay; @@ -32,7 +33,7 @@ use plain_year_month::PlainYearMonth; /// /// A user-defined calendar implements all of the `CalendarProtocolMethods` /// and therefore satisfies the requirements to be used as a calendar. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Trace, Finalize)] pub(crate) struct JsCustomCalendar { calendar: JsObject, } diff --git a/core/engine/src/builtins/temporal/zoned_date_time/mod.rs b/core/engine/src/builtins/temporal/zoned_date_time/mod.rs index 10cba200be8..eab3c7b1e36 100644 --- a/core/engine/src/builtins/temporal/zoned_date_time/mod.rs +++ b/core/engine/src/builtins/temporal/zoned_date_time/mod.rs @@ -18,7 +18,7 @@ use super::JsCustomCalendar; // SAFETY: ZonedDateTime does not contain any traceable types. #[boa_gc(unsafe_empty_trace)] pub struct ZonedDateTime { - inner: InnerZdt, + pub(crate) inner: InnerZdt, } impl BuiltInObject for ZonedDateTime { diff --git a/core/temporal/src/components/calendar.rs b/core/temporal/src/components/calendar.rs index 6df7133ef69..00655d9bb07 100644 --- a/core/temporal/src/components/calendar.rs +++ b/core/temporal/src/components/calendar.rs @@ -294,6 +294,7 @@ impl FromStr for CalendarSlot { type Err = TemporalError; fn from_str(s: &str) -> Result { + // NOTE(nekesss): Catch the iso identifier here, as `iso8601` is not a valid ID below. if s == "iso8601" { return Ok(CalendarSlot::Builtin(AnyCalendar::Iso(Iso))); } @@ -815,11 +816,11 @@ impl CalendarSlot { } } -/// An empty `CalendarProtocol` impl that will panic if treated as a valid calendar. +/// An empty `CalendarProtocol` implementation on `()`. /// /// # Panics /// -/// Attempting to use this calendar as a valid calendar is an error and will cause a panic. +/// Attempting to use this empty calendar implementation as a valid calendar is an error and will cause a panic. impl CalendarProtocol for () { fn date_from_fields( &self, diff --git a/core/temporal/src/components/zoneddatetime.rs b/core/temporal/src/components/zoneddatetime.rs index baa90ed7337..b766e098101 100644 --- a/core/temporal/src/components/zoneddatetime.rs +++ b/core/temporal/src/components/zoneddatetime.rs @@ -54,9 +54,8 @@ impl ZonedDateTime { /// Returns the `ZonedDateTime`'s Calendar identifier. #[inline] #[must_use] - pub fn calendar_id(&self) -> String { - // TODO: Implement Identifier method on `CalendarSlot` - String::from("Not yet implemented.") + pub fn calendar(&self) -> &CalendarSlot { + &self.calendar } /// Returns the `epochSeconds` value of this `ZonedDateTime`.