Changeset 293708 in webkit


Ignore:
Timestamp:
May 2, 2022 6:55:37 PM (3 months ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Add ISO8601 based Temporal.PlainDate getters
https://bugs.webkit.org/show_bug.cgi?id=239949

Reviewed by Ross Kirsling and Dean Jackson.

This patch adds missing getters of Temporal.PlainDate. Currently, we are not querying to Calendar.
It will be wired once we bake Calendar completely.

  • JSTests/stress/temporal-plaindate.js:

(print):
(shouldBe):

  • Source/JavaScriptCore/runtime/ISO8601.cpp:

(JSC::ISO8601::dayOfWeek):
(JSC::ISO8601::dayOfYear):
(JSC::ISO8601::weekOfYear):
(JSC::ISO8601::daysInMonth):
(JSC::ISO8601::monthCode):

  • Source/JavaScriptCore/runtime/ISO8601.h:
  • Source/JavaScriptCore/runtime/TemporalPlainDate.cpp:

(JSC::TemporalPlainDate::from):
(JSC::TemporalPlainDate::monthCode const):
(JSC::TemporalPlainDate::dayOfWeek const):
(JSC::TemporalPlainDate::dayOfYear const):
(JSC::TemporalPlainDate::weekOfYear const):

  • Source/JavaScriptCore/runtime/TemporalPlainDate.h:
  • Source/JavaScriptCore/runtime/TemporalPlainDatePrototype.cpp:

(JSC::JSC_DEFINE_CUSTOM_GETTER):

Canonical link: https://commits.webkit.org/250197@main

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r293666 r293708  
     12022-05-01  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Add ISO8601 based Temporal.PlainDate getters
     4        https://bugs.webkit.org/show_bug.cgi?id=239949
     5
     6        Reviewed by Ross Kirsling and Dean Jackson.
     7
     8        * stress/temporal-plaindate.js:
     9        (print):
     10        (shouldBe):
     11
    1122022-05-02  Angelos Oikonomopoulos  <angelos@igalia.com>
    213
  • trunk/JSTests/stress/temporal-plaindate.js

    r290282 r293708  
    164164}
    165165
    166 // FIXME: This relies on Temporal.PlainDate.from(object).
    167 // {
    168 //     let one = Temporal.PlainDate.from('1001-01-01');
    169 //     let two = Temporal.PlainDate.from('1002-01-01');
    170 //     let three = Temporal.PlainDate.from('1000-02-02');
    171 //     let four = Temporal.PlainDate.from('1001-01-02');
    172 //     let five = Temporal.PlainDate.from('1001-02-01');
    173 //     let sorted = [one, two, three, four, five].sort(Temporal.PlainDate.compare);
    174 //     shouldBe(sorted.join(' '), `1000-02-02 1001-01-01 1001-01-02 1001-02-01 1002-01-01`);
    175 // }
     166{
     167    let one = Temporal.PlainDate.from('1001-01-01');
     168    let two = Temporal.PlainDate.from('1002-01-01');
     169    let three = Temporal.PlainDate.from('1000-02-02');
     170    let four = Temporal.PlainDate.from('1001-01-02');
     171    let five = Temporal.PlainDate.from('1001-02-01');
     172    let sorted = [one, two, three, four, five].sort(Temporal.PlainDate.compare);
     173    shouldBe(sorted.join(' '), `1000-02-02 1001-01-01 1001-01-02 1001-02-01 1002-01-01`);
     174}
     175
     176{
     177    for (let i = 0; i < 12; ++i) {
     178        let dt = new Temporal.PlainDate(1995, 1 + i, 11 + i);
     179        shouldBe(dt.monthCode, `M${String(1 + i).padStart(2, '0')}`);
     180    }
     181}
     182
     183{
     184    let week = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'];
     185    for (let i = 0; i < 7; ++i) {
     186        let dt = new Temporal.PlainDate(1995, 12, 11 + i);
     187        shouldBe(week[dt.dayOfWeek - 1], week[i]);
     188    }
     189}
     190{
     191    shouldBe(Temporal.PlainDate.from('1995-12-07').dayOfWeek, 4);
     192    shouldBe(Temporal.PlainDate.from('1995-12-08').dayOfWeek, 5);
     193    shouldBe(Temporal.PlainDate.from('1995-12-09').dayOfWeek, 6);
     194    shouldBe(Temporal.PlainDate.from('1995-12-10').dayOfWeek, 7);
     195    shouldBe(Temporal.PlainDate.from('1995-12-11').dayOfWeek, 1);
     196    shouldBe(Temporal.PlainDate.from('1995-12-12').dayOfWeek, 2);
     197    shouldBe(Temporal.PlainDate.from('1995-12-13').dayOfWeek, 3);
     198    shouldBe(Temporal.PlainDate.from('1995-12-14').dayOfWeek, 4);
     199}
     200
     201{
     202    let tests = [
     203        [ '1995-01-01', 1 ],
     204        [ '1995-12-07', 341 ],
     205        [ '1995-12-31', 365 ],
     206        [ '2000-01-01', 1 ],
     207        [ '2000-12-07', 342 ],
     208        [ '2000-12-31', 366 ],
     209        [ '2004-01-01', 1 ],
     210        [ '2004-12-07', 342 ],
     211        [ '2004-12-31', 366 ],
     212        [ '2100-01-01', 1 ],
     213        [ '2100-12-07', 341 ],
     214        [ '2100-12-31', 365 ],
     215    ];
     216    for (let test of tests) {
     217        let dt = Temporal.PlainDate.from(test[0]);
     218        shouldBe(dt.dayOfYear, test[1]);
     219    }
     220}
     221
     222{
     223    shouldBe(Temporal.PlainDate.from('1996-12-31').weekOfYear, 1);
     224    shouldBe(Temporal.PlainDate.from('1997-12-31').weekOfYear, 1);
     225    shouldBe(Temporal.PlainDate.from('1998-12-27').weekOfYear, 52);
     226    shouldBe(Temporal.PlainDate.from('1998-12-31').weekOfYear, 53);
     227    shouldBe(Temporal.PlainDate.from('1999-12-31').weekOfYear, 52);
     228    shouldBe(Temporal.PlainDate.from('2000-12-31').weekOfYear, 52);
     229
     230    shouldBe(Temporal.PlainDate.from('1995-12-07').weekOfYear, 49);
     231    shouldBe(Temporal.PlainDate.from('1995-12-08').weekOfYear, 49);
     232    shouldBe(Temporal.PlainDate.from('1995-12-09').weekOfYear, 49);
     233    shouldBe(Temporal.PlainDate.from('1995-12-10').weekOfYear, 49);
     234    shouldBe(Temporal.PlainDate.from('1995-12-11').weekOfYear, 50);
     235    shouldBe(Temporal.PlainDate.from('1995-12-31').weekOfYear, 52);
     236    shouldBe(Temporal.PlainDate.from('1995-01-20').weekOfYear, 3);
     237
     238    shouldBe(Temporal.PlainDate.from('1995-01-02').weekOfYear, 1);
     239    shouldBe(Temporal.PlainDate.from('1995-01-03').weekOfYear, 1);
     240    shouldBe(Temporal.PlainDate.from('1995-01-04').weekOfYear, 1);
     241    shouldBe(Temporal.PlainDate.from('1995-01-05').weekOfYear, 1);
     242    shouldBe(Temporal.PlainDate.from('1995-01-06').weekOfYear, 1);
     243    shouldBe(Temporal.PlainDate.from('1995-01-07').weekOfYear, 1);
     244    shouldBe(Temporal.PlainDate.from('1995-01-08').weekOfYear, 1);
     245    shouldBe(Temporal.PlainDate.from('1995-01-09').weekOfYear, 2);
     246
     247    shouldBe(Temporal.PlainDate.from('1994-12-25').weekOfYear, 51); // Thursday
     248    shouldBe(Temporal.PlainDate.from('1994-12-26').weekOfYear, 52); // Friday
     249    shouldBe(Temporal.PlainDate.from('1994-12-27').weekOfYear, 52); // Saturday
     250    shouldBe(Temporal.PlainDate.from('1994-12-28').weekOfYear, 52); // Sunday
     251    shouldBe(Temporal.PlainDate.from('1994-12-29').weekOfYear, 52); // Monday
     252    shouldBe(Temporal.PlainDate.from('1994-12-30').weekOfYear, 52); // Tuesday
     253    shouldBe(Temporal.PlainDate.from('1994-12-31').weekOfYear, 52); // Wednesday
     254    shouldBe(Temporal.PlainDate.from('1995-01-01').weekOfYear, 52); // Thursday
     255}
     256
     257{
     258    shouldBe(Temporal.PlainDate.from('1995-12-07').daysInWeek, 7);
     259    shouldBe(Temporal.PlainDate.from('2001-12-07').daysInWeek, 7);
     260    shouldBe(Temporal.PlainDate.from('2000-12-07').daysInWeek, 7);
     261    shouldBe(Temporal.PlainDate.from('2004-12-07').daysInWeek, 7);
     262    shouldBe(Temporal.PlainDate.from('2100-12-07').daysInWeek, 7);
     263}
     264
     265{
     266    let days = [
     267        [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
     268        [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
     269    ];
     270    for (let i = 0; i < 12; ++i) {
     271        let dt = new Temporal.PlainDate(1995, 1 + i, 11 + i);
     272        shouldBe(dt.daysInMonth, days[0][i]);
     273    }
     274    for (let i = 0; i < 12; ++i) {
     275        let dt = new Temporal.PlainDate(2004, 1 + i, 11 + i);
     276        shouldBe(dt.daysInMonth, days[1][i]);
     277    }
     278}
     279
     280{
     281    shouldBe(Temporal.PlainDate.from('1995-12-07').daysInYear, 365);
     282    shouldBe(Temporal.PlainDate.from('2001-12-07').daysInYear, 365);
     283    shouldBe(Temporal.PlainDate.from('2000-12-07').daysInYear, 366);
     284    shouldBe(Temporal.PlainDate.from('2004-12-07').daysInYear, 366);
     285    shouldBe(Temporal.PlainDate.from('2100-12-07').daysInYear, 365);
     286}
     287
     288{
     289    shouldBe(Temporal.PlainDate.from('1995-12-07').monthsInYear, 12);
     290    shouldBe(Temporal.PlainDate.from('2001-12-07').monthsInYear, 12);
     291    shouldBe(Temporal.PlainDate.from('2000-12-07').monthsInYear, 12);
     292    shouldBe(Temporal.PlainDate.from('2004-12-07').monthsInYear, 12);
     293    shouldBe(Temporal.PlainDate.from('2100-12-07').monthsInYear, 12);
     294}
     295
     296{
     297    shouldBe(Temporal.PlainDate.from('1995-12-07').inLeapYear, false);
     298    shouldBe(Temporal.PlainDate.from('2001-12-07').inLeapYear, false);
     299    shouldBe(Temporal.PlainDate.from('2000-12-07').inLeapYear, true);
     300    shouldBe(Temporal.PlainDate.from('2004-12-07').inLeapYear, true);
     301    shouldBe(Temporal.PlainDate.from('2100-12-07').inLeapYear, false);
     302}
     303
     304{
     305    let getterNames = [
     306        "year",
     307        "month",
     308        "monthCode",
     309        "day",
     310        "dayOfWeek",
     311        "dayOfYear",
     312        "weekOfYear",
     313        "daysInWeek",
     314        "daysInMonth",
     315        "daysInYear",
     316        "monthsInYear",
     317        "inLeapYear",
     318    ];
     319    for (let getterName of getterNames) {
     320        let getter = Reflect.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, getterName).get;
     321        shouldBe(typeof getter, 'function');
     322        shouldThrow(() => {
     323            getter.call({});
     324        }, TypeError);
     325    }
     326}
  • trunk/Source/JavaScriptCore/ChangeLog

    r293693 r293708  
     12022-05-01  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Add ISO8601 based Temporal.PlainDate getters
     4        https://bugs.webkit.org/show_bug.cgi?id=239949
     5
     6        Reviewed by Ross Kirsling and Dean Jackson.
     7
     8        This patch adds missing getters of Temporal.PlainDate. Currently, we are not querying to Calendar.
     9        It will be wired once we bake Calendar completely.
     10
     11        * runtime/ISO8601.cpp:
     12        (JSC::ISO8601::dayOfWeek):
     13        (JSC::ISO8601::dayOfYear):
     14        (JSC::ISO8601::weekOfYear):
     15        (JSC::ISO8601::daysInMonth):
     16        (JSC::ISO8601::monthCode):
     17        * runtime/ISO8601.h:
     18        * runtime/TemporalPlainDate.cpp:
     19        (JSC::TemporalPlainDate::from):
     20        (JSC::TemporalPlainDate::monthCode const):
     21        (JSC::TemporalPlainDate::dayOfWeek const):
     22        (JSC::TemporalPlainDate::dayOfYear const):
     23        (JSC::TemporalPlainDate::weekOfYear const):
     24        * runtime/TemporalPlainDate.h:
     25        * runtime/TemporalPlainDatePrototype.cpp:
     26        (JSC::JSC_DEFINE_CUSTOM_GETTER):
     27
    1282022-05-02  Yusuke Suzuki  <ysuzuki@apple.com>
    229
  • trunk/Source/JavaScriptCore/runtime/ISO8601.cpp

    r290282 r293708  
    10961096}
    10971097
     1098uint8_t dayOfWeek(PlainDate plainDate)
     1099{
     1100    Int128 dateDays = static_cast<Int128>(dateToDaysFrom1970(plainDate.year(), plainDate.month() - 1, plainDate.day()));
     1101    int weekDay = static_cast<int>((dateDays + 4) % 7);
     1102    if (weekDay < 0)
     1103        weekDay += 7;
     1104    return !weekDay ? 7 : weekDay;
     1105}
     1106
     1107uint16_t dayOfYear(PlainDate plainDate)
     1108{
     1109    return dayInYear(plainDate.year(), plainDate.month() - 1, plainDate.day()) + 1; // Always start with 1 (1/1 is 1).
     1110}
     1111
     1112uint8_t weekOfYear(PlainDate plainDate)
     1113{
     1114    int32_t dayOfYear = ISO8601::dayOfYear(plainDate);
     1115    int32_t dayOfWeek = ISO8601::dayOfWeek(plainDate);
     1116
     1117    // ISO week 1 is the week containing the first Thursday (4) of the year.
     1118    // https://en.wikipedia.org/wiki/ISO_week_date#Algorithms
     1119    int32_t week = (dayOfYear - dayOfWeek + 10) / 7;
     1120    if (week <= 0) {
     1121        // Previous year's last week. Thus, 52 or 53 weeks. Getting weeks in the previous year.
     1122        //
     1123        // https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
     1124        // > The long years, with 53 weeks in them, can be described by any of the following equivalent definitions:
     1125        // >  - any year ending on Thursday (D, ED) and any leap year ending on Friday (DC)
     1126
     1127        int32_t dayOfWeekForJanuaryFirst = ISO8601::dayOfWeek(PlainDate { plainDate.year(), 1, 1 });
     1128
     1129        // Any year ending on Thursday (D, ED) -> this year's 1/1 is Friday.
     1130        if (dayOfWeekForJanuaryFirst == 5)
     1131            return 53;
     1132
     1133        // Any leap year ending on Friday (DC) -> this year's 1/1 is Saturday and previous year is a leap year.
     1134        if (dayOfWeekForJanuaryFirst == 6 && isLeapYear(plainDate.year() - 1))
     1135            return 53;
     1136
     1137        return 52;
     1138    }
     1139
     1140    if (week == 53) {
     1141        // Check whether this is in next year's week 1.
     1142        int32_t daysInYear = isLeapYear(plainDate.year()) ? 366 : 365;
     1143        if ((daysInYear - dayOfYear) < (4 - dayOfWeek))
     1144            return 1;
     1145    }
     1146
     1147    return week;
     1148}
     1149
     1150static constexpr uint8_t daysInMonths[2][12] = {
     1151    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
     1152    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
     1153};
     1154
     1155uint8_t daysInMonth(int32_t year, uint8_t month)
     1156{
     1157    return daysInMonths[!!isLeapYear(year)][month - 1];
     1158}
     1159
    10981160// https://tc39.es/proposal-temporal/#sec-temporal-formattimezoneoffsetstring
    10991161String formatTimeZoneOffsetString(int64_t offset)
     
    11771239}
    11781240
     1241String monthCode(uint32_t month)
     1242{
     1243    return makeString('M', pad('0', 2, month));
     1244}
     1245
    11791246// IsValidDuration ( years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds )
    11801247// https://tc39.es/proposal-temporal/#sec-temporal-isvalidduration
  • trunk/Source/JavaScriptCore/runtime/ISO8601.h

    r290282 r293708  
    265265private:
    266266    int32_t m_year : 21; // ECMAScript max / min date's year can be represented <= 20 bits.
    267     int32_t m_month : 5;
    268     int32_t m_day : 6;
     267    int32_t m_month : 5; // Starts with 1.
     268    int32_t m_day : 6; // Starts with 1.
    269269};
    270270#if COMPILER(GCC_COMPATIBLE)
     
    297297std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>>> parseDateTime(StringView);
    298298std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarDateTime(StringView);
     299uint8_t dayOfWeek(PlainDate);
     300uint16_t dayOfYear(PlainDate);
     301uint8_t weeksInYear(int32_t year);
     302uint8_t weekOfYear(PlainDate);
     303uint8_t daysInMonth(int32_t year, uint8_t month);
    299304String formatTimeZoneOffsetString(int64_t);
    300305String temporalTimeToString(PlainTime, std::tuple<Precision, unsigned> precision);
    301306String temporalDateToString(PlainDate);
     307String monthCode(uint32_t);
    302308unsigned daysInMonth(int32_t year, unsigned month);
    303309
  • trunk/Source/JavaScriptCore/runtime/TemporalPlainDate.cpp

    r292929 r293708  
    161161
    162162    if (itemValue.isObject()) {
     163        if (itemValue.inherits<TemporalPlainDate>())
     164            return jsCast<TemporalPlainDate*>(itemValue);
    163165        throwRangeError(globalObject, scope, "unimplemented: from object"_s);
    164166        return { };
     
    202204}
    203205
     206String TemporalPlainDate::monthCode() const
     207{
     208    return ISO8601::monthCode(m_plainDate.month());
     209}
     210
     211uint8_t TemporalPlainDate::dayOfWeek() const
     212{
     213    return ISO8601::dayOfWeek(m_plainDate);
     214}
     215
     216uint16_t TemporalPlainDate::dayOfYear() const
     217{
     218    return ISO8601::dayOfYear(m_plainDate);
     219}
     220
     221uint8_t TemporalPlainDate::weekOfYear() const
     222{
     223    return ISO8601::weekOfYear(m_plainDate);
     224}
     225
    204226} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/TemporalPlainDate.h

    r290209 r293708  
    5959#undef JSC_DEFINE_TEMPORAL_PLAIN_DATE_FIELD
    6060
     61    String monthCode() const;
     62    uint8_t dayOfWeek() const;
     63    uint16_t dayOfYear() const;
     64    uint8_t weekOfYear() const;
     65
    6166    String toString(JSGlobalObject*, JSValue options) const;
    6267    String toString() const
  • trunk/Source/JavaScriptCore/runtime/TemporalPlainDatePrototype.cpp

    r292929 r293708  
    3737static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterYear);
    3838static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonth);
     39static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthCode);
    3940static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDay);
     41static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfWeek);
     42static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfYear);
     43static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterWeekOfYear);
     44static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInWeek);
     45static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInMonth);
     46static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInYear);
     47static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthsInYear);
     48static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterInLeapYear);
    4049
    4150}
     
    5261  year             temporalPlainDatePrototypeGetterYear             DontEnum|ReadOnly|CustomAccessor
    5362  month            temporalPlainDatePrototypeGetterMonth            DontEnum|ReadOnly|CustomAccessor
     63  monthCode        temporalPlainDatePrototypeGetterMonthCode        DontEnum|ReadOnly|CustomAccessor
    5464  day              temporalPlainDatePrototypeGetterDay              DontEnum|ReadOnly|CustomAccessor
     65  dayOfWeek        temporalPlainDatePrototypeGetterDayOfWeek        DontEnum|ReadOnly|CustomAccessor
     66  dayOfYear        temporalPlainDatePrototypeGetterDayOfYear        DontEnum|ReadOnly|CustomAccessor
     67  weekOfYear       temporalPlainDatePrototypeGetterWeekOfYear       DontEnum|ReadOnly|CustomAccessor
     68  daysInWeek       temporalPlainDatePrototypeGetterDaysInWeek       DontEnum|ReadOnly|CustomAccessor
     69  daysInMonth      temporalPlainDatePrototypeGetterDaysInMonth      DontEnum|ReadOnly|CustomAccessor
     70  daysInYear       temporalPlainDatePrototypeGetterDaysInYear       DontEnum|ReadOnly|CustomAccessor
     71  monthsInYear     temporalPlainDatePrototypeGetterMonthsInYear     DontEnum|ReadOnly|CustomAccessor
     72  inLeapYear       temporalPlainDatePrototypeGetterInLeapYear       DontEnum|ReadOnly|CustomAccessor
    5573@end
    5674*/
     
    117135}
    118136
     137JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthCode, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     138{
     139    VM& vm = globalObject->vm();
     140    auto scope = DECLARE_THROW_SCOPE(vm);
     141
     142    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     143    if (!plainDate)
     144        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.monthCode called on value that's not a plainDate"_s);
     145
     146    return JSValue::encode(jsNontrivialString(vm, plainDate->monthCode()));
     147}
     148
    119149JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDay, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
    120150{
     
    129159}
    130160
     161JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfWeek, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     162{
     163    VM& vm = globalObject->vm();
     164    auto scope = DECLARE_THROW_SCOPE(vm);
     165
     166    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     167    if (!plainDate)
     168        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.dayOfWeek called on value that's not a plainDate"_s);
     169
     170    return JSValue::encode(jsNumber(plainDate->dayOfWeek()));
     171}
     172
     173JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     174{
     175    VM& vm = globalObject->vm();
     176    auto scope = DECLARE_THROW_SCOPE(vm);
     177
     178    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     179    if (!plainDate)
     180        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.dayOfYear called on value that's not a plainDate"_s);
     181
     182    return JSValue::encode(jsNumber(plainDate->dayOfYear()));
     183}
     184
     185JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterWeekOfYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     186{
     187    VM& vm = globalObject->vm();
     188    auto scope = DECLARE_THROW_SCOPE(vm);
     189
     190    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     191    if (!plainDate)
     192        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.weekOfYear called on value that's not a plainDate"_s);
     193
     194    return JSValue::encode(jsNumber(plainDate->weekOfYear()));
     195}
     196
     197JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInWeek, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     198{
     199    VM& vm = globalObject->vm();
     200    auto scope = DECLARE_THROW_SCOPE(vm);
     201
     202    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     203    if (!plainDate)
     204        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.daysInWeek called on value that's not a plainDate"_s);
     205
     206    return JSValue::encode(jsNumber(7)); // ISO8601 calendar always returns 7.
     207}
     208
     209JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInMonth, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     210{
     211    VM& vm = globalObject->vm();
     212    auto scope = DECLARE_THROW_SCOPE(vm);
     213
     214    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     215    if (!plainDate)
     216        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.daysInMonth called on value that's not a plainDate"_s);
     217
     218    return JSValue::encode(jsNumber(ISO8601::daysInMonth(plainDate->year(), plainDate->month())));
     219}
     220
     221JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     222{
     223    VM& vm = globalObject->vm();
     224    auto scope = DECLARE_THROW_SCOPE(vm);
     225
     226    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     227    if (!plainDate)
     228        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.daysInYear called on value that's not a plainDate"_s);
     229
     230    return JSValue::encode(jsNumber(isLeapYear(plainDate->year()) ? 366 : 365));
     231}
     232
     233JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthsInYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     234{
     235    VM& vm = globalObject->vm();
     236    auto scope = DECLARE_THROW_SCOPE(vm);
     237
     238    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     239    if (!plainDate)
     240        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.monthsInYear called on value that's not a plainDate"_s);
     241
     242    return JSValue::encode(jsNumber(12)); // ISO8601 calendar always returns 12.
     243}
     244
     245JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterInLeapYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
     246{
     247    VM& vm = globalObject->vm();
     248    auto scope = DECLARE_THROW_SCOPE(vm);
     249
     250    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
     251    if (!plainDate)
     252        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.inLeapYear called on value that's not a plainDate"_s);
     253
     254    return JSValue::encode(jsBoolean(isLeapYear(plainDate->year())));
     255}
    131256
    132257} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.