From 54af3a539627ddbc7f6c487f6596ae3ce5ec8253 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 10 Mar 2022 18:10:11 +0100 Subject: [PATCH] LibJS: Adjust grammar for DateExtendedYear to exclude -000000 This is an editorial change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/fb3e656 We lose the custom error message, but it's not the end of the world. --- Userland/Libraries/LibJS/Runtime/ErrorTypes.h | 1 - .../Runtime/Temporal/AbstractOperations.cpp | 32 ++++++++----------- .../LibJS/Runtime/Temporal/ISO8601.cpp | 3 ++ .../Temporal/PlainDate/PlainDate.from.js | 4 +-- .../PlainDateTime/PlainDateTime.from.js | 4 +-- .../PlainMonthDay/PlainMonthDay.from.js | 4 +-- .../Temporal/PlainTime/PlainTime.from.js | 4 +-- .../PlainYearMonth/PlainYearMonth.from.js | 6 ++-- 8 files changed, 28 insertions(+), 30 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h index 3086483b7b..91f4019f41 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h +++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h @@ -236,7 +236,6 @@ M(TemporalInvalidDurationString, "Invalid duration string '{}'") \ M(TemporalInvalidDurationStringFractionNotLast, "Invalid duration string '{}': fractional {} must not be proceeded by {}") \ M(TemporalInvalidEpochNanoseconds, "Invalid epoch nanoseconds value, must be in range -86400 * 10^17 to 86400 * 10^17") \ - M(TemporalInvalidExtendedYearNegativeZero, "Invalid extended year, must not be negative zero") \ M(TemporalInvalidInstantString, "Invalid instant string '{}'") \ M(TemporalInvalidISODate, "Invalid ISO date") \ M(TemporalInvalidMonthCode, "Invalid month code") \ diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp index 341108a138..332d8916da 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp @@ -1113,47 +1113,43 @@ ThrowCompletionOr parse_iso_date_time(GlobalObject& global_object, else normalized_year = year_part.value_or("0"); - // 7. If SameValue(year, "-000000") is true, throw a RangeError exception. - if (normalized_year == "-000000"sv) - return vm.throw_completion(global_object, ErrorType::TemporalInvalidExtendedYearNegativeZero); - - // 8. Set year to ! ToIntegerOrInfinity(year). + // 7. Set year to ! ToIntegerOrInfinity(year). auto year = *normalized_year.to_int(); u8 month; - // 9. If month is undefined, then + // 8. If month is undefined, then if (!month_part.has_value()) { // a. Set month to 1. month = 1; } - // 10. Else, + // 9. Else, else { // a. Set month to ! ToIntegerOrInfinity(month). month = *month_part->to_uint(); } u8 day; - // 11. If day is undefined, then + // 10. If day is undefined, then if (!day_part.has_value()) { // a. Set day to 1. day = 1; } - // 12. Else, + // 11. Else, else { // a. Set day to ! ToIntegerOrInfinity(day). day = *day_part->to_uint(); } - // 13. Set hour to ! ToIntegerOrInfinity(hour). + // 12. Set hour to ! ToIntegerOrInfinity(hour). u8 hour = *hour_part.value_or("0"sv).to_uint(); - // 14. Set minute to ! ToIntegerOrInfinity(minute). + // 13. Set minute to ! ToIntegerOrInfinity(minute). u8 minute = *minute_part.value_or("0"sv).to_uint(); - // 15. Set second to ! ToIntegerOrInfinity(second). + // 14. Set second to ! ToIntegerOrInfinity(second). u8 second = *second_part.value_or("0"sv).to_uint(); - // 16. If second is 60, then + // 15. If second is 60, then if (second == 60) { // a. Set second to 59. second = 59; @@ -1162,7 +1158,7 @@ ThrowCompletionOr parse_iso_date_time(GlobalObject& global_object, u16 millisecond; u16 microsecond; u16 nanosecond; - // 17. If fraction is not undefined, then + // 16. If fraction is not undefined, then if (fraction_part.has_value()) { // a. Set fraction to the string-concatenation of the previous value of fraction and the string "000000000". auto fraction = String::formatted("{}000000000", *fraction_part); @@ -1176,7 +1172,7 @@ ThrowCompletionOr parse_iso_date_time(GlobalObject& global_object, // g. Set nanosecond to ! ToIntegerOrInfinity(nanosecond). nanosecond = *fraction.substring(7, 3).to_uint(); } - // 18. Else, + // 17. Else, else { // a. Let millisecond be 0. millisecond = 0; @@ -1186,15 +1182,15 @@ ThrowCompletionOr parse_iso_date_time(GlobalObject& global_object, nanosecond = 0; } - // 19. If ! IsValidISODate(year, month, day) is false, throw a RangeError exception. + // 18. If ! IsValidISODate(year, month, day) is false, throw a RangeError exception. if (!is_valid_iso_date(year, month, day)) return vm.throw_completion(global_object, ErrorType::TemporalInvalidISODate); - // 20. If ! IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception. + // 19. 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::TemporalInvalidTime); - // 21. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond, [[Calendar]]: calendar }. + // 20. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond, [[Calendar]]: calendar }. return ISODateTime { .year = year, .month = month, .day = day, .hour = hour, .minute = minute, .second = second, .millisecond = millisecond, .microsecond = microsecond, .nanosecond = nanosecond, .calendar = Optional(move(calendar_part)) }; } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp index 1777237b69..f55e215686 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp @@ -265,6 +265,9 @@ bool ISO8601Parser::parse_date_year() return false; } } + // It is a Syntax Error if DateExtendedYear is "-000000" or "−000000" (U+2212 MINUS SIGN followed by 000000). + if (transaction.parsed_string_view().is_one_of("-000000"sv, "−000000"sv)) + return false; m_state.parse_result.date_year = transaction.parsed_string_view(); transaction.commit(); return true; diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js index 5a52b58e2c..31e6b88c91 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js @@ -53,9 +53,9 @@ describe("errors", () => { test("extended year must not be negative zero", () => { expect(() => { Temporal.PlainDate.from("-000000-01-01"); - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid date string '-000000-01-01'"); expect(() => { Temporal.PlainDate.from("−000000-01-01"); // U+2212 - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid date string '−000000-01-01'"); }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js index 66cea37352..6b2bd77350 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js @@ -190,9 +190,9 @@ describe("errors", () => { test("extended year must not be negative zero", () => { expect(() => { Temporal.PlainDateTime.from("-000000-01-01"); - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid date time string '-000000-01-01'"); expect(() => { Temporal.PlainDateTime.from("−000000-01-01"); // U+2212 - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid date time string '−000000-01-01'"); }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainMonthDay/PlainMonthDay.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainMonthDay/PlainMonthDay.from.js index bedcd2952e..276f676237 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainMonthDay/PlainMonthDay.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainMonthDay/PlainMonthDay.from.js @@ -79,9 +79,9 @@ describe("errors", () => { test("extended year must not be negative zero", () => { expect(() => { Temporal.PlainMonthDay.from("-000000-01-01"); - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid month day string '-000000-01-01'"); expect(() => { Temporal.PlainMonthDay.from("−000000-01-01"); // U+2212 - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid month day string '−000000-01-01'"); }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js index d223b2f07e..9ff8e384ee 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js @@ -68,10 +68,10 @@ describe("errors", () => { test("extended year must not be negative zero", () => { expect(() => { Temporal.PlainTime.from("-000000-01-01T00:00:00"); - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid time string '-000000-01-01T00:00:00'"); expect(() => { Temporal.PlainTime.from("−000000-01-01T00:00:00"); // U+2212 - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid time string '−000000-01-01T00:00:00'"); }); test("ambiguous string must contain a time designator", () => { diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js index 62348189e2..75cbfce1ae 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js @@ -105,9 +105,9 @@ describe("errors", () => { test("extended year must not be negative zero", () => { expect(() => { Temporal.PlainYearMonth.from("-000000-01"); - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + }).toThrowWithMessage(RangeError, "Invalid year month string '-000000-01'"); expect(() => { - Temporal.PlainYearMonth.from("−000000-01-01"); // U+2212 - }).toThrowWithMessage(RangeError, "Invalid extended year, must not be negative zero"); + Temporal.PlainYearMonth.from("−000000-01"); // U+2212 + }).toThrowWithMessage(RangeError, "Invalid year month string '−000000-01'"); }); });