From 690585323d174d6138d51d3741b584a6cf0f4425 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 14 Jun 2022 23:40:58 +0100 Subject: [PATCH] LibJS: Prefer Else + Assertion over If for constrained values This is an editorial change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/2088eaa --- .../LibJS/Runtime/Temporal/PlainDate.cpp | 38 ++++++++++--------- .../LibJS/Runtime/Temporal/PlainTime.cpp | 12 +++--- .../LibJS/Runtime/Temporal/PlainYearMonth.cpp | 12 +++--- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp index 1139aa3b54..4ce2f1cf85 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp @@ -266,27 +266,30 @@ DateDurationRecord difference_iso_date(GlobalObject& global_object, i32 year1, u // t. Return ! CreateDateDurationRecord(years, months, 0, days). return create_date_duration_record(years, months, 0, days); } - // 2. If largestUnit is "day" or "week", then + // 2. Else, else { - // a. Let epochDays1 be MakeDay(𝔽(y1), 𝔽(m1 - 1), 𝔽(d1)). + // a. Assert: largestUnit is "day" or "week". + VERIFY(largest_unit.is_one_of("day"sv, "week"sv)); + + // b. Let epochDays1 be MakeDay(𝔽(y1), 𝔽(m1 - 1), 𝔽(d1)). auto epoch_days_1 = make_day(year1, month1 - 1, day1); - // b. Assert: epochDays1 is finite. + // c. Assert: epochDays1 is finite. VERIFY(isfinite(epoch_days_1)); - // c. Let epochDays2 be MakeDay(𝔽(y2), 𝔽(m2 - 1), 𝔽(d2)). + // d. Let epochDays2 be MakeDay(𝔽(y2), 𝔽(m2 - 1), 𝔽(d2)). auto epoch_days_2 = make_day(year2, month2 - 1, day2); - // d. Assert: epochDays2 is finite. + // e. Assert: epochDays2 is finite. VERIFY(isfinite(epoch_days_2)); - // e. Let days be ℝ(epochDays2) - ℝ(epochDays1). + // f. Let days be ℝ(epochDays2) - ℝ(epochDays1). auto days = epoch_days_2 - epoch_days_1; - // f. Let weeks be 0. + // g. Let weeks be 0. double weeks = 0; - // g. If largestUnit is "week", then + // h. If largestUnit is "week", then if (largest_unit == "week"sv) { // i. Set weeks to RoundTowardsZero(days / 7). weeks = trunc(days / 7); @@ -295,10 +298,9 @@ DateDurationRecord difference_iso_date(GlobalObject& global_object, i32 year1, u days = fmod(days, 7); } - // h. Return ! CreateDateDurationRecord(0, 0, weeks, days). + // i. Return ! CreateDateDurationRecord(0, 0, weeks, days). return create_date_duration_record(0, 0, weeks, days); } - VERIFY_NOT_REACHED(); } // 3.5.4 RegulateISODate ( year, month, day, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulateisodate @@ -326,27 +328,29 @@ ThrowCompletionOr regulate_iso_date(GlobalObject& global_object, // b. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day }. return ISODateRecord { .year = y, .month = m, .day = d }; } - // 2. If overflow is "constrain", then - else if (overflow == "constrain"sv) { + // 2. Else, + else { + // a. Assert: overflow is "constrain". + VERIFY(overflow == "constrain"sv); + // IMPLEMENTATION DEFINED: This is an optimization that allows us to treat this double as normal integer from this point onwards. This // does not change the exposed behavior as the parent's call to CreateTemporalDate will immediately check that this value is a valid // ISO value for years: -273975 - 273975, which is a subset of this check. if (!AK::is_within_range(year)) return vm.throw_completion(global_object, ErrorType::TemporalInvalidPlainDate); - // a. Set month to the result of clamping month between 1 and 12. + // b. Set month to the result of clamping month between 1 and 12. month = clamp(month, 1, 12); - // b. Let daysInMonth be ! ISODaysInMonth(year, month). + // c. Let daysInMonth be ! ISODaysInMonth(year, month). auto days_in_month = iso_days_in_month(static_cast(year), static_cast(month)); - // c. Set day to the result of clamping day between 1 and daysInMonth. + // d. Set day to the result of clamping day between 1 and daysInMonth. day = clamp(day, 1, days_in_month); - // d. Return CreateISODateRecord(year, month, day). + // e. Return CreateISODateRecord(year, month, day). return create_iso_date_record(static_cast(year), static_cast(month), static_cast(day)); } - VERIFY_NOT_REACHED(); } // 3.5.5 IsValidISODate ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidisodate diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp index 2c1ac87cce..af7e3676b3 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp @@ -168,18 +168,18 @@ ThrowCompletionOr regulate_time(GlobalObject& global_object, doubl // a. Return ! ConstrainTime(hour, minute, second, millisecond, microsecond, nanosecond). return constrain_time(hour, minute, second, millisecond, microsecond, nanosecond); } + // 4. Else, + else { + // a. Assert: overflow is "reject". + VERIFY(overflow == "reject"sv); - // 4. If overflow is "reject", then - if (overflow == "reject"sv) { - // a. If IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception. + // b. If IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception. if (!is_valid_time(hour, minute, second, millisecond, microsecond, nanosecond)) return vm.throw_completion(global_object, ErrorType::TemporalInvalidPlainTime); - // b. Return the Record { [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }. + // c. Return the Record { [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }. return TemporalTime { .hour = static_cast(hour), .minute = static_cast(minute), .second = static_cast(second), .millisecond = static_cast(millisecond), .microsecond = static_cast(microsecond), .nanosecond = static_cast(nanosecond) }; } - - VERIFY_NOT_REACHED(); } // 4.5.4 IsValidTime ( hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidtime diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp index 39fd9f5267..cf8663e025 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp @@ -106,24 +106,24 @@ ThrowCompletionOr regulate_iso_year_month(GlobalObject& global_obj // a. Return ! ConstrainISOYearMonth(year, month). return constrain_iso_year_month(year, month); } + // 4. Else, + else { + // a. Assert: overflow is "reject". + VERIFY(overflow == "reject"sv); - // 4. If overflow is "reject", then - if (overflow == "reject"sv) { // IMPLEMENTATION DEFINED: This is an optimization that allows us to treat these doubles as normal integers from this point onwards. // This does not change the exposed behavior as the call to IsValidISOMonth and subsequent call to CreateTemporalDateTime will check // that these values are valid ISO values (for years: -273975 - 273975, for months: 1 - 12) all of which are subsets of this check. if (!AK::is_within_range(year) || !AK::is_within_range(month)) return vm.throw_completion(global_object, ErrorType::TemporalInvalidPlainYearMonth); - // a. If ! IsValidISOMonth(month) is false, throw a RangeError exception. + // b. If ! IsValidISOMonth(month) is false, throw a RangeError exception. if (!is_valid_iso_month(month)) return vm.throw_completion(global_object, ErrorType::TemporalInvalidPlainYearMonth); - // b. Return the Record { [[Year]]: year, [[Month]]: month }. + // c. Return the Record { [[Year]]: year, [[Month]]: month }. return ISOYearMonth { .year = static_cast(year), .month = static_cast(month), .reference_iso_day = 0 }; } - - VERIFY_NOT_REACHED(); } // 9.5.3 IsValidISOMonth ( month ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidisomonth