Skip to content

Commit 0d068db

Browse files
0Zenoaapoalas
andauthored
feat(ecmascript): PlainTime.prototype.toLocaleString (#987)
* fix(ecmascript): PlainTime constructor arguments * chore(test262): Update expectations --------- Co-authored-by: Aapo Alasuutari <aapo.alasuutari@gmail.com>
1 parent 9bf44d2 commit 0d068db

4 files changed

Lines changed: 58 additions & 92 deletions

File tree

nova_vm/src/ecmascript/builtins/temporal/plain_time/plain_time_constructor.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,20 @@ impl BuiltinIntrinsicConstructor for TemporalPlainTimeConstructor {
2626
}
2727

2828
impl TemporalPlainTimeConstructor {
29-
/// ### [4.1.1 Temporal.PlainTime](https://tc39.es/proposal-temporal/#sec-temporal.plaintime)
29+
/// ### [4.1.1 Temporal.PlainTime ( [ hour [ , minute [ , second [ , millisecond [ , microsecond [ , nanosecond ] ] ] ] ] ] )](https://tc39.es/proposal-temporal/#sec-temporal.plaintime)
3030
fn constructor<'gc>(
3131
agent: &mut Agent,
3232
_: Value,
3333
args: ArgumentsList,
3434
new_target: Option<Object>,
3535
mut gc: GcScope<'gc, '_>,
3636
) -> JsResult<'gc, Value<'gc>> {
37-
let hours = args.get(1).scope(agent, gc.nogc());
38-
let minutes = args.get(2).scope(agent, gc.nogc());
39-
let seconds = args.get(3).scope(agent, gc.nogc());
40-
let milliseconds = args.get(4).scope(agent, gc.nogc());
41-
let microseconds = args.get(5).scope(agent, gc.nogc());
42-
let nanoseconds = args.get(6).scope(agent, gc.nogc());
37+
let hour = args.get(0).scope(agent, gc.nogc());
38+
let minute = args.get(1).scope(agent, gc.nogc());
39+
let second = args.get(2).scope(agent, gc.nogc());
40+
let millisecond = args.get(3).scope(agent, gc.nogc());
41+
let microsecond = args.get(4).scope(agent, gc.nogc());
42+
let nanosecond = args.get(5).scope(agent, gc.nogc());
4343

4444
let new_target = new_target.bind(gc.nogc());
4545

@@ -58,64 +58,63 @@ impl TemporalPlainTimeConstructor {
5858
let new_target = new_target.scope(agent, gc.nogc());
5959

6060
// 2. If hour is undefined, set hour to 0; else set hour to ? ToIntegerWithTruncation(hour).
61-
let hour = if hours.get(agent).is_undefined() {
61+
let hour = if hour.get(agent).is_undefined() {
6262
0
6363
} else {
6464
u8::try_from(
65-
to_integer_with_truncation(agent, hours.get(agent), gc.reborrow()).unbind()?,
65+
to_integer_with_truncation(agent, hour.get(agent), gc.reborrow()).unbind()?,
6666
)
6767
.unwrap_or(u8::MAX)
6868
};
6969

7070
// 3. If minute is undefined, set minute to 0; else set minute to ? ToIntegerWithTruncation(minute).
71-
let minute = if minutes.get(agent).is_undefined() {
71+
let minute = if minute.get(agent).is_undefined() {
7272
0
7373
} else {
7474
u8::try_from(
75-
to_integer_with_truncation(agent, minutes.get(agent), gc.reborrow()).unbind()?,
75+
to_integer_with_truncation(agent, minute.get(agent), gc.reborrow()).unbind()?,
7676
)
7777
.unwrap_or(u8::MAX)
7878
};
7979

8080
// 4. If second is undefined, set second to 0; else set second to ? ToIntegerWithTruncation(second).
81-
let second = if seconds.get(agent).is_undefined() {
81+
let second = if second.get(agent).is_undefined() {
8282
0
8383
} else {
8484
u8::try_from(
85-
to_integer_with_truncation(agent, seconds.get(agent), gc.reborrow()).unbind()?,
85+
to_integer_with_truncation(agent, second.get(agent), gc.reborrow()).unbind()?,
8686
)
8787
.unwrap_or(u8::MAX)
8888
};
8989

9090
// 5. If millisecond is undefined, set millisecond to 0; else set millisecond to ? ToIntegerWithTruncation(millisecond).
91-
let millisecond = if milliseconds.get(agent).is_undefined() {
91+
let millisecond = if millisecond.get(agent).is_undefined() {
9292
0
9393
} else {
9494
u16::try_from(
95-
to_integer_with_truncation(agent, milliseconds.get(agent), gc.reborrow())
95+
to_integer_with_truncation(agent, millisecond.get(agent), gc.reborrow())
9696
.unbind()?,
9797
)
9898
.unwrap_or(u16::MAX)
9999
};
100100

101101
// 6. If microsecond is undefined, set microsecond to 0; else set microsecond to ? ToIntegerWithTruncation(microsecond).
102-
let microsecond = if microseconds.get(agent).is_undefined() {
102+
let microsecond = if microsecond.get(agent).is_undefined() {
103103
0
104104
} else {
105105
u16::try_from(
106-
to_integer_with_truncation(agent, microseconds.get(agent), gc.reborrow())
106+
to_integer_with_truncation(agent, microsecond.get(agent), gc.reborrow())
107107
.unbind()?,
108108
)
109109
.unwrap_or(u16::MAX)
110110
};
111111

112112
// 7. If nanosecond is undefined, set nanosecond to 0; else set nanosecond to ? ToIntegerWithTruncation(nanosecond).
113-
let nanosecond = if nanoseconds.get(agent).is_undefined() {
113+
let nanosecond = if nanosecond.get(agent).is_undefined() {
114114
0
115115
} else {
116116
u16::try_from(
117-
to_integer_with_truncation(agent, nanoseconds.get(agent), gc.reborrow())
118-
.unbind()?,
117+
to_integer_with_truncation(agent, nanosecond.get(agent), gc.reborrow()).unbind()?,
119118
)
120119
.unwrap_or(u16::MAX)
121120
};

nova_vm/src/ecmascript/builtins/temporal/plain_time/plain_time_prototype.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ impl Builtin for TemporalPlainTimePrototypeToJSON {
101101
const BEHAVIOUR: Behaviour = Behaviour::Regular(TemporalPlainTimePrototype::to_json);
102102
}
103103

104+
struct TemporalPlainTimePrototypeToLocaleString;
105+
impl Builtin for TemporalPlainTimePrototypeToLocaleString {
106+
const NAME: String<'static> = BUILTIN_STRING_MEMORY.toLocaleString;
107+
const LENGTH: u8 = 0;
108+
const BEHAVIOUR: Behaviour = Behaviour::Regular(TemporalPlainTimePrototype::to_locale_string);
109+
}
110+
104111
struct TemporalPlainTimePrototypeToString;
105112
impl Builtin for TemporalPlainTimePrototypeToString {
106113
const NAME: String<'static> = BUILTIN_STRING_MEMORY.toString;
@@ -273,6 +280,29 @@ impl TemporalPlainTimePrototype {
273280
}
274281
}
275282

283+
/// ### [4.3.17 Temporal.PlainTime.prototype.toLocaleString ( [ locales [ , options ] ] )](https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype.tolocalestring)
284+
/// An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript
285+
/// implementation does not include the ECMA-402 API the following specification of this method is used. The meanings of the optional parameters to this method are defined
286+
/// in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.
287+
fn to_locale_string<'gc>(
288+
agent: &mut Agent,
289+
this_value: Value,
290+
_args: ArgumentsList,
291+
gc: GcScope<'gc, '_>,
292+
) -> JsResult<'gc, Value<'gc>> {
293+
let gc = gc.into_nogc();
294+
// 1. Let plainTime be the this value.
295+
let value = this_value.bind(gc);
296+
// 2. Perform ? RequireInternalSlot(plainTime, [[InitializedTemporalTime]]).
297+
let plain_time = require_internal_slot_temporal_plain_time(agent, value, gc)?;
298+
// 3. Return TimeRecordToString(plainTime.[[Time]], auto).
299+
let options: ToStringRoundingOptions = ToStringRoundingOptions::default(); // defaults Precision to Auto
300+
match plain_time.inner_plain_time(agent).to_ixdtf_string(options) {
301+
Ok(string) => Ok(Value::from_string(agent, string, gc)),
302+
Err(err) => Err(temporal_err_to_js_err(agent, err, gc)),
303+
}
304+
}
305+
276306
/// ### [4.3.16 Temporal.PlainTime.prototype.toString ( [ options ] )](https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype.tostring)
277307
fn to_string<'gc>(
278308
agent: &mut Agent,
@@ -365,7 +395,7 @@ impl TemporalPlainTimePrototype {
365395
let plain_time_constructor = intrinsics.temporal_plain_time();
366396

367397
OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this)
368-
.with_property_capacity(13)
398+
.with_property_capacity(14)
369399
.with_prototype(object_prototype)
370400
.with_constructor_property(plain_time_constructor)
371401
.with_builtin_function_getter_property::<TemporalPlainTimePrototypeGetHour>()
@@ -377,6 +407,7 @@ impl TemporalPlainTimePrototype {
377407
.with_builtin_function_property::<TemporalPlainTimePrototypeAdd>()
378408
.with_builtin_function_property::<TemporalPlainTimePrototypeSubtract>()
379409
.with_builtin_function_property::<TemporalPlainTimePrototypeToJSON>()
410+
.with_builtin_function_property::<TemporalPlainTimePrototypeToLocaleString>()
380411
.with_builtin_function_property::<TemporalPlainTimePrototypeToString>()
381412
.with_builtin_function_property::<TemporalPlainTimePrototypeValueOf>()
382413
.with_property(|builder| {

0 commit comments

Comments
 (0)