summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2022-11-02 18:26:46 +0000
committerLinus Groh <mail@linusgroh.de>2022-11-03 19:15:50 +0000
commit192aa75279448dec13258d89e3c9827bfa7833f0 (patch)
tree8694d8e276dc3d6f4005e8faf5aee27420ea2dcf /Userland/Libraries
parent0f2b4d0aacb03e0df6bb9095108d077fc48092c0 (diff)
downloadserenity-192aa75279448dec13258d89e3c9827bfa7833f0.zip
LibJS: Align ISO 8601 grammar with annotations from IXDTF
This is a normative change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/c64b844
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Runtime/ErrorTypes.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp46
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp248
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h31
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js6
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.withCalendar.js4
6 files changed, 244 insertions, 92 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
index ee95921da4..a65e027f6d 100644
--- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
+++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
@@ -280,6 +280,7 @@
M(TemporalPropertyMustBeFinite, "Property must not be Infinity") \
M(TemporalPropertyMustBePositiveInteger, "Property must be a positive integer") \
M(TemporalTimeZoneOffsetStringMismatch, "Time zone offset string mismatch: '{}' is not equal to '{}'") \
+ M(TemporalUnknownCriticalAnnotation, "Unknown annotation key in critical annotation: '{}'") \
M(TemporalZonedDateTimeRoundZeroOrNegativeLengthDay, "Cannot round a ZonedDateTime in a calendar or time zone that has zero or " \
"negative length days") \
M(ThisHasNotBeenInitialized, "|this| has not been initialized") \
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
index ae7bdf165e..c7877eb253 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
@@ -1215,7 +1215,7 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(VM& vm, StringView iso_string
// 13.28 ParseISODateTime ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parseisodatetime
ThrowCompletionOr<ISODateTime> parse_iso_date_time(VM& vm, ParseResult const& parse_result)
{
- // 4. Let each of year, month, day, hour, minute, second, fSeconds, and calendar be the source text matched by the respective DateYear, DateMonth, DateDay, TimeHour, TimeMinute, TimeSecond, TimeFraction, and CalendarName Parse Node contained within parseResult, or an empty sequence of code points if not present.
+ // 4. Let each of year, month, day, hour, minute, second, and fSeconds be the source text matched by the respective DateYear, DateMonth, DateDay, TimeHour, TimeMinute, TimeSecond, and TimeFraction Parse Node contained within parseResult, or an empty sequence of code points if not present.
auto year = parse_result.date_year;
auto month = parse_result.date_month;
auto day = parse_result.date_day;
@@ -1223,7 +1223,6 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(VM& vm, ParseResult const& pa
auto minute = parse_result.time_minute;
auto second = parse_result.time_second;
auto f_seconds = parse_result.time_fraction;
- auto calendar = parse_result.calendar_name;
// 5. If the first code point of year is U+2212 (MINUS SIGN), replace the first code point with U+002D (HYPHEN-MINUS).
Optional<String> normalized_year;
@@ -1342,22 +1341,35 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(VM& vm, ParseResult const& pa
}
}
- Optional<String> calendar_val;
+ // 23. Let calendar be undefined.
+ Optional<String> calendar;
- // 23. If calendar is empty, then
- if (!calendar.has_value()) {
- // a. Let calendarVal be undefined.
- calendar_val = {};
- }
- // 24. Else,
- else {
- // a. Let calendarVal be CodePointsToString(calendar).
- // NOTE: This turns the StringView into a String.
- calendar_val = *calendar;
+ // 24. For each Annotation Parse Node annotation contained within parseResult, do
+ for (auto const& annotation : parse_result.annotations) {
+ // a. Let key be the source text matched by the AnnotationKey Parse Node contained within annotation.
+ auto const& key = annotation.key;
+
+ // b. If CodePointsToString(key) is "u-ca", then
+ if (key == "u-ca"sv) {
+ // i. If calendar is undefined, then
+ if (!calendar.has_value()) {
+ // 1. Let value be the source text matched by the AnnotationValue Parse Node contained within annotation.
+ auto const& value = annotation.value;
+
+ // 2. Let calendar be CodePointsToString(value).
+ calendar = value;
+ }
+ }
+ // c. Else,
+ else {
+ // i. If annotation contains an AnnotationCriticalFlag Parse Node, throw a RangeError exception.
+ if (annotation.critical)
+ return vm.throw_completion<RangeError>(ErrorType::TemporalUnknownCriticalAnnotation, key);
+ }
}
- // 25. Return the Record { [[Year]]: yearMV, [[Month]]: monthMV, [[Day]]: dayMV, [[Hour]]: hourMV, [[Minute]]: minuteMV, [[Second]]: secondMV, [[Millisecond]]: millisecondMV, [[Microsecond]]: microsecondMV, [[Nanosecond]]: nanosecondMV, [[TimeZone]]: timeZoneResult, [[Calendar]]: calendarVal, }.
- return ISODateTime { .year = year_mv, .month = month_mv, .day = day_mv, .hour = hour_mv, .minute = minute_mv, .second = second_mv, .millisecond = millisecond_mv, .microsecond = microsecond_mv, .nanosecond = nanosecond_mv, .time_zone = move(time_zone_result), .calendar = move(calendar_val) };
+ // 25. Return the Record { [[Year]]: yearMV, [[Month]]: monthMV, [[Day]]: dayMV, [[Hour]]: hourMV, [[Minute]]: minuteMV, [[Second]]: secondMV, [[Millisecond]]: millisecondMV, [[Microsecond]]: microsecondMV, [[Nanosecond]]: nanosecondMV, [[TimeZone]]: timeZoneResult, [[Calendar]]: calendar }.
+ return ISODateTime { .year = year_mv, .month = month_mv, .day = day_mv, .hour = hour_mv, .minute = minute_mv, .second = second_mv, .millisecond = millisecond_mv, .microsecond = microsecond_mv, .nanosecond = nanosecond_mv, .time_zone = move(time_zone_result), .calendar = move(calendar) };
}
// 13.29 ParseTemporalInstantString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalinstantstring
@@ -1419,8 +1431,8 @@ ThrowCompletionOr<String> parse_temporal_calendar_string(VM& vm, String const& i
}
// 3. Else,
else {
- // a. Set parseResult to ParseText(StringToCodePoints(isoString), CalendarName).
- auto parse_result = parse_iso8601(Production::CalendarName, iso_string);
+ // a. Set parseResult to ParseText(StringToCodePoints(isoString), AnnotationValue).
+ auto parse_result = parse_iso8601(Production::AnnotationValue, iso_string);
// b. If parseResult is a List of errors, throw a RangeError exception.
if (!parse_result.has_value())
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp
index 311528fb4c..243f34a8b5 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp
@@ -269,6 +269,14 @@ bool ISO8601Parser::parse_utc_designator()
return true;
}
+// https://tc39.es/proposal-temporal/#prod-AnnotationCriticalFlag
+bool ISO8601Parser::parse_annotation_critical_flag()
+{
+ // AnnotationCriticalFlag :
+ // !
+ return m_state.lexer.consume_specific('!');
+}
+
// https://tc39.es/proposal-temporal/#prod-DateYear
bool ISO8601Parser::parse_date_year()
{
@@ -822,10 +830,11 @@ bool ISO8601Parser::parse_time_zone_identifier()
bool ISO8601Parser::parse_time_zone_bracketed_annotation()
{
// TimeZoneBracketedAnnotation :
- // [ TimeZoneIdentifier ]
+ // [ AnnotationCriticalFlag[opt] TimeZoneIdentifier ]
StateTransaction transaction { *this };
if (!m_state.lexer.consume_specific('['))
return false;
+ (void)parse_annotation_critical_flag();
if (!parse_time_zone_identifier())
return false;
if (!m_state.lexer.consume_specific(']'))
@@ -876,53 +885,166 @@ bool ISO8601Parser::parse_time_zone()
return true;
}
-// https://tc39.es/proposal-temporal/#prod-CalendarName
-bool ISO8601Parser::parse_calendar_name()
+// https://tc39.es/proposal-temporal/#prod-AKeyLeadingChar
+bool ISO8601Parser::parse_a_key_leading_char()
+{
+ // AKeyLeadingChar :
+ // LowercaseAlpha
+ // _
+ if (m_state.lexer.next_is(is_ascii_lower_alpha)) {
+ m_state.lexer.consume();
+ return true;
+ }
+ return m_state.lexer.consume_specific('_');
+}
+
+// https://tc39.es/proposal-temporal/#prod-AKeyChar
+bool ISO8601Parser::parse_a_key_char()
{
- // CalChar :
+ // AKeyChar :
+ // AKeyLeadingChar
+ // DecimalDigit
+ // -
+ if (parse_a_key_leading_char())
+ return true;
+ if (parse_decimal_digit())
+ return true;
+ return m_state.lexer.consume_specific('-');
+}
+
+// https://tc39.es/proposal-temporal/#prod-AValChar
+bool ISO8601Parser::parse_a_val_char()
+{
+ // AValChar :
// Alpha
// DecimalDigit
- // CalendarNameComponent :
- // CalChar CalChar CalChar CalChar[opt] CalChar[opt] CalChar[opt] CalChar[opt] CalChar[opt]
- // CalendarNameTail :
- // CalendarNameComponent
- // CalendarNameComponent - CalendarNameTail
- // CalendarName :
- // CalendarNameTail
- auto parse_calendar_name_component = [&] {
- for (size_t i = 0; i < 8; ++i) {
- if (!m_state.lexer.next_is(is_ascii_alphanumeric))
- return i > 2;
- m_state.lexer.consume();
- }
+ if (m_state.lexer.next_is(is_ascii_alpha)) {
+ m_state.lexer.consume();
return true;
- };
+ }
+ return parse_decimal_digit();
+}
+
+// https://tc39.es/proposal-temporal/#prod-AnnotationKeyTail
+bool ISO8601Parser::parse_annotation_key_tail()
+{
+ // AnnotationKeyTail :
+ // AKeyChar AnnotationKeyTail[opt]
+ if (!parse_a_key_char())
+ return false;
+ // This is implemented without recursion to prevent stack overflow with annotation key tails that have many characters.
+ while (parse_a_key_char())
+ ;
+ return true;
+}
+
+// https://tc39.es/proposal-temporal/#prod-AnnotationKey
+bool ISO8601Parser::parse_annotation_key()
+{
+ // AnnotationKey :
+ // AKeyLeadingChar AnnotationKeyTail[opt]
StateTransaction transaction { *this };
- do {
- if (!parse_calendar_name_component())
+ if (!parse_a_key_leading_char()) {
+ m_state.parse_result.annotation_key = Optional<StringView> {};
+ return false;
+ }
+ (void)parse_annotation_key_tail();
+ m_state.parse_result.annotation_key = transaction.parsed_string_view();
+ transaction.commit();
+ return true;
+}
+
+// https://tc39.es/proposal-temporal/#prod-AnnotationValueComponent
+bool ISO8601Parser::parse_annotation_value_component()
+{
+ // AnnotationValueComponent :
+ // AValChar AnnotationValueComponent[opt]
+ if (!parse_a_val_char())
+ return false;
+ // This is implemented without recursion to prevent stack overflow with annotation value components that have many characters.
+ while (parse_a_val_char())
+ ;
+ return true;
+}
+
+// https://tc39.es/proposal-temporal/#prod-AnnotationValueTail
+bool ISO8601Parser::parse_annotation_value_tail()
+{
+ // AnnotationValueTail :
+ // AnnotationValueComponent
+ // AnnotationValueComponent - AnnotationValueTail
+ // This is implemented without recursion to prevent stack overflow with annotation values that have many dashes.
+ for (;;) {
+ if (!parse_annotation_value_component())
return false;
- } while (m_state.lexer.consume_specific('-'));
- m_state.parse_result.calendar_name = transaction.parsed_string_view();
+
+ if (!m_state.lexer.consume_specific('-'))
+ break;
+ }
+
+ return true;
+}
+
+// https://tc39.es/proposal-temporal/#prod-AnnotationValue
+bool ISO8601Parser::parse_annotation_value()
+{
+ // AnnotationValue :
+ // AnnotationValueTail
+ StateTransaction transaction { *this };
+ if (!parse_annotation_value_tail()) {
+ m_state.parse_result.annotation_value = Optional<StringView> {};
+ return false;
+ }
+ m_state.parse_result.annotation_value = transaction.parsed_string_view();
transaction.commit();
return true;
}
-// https://tc39.es/proposal-temporal/#prod-Calendar
-bool ISO8601Parser::parse_calendar()
+// https://tc39.es/proposal-temporal/#prod-Annotation
+bool ISO8601Parser::parse_annotation()
{
- // Calendar :
- // [u-ca= CalendarName ]
+ // Annotation :
+ // [ AnnotationCriticalFlag[opt] AnnotationKey = AnnotationValue ]
StateTransaction transaction { *this };
- if (!m_state.lexer.consume_specific("[u-ca="sv))
+ if (!m_state.lexer.consume_specific('['))
return false;
- if (!parse_calendar_name())
+
+ Annotation annotation;
+
+ annotation.critical = parse_annotation_critical_flag();
+
+ if (!parse_annotation_key())
+ return false;
+ annotation.key = m_state.parse_result.annotation_key.value();
+
+ if (!m_state.lexer.consume_specific('='))
+ return false;
+
+ if (!parse_annotation_value())
return false;
+ annotation.value = m_state.parse_result.annotation_value.value();
+
if (!m_state.lexer.consume_specific(']'))
return false;
+
+ m_state.parse_result.annotations.append(annotation);
transaction.commit();
return true;
}
+// https://tc39.es/proposal-temporal/#prod-Annotations
+bool ISO8601Parser::parse_annotations()
+{
+ // Annotations :
+ // Annotation Annotations[opt]
+ if (!parse_annotation())
+ return false;
+ // This is implemented without recursion to prevent stack overflow with ISO strings that have many annotations.
+ while (parse_annotation())
+ ;
+ return true;
+}
+
// https://tc39.es/proposal-temporal/#prod-TimeSpec
bool ISO8601Parser::parse_time_spec()
{
@@ -995,17 +1117,17 @@ bool ISO8601Parser::parse_date_time()
return true;
}
-// https://tc39.es/proposal-temporal/#prod-CalendarTime
-bool ISO8601Parser::parse_calendar_time()
+// https://tc39.es/proposal-temporal/#prod-AnnotatedTime
+bool ISO8601Parser::parse_annotated_time()
{
- // CalendarTime :
- // TimeDesignator TimeSpec TimeZone[opt] Calendar[opt]
- // TimeSpecWithOptionalTimeZoneNotAmbiguous Calendar[opt]
+ // AnnotatedTime :
+ // TimeDesignator TimeSpec TimeZone[opt] Annotations[opt]
+ // TimeSpecWithOptionalTimeZoneNotAmbiguous Annotations[opt]
{
StateTransaction transaction { *this };
if (parse_time_designator() && parse_time_spec()) {
(void)parse_time_zone();
- (void)parse_calendar();
+ (void)parse_annotations();
transaction.commit();
return true;
}
@@ -1013,34 +1135,34 @@ bool ISO8601Parser::parse_calendar_time()
StateTransaction transaction { *this };
if (!parse_time_spec_with_optional_time_zone_not_ambiguous())
return false;
- (void)parse_calendar();
+ (void)parse_annotations();
transaction.commit();
return true;
}
-// https://tc39.es/proposal-temporal/#prod-CalendarDateTime
-bool ISO8601Parser::parse_calendar_date_time()
+// https://tc39.es/proposal-temporal/#prod-AnnotatedDateTime
+bool ISO8601Parser::parse_annotated_date_time()
{
- // CalendarDateTime :
- // DateTime Calendar[opt]
+ // AnnotatedDateTime :
+ // DateTime Annotations[opt]
if (!parse_date_time())
return false;
- (void)parse_calendar();
+ (void)parse_annotations();
return true;
}
-// https://tc39.es/proposal-temporal/#prod-CalendarDateTimeTimeRequired
-bool ISO8601Parser::parse_calendar_date_time_time_required()
+// https://tc39.es/proposal-temporal/#prod-AnnotatedDateTimeTimeRequired
+bool ISO8601Parser::parse_annotated_date_time_time_required()
{
- // CalendarDateTimeTimeRequired :
- // Date TimeSpecSeparator TimeZone[opt] Calendar[opt]
+ // AnnotatedDateTimeTimeRequired :
+ // Date TimeSpecSeparator TimeZone[opt] Annotations[opt]
StateTransaction transaction { *this };
if (!parse_date())
return false;
if (!parse_time_spec_separator())
return false;
(void)parse_time_zone();
- (void)parse_calendar();
+ (void)parse_annotations();
transaction.commit();
return true;
}
@@ -1348,14 +1470,14 @@ bool ISO8601Parser::parse_duration()
bool ISO8601Parser::parse_temporal_instant_string()
{
// TemporalInstantString :
- // Date TimeSpecSeparator[opt] TimeZoneOffsetRequired Calendar[opt]
+ // Date TimeSpecSeparator[opt] TimeZoneOffsetRequired Annotations[opt]
StateTransaction transaction { *this };
if (!parse_date())
return false;
(void)parse_time_spec_separator();
if (!parse_time_zone_offset_required())
return false;
- (void)parse_calendar();
+ (void)parse_annotations();
transaction.commit();
return true;
}
@@ -1364,8 +1486,8 @@ bool ISO8601Parser::parse_temporal_instant_string()
bool ISO8601Parser::parse_temporal_date_time_string()
{
// TemporalDateTimeString :
- // CalendarDateTime
- return parse_calendar_date_time();
+ // AnnotatedDateTime
+ return parse_annotated_date_time();
}
// https://tc39.es/proposal-temporal/#prod-TemporalDurationString
@@ -1381,10 +1503,10 @@ bool ISO8601Parser::parse_temporal_month_day_string()
{
// TemporalMonthDayString :
// DateSpecMonthDay
- // CalendarDateTime
- // NOTE: Reverse order here because `DateSpecMonthDay` can be a subset of `CalendarDateTime`,
+ // AnnotatedDateTime
+ // NOTE: Reverse order here because `DateSpecMonthDay` can be a subset of `AnnotatedDateTime`,
// so we'd not attempt to parse that but may not exhaust the input string.
- return parse_calendar_date_time()
+ return parse_annotated_date_time()
|| parse_date_spec_month_day();
}
@@ -1392,12 +1514,12 @@ bool ISO8601Parser::parse_temporal_month_day_string()
bool ISO8601Parser::parse_temporal_time_string()
{
// TemporalTimeString :
- // CalendarTime
- // CalendarDateTimeTimeRequired
- // NOTE: Reverse order here because `Time` can be a subset of `CalendarDateTimeTimeRequired`,
+ // AnnotatedTime
+ // AnnotatedDateTimeTimeRequired
+ // NOTE: Reverse order here because `AnnotatedTime` can be a subset of `AnnotatedDateTimeTimeRequired`,
// so we'd not attempt to parse that but may not exhaust the input string.
- return parse_calendar_date_time_time_required()
- || parse_calendar_time();
+ return parse_annotated_date_time_time_required()
+ || parse_annotated_time();
}
// https://tc39.es/proposal-temporal/#prod-TemporalYearMonthString
@@ -1405,10 +1527,10 @@ bool ISO8601Parser::parse_temporal_year_month_string()
{
// TemporalYearMonthString :
// DateSpecYearMonth
- // CalendarDateTime
- // NOTE: Reverse order here because `DateSpecYearMonth` can be a subset of `CalendarDateTime`,
+ // AnnotatedDateTime
+ // NOTE: Reverse order here because `DateSpecYearMonth` can be a subset of `AnnotatedDateTime`,
// so we'd not attempt to parse that but may not exhaust the input string.
- return parse_calendar_date_time()
+ return parse_annotated_date_time()
|| parse_date_spec_year_month();
}
@@ -1416,14 +1538,14 @@ bool ISO8601Parser::parse_temporal_year_month_string()
bool ISO8601Parser::parse_temporal_zoned_date_time_string()
{
// TemporalZonedDateTimeString :
- // Date TimeSpecSeparator[opt] TimeZoneNameRequired Calendar[opt]
+ // Date TimeSpecSeparator[opt] TimeZoneNameRequired Annotations[opt]
StateTransaction transaction { *this };
if (!parse_date())
return false;
(void)parse_time_spec_separator();
if (!parse_time_zone_name_required())
return false;
- (void)parse_calendar();
+ (void)parse_annotations();
transaction.commit();
return true;
}
@@ -1440,7 +1562,7 @@ bool ISO8601Parser::parse_temporal_zoned_date_time_string()
__JS_ENUMERATE(TemporalZonedDateTimeString, parse_temporal_zoned_date_time_string) \
__JS_ENUMERATE(TimeZoneIdentifier, parse_time_zone_identifier) \
__JS_ENUMERATE(TimeZoneNumericUTCOffset, parse_time_zone_numeric_utc_offset) \
- __JS_ENUMERATE(CalendarName, parse_calendar_name) \
+ __JS_ENUMERATE(AnnotationValue, parse_annotation_value) \
__JS_ENUMERATE(DateMonth, parse_date_month)
Optional<ParseResult> parse_iso8601(Production production, StringView input)
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h
index fa409b8325..939210de90 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h
@@ -13,6 +13,12 @@
namespace JS::Temporal {
+struct Annotation {
+ bool critical { false };
+ StringView key;
+ StringView value;
+};
+
struct ParseResult {
Optional<StringView> sign;
Optional<StringView> date_year;
@@ -22,7 +28,6 @@ struct ParseResult {
Optional<StringView> time_minute;
Optional<StringView> time_second;
Optional<StringView> time_fraction;
- Optional<StringView> calendar_name;
Optional<StringView> utc_designator;
Optional<StringView> time_zone_bracketed_annotation;
Optional<StringView> time_zone_numeric_utc_offset;
@@ -42,6 +47,9 @@ struct ParseResult {
Optional<StringView> duration_minutes_fraction;
Optional<StringView> duration_whole_seconds;
Optional<StringView> duration_seconds_fraction;
+ Optional<StringView> annotation_key;
+ Optional<StringView> annotation_value;
+ Vector<Annotation> annotations;
};
enum class Production {
@@ -54,7 +62,7 @@ enum class Production {
TemporalZonedDateTimeString,
TimeZoneIdentifier,
TimeZoneNumericUTCOffset,
- CalendarName,
+ AnnotationValue,
DateMonth,
};
@@ -97,6 +105,7 @@ public:
[[nodiscard]] bool parse_weeks_designator();
[[nodiscard]] bool parse_years_designator();
[[nodiscard]] bool parse_utc_designator();
+ [[nodiscard]] bool parse_annotation_critical_flag();
[[nodiscard]] bool parse_date_year();
[[nodiscard]] bool parse_date_month();
[[nodiscard]] bool parse_date_month_with_thirty_days();
@@ -131,15 +140,23 @@ public:
[[nodiscard]] bool parse_time_zone_offset_required();
[[nodiscard]] bool parse_time_zone_name_required();
[[nodiscard]] bool parse_time_zone();
- [[nodiscard]] bool parse_calendar_name();
- [[nodiscard]] bool parse_calendar();
+ [[nodiscard]] bool parse_a_key_leading_char();
+ [[nodiscard]] bool parse_a_key_char();
+ [[nodiscard]] bool parse_a_val_char();
+ [[nodiscard]] bool parse_annotation_key_tail();
+ [[nodiscard]] bool parse_annotation_key();
+ [[nodiscard]] bool parse_annotation_value_component();
+ [[nodiscard]] bool parse_annotation_value_tail();
+ [[nodiscard]] bool parse_annotation_value();
+ [[nodiscard]] bool parse_annotation();
+ [[nodiscard]] bool parse_annotations();
[[nodiscard]] bool parse_time_spec();
[[nodiscard]] bool parse_time_spec_with_optional_time_zone_not_ambiguous();
[[nodiscard]] bool parse_time_spec_separator();
[[nodiscard]] bool parse_date_time();
- [[nodiscard]] bool parse_calendar_time();
- [[nodiscard]] bool parse_calendar_date_time();
- [[nodiscard]] bool parse_calendar_date_time_time_required();
+ [[nodiscard]] bool parse_annotated_time();
+ [[nodiscard]] bool parse_annotated_date_time();
+ [[nodiscard]] bool parse_annotated_date_time_time_required();
[[nodiscard]] bool parse_duration_whole_seconds();
[[nodiscard]] bool parse_duration_seconds_fraction();
[[nodiscard]] bool parse_duration_seconds_part();
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js
index 99e9740e8d..d4ed39d3bf 100644
--- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js
+++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js
@@ -65,12 +65,12 @@ describe("errors", () => {
);
});
- test("calendar annotation must match calendar grammar even though it's ignored", () => {
+ test("annotations must match annotation grammar even though they're ignored", () => {
expect(() => {
- Temporal.Instant.from("1970-01-01T00:00Z[u-ca=SerenityOS]");
+ Temporal.Instant.from("1970-01-01T00:00Z[SerenityOS=cool]");
}).toThrowWithMessage(
RangeError,
- "Invalid instant string '1970-01-01T00:00Z[u-ca=SerenityOS]'"
+ "Invalid instant string '1970-01-01T00:00Z[SerenityOS=cool]'"
);
});
});
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.withCalendar.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.withCalendar.js
index 0282d07fae..def2acf299 100644
--- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.withCalendar.js
+++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.withCalendar.js
@@ -31,11 +31,11 @@ describe("errors", () => {
}).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime");
});
- test("from invalid calendar string", () => {
+ test("from invalid calendar identifier", () => {
const zonedDateTime = new Temporal.ZonedDateTime(1n, {}, {});
expect(() => {
zonedDateTime.withCalendar("iso8602foobar");
- }).toThrowWithMessage(RangeError, "Invalid calendar string 'iso8602foobar'");
+ }).toThrowWithMessage(RangeError, "Invalid calendar identifier 'iso8602foobar'");
});
});