commit 18d4db910547464c5b8ca8870b9f9b69b17779de
parent 090cc6a8816c30681e75de342b716a7022548e27
Author: André Bargull <andre.bargull@gmail.com>
Date: Thu, 27 Nov 2025 10:03:37 +0000
Bug 1999316 - Part 2: Add IsValidMonthCodeForCalendar. r=spidermonkey-reviewers,mgaudet
And add some more comments.
Differential Revision: https://phabricator.services.mozilla.com/D272031
Diffstat:
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/js/src/builtin/temporal/Calendar.cpp b/js/src/builtin/temporal/Calendar.cpp
@@ -923,7 +923,7 @@ static mozilla::Result<UniqueICU4XDate, CalendarError> CreateDateFromCodes(
MOZ_ASSERT(CalendarErasAsEnumSet(calendarId).contains(eraYear.era));
MOZ_ASSERT_IF(CalendarEraRelevant(calendarId), eraYear.year > 0);
MOZ_ASSERT(mozilla::Abs(eraYear.year) <= MaximumCalendarYear(calendarId));
- MOZ_ASSERT(CalendarMonthCodes(calendarId).contains(monthCode));
+ MOZ_ASSERT(IsValidMonthCodeForCalendar(calendarId, monthCode));
MOZ_ASSERT(day > 0);
MOZ_ASSERT(day <= CalendarDaysInMonth(calendarId).second);
@@ -1040,7 +1040,7 @@ static UniqueICU4XDate CreateDateFromCodes(
JSContext* cx, CalendarId calendarId, const icu4x::capi::Calendar* calendar,
EraYear eraYear, MonthCode monthCode, int32_t day,
TemporalOverflow overflow) {
- MOZ_ASSERT(CalendarMonthCodes(calendarId).contains(monthCode));
+ MOZ_ASSERT(IsValidMonthCodeForCalendar(calendarId, monthCode));
MOZ_ASSERT(day > 0);
MOZ_ASSERT(day <= CalendarDaysInMonth(calendarId).second);
@@ -1850,8 +1850,7 @@ static bool CalendarFieldMonth(JSContext* cx, CalendarId calendar,
}
// Ensure the month code is valid for this calendar.
- const auto& monthCodes = CalendarMonthCodes(calendar);
- if (!monthCodes.contains(fromMonthCode)) {
+ if (!IsValidMonthCodeForCalendar(calendar, fromMonthCode)) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_TEMPORAL_CALENDAR_INVALID_MONTHCODE,
MonthCodeString{monthCode}.toCString());
diff --git a/js/src/builtin/temporal/MonthCode.h b/js/src/builtin/temporal/MonthCode.h
@@ -148,6 +148,9 @@ class MonthCode final {
};
class MonthCodes final {
+ // Common month codes supported by all calendars.
+ //
+ // See IsValidMonthCodeForCalendar, step 1.
mozilla::EnumSet<MonthCode::Code> monthCodes_{
MonthCode::Code::M01, MonthCode::Code::M02, MonthCode::Code::M03,
MonthCode::Code::M04, MonthCode::Code::M05, MonthCode::Code::M06,
@@ -162,11 +165,11 @@ class MonthCodes final {
}
}
- bool contains(MonthCode monthCode) const {
+ constexpr bool contains(MonthCode monthCode) const {
return monthCodes_.contains(monthCode.code());
}
- bool contains(const MonthCodes& monthCodes) const {
+ constexpr bool contains(const MonthCodes& monthCodes) const {
return monthCodes_.contains(monthCodes.monthCodes_);
}
};
@@ -190,8 +193,10 @@ class MonthCodes final {
//
// https://docs.rs/icu/latest/icu/calendar/cal/struct.Hebrew.html#month-codes
namespace monthcodes {
+// The ISO8601 calendar doesn't have any additional month codes.
inline constexpr MonthCodes ISO8601 = {};
+// The Chinese/Dangi calendars can have a leap month inserted after every month.
inline constexpr MonthCodes ChineseOrDangi = {
// Leap months.
MonthCode{1, /* isLeapMonth = */ true},
@@ -208,11 +213,13 @@ inline constexpr MonthCodes ChineseOrDangi = {
MonthCode{12, /* isLeapMonth = */ true},
};
+// The Coptic/Ethiopian calendars has a thirteenth month.
inline constexpr MonthCodes CopticOrEthiopian = {
// Short epagomenal month.
MonthCode{13},
};
+// The Hebrew calendar has a single leap month.
inline constexpr MonthCodes Hebrew = {
// Leap month Adar I.
MonthCode{5, /* isLeapMonth = */ true},
@@ -248,6 +255,13 @@ constexpr auto& CalendarMonthCodes(CalendarId id) {
MOZ_CRASH("invalid calendar id");
}
+/**
+ * IsValidMonthCodeForCalendar ( calendar, monthCode )
+ */
+constexpr bool IsValidMonthCodeForCalendar(CalendarId id, MonthCode monthCode) {
+ return CalendarMonthCodes(id).contains(monthCode);
+}
+
constexpr bool CalendarHasLeapMonths(CalendarId id) {
switch (id) {
case CalendarId::ISO8601: