mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:07:45 +00:00
LibJS: Fully parse the TimeZoneIANAName production
Currently does nothing as we'll declare everything other than UTC as invalid, but it's a first step towards supporting named time zones :^)
This commit is contained in:
parent
6a4d06e739
commit
3bd7f5b89e
3 changed files with 64 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -824,31 +824,81 @@ bool ISO8601Parser::parse_time_zone_utc_offset_name()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tc39.es/proposal-temporal/#prod-TimeZoneIANAName
|
// https://tc39.es/proposal-temporal/#prod-TZLeadingChar
|
||||||
bool ISO8601Parser::parse_time_zone_iana_name()
|
bool ISO8601Parser::parse_tz_leading_char()
|
||||||
{
|
{
|
||||||
// TZLeadingChar :
|
// TZLeadingChar :
|
||||||
// Alpha
|
// Alpha
|
||||||
// .
|
// .
|
||||||
// _
|
// _
|
||||||
|
if (m_state.lexer.next_is(is_ascii_alpha)) {
|
||||||
|
m_state.lexer.consume();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return m_state.lexer.consume_specific('.')
|
||||||
|
|| m_state.lexer.consume_specific('_');
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.es/proposal-temporal/#prod-TZChar
|
||||||
|
bool ISO8601Parser::parse_tz_char()
|
||||||
|
{
|
||||||
// TZChar :
|
// TZChar :
|
||||||
// Alpha
|
// Alpha
|
||||||
// .
|
// .
|
||||||
// -
|
// -
|
||||||
// _
|
// _
|
||||||
|
if (m_state.lexer.next_is(is_ascii_alpha)) {
|
||||||
|
m_state.lexer.consume();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return m_state.lexer.consume_specific('.')
|
||||||
|
|| m_state.lexer.consume_specific('-')
|
||||||
|
|| m_state.lexer.consume_specific('_');
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.es/proposal-temporal/#prod-TimeZoneIANANameComponent
|
||||||
|
bool ISO8601Parser::parse_time_zone_iana_component()
|
||||||
|
{
|
||||||
// TimeZoneIANANameComponent :
|
// TimeZoneIANANameComponent :
|
||||||
// TZLeadingChar TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] but not one of . or ..
|
// TZLeadingChar TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] but not one of . or ..
|
||||||
|
StateTransaction transaction { *this };
|
||||||
|
if (!parse_tz_leading_char())
|
||||||
|
return false;
|
||||||
|
for (size_t i = 0; i < 13; ++i) {
|
||||||
|
if (!parse_tz_char())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (transaction.parsed_string_view().is_one_of("."sv, ".."sv))
|
||||||
|
return false;
|
||||||
|
transaction.commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.es/proposal-temporal/#prod-TimeZoneIANANameTail
|
||||||
|
bool ISO8601Parser::parse_time_zone_iana_name_tail()
|
||||||
|
{
|
||||||
// TimeZoneIANANameTail :
|
// TimeZoneIANANameTail :
|
||||||
// TimeZoneIANANameComponent
|
// TimeZoneIANANameComponent
|
||||||
// TimeZoneIANANameComponent / TimeZoneIANANameTail
|
// TimeZoneIANANameComponent / TimeZoneIANANameTail
|
||||||
|
StateTransaction transaction { *this };
|
||||||
|
if (!parse_time_zone_iana_component())
|
||||||
|
return false;
|
||||||
|
while (m_state.lexer.next_is('/')) {
|
||||||
|
m_state.lexer.consume();
|
||||||
|
if (!parse_time_zone_iana_component())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
transaction.commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.es/proposal-temporal/#prod-TimeZoneIANAName
|
||||||
|
bool ISO8601Parser::parse_time_zone_iana_name()
|
||||||
|
{
|
||||||
// TimeZoneIANAName :
|
// TimeZoneIANAName :
|
||||||
// TimeZoneIANANameTail
|
// TimeZoneIANANameTail
|
||||||
StateTransaction transaction { *this };
|
StateTransaction transaction { *this };
|
||||||
// TODO: Implement the full production. Currently, anything other than "UTC" would get rejected as unknown anyway.
|
if (!parse_time_zone_iana_name_tail())
|
||||||
auto success = (m_state.lexer.consume_specific('U') || m_state.lexer.consume_specific('u'))
|
|
||||||
&& (m_state.lexer.consume_specific('T') || m_state.lexer.consume_specific('t'))
|
|
||||||
&& (m_state.lexer.consume_specific('C') || m_state.lexer.consume_specific('c'));
|
|
||||||
if (!success)
|
|
||||||
return false;
|
return false;
|
||||||
m_state.parse_result.time_zone_iana_name = transaction.parsed_string_view();
|
m_state.parse_result.time_zone_iana_name = transaction.parsed_string_view();
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -131,6 +131,10 @@ public:
|
||||||
[[nodiscard]] bool parse_time_zone_numeric_utc_offset_not_ambiguous();
|
[[nodiscard]] bool parse_time_zone_numeric_utc_offset_not_ambiguous();
|
||||||
[[nodiscard]] bool parse_time_zone_numeric_utc_offset_not_ambiguous_allowed_negative_hour();
|
[[nodiscard]] bool parse_time_zone_numeric_utc_offset_not_ambiguous_allowed_negative_hour();
|
||||||
[[nodiscard]] bool parse_time_zone_utc_offset_name();
|
[[nodiscard]] bool parse_time_zone_utc_offset_name();
|
||||||
|
[[nodiscard]] bool parse_tz_leading_char();
|
||||||
|
[[nodiscard]] bool parse_tz_char();
|
||||||
|
[[nodiscard]] bool parse_time_zone_iana_component();
|
||||||
|
[[nodiscard]] bool parse_time_zone_iana_name_tail();
|
||||||
[[nodiscard]] bool parse_time_zone_iana_name();
|
[[nodiscard]] bool parse_time_zone_iana_name();
|
||||||
[[nodiscard]] bool parse_time_zone_bracketed_name();
|
[[nodiscard]] bool parse_time_zone_bracketed_name();
|
||||||
[[nodiscard]] bool parse_time_zone_bracketed_annotation();
|
[[nodiscard]] bool parse_time_zone_bracketed_annotation();
|
||||||
|
|
|
@ -36,6 +36,6 @@ describe("errors", () => {
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
zonedDateTime.withTimeZone("UTCfoobar");
|
zonedDateTime.withTimeZone("UTCfoobar");
|
||||||
}).toThrowWithMessage(RangeError, "Invalid time zone string 'UTCfoobar'");
|
}).toThrowWithMessage(RangeError, "Invalid time zone name 'UTCfoobar'");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue