mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:17:35 +00:00
LibJS: Require 'T' prefix for ambiguous time-only strings
This is a normative change in the Temporal spec.
See: 514ede3
This commit is contained in:
parent
a73c71e877
commit
3ab1c52e2b
4 changed files with 443 additions and 29 deletions
|
@ -416,6 +416,169 @@ bool ISO8601Parser::parse_time_second()
|
|||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeHourNotValidMonth
|
||||
bool ISO8601Parser::parse_time_hour_not_valid_month()
|
||||
{
|
||||
// TimeHourNotValidMonth : one of
|
||||
// 00 13 14 15 16 17 18 19 20 21 23
|
||||
StateTransaction transaction { *this };
|
||||
auto success = m_state.lexer.consume_specific("00"sv)
|
||||
|| m_state.lexer.consume_specific("13"sv)
|
||||
|| m_state.lexer.consume_specific("14"sv)
|
||||
|| m_state.lexer.consume_specific("15"sv)
|
||||
|| m_state.lexer.consume_specific("16"sv)
|
||||
|| m_state.lexer.consume_specific("17"sv)
|
||||
|| m_state.lexer.consume_specific("18"sv)
|
||||
|| m_state.lexer.consume_specific("19"sv)
|
||||
|| m_state.lexer.consume_specific("20"sv)
|
||||
|| m_state.lexer.consume_specific("21"sv)
|
||||
|| m_state.lexer.consume_specific("22"sv)
|
||||
|| m_state.lexer.consume_specific("23"sv);
|
||||
if (!success)
|
||||
return false;
|
||||
m_state.parse_result.time_hour_not_valid_month = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeHourNotThirtyOneDayMonth
|
||||
bool ISO8601Parser::parse_time_hour_not_thirty_one_day_month()
|
||||
{
|
||||
// TimeHourNotThirtyOneDayMonth : one of
|
||||
// 02 04 06 09 11
|
||||
StateTransaction transaction { *this };
|
||||
auto success = m_state.lexer.consume_specific("02"sv)
|
||||
|| m_state.lexer.consume_specific("04"sv)
|
||||
|| m_state.lexer.consume_specific("06"sv)
|
||||
|| m_state.lexer.consume_specific("09"sv)
|
||||
|| m_state.lexer.consume_specific("11"sv);
|
||||
if (!success)
|
||||
return false;
|
||||
m_state.parse_result.time_hour_not_thirty_one_day_month = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeHourTwoOnly
|
||||
bool ISO8601Parser::parse_time_hour_two_only()
|
||||
{
|
||||
// TimeHourTwoOnly :
|
||||
// 02
|
||||
StateTransaction transaction { *this };
|
||||
if (!m_state.lexer.consume_specific("02"sv))
|
||||
return false;
|
||||
m_state.parse_result.time_hour_two_only = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeMinuteNotValidDay
|
||||
bool ISO8601Parser::parse_time_minute_not_valid_day()
|
||||
{
|
||||
// TimeMinuteNotValidDay :
|
||||
// 00
|
||||
// 32
|
||||
// 33
|
||||
// 34
|
||||
// 35
|
||||
// 36
|
||||
// 37
|
||||
// 38
|
||||
// 39
|
||||
// 4 DecimalDigit
|
||||
// 5 DecimalDigit
|
||||
// 60
|
||||
StateTransaction transaction { *this };
|
||||
if (m_state.lexer.consume_specific('4') || m_state.lexer.consume_specific('5')) {
|
||||
if (!parse_decimal_digit())
|
||||
return false;
|
||||
} else {
|
||||
auto success = m_state.lexer.consume_specific("00"sv)
|
||||
|| m_state.lexer.consume_specific("32"sv)
|
||||
|| m_state.lexer.consume_specific("33"sv)
|
||||
|| m_state.lexer.consume_specific("34"sv)
|
||||
|| m_state.lexer.consume_specific("35"sv)
|
||||
|| m_state.lexer.consume_specific("36"sv)
|
||||
|| m_state.lexer.consume_specific("37"sv)
|
||||
|| m_state.lexer.consume_specific("38"sv)
|
||||
|| m_state.lexer.consume_specific("39"sv)
|
||||
|| m_state.lexer.consume_specific("60"sv);
|
||||
if (!success)
|
||||
return false;
|
||||
}
|
||||
m_state.parse_result.time_minute_not_valid_day = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeMinuteThirtyOnly
|
||||
bool ISO8601Parser::parse_time_minute_thirty_only()
|
||||
{
|
||||
// TimeMinuteThirtyOnly :
|
||||
// 30
|
||||
StateTransaction transaction { *this };
|
||||
if (!m_state.lexer.consume_specific("30"sv))
|
||||
return false;
|
||||
m_state.parse_result.time_minute_thirty_only = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeMinuteThirtyOneOnly
|
||||
bool ISO8601Parser::parse_time_minute_thirty_one_only()
|
||||
{
|
||||
// TimeMinuteThirtyOneOnly :
|
||||
// 31
|
||||
StateTransaction transaction { *this };
|
||||
if (!m_state.lexer.consume_specific("31"sv))
|
||||
return false;
|
||||
m_state.parse_result.time_minute_thirty_one_only = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeSecondNotValidMonth
|
||||
bool ISO8601Parser::parse_time_second_not_valid_month()
|
||||
{
|
||||
// TimeSecondNotValidMonth :
|
||||
// 00
|
||||
// 13
|
||||
// 14
|
||||
// 15
|
||||
// 16
|
||||
// 17
|
||||
// 18
|
||||
// 19
|
||||
// 2 DecimalDigit
|
||||
// 3 DecimalDigit
|
||||
// 4 DecimalDigit
|
||||
// 5 DecimalDigit
|
||||
// 60
|
||||
StateTransaction transaction { *this };
|
||||
if (m_state.lexer.consume_specific('2')
|
||||
|| m_state.lexer.consume_specific('3')
|
||||
|| m_state.lexer.consume_specific('4')
|
||||
|| m_state.lexer.consume_specific('5')) {
|
||||
if (!parse_decimal_digit())
|
||||
return false;
|
||||
} else {
|
||||
auto success = m_state.lexer.consume_specific("00"sv)
|
||||
|| m_state.lexer.consume_specific("13"sv)
|
||||
|| m_state.lexer.consume_specific("14"sv)
|
||||
|| m_state.lexer.consume_specific("15"sv)
|
||||
|| m_state.lexer.consume_specific("16"sv)
|
||||
|| m_state.lexer.consume_specific("17"sv)
|
||||
|| m_state.lexer.consume_specific("18"sv)
|
||||
|| m_state.lexer.consume_specific("19"sv)
|
||||
|| m_state.lexer.consume_specific("60"sv);
|
||||
if (!success)
|
||||
return false;
|
||||
}
|
||||
m_state.parse_result.time_second_not_valid_month = transaction.parsed_string_view();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-FractionalPart
|
||||
bool ISO8601Parser::parse_fractional_part()
|
||||
{
|
||||
|
@ -576,6 +739,61 @@ bool ISO8601Parser::parse_time_zone_utc_offset()
|
|||
|| parse_utc_designator();
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeZoneNumericUTCOffsetNotAmbiguous
|
||||
bool ISO8601Parser::parse_time_zone_numeric_utc_offset_not_ambiguous()
|
||||
{
|
||||
// TimeZoneNumericUTCOffsetNotAmbiguous :
|
||||
// + TimeZoneUTCOffsetHour
|
||||
// U+2212 TimeZoneUTCOffsetHour
|
||||
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour : TimeZoneUTCOffsetMinute
|
||||
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour TimeZoneUTCOffsetMinute
|
||||
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour : TimeZoneUTCOffsetMinute : TimeZoneUTCOffsetSecond TimeZoneUTCOffsetFraction[opt]
|
||||
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour TimeZoneUTCOffsetMinute TimeZoneUTCOffsetSecond TimeZoneUTCOffsetFraction[opt]
|
||||
StateTransaction transaction { *this };
|
||||
if (m_state.lexer.consume_specific('+') || m_state.lexer.consume_specific("\xE2\x88\x92"sv)) {
|
||||
if (!parse_time_zone_utc_offset_hour())
|
||||
return false;
|
||||
} else {
|
||||
if (!parse_time_zone_utc_offset_sign())
|
||||
return false;
|
||||
if (!parse_time_zone_utc_offset_hour())
|
||||
return false;
|
||||
if (m_state.lexer.consume_specific(':')) {
|
||||
if (!parse_time_zone_utc_offset_minute())
|
||||
return false;
|
||||
if (m_state.lexer.consume_specific(':')) {
|
||||
if (!parse_time_zone_utc_offset_second())
|
||||
return false;
|
||||
(void)parse_time_zone_utc_offset_fraction();
|
||||
}
|
||||
} else {
|
||||
if (!parse_time_zone_utc_offset_minute())
|
||||
return false;
|
||||
if (parse_time_zone_utc_offset_second())
|
||||
(void)parse_time_zone_utc_offset_fraction();
|
||||
}
|
||||
}
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeZoneNumericUTCOffsetNotAmbiguousAllowedNegativeHour
|
||||
bool ISO8601Parser::parse_time_zone_numeric_utc_offset_not_ambiguous_allowed_negative_hour()
|
||||
{
|
||||
// TimeZoneNumericUTCOffsetNotAmbiguousAllowedNegativeHour :
|
||||
// TimeZoneNumericUTCOffsetNotAmbiguous
|
||||
// - TimeHourNotValidMonth
|
||||
StateTransaction transaction { *this };
|
||||
if (!parse_time_zone_numeric_utc_offset_not_ambiguous()) {
|
||||
if (!m_state.lexer.consume_specific('-'))
|
||||
return false;
|
||||
if (!parse_time_hour_not_valid_month())
|
||||
return false;
|
||||
}
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetName
|
||||
bool ISO8601Parser::parse_time_zone_utc_offset_name()
|
||||
{
|
||||
|
@ -786,6 +1004,120 @@ bool ISO8601Parser::parse_time_spec()
|
|||
return true;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeHourMinuteBasicFormatNotAmbiguous
|
||||
bool ISO8601Parser::parse_time_hour_minute_basic_format_not_ambiguous()
|
||||
{
|
||||
// TimeHourMinuteBasicFormatNotAmbiguous :
|
||||
// TimeHourNotValidMonth TimeMinute
|
||||
// TimeHour TimeMinuteNotValidDay
|
||||
// TimeHourNotThirtyOneDayMonth TimeMinuteThirtyOneOnly
|
||||
// TimeHourTwoOnly TimeMinuteThirtyOnly
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour_not_valid_month() && parse_time_minute()) {
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour() && parse_time_minute_not_valid_day()) {
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour_not_thirty_one_day_month() && parse_time_minute_thirty_one_only()) {
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour_two_only() && parse_time_minute_thirty_only()) {
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeSpecWithOptionalTimeZoneNotAmbiguous
|
||||
bool ISO8601Parser::parse_time_spec_with_optional_time_zone_not_ambiguous()
|
||||
{
|
||||
// TimeSpecWithOptionalTimeZoneNotAmbiguous :
|
||||
// TimeHour TimeZoneNumericUTCOffsetNotAmbiguous[opt] TimeZoneBracketedAnnotation[opt]
|
||||
// TimeHourNotValidMonth TimeZone
|
||||
// TimeHour : TimeMinute TimeZone[opt]
|
||||
// TimeHourMinuteBasicFormatNotAmbiguous TimeZoneBracketedAnnotation[opt]
|
||||
// TimeHour TimeMinute TimeZoneNumericUTCOffsetNotAmbiguousAllowedNegativeHour TimeZoneBracketedAnnotation[opt]
|
||||
// TimeHour : TimeMinute : TimeSecond TimeFraction[opt] TimeZone[opt]
|
||||
// TimeHour TimeMinute TimeSecondNotValidMonth TimeZone[opt]
|
||||
// TimeHour TimeMinute TimeSecond TimeFraction TimeZone[opt]
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour()) {
|
||||
if (m_state.lexer.consume_specific(':')) {
|
||||
if (parse_time_minute()) {
|
||||
if (m_state.lexer.consume_specific(':')) {
|
||||
if (parse_time_second()) {
|
||||
(void)parse_time_fraction();
|
||||
(void)parse_time_zone();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
(void)parse_time_zone();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (parse_time_minute()) {
|
||||
if (parse_time_zone_numeric_utc_offset_not_ambiguous_allowed_negative_hour()) {
|
||||
(void)parse_time_zone_bracketed_annotation();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
{
|
||||
StateTransaction sub_transaction { *this };
|
||||
if (parse_time_second() && parse_time_fraction()) {
|
||||
(void)parse_time_zone();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (parse_time_second_not_valid_month()) {
|
||||
(void)parse_time_zone();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
(void)parse_time_zone_numeric_utc_offset_not_ambiguous();
|
||||
(void)parse_time_zone_bracketed_annotation();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour_not_valid_month() && parse_time_zone()) {
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_hour_minute_basic_format_not_ambiguous()) {
|
||||
(void)parse_time_zone_bracketed_annotation();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-TimeSpecSeparator
|
||||
bool ISO8601Parser::parse_time_spec_separator()
|
||||
{
|
||||
|
@ -816,15 +1148,29 @@ bool ISO8601Parser::parse_date_time()
|
|||
bool ISO8601Parser::parse_calendar_time()
|
||||
{
|
||||
// CalendarTime :
|
||||
// TimeDesignator[opt] TimeSpec TimeZone[opt] Calendar[opt]
|
||||
StateTransaction transaction { *this };
|
||||
(void)parse_time_designator();
|
||||
if (!parse_time_spec())
|
||||
return false;
|
||||
(void)parse_time_zone();
|
||||
(void)parse_calendar();
|
||||
transaction.commit();
|
||||
return true;
|
||||
// TimeDesignator TimeSpec TimeZone[opt] Calendar[opt]
|
||||
// TimeSpec TimeZone[opt] Calendar
|
||||
// TimeSpecWithOptionalTimeZoneNotAmbiguous
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_designator() && parse_time_spec()) {
|
||||
(void)parse_time_zone();
|
||||
(void)parse_calendar();
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
StateTransaction transaction { *this };
|
||||
if (parse_time_spec()) {
|
||||
(void)parse_time_zone();
|
||||
if (parse_calendar()) {
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parse_time_spec_with_optional_time_zone_not_ambiguous();
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-temporal/#prod-CalendarDateTime
|
||||
|
@ -1336,4 +1682,5 @@ Optional<ParseResult> parse_iso8601(Production production, StringView input)
|
|||
|
||||
return parser.parse_result();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue