diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp index 3617320819..b7a129af30 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp @@ -191,25 +191,33 @@ ThrowCompletionOr> get_string_or_number_option(Globa return value.as_string().string(); } -// 13.5 ToTemporalOverflow ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloverflow -ThrowCompletionOr to_temporal_overflow(GlobalObject& global_object, Object const& normalized_options) +// 13.5 ToTemporalOverflow ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloverflow +ThrowCompletionOr to_temporal_overflow(GlobalObject& global_object, Object const* options) { auto& vm = global_object.vm(); - // 1. Return ? GetOption(normalizedOptions, "overflow", « String », « "constrain", "reject" », "constrain"). - auto option = TRY(get_option(global_object, normalized_options, vm.names.overflow, { OptionType::String }, { "constrain"sv, "reject"sv }, js_string(vm, "constrain"))); + // 1. If options is undefined, return "constrain". + if (options == nullptr) + return "constrain"sv; + + // 2. Return ? GetOption(options, "overflow", « String », « "constrain", "reject" », "constrain"). + auto option = TRY(get_option(global_object, *options, vm.names.overflow, { OptionType::String }, { "constrain"sv, "reject"sv }, js_string(vm, "constrain"))); VERIFY(option.is_string()); return option.as_string().string(); } -// 13.6 ToTemporalDisambiguation ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation -ThrowCompletionOr to_temporal_disambiguation(GlobalObject& global_object, Object const& normalized_options) +// 13.6 ToTemporalDisambiguation ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation +ThrowCompletionOr to_temporal_disambiguation(GlobalObject& global_object, Object const* options) { auto& vm = global_object.vm(); - // 1. Return ? GetOption(normalizedOptions, "disambiguation", « String », « "compatible", "earlier", "later", "reject" », "compatible"). - auto option = TRY(get_option(global_object, normalized_options, vm.names.disambiguation, { OptionType::String }, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, js_string(vm, "compatible"))); + // 1. If options is undefined, return "compatible". + if (options == nullptr) + return "compatible"sv; + + // 2. Return ? GetOption(options, "disambiguation", « String », « "compatible", "earlier", "later", "reject" », "compatible"). + auto option = TRY(get_option(global_object, *options, vm.names.disambiguation, { OptionType::String }, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, js_string(vm, "compatible"))); VERIFY(option.is_string()); return option.as_string().string(); @@ -242,13 +250,17 @@ StringView negate_temporal_rounding_mode(String const& rounding_mode) return rounding_mode; } -// 13.9 ToTemporalOffset ( normalizedOptions, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloffset -ThrowCompletionOr to_temporal_offset(GlobalObject& global_object, Object const& normalized_options, String const& fallback) +// 13.9 ToTemporalOffset ( options, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloffset +ThrowCompletionOr to_temporal_offset(GlobalObject& global_object, Object const* options, String const& fallback) { auto& vm = global_object.vm(); - // 1. Return ? GetOption(normalizedOptions, "offset", « String », « "prefer", "use", "ignore", "reject" », fallback). - auto option = TRY(get_option(global_object, normalized_options, vm.names.offset, { OptionType::String }, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, js_string(vm, fallback))); + // 1. If options is undefined, return fallback. + if (options == nullptr) + return fallback; + + // 2. Return ? GetOption(options, "offset", « String », « "prefer", "use", "ignore", "reject" », fallback). + auto option = TRY(get_option(global_object, *options, vm.names.offset, { OptionType::String }, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, js_string(vm, fallback))); VERIFY(option.is_string()); return option.as_string().string(); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h index b85003597b..32a2c9ed9d 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h @@ -102,11 +102,11 @@ ThrowCompletionOr get_options_object(GlobalObject&, Value options); ThrowCompletionOr get_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector const& types, Vector const& values, Value fallback); template ThrowCompletionOr> get_string_or_number_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector const& string_values, NumberType minimum, NumberType maximum, Value fallback); -ThrowCompletionOr to_temporal_overflow(GlobalObject&, Object const& normalized_options); -ThrowCompletionOr to_temporal_disambiguation(GlobalObject&, Object const& normalized_options); +ThrowCompletionOr to_temporal_overflow(GlobalObject&, Object const* options); +ThrowCompletionOr to_temporal_disambiguation(GlobalObject&, Object const* options); ThrowCompletionOr to_temporal_rounding_mode(GlobalObject&, Object const& normalized_options, String const& fallback); StringView negate_temporal_rounding_mode(String const& rounding_mode); -ThrowCompletionOr to_temporal_offset(GlobalObject&, Object const& normalized_options, String const& fallback); +ThrowCompletionOr to_temporal_offset(GlobalObject&, Object const* options, String const& fallback); ThrowCompletionOr to_show_calendar_option(GlobalObject&, Object const& normalized_options); ThrowCompletionOr to_show_time_zone_name_option(GlobalObject&, Object const& normalized_options); ThrowCompletionOr to_show_offset_option(GlobalObject&, Object const& normalized_options); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index fed58aee8d..7838d0d67f 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -134,27 +134,29 @@ ThrowCompletionOr calendar_merge_fields(GlobalObject& global_object, Ob return &result.as_object(); } -// 12.1.7 CalendarDateAdd ( calendar, date, duration, options [ , dateAdd ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateadd +// 12.1.7 CalendarDateAdd ( calendar, date, duration [ , options [ , dateAdd ] ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateadd ThrowCompletionOr calendar_date_add(GlobalObject& global_object, Object& calendar, Value date, Duration& duration, Object* options, FunctionObject* date_add) { // NOTE: `date` is a `Value` because we sometimes need to pass a PlainDate, sometimes a PlainDateTime, and sometimes undefined. auto& vm = global_object.vm(); // 1. Assert: Type(calendar) is Object. + // 2. If options is not present, set options to undefined. + // 3. Assert: Type(options) is Object or Undefined. - // 2. If dateAdd is not present, set dateAdd to ? GetMethod(calendar, "dateAdd"). + // 4. If dateAdd is not present, set dateAdd to ? GetMethod(calendar, "dateAdd"). if (!date_add) date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd)); - // 3. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »). + // 5. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »). auto added_date = TRY(call(global_object, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined())); - // 4. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]). + // 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]). auto* added_date_object = TRY(added_date.to_object(global_object)); if (!is(added_date_object)) return vm.throw_completion(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); - // 5. Return addedDate. + // 7. Return addedDate. return static_cast(added_date_object); } @@ -456,23 +458,25 @@ ThrowCompletionOr get_temporal_calendar_with_iso_default(GlobalObject& return to_temporal_calendar_with_iso_default(global_object, calendar_like); } -// 12.1.24 DateFromFields ( calendar, fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-datefromfields +// 12.1.24 DateFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-datefromfields ThrowCompletionOr date_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options) { auto& vm = global_object.vm(); // 1. Assert: Type(calendar) is Object. // 2. Assert: Type(fields) is Object. + // 3. If options is not present, set options to undefined. + // 4. Assert: Type(options) is Object or Undefined. - // 3. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »). + // 5. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »). auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, options ?: js_undefined())); - // 4. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]). + // 6. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]). auto* date_object = TRY(date.to_object(global_object)); if (!is(date_object)) return vm.throw_completion(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); - // 5. Return date. + // 7. Return date. return static_cast(date_object); } @@ -483,10 +487,8 @@ ThrowCompletionOr year_month_from_fields(GlobalObject& global_o // 1. Assert: Type(calendar) is Object. // 2. Assert: Type(fields) is Object. - // 3. If options is not present, then - // a. Set options to undefined. - // 4. Else, - // a. Assert: Type(options) is Object. + // 3. If options is not present, set options to undefined. + // 4. Assert: Type(options) is Object or Undefined. // 5. Let yearMonth be ? Invoke(calendar, "yearMonthFromFields", « fields, options »). auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined())); @@ -507,10 +509,8 @@ ThrowCompletionOr month_day_from_fields(GlobalObject& global_obj // 1. Assert: Type(calendar) is Object. // 2. Assert: Type(fields) is Object. - // 3. If options is not present, then - // a. Set options to undefined. - // 4. Else, - // a. Assert: Type(options) is Object. + // 3. If options is not present, set options to undefined. + // 4. Assert: Type(options) is Object or Undefined. // 5. Let monthDay be ? Invoke(calendar, "monthDayFromFields", « fields, options »). auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined())); @@ -794,7 +794,7 @@ ThrowCompletionOr iso_date_from_fields(GlobalObject& global_object, Obj // 1. Assert: Type(fields) is Object. // 2. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, options)); + auto overflow = TRY(to_temporal_overflow(global_object, &options)); // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»). auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day", "month", "monthCode", "year" }, {})); @@ -828,7 +828,7 @@ ThrowCompletionOr iso_year_month_from_fields(GlobalObject& global_ // 1. Assert: Type(fields) is Object. // 2. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, options)); + auto overflow = TRY(to_temporal_overflow(global_object, &options)); // 3. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode", "year" », «»). auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "month"sv, "monthCode"sv, "year"sv }, {})); @@ -858,7 +858,7 @@ ThrowCompletionOr iso_month_day_from_fields(GlobalObject& global_ob // 1. Assert: Type(fields) is Object. // 2. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, options)); + auto overflow = TRY(to_temporal_overflow(global_object, &options)); // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»). auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, {})); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h index a9d77979fe..c0e97915f4 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2021, Idan Horowitz - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ @@ -36,7 +36,7 @@ ThrowCompletionOr get_builtin_calendar(GlobalObject&, String const& i Calendar* get_iso8601_calendar(GlobalObject&); ThrowCompletionOr> calendar_fields(GlobalObject&, Object& calendar, Vector const& field_names); ThrowCompletionOr calendar_merge_fields(GlobalObject&, Object& calendar, Object& fields, Object& additional_fields); -ThrowCompletionOr calendar_date_add(GlobalObject&, Object& calendar, Value date, Duration&, Object* options, FunctionObject* date_add = nullptr); +ThrowCompletionOr calendar_date_add(GlobalObject&, Object& calendar, Value date, Duration&, Object* options = nullptr, FunctionObject* date_add = nullptr); ThrowCompletionOr calendar_date_until(GlobalObject&, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until = nullptr); ThrowCompletionOr calendar_year(GlobalObject&, Object& calendar, Object& date_like); ThrowCompletionOr calendar_month(GlobalObject&, Object& calendar, Object& date_like); @@ -57,7 +57,7 @@ ThrowCompletionOr to_temporal_calendar_with_iso_default(GlobalObject&, ThrowCompletionOr get_temporal_calendar_with_iso_default(GlobalObject&, Object&); ThrowCompletionOr date_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr); ThrowCompletionOr year_month_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr); -ThrowCompletionOr month_day_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options = nullptr); +ThrowCompletionOr month_day_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr); String format_calendar_annotation(StringView id, StringView show_calendar); ThrowCompletionOr calendar_equals(GlobalObject&, Object& one, Object& two); ThrowCompletionOr consolidate_calendars(GlobalObject&, Object& one, Object& two); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp index cee75fcead..67cad35cb4 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp @@ -172,7 +172,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_add) auto* options = TRY(get_options_object(global_object, vm.argument(2))); // 7. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, *options)); + auto overflow = TRY(to_temporal_overflow(global_object, options)); // 8. Let balanceResult be ! BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day"). // FIXME: Narrowing conversion from 'double' to 'i64' diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp index 3c7fb1eafe..370f690747 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -623,31 +623,28 @@ ThrowCompletionOr unbalance_duration_relative(GlobalObject& // d. Repeat, while years ≠ 0, while (years != 0) { - // i. Let addOptions be OrdinaryObjectCreate(null). - auto* add_options = Object::create(global_object, nullptr); + // i. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd). + auto* new_relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *one_year, nullptr, date_add)); - // ii. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd). - auto* new_relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *one_year, add_options, date_add)); - - // iii. Let untilOptions be OrdinaryObjectCreate(null). + // ii. Let untilOptions be OrdinaryObjectCreate(null). auto* until_options = Object::create(global_object, nullptr); - // iv. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). + // iii. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv))); - // v. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). + // iv. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). auto* until_result = TRY(calendar_date_until(global_object, *calendar, relative_to, new_relative_to, *until_options, date_until)); - // vi. Let oneYearMonths be untilResult.[[Months]]. + // v. Let oneYearMonths be untilResult.[[Months]]. auto one_year_months = until_result->months(); - // vii. Set relativeTo to newRelativeTo. + // vi. Set relativeTo to newRelativeTo. relative_to = new_relative_to; - // viii. Set years to years − sign. + // vii. Set years to years − sign. years -= sign; - // ix. Set months to months + oneYearMonths. + // viii. Set months to months + oneYearMonths. months += one_year_months; } } @@ -844,28 +841,25 @@ ThrowCompletionOr balance_duration_relative(GlobalObject& gl // i. Let dateAdd be ? GetMethod(calendar, "dateAdd"). auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd)); - // j. Let addOptions be OrdinaryObjectCreate(null). - auto* add_options = Object::create(global_object, nullptr); + // j. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd). + auto* new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, nullptr, date_add)); - // k. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd). - auto* new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, add_options, date_add)); - - // l. Let dateUntil be ? GetMethod(calendar, "dateUntil"). + // k. Let dateUntil be ? GetMethod(calendar, "dateUntil"). auto* date_until = TRY(Value(&calendar).get_method(global_object, vm.names.dateUntil)); - // m. Let untilOptions be OrdinaryObjectCreate(null). + // l. Let untilOptions be OrdinaryObjectCreate(null). auto* until_options = Object::create(global_object, nullptr); - // n. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). + // m. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv))); - // o. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). + // n. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). auto* until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until)); - // p. Let oneYearMonths be untilResult.[[Months]]. + // o. Let oneYearMonths be untilResult.[[Months]]. auto one_year_months = until_result->months(); - // q. Repeat, while abs(months) ≥ abs(oneYearMonths), + // p. Repeat, while abs(months) ≥ abs(oneYearMonths), while (fabs(months) >= fabs(one_year_months)) { // i. Set months to months − oneYearMonths. months -= one_year_months; @@ -876,22 +870,19 @@ ThrowCompletionOr balance_duration_relative(GlobalObject& gl // iii. Set relativeTo to newRelativeTo. relative_to = new_relative_to; - // iv. Set addOptions to OrdinaryObjectCreate(null). - add_options = Object::create(global_object, nullptr); + // iv. Set newRelativeTo to ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd). + new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, nullptr, date_add)); - // v. Set newRelativeTo to ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd). - new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, add_options, date_add)); - - // vi. Set untilOptions to OrdinaryObjectCreate(null). + // v. Set untilOptions to OrdinaryObjectCreate(null). until_options = Object::create(global_object, nullptr); - // vii. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). + // vi. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv))); - // viii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). + // vii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until)); - // ix. Set oneYearMonths to untilResult.[[Months]]. + // viii. Set oneYearMonths to untilResult.[[Months]]. one_year_months = until_result->months(); } } @@ -1009,35 +1000,29 @@ ThrowCompletionOr add_duration(GlobalObject& global_object, doub // d. Let dateAdd be ? GetMethod(calendar, "dateAdd"). auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd)); - // e. Let firstAddOptions be OrdinaryObjectCreate(null). - auto* first_add_options = Object::create(global_object, nullptr); + // e. Let intermediate be ? CalendarDateAdd(calendar, relativeTo, dateDuration1, undefined, dateAdd). + auto* intermediate = TRY(calendar_date_add(global_object, calendar, &relative_to, *date_duration1, nullptr, date_add)); - // f. Let intermediate be ? CalendarDateAdd(calendar, relativeTo, dateDuration1, firstAddOptions, dateAdd). - auto* intermediate = TRY(calendar_date_add(global_object, calendar, &relative_to, *date_duration1, first_add_options, date_add)); + // f. Let end be ? CalendarDateAdd(calendar, intermediate, dateDuration2, undefined, dateAdd). + auto* end = TRY(calendar_date_add(global_object, calendar, intermediate, *date_duration2, nullptr, date_add)); - // g. Let secondAddOptions be OrdinaryObjectCreate(null). - auto* second_add_options = Object::create(global_object, nullptr); - - // h. Let end be ? CalendarDateAdd(calendar, intermediate, dateDuration2, secondAddOptions, dateAdd). - auto* end = TRY(calendar_date_add(global_object, calendar, intermediate, *date_duration2, second_add_options, date_add)); - - // i. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit). + // g. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit). auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit); - // j. Let differenceOptions be OrdinaryObjectCreate(null). + // h. Let differenceOptions be OrdinaryObjectCreate(null). auto* difference_options = Object::create(global_object, nullptr); - // k. Perform ! CreateDataPropertyOrThrow(differenceOptions, "largestUnit", dateLargestUnit). + // i. Perform ! CreateDataPropertyOrThrow(differenceOptions, "largestUnit", dateLargestUnit). MUST(difference_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, date_largest_unit))); - // l. Let dateDifference be ? CalendarDateUntil(calendar, relativeTo, end, differenceOptions). + // j. Let dateDifference be ? CalendarDateUntil(calendar, relativeTo, end, differenceOptions). auto* date_difference = TRY(calendar_date_until(global_object, calendar, &relative_to, end, *difference_options)); - // m. Let result be ! BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit). + // k. Let result be ! BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit). // FIXME: Narrowing conversion from 'double' to 'i64' auto result = MUST(balance_duration(global_object, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit)); - // n. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]). + // l. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]). return create_duration_record(global_object, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds); } @@ -1075,16 +1060,13 @@ ThrowCompletionOr add_duration(GlobalObject& global_object, doub // 7.5.23 MoveRelativeDate ( calendar, relativeTo, duration ), https://tc39.es/proposal-temporal/#sec-temporal-moverelativedate ThrowCompletionOr move_relative_date(GlobalObject& global_object, Object& calendar, PlainDate& relative_to, Duration& duration) { - // 1. Let options be OrdinaryObjectCreate(null). - auto* options = Object::create(global_object, nullptr); + // 1. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options). + auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration)); - // 2. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options). - auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration, options)); - - // 3. Let days be ! DaysUntil(relativeTo, newDate). + // 2. Let days be ! DaysUntil(relativeTo, newDate). auto days = days_until(global_object, relative_to, *new_date); - // 4. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }. + // 3. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }. return MoveRelativeDateResult { .relative_to = make_handle(new_date), .days = days }; } @@ -1199,94 +1181,82 @@ ThrowCompletionOr round_duration(GlobalObject& global_object, d // b. Let dateAdd be ? GetMethod(calendar, "dateAdd"). auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd)); - // c. Let firstAddOptions be OrdinaryObjectCreate(null). - auto* first_add_options = Object::create(global_object, nullptr); + // c. Let yearsLater be ? CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd). + auto* years_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, nullptr, date_add)); - // d. Let yearsLater be ? CalendarDateAdd(calendar, relativeTo, yearsDuration, firstAddOptions, dateAdd). - auto* years_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, first_add_options, date_add)); - - // e. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0). + // d. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0). auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0)); - // f. Let secondAddOptions be OrdinaryObjectCreate(null). - auto* second_add_options = Object::create(global_object, nullptr); + // e. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd). + auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, nullptr, date_add)); - // g. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, secondAddOptions, dateAdd). - auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, second_add_options, date_add)); - - // h. Let monthsWeeksInDays be ? DaysUntil(yearsLater, yearsMonthsWeeksLater). + // f. Let monthsWeeksInDays be ? DaysUntil(yearsLater, yearsMonthsWeeksLater). auto months_weeks_in_days = days_until(global_object, *years_later, *years_months_weeks_later); - // i. Set relativeTo to yearsLater. + // g. Set relativeTo to yearsLater. relative_to = years_later; - // j. Let days be days + monthsWeeksInDays. + // h. Let days be days + monthsWeeksInDays. days += months_weeks_in_days; - // k. Let daysDuration be ? CreateTemporalDuration(0, 0, 0, days, 0, 0, 0, 0, 0, 0). + // i. Let daysDuration be ? CreateTemporalDuration(0, 0, 0, days, 0, 0, 0, 0, 0, 0). auto* days_duration = TRY(create_temporal_duration(global_object, 0, 0, 0, days, 0, 0, 0, 0, 0, 0)); - // l. Let thirdAddOptions be OrdinaryObjectCreate(null). - auto* third_add_options = Object::create(global_object, nullptr); + // j. Let daysLater be ? CalendarDateAdd(calendar, relativeTo, daysDuration, undefined, dateAdd). + auto* days_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *days_duration, nullptr, date_add)); - // m. Let daysLater be ? CalendarDateAdd(calendar, relativeTo, daysDuration, thirdAddOptions, dateAdd). - auto* days_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *days_duration, third_add_options, date_add)); - - // n. Let untilOptions be OrdinaryObjectCreate(null). + // k. Let untilOptions be OrdinaryObjectCreate(null). auto* until_options = Object::create(global_object, nullptr); - // o. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "year"). + // l. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "year"). MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "year"sv))); - // p. Let timePassed be ? CalendarDateUntil(calendar, relativeTo, daysLater, untilOptions). + // m. Let timePassed be ? CalendarDateUntil(calendar, relativeTo, daysLater, untilOptions). auto* time_passed = TRY(calendar_date_until(global_object, *calendar, relative_to, days_later, *until_options)); - // q. Let yearsPassed be timePassed.[[Years]]. + // n. Let yearsPassed be timePassed.[[Years]]. auto years_passed = time_passed->years(); - // r. Set years to years + yearsPassed. + // o. Set years to years + yearsPassed. years += years_passed; - // s. Let oldRelativeTo be relativeTo. + // p. Let oldRelativeTo be relativeTo. auto* old_relative_to = relative_to; - // t. Let yearsDuration be ! CreateTemporalDuration(yearsPassed, 0, 0, 0, 0, 0, 0, 0, 0, 0). + // q. Let yearsDuration be ! CreateTemporalDuration(yearsPassed, 0, 0, 0, 0, 0, 0, 0, 0, 0). years_duration = MUST(create_temporal_duration(global_object, years_passed, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - // u. Let fourthAddOptions be OrdinaryObjectCreate(null). - auto* fourth_add_options = Object::create(global_object, nullptr); + // r. Set relativeTo to ? CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd). + relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, nullptr, date_add)); - // v. Set relativeTo to ? CalendarDateAdd(calendar, relativeTo, yearsDuration, fourthAddOptions, dateAdd). - relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, fourth_add_options, date_add)); - - // w. Let daysPassed be ? DaysUntil(oldRelativeTo, relativeTo). + // s. Let daysPassed be ? DaysUntil(oldRelativeTo, relativeTo). auto days_passed = days_until(global_object, *old_relative_to, *relative_to); - // x. Set days to days - daysPassed. + // t. Set days to days - daysPassed. days -= days_passed; - // y. If days < 0, let sign be −1; else, let sign be 1. + // u. If days < 0, let sign be −1; else, let sign be 1. auto sign = days < 0 ? -1 : 1; - // z. Let oneYear be ! CreateTemporalDuration(sign, 0, 0, 0, 0, 0, 0, 0, 0, 0). + // v. Let oneYear be ! CreateTemporalDuration(sign, 0, 0, 0, 0, 0, 0, 0, 0, 0). auto* one_year = MUST(create_temporal_duration(global_object, sign, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - // aa. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneYear). + // w. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneYear). auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_year)); - // ab. Let oneYearDays be moveResult.[[Days]]. + // x. Let oneYearDays be moveResult.[[Days]]. auto one_year_days = move_result.days; - // ac. Let fractionalYears be years + days / abs(oneYearDays). + // y. Let fractionalYears be years + days / abs(oneYearDays). auto fractional_years = years + days / fabs(one_year_days); - // ad. Set years to ! RoundNumberToIncrement(fractionalYears, increment, roundingMode). + // z. Set years to ! RoundNumberToIncrement(fractionalYears, increment, roundingMode). years = (double)round_number_to_increment(fractional_years, increment, rounding_mode); - // ae. Set remainder to fractionalYears - years. + // aa. Set remainder to fractionalYears - years. remainder = fractional_years - years; - // af. Set months, weeks, and days to 0. + // ab. Set months, weeks, and days to 0. months = 0; weeks = 0; days = 0; @@ -1301,46 +1271,40 @@ ThrowCompletionOr round_duration(GlobalObject& global_object, d // b. Let dateAdd be ? GetMethod(calendar, "dateAdd"). auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd)); - // c. Let firstAddOptions be OrdinaryObjectCreate(null). - auto* first_add_options = Object::create(global_object, nullptr); + // c. Let yearsMonthsLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonths, undefined, dateAdd). + auto* years_months_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months, nullptr, date_add)); - // d. Let yearsMonthsLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonths, firstAddOptions, dateAdd). - auto* years_months_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months, first_add_options, date_add)); - - // e. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0). + // d. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0). auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0)); - // f. Let secondAddOptions be OrdinaryObjectCreate(null). - auto* seconds_add_options = Object::create(global_object, nullptr); + // e. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd). + auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, nullptr, date_add)); - // g. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, secondAddOptions, dateAdd). - auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, seconds_add_options, date_add)); - - // h. Let weeksInDays be ? DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater). + // f. Let weeksInDays be ? DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater). auto weeks_in_days = days_until(global_object, *years_months_later, *years_months_weeks_later); - // i. Set relativeTo to yearsMonthsLater. + // g. Set relativeTo to yearsMonthsLater. relative_to = years_months_later; - // j. Let days be days + weeksInDays. + // h. Let days be days + weeksInDays. days += weeks_in_days; - // k. If days < 0, let sign be −1; else, let sign be 1. + // i. If days < 0, let sign be −1; else, let sign be 1. auto sign = days < 0 ? -1 : 1; - // l. Let oneMonth be ! CreateTemporalDuration(0, sign, 0, 0, 0, 0, 0, 0, 0, 0). + // j. Let oneMonth be ! CreateTemporalDuration(0, sign, 0, 0, 0, 0, 0, 0, 0, 0). auto* one_month = MUST(create_temporal_duration(global_object, 0, sign, 0, 0, 0, 0, 0, 0, 0, 0)); - // m. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneMonth). + // k. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneMonth). auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_month)); - // n. Set relativeTo to moveResult.[[RelativeTo]]. + // l. Set relativeTo to moveResult.[[RelativeTo]]. relative_to = move_result.relative_to.cell(); - // o. Let oneMonthDays be moveResult.[[Days]]. + // m. Let oneMonthDays be moveResult.[[Days]]. auto one_month_days = move_result.days; - // p. Repeat, while abs(days) ≥ abs(oneMonthDays), + // n. Repeat, while abs(days) ≥ abs(oneMonthDays), while (fabs(days) >= fabs(one_month_days)) { // i. Set months to months + sign. months += sign; @@ -1358,16 +1322,16 @@ ThrowCompletionOr round_duration(GlobalObject& global_object, d one_month_days = move_result.days; } - // q. Let fractionalMonths be months + days / abs(oneMonthDays). + // o. Let fractionalMonths be months + days / abs(oneMonthDays). auto fractional_months = months + days / fabs(one_month_days); - // r. Set months to ! RoundNumberToIncrement(fractionalMonths, increment, roundingMode). + // p. Set months to ! RoundNumberToIncrement(fractionalMonths, increment, roundingMode). months = (double)round_number_to_increment(fractional_months, increment, rounding_mode); - // s. Set remainder to fractionalMonths - months. + // q. Set remainder to fractionalMonths - months. remainder = fractional_months - months; - // t. Set weeks and days to 0. + // r. Set weeks and days to 0. weeks = 0; days = 0; } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp index 85d62dc2cd..0c64f7c2b7 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp @@ -73,11 +73,8 @@ ThrowCompletionOr to_temporal_date(GlobalObject& global_object, Valu { auto& vm = global_object.vm(); - // 1. If options is not present, set options to OrdinaryObjectCreate(null). - if (!options) - options = Object::create(global_object, nullptr); - - // 2. Assert: Type(options) is Object. + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. // 3. If Type(item) is Object, then if (item.is_object()) { @@ -123,7 +120,7 @@ ThrowCompletionOr to_temporal_date(GlobalObject& global_object, Valu } // 4. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // 5. Let string be ? ToString(item). auto string = TRY(item.to_string(global_object)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp index 51a7471c6c..2c7bab9210 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp @@ -84,7 +84,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateConstructor::from) if (item.is_object() && is(item.as_object())) { auto& plain_date_item = static_cast(item.as_object()); // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // b. Return ? CreateTemporalDate(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[Calendar]]). return TRY(create_temporal_date(global_object, plain_date_item.iso_year(), plain_date_item.iso_month(), plain_date_item.iso_day(), plain_date_item.calendar())); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp index 6b179621c5..8de4a05592 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp @@ -108,7 +108,7 @@ ThrowCompletionOr interpret_temporal_date_time_fields(GlobalObject& auto unregulated_time_result = TRY(to_temporal_time_record(global_object, fields)); // 2. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, options)); + auto overflow = TRY(to_temporal_overflow(global_object, &options)); // 3. Let temporalDate be ? DateFromFields(calendar, fields, options). auto* temporal_date = TRY(date_from_fields(global_object, calendar, fields, &options)); @@ -135,14 +135,13 @@ ThrowCompletionOr to_temporal_date_time(GlobalObject& global_obj { auto& vm = global_object.vm(); - // 1. If options is not present, set options to OrdinaryObjectCreate(null). - if (!options) - options = Object::create(global_object, nullptr); + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. Object* calendar; ISODateTime result; - // 2. If Type(item) is Object, then + // 3. If Type(item) is Object, then if (item.is_object()) { auto& item_object = item.as_object(); @@ -183,10 +182,10 @@ ThrowCompletionOr to_temporal_date_time(GlobalObject& global_obj // g. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options). result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options)); } - // 3. Else, + // 4. Else, else { // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // b. Let string be ? ToString(item). auto string = TRY(item.to_string(global_object)); @@ -204,7 +203,7 @@ ThrowCompletionOr to_temporal_date_time(GlobalObject& global_obj calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, *result.calendar) : js_undefined())); } - // 4. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar). + // 5. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar). return create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, *calendar); } @@ -353,23 +352,26 @@ ISODateTime round_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute, // 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime ThrowCompletionOr difference_iso_date_time(GlobalObject& global_object, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object* options) { - // 1. If options is not present, set options to OrdinaryObjectCreate(null). + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. + + // FIXME: `options` is being passed to MergeLargestUnitOption unconditionally, which expects it to not be undefined (spec issue: https://github.com/tc39/proposal-temporal/issues/2132). if (!options) options = Object::create(global_object, nullptr); - // 2. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2). + // 3. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2). auto time_difference = difference_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2); - // 3. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]). + // 4. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]). auto time_sign = duration_sign(0, 0, 0, time_difference.days, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, time_difference.nanoseconds); - // 4. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1). + // 5. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1). auto date_sign = compare_iso_date(year2, month2, day2, year1, month1, day1); - // 5. Let adjustedDate be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]). + // 6. Let adjustedDate be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]). auto adjusted_date = balance_iso_date(year1, month1, day1 + time_difference.days); - // 6. If timeSign is -dateSign, then + // 7. If timeSign is -dateSign, then if (time_sign == -date_sign) { // a. Set adjustedDate to ! BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] - timeSign). adjusted_date = balance_iso_date(adjusted_date.year, adjusted_date.month, adjusted_date.day - time_sign); @@ -378,25 +380,25 @@ ThrowCompletionOr difference_iso_date_time(GlobalObject& global_ time_difference = TRY(balance_duration(global_object, -time_sign, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit)); } - // 7. Let date1 be ? CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar). + // 8. Let date1 be ? CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar). auto* date1 = TRY(create_temporal_date(global_object, adjusted_date.year, adjusted_date.month, adjusted_date.day, calendar)); - // 8. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar). + // 9. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar). auto* date2 = TRY(create_temporal_date(global_object, year2, month2, day2, calendar)); - // 9. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit). + // 10. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit). auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit); - // 10. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit). + // 11. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit). auto* until_options = TRY(merge_largest_unit_option(global_object, *options, date_largest_unit)); - // 11. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions). + // 12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions). auto* date_difference = TRY(calendar_date_until(global_object, calendar, date1, date2, *until_options)); - // 12. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit). + // 13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit). auto balance_result = TRY(balance_duration(global_object, date_difference->days(), time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit)); - // 13. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]). + // 14. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]). return create_duration_record(date_difference->years(), date_difference->months(), date_difference->weeks(), balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds); } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimeConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimeConstructor.cpp index add0399202..e00236bc86 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimeConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimeConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ @@ -105,7 +105,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimeConstructor::from) auto& plain_date_time = static_cast(item.as_object()); // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // b. Return ? CreateTemporalDateTime(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[ISOHour]], item.[[ISOMinute]], item.[[ISOSecond]], item.[[ISOMillisecond]], item.[[ISOMicrosecond]], item.[[ISONanosecond]], item.[[Calendar]]). return TRY(create_temporal_date_time(global_object, plain_date_time.iso_year(), plain_date_time.iso_month(), plain_date_time.iso_day(), plain_date_time.iso_hour(), plain_date_time.iso_minute(), plain_date_time.iso_second(), plain_date_time.iso_millisecond(), plain_date_time.iso_microsecond(), plain_date_time.iso_nanosecond(), plain_date_time.calendar())); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp index 960a1d2a18..e5f6b21e4b 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp @@ -766,7 +766,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_zoned_date_time) auto* options = TRY(get_options_object(global_object, vm.argument(1))); // 5. Let disambiguation be ? ToTemporalDisambiguation(options). - auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); + auto disambiguation = TRY(to_temporal_disambiguation(global_object, options)); // 6. Let instant be ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation). auto* instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp index f38d9d0df5..15717b6b55 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp @@ -38,14 +38,13 @@ ThrowCompletionOr to_temporal_month_day(GlobalObject& global_obj { auto& vm = global_object.vm(); - // 1. If options is not present, set options to OrdinaryObjectCreate(null). - if (!options) - options = Object::create(global_object, nullptr); + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. - // 2. Let referenceISOYear be 1972 (the first leap year after the Unix epoch). + // 3. Let referenceISOYear be 1972 (the first leap year after the Unix epoch). i32 reference_iso_year = 1972; - // 3. If Type(item) is Object, then + // 4. If Type(item) is Object, then if (item.is_object()) { auto& item_object = item.as_object(); @@ -118,32 +117,30 @@ ThrowCompletionOr to_temporal_month_day(GlobalObject& global_obj return month_day_from_fields(global_object, *calendar, *fields, options); } - // 4. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + // 5. Perform ? ToTemporalOverflow(options). + (void)TRY(to_temporal_overflow(global_object, options)); - // 5. Let string be ? ToString(item). + // 6. Let string be ? ToString(item). auto string = TRY(item.to_string(global_object)); - // 6. Let result be ? ParseTemporalMonthDayString(string). + // 7. Let result be ? ParseTemporalMonthDayString(string). auto result = TRY(parse_temporal_month_day_string(global_object, string)); - // 7. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]). + // 8. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]). auto* calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, move(*result.calendar)) : js_undefined())); - // 8. If result.[[Year]] is undefined, then + // 9. If result.[[Year]] is undefined, then if (!result.year.has_value()) { // a. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear). return TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year)); } - // 9. Set result to ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear). + // 10. Set result to ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear). auto* plain_month_day = TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year)); - // 10. Let canonicalMonthDayOptions be OrdinaryObjectCreate(null). - auto* canonical_month_day_options = Object::create(global_object, nullptr); - - // 11. Return ? MonthDayFromFields(calendar, result, canonicalMonthDayOptions). - return TRY(month_day_from_fields(global_object, *calendar, *plain_month_day, canonical_month_day_options)); + // 11. NOTE: The following operation is called without options, in order for the calendar to store a canonical value in the [[ISOYear]] internal slot of the result. + // 12. Return ? MonthDayFromFields(calendar, result). + return TRY(month_day_from_fields(global_object, *calendar, *plain_month_day)); } // 10.5.2 CreateTemporalMonthDay ( isoMonth, isoDay, calendar, referenceISOYear [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporalmonthday diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDayConstructor.cpp index 5be954b832..91df5cfe80 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDayConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDayConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ @@ -93,7 +93,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainMonthDayConstructor::from) // 2. If Type(item) is Object and item has an [[InitializedTemporalMonthDay]] internal slot, then if (item.is_object() && is(item.as_object())) { // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); auto& plain_month_day_object = static_cast(item.as_object()); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp index ee346afc32..3c377d216a 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ @@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimeConstructor::from) auto* options = TRY(get_options_object(global_object, vm.argument(1))); // 2. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, *options)); + auto overflow = TRY(to_temporal_overflow(global_object, options)); auto item = vm.argument(0); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp index b0a97547fd..81296e087c 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp @@ -207,7 +207,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::with) auto* options = TRY(get_options_object(global_object, vm.argument(1))); // 7. Let overflow be ? ToTemporalOverflow(options). - auto overflow = TRY(to_temporal_overflow(global_object, *options)); + auto overflow = TRY(to_temporal_overflow(global_object, options)); // 8. If partialTime.[[Hour]] is not undefined, then // a. Let hour be partialTime.[[Hour]]. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp index f122784630..d84419fbcf 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp @@ -35,11 +35,8 @@ ThrowCompletionOr to_temporal_year_month(GlobalObject& global_o { auto& vm = global_object.vm(); - // 1. If options is not present, set options to OrdinaryObjectCreate(null). - if (!options) - options = Object::create(global_object, nullptr); - - // 2. Assert: Type(options) is Object. + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. // 3. If Type(item) is Object, then if (item.is_object()) { @@ -65,7 +62,7 @@ ThrowCompletionOr to_temporal_year_month(GlobalObject& global_o } // 4. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // 5. Let string be ? ToString(item). auto string = TRY(item.to_string(global_object)); @@ -79,11 +76,9 @@ ThrowCompletionOr to_temporal_year_month(GlobalObject& global_o // 8. Set result to ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[Day]]). auto* creation_result = TRY(create_temporal_year_month(global_object, result.year, result.month, *calendar, result.day)); - // 9. Let canonicalYearMonthOptions be OrdinaryObjectCreate(null). - auto* canonical_year_month_options = Object::create(global_object, nullptr); - - // 10. Return ? YearMonthFromFields(calendar, result, canonicalYearMonthOptions). - return year_month_from_fields(global_object, *calendar, *creation_result, canonical_year_month_options); + // 9. NOTE: The following operation is called without options, in order for the calendar to store a canonical value in the [[ISODay]] internal slot of the result. + // 10. Return ? YearMonthFromFields(calendar, result). + return year_month_from_fields(global_object, *calendar, *creation_result); } // 9.5.2 RegulateISOYearMonth ( year, month, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulateisoyearmonth diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp index edd2b55a15..071c1e19d0 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * Copyright (c) 2021, Luke Wilde * * SPDX-License-Identifier: BSD-2-Clause @@ -95,7 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainYearMonthConstructor::from) // 2. If Type(item) is Object and item has an [[InitializedTemporalYearMonth]] internal slot, then if (item.is_object() && is(item.as_object())) { // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); auto& plain_year_month_object = static_cast(item.as_object()); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp index c02de4919f..809c193ad8 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp @@ -119,7 +119,7 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::get_instant_for) auto* options = TRY(get_options_object(global_object, vm.argument(1))); // 5. Let disambiguation be ? ToTemporalDisambiguation(options). - auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); + auto disambiguation = TRY(to_temporal_disambiguation(global_object, options)); // 6. Return ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation). return TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp index d3ae9db699..80fd7391ed 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp @@ -118,14 +118,13 @@ ThrowCompletionOr to_temporal_zoned_date_time(GlobalObject& glob { auto& vm = global_object.vm(); - // 1. If options is not present, set options to OrdinaryObjectCreate(null). - if (!options) - options = Object::create(global_object, nullptr); + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. - // 2. Let offsetBehaviour be option. + // 3. Let offsetBehaviour be option. auto offset_behavior = OffsetBehavior::Option; - // 3. Let matchBehaviour be match exactly. + // 4. Let matchBehaviour be match exactly. auto match_behavior = MatchBehavior::MatchExactly; Object* calendar = nullptr; @@ -133,7 +132,7 @@ ThrowCompletionOr to_temporal_zoned_date_time(GlobalObject& glob Optional offset_string; ISODateTime result; - // 4. If Type(item) is Object, then + // 5. If Type(item) is Object, then if (item.is_object()) { auto& item_object = item.as_object(); @@ -181,10 +180,10 @@ ThrowCompletionOr to_temporal_zoned_date_time(GlobalObject& glob // l. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options). result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options)); } - // 5. Else, + // 6. Else, else { // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // b. Let string be ? ToString(item). auto string = TRY(item.to_string(global_object)); @@ -241,25 +240,25 @@ ThrowCompletionOr to_temporal_zoned_date_time(GlobalObject& glob result = move(parsed_result.date_time); } - // 6. Let offsetNanoseconds be 0. + // 7. Let offsetNanoseconds be 0. double offset_nanoseconds = 0; - // 7. If offsetBehaviour is option, then + // 8. If offsetBehaviour is option, then if (offset_behavior == OffsetBehavior::Option) { // a. Set offsetNanoseconds to ? ParseTimeZoneOffsetString(offsetString). offset_nanoseconds = TRY(parse_time_zone_offset_string(global_object, *offset_string)); } - // 8. Let disambiguation be ? ToTemporalDisambiguation(options). - auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); + // 9. Let disambiguation be ? ToTemporalDisambiguation(options). + auto disambiguation = TRY(to_temporal_disambiguation(global_object, options)); - // 9. Let offsetOption be ? ToTemporalOffset(options, "reject"). - auto offset_option = TRY(to_temporal_offset(global_object, *options, "reject")); + // 10. Let offsetOption be ? ToTemporalOffset(options, "reject"). + auto offset_option = TRY(to_temporal_offset(global_object, options, "reject")); - // 10. Let epochNanoseconds be ? InterpretISODateTimeOffset(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour). + // 11. Let epochNanoseconds be ? InterpretISODateTimeOffset(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour). auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, offset_behavior, offset_nanoseconds, time_zone, disambiguation, offset_option, match_behavior)); - // 11. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). + // 12. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). return MUST(create_temporal_zoned_date_time(global_object, *epoch_nanoseconds, *time_zone, *calendar)); } @@ -367,38 +366,37 @@ ThrowCompletionOr temporal_zoned_date_time_to_string(GlobalObject& globa // 6.5.5 AddZonedDateTime ( epochNanoseconds, timeZone, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-addzoneddatetime ThrowCompletionOr add_zoned_date_time(GlobalObject& global_object, BigInt const& epoch_nanoseconds, Value time_zone, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options) { - // 1. If options is not present, set options to OrdinaryObjectCreate(null). - if (!options) - options = Object::create(global_object, nullptr); + // 1. If options is not present, set options to undefined. + // 2. Assert: Type(options) is Object or Undefined. - // 2. If all of years, months, weeks, and days are 0, then + // 3. If all of years, months, weeks, and days are 0, then if (years == 0 && months == 0 && weeks == 0 && days == 0) { // a. Return ! AddInstant(epochNanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds). return MUST(add_instant(global_object, epoch_nanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds)); } - // 3. Let instant be ! CreateTemporalInstant(epochNanoseconds). + // 4. Let instant be ! CreateTemporalInstant(epochNanoseconds). auto* instant = MUST(create_temporal_instant(global_object, epoch_nanoseconds)); - // 4. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar). + // 5. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar). auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(global_object, time_zone, *instant, calendar)); - // 5. Let datePart be ? CreateTemporalDate(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], calendar). + // 6. Let datePart be ? CreateTemporalDate(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], calendar). auto* date_part = TRY(create_temporal_date(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), calendar)); - // 6. Let dateDuration be ! CreateTemporalDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0). + // 7. Let dateDuration be ! CreateTemporalDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0). auto* date_duration = MUST(create_temporal_duration(global_object, years, months, weeks, days, 0, 0, 0, 0, 0, 0)); - // 7. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options). + // 8. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options). auto* added_date = TRY(calendar_date_add(global_object, calendar, date_part, *date_duration, options)); - // 8. Let intermediateDateTime be ? CreateTemporalDateTime(addedDate.[[ISOYear]], addedDate.[[ISOMonth]], addedDate.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], calendar). + // 9. Let intermediateDateTime be ? CreateTemporalDateTime(addedDate.[[ISOYear]], addedDate.[[ISOMonth]], addedDate.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], calendar). auto* intermediate_date_time = TRY(create_temporal_date_time(global_object, added_date->iso_year(), added_date->iso_month(), added_date->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), calendar)); - // 9. Let intermediateInstant be ? BuiltinTimeZoneGetInstantFor(timeZone, intermediateDateTime, "compatible"). + // 10. Let intermediateInstant be ? BuiltinTimeZoneGetInstantFor(timeZone, intermediateDateTime, "compatible"). auto* intermediate_instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *intermediate_date_time, "compatible"sv)); - // 10. Return ! AddInstant(intermediateInstant.[[Nanoseconds]], hours, minutes, seconds, milliseconds, microseconds, nanoseconds). + // 11. Return ! AddInstant(intermediateInstant.[[Nanoseconds]], hours, minutes, seconds, milliseconds, microseconds, nanoseconds). return MUST(add_instant(global_object, intermediate_instant->nanoseconds(), hours, minutes, seconds, milliseconds, microseconds, nanoseconds)); } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp index 71b807f2c9..64f16cb0d4 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021-2022, Linus Groh * Copyright (c) 2021, Luke Wilde * * SPDX-License-Identifier: BSD-2-Clause @@ -83,13 +83,13 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimeConstructor::from) auto& item_object = static_cast(item.as_object()); // a. Perform ? ToTemporalOverflow(options). - (void)TRY(to_temporal_overflow(global_object, *options)); + (void)TRY(to_temporal_overflow(global_object, options)); // b. Perform ? ToTemporalDisambiguation(options). - (void)TRY(to_temporal_disambiguation(global_object, *options)); + (void)TRY(to_temporal_disambiguation(global_object, options)); // c. Perform ? ToTemporalOffset(options, "reject"). - (void)TRY(to_temporal_offset(global_object, *options, "reject")); + (void)TRY(to_temporal_offset(global_object, options, "reject")); // d. Return ! CreateTemporalZonedDateTime(item.[[Nanoseconds]], item.[[TimeZone]], item.[[Calendar]]). return MUST(create_temporal_zoned_date_time(global_object, item_object.nanoseconds(), item_object.time_zone(), item_object.calendar())); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp index 1f5319cf5d..b080f45ac0 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp @@ -751,10 +751,10 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with) auto* options = TRY(get_options_object(global_object, vm.argument(1))); // 10. Let disambiguation be ? ToTemporalDisambiguation(options). - auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); + auto disambiguation = TRY(to_temporal_disambiguation(global_object, options)); // 11. Let offset be ? ToTemporalOffset(options, "prefer"). - auto offset = TRY(to_temporal_offset(global_object, *options, "prefer"sv)); + auto offset = TRY(to_temporal_offset(global_object, options, "prefer"sv)); // 12. Let timeZone be zonedDateTime.[[TimeZone]]. auto& time_zone = zoned_date_time->time_zone();