Skip to content

Commit

Permalink
Initial implementation for Intl.DateTimeFormat
Browse files Browse the repository at this point in the history
  • Loading branch information
NorbertGarfield committed Apr 11, 2022
1 parent 34303f1 commit a68edde
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
114 changes: 114 additions & 0 deletions boa_engine/src/builtins/intl/date_time_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//! This module implements the global `Intl.DateTimeFormat` object.
//!
//! `Intl.DateTimeFormat` is a built-in object that has properties and methods for date and time i18n.
//!
//! More information:
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma402/#datetimeformat-objects
use crate::{
builtins::BuiltIn,
context::intrinsics::StandardConstructors,
object::internal_methods::get_prototype_from_constructor,
object::{JsObject, ObjectData, ObjectInitializer},
property::Attribute,
symbol::WellKnownSymbols,
Context, JsResult, JsValue,
};

use boa_gc::{Finalize, Trace};
use boa_profiler::Profiler;
use tap::{Conv, Pipe};

/// JavaScript `Intl.DateTimeFormat` object.
#[derive(Debug, Clone, Trace, Finalize)]
pub struct DateTimeFormat {
initialized_date_time_format: bool,
locale: String,
calendar: String,
numbering_system: String,
time_zone: String,
weekday: String,
era: String,
year: String,
month: String,
day: String,
day_period: String,
hour: String,
minute: String,
second: String,
fractional_second_digits: String,
time_zone_name: String,
hour_cycle: String,
pattern: String,
bound_format: String,
}

impl BuiltIn for DateTimeFormat {
const NAME: &'static str = "Intl.DateTimeFormat";

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

let string_tag = WellKnownSymbols::to_string_tag();
ObjectInitializer::new(context)
.property(
string_tag,
Self::NAME,
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.build()
.conv::<JsValue>()
.pipe(Some)
}
}

impl DateTimeFormat {
/// The `Intl.DateTimeFormat` constructor is the `%DateTimeFormat%` intrinsic object and a standard built-in property of the `Intl` object.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma402/#datetimeformat-objects
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
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.
let prototype = get_prototype_from_constructor(
new_target,
StandardConstructors::date_time_format,
context,
)?;
// 2. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%DateTimeFormat.prototype%", « [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[FractionalSecondDigits]], [[TimeZoneName]], [[HourCycle]], [[Pattern]], [[BoundFormat]] »).
let date_time_format = JsObject::from_proto_and_data(
prototype,
ObjectData::date_time_format(Box::new(Self {
initialized_date_time_format: true,
locale: "en-US".to_string(),
calendar: "gregory".to_string(),
numbering_system: "arab".to_string(),
time_zone: "UTC".to_string(),
weekday: "narrow".to_string(),
era: "narrow".to_string(),
year: "numeric".to_string(),
month: "narrow".to_string(),
day: "numeric".to_string(),
day_period: "narrow".to_string(),
hour: "numeric".to_string(),
minute: "numeric".to_string(),
second: "numeric".to_string(),
fractional_second_digits: "".to_string(),
time_zone_name: "".to_string(),
hour_cycle: "h24".to_string(),
pattern: "{hour}:{minute}".to_string(),
bound_format: "undefined".to_string(),
})),
);
Ok(JsValue::Object(date_time_format))
}
}
16 changes: 15 additions & 1 deletion boa_engine/src/builtins/intl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
//! [spec]: https://tc39.es/ecma402/#intl-object
use crate::{
builtins::intl::date_time_format::DateTimeFormat,
builtins::{Array, BuiltIn, JsArgs},
object::ObjectInitializer,
object::{FunctionBuilder, ObjectInitializer},
property::Attribute,
symbol::WellKnownSymbols,
Context, JsResult, JsString, JsValue,
};

pub mod date_time_format;

use boa_profiler::Profiler;
use indexmap::IndexSet;
use tap::{Conv, Pipe};
Expand All @@ -29,13 +33,23 @@ impl BuiltIn for Intl {
let _timer = Profiler::global().start_event(Self::NAME, "init");

let string_tag = WellKnownSymbols::to_string_tag();
let date_time_format = FunctionBuilder::native(context, DateTimeFormat::constructor)
.name("Intl.DateTimeFormat")
.length(0)
.constructor(true)
.build();
ObjectInitializer::new(context)
.function(Self::get_canonical_locales, "getCanonicalLocales", 1)
.property(
string_tag,
Self::NAME,
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
"DateTimeFormat",
date_time_format,
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.build()
.conv::<JsValue>()
.pipe(Some)
Expand Down
7 changes: 7 additions & 0 deletions boa_engine/src/context/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub struct StandardConstructors {
typed_float64_array: StandardConstructor,
array_buffer: StandardConstructor,
data_view: StandardConstructor,
date_time_format: StandardConstructor,
}

impl Default for StandardConstructors {
Expand Down Expand Up @@ -157,6 +158,7 @@ impl Default for StandardConstructors {
typed_float64_array: StandardConstructor::default(),
array_buffer: StandardConstructor::default(),
data_view: StandardConstructor::default(),
date_time_format: StandardConstructor::default(),
}
}
}
Expand Down Expand Up @@ -341,6 +343,11 @@ impl StandardConstructors {
pub fn data_view(&self) -> &StandardConstructor {
&self.data_view
}

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

/// Cached intrinsic objects
Expand Down
11 changes: 11 additions & 0 deletions boa_engine/src/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::{
arguments::ParameterMap, BoundFunction, Captures, Function, NativeFunctionSignature,
},
generator::Generator,
intl::date_time_format::DateTimeFormat,
map::map_iterator::MapIterator,
map::ordered_map::OrderedMap,
object::for_in_iterator::ForInIterator,
Expand Down Expand Up @@ -161,6 +162,7 @@ pub enum ObjectKind {
Arguments(Arguments),
NativeObject(Box<dyn NativeObject>),
IntegerIndexed(IntegerIndexed),
DateTimeFormat(Box<DateTimeFormat>),
}

impl ObjectData {
Expand Down Expand Up @@ -417,6 +419,14 @@ impl ObjectData {
internal_methods: &INTEGER_INDEXED_EXOTIC_INTERNAL_METHODS,
}
}

/// Create the `DateTimeFormat` object data
pub fn date_time_format(date_time_fmt: Box<DateTimeFormat>) -> Self {
Self {
kind: ObjectKind::DateTimeFormat(date_time_fmt),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
}

impl Display for ObjectKind {
Expand Down Expand Up @@ -451,6 +461,7 @@ impl Display for ObjectKind {
Self::NativeObject(_) => "NativeObject",
Self::IntegerIndexed(_) => "TypedArray",
Self::DataView(_) => "DataView",
Self::DateTimeFormat(_) => "DateTimeFormat",
})
}
}
Expand Down

0 comments on commit a68edde

Please sign in to comment.