Skip to content

Commit 3e6cadd

Browse files
ptomatocjtenny
andcommitted
Avoid re-Getting calendar.dateAdd/dateUntil methods
When the methods are called more than once, we Get the property of the calendar at the beginning of the operation and use it consistently throughout the body. This was mostly done correctly in the spec text, but there was one spot where it wasn't. Adds an optional argument to CalendarDateAdd and CalendarDateUntil for passing in the method if it has already been cached. Co-authored-by: Cam Tenny <[email protected]>
1 parent 9842e3c commit 3e6cadd

File tree

1 file changed

+56
-26
lines changed

1 file changed

+56
-26
lines changed

lib/ecmascript.mjs

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,14 +1745,18 @@ export const ES = ObjectAssign({}, ES2020, {
17451745
if (mergeFields === undefined) return { ...fields, ...additionalFields };
17461746
return ES.Call(mergeFields, calendar, [fields, additionalFields]);
17471747
},
1748-
CalendarDateAdd: (calendar, date, duration, options) => {
1749-
const dateAdd = ES.GetMethod(calendar, 'dateAdd');
1748+
CalendarDateAdd: (calendar, date, duration, options, dateAdd) => {
1749+
if (dateAdd === undefined) {
1750+
dateAdd = ES.GetMethod(calendar, 'dateAdd');
1751+
}
17501752
const result = ES.Call(dateAdd, calendar, [date, duration, options]);
17511753
if (!ES.IsTemporalDate(result)) throw new TypeError('invalid result');
17521754
return result;
17531755
},
1754-
CalendarDateUntil: (calendar, date, otherDate, options) => {
1755-
const dateUntil = ES.GetMethod(calendar, 'dateUntil');
1756+
CalendarDateUntil: (calendar, date, otherDate, options, dateUntil) => {
1757+
if (dateUntil === undefined) {
1758+
dateUntil = ES.GetMethod(calendar, 'dateUntil');
1759+
}
17561760
const result = ES.Call(dateUntil, calendar, [date, otherDate, options]);
17571761
if (!ES.IsTemporalDuration(result)) throw new TypeError('invalid result');
17581762
return result;
@@ -2858,15 +2862,24 @@ export const ES = ObjectAssign({}, ES2020, {
28582862
// no-op
28592863
break;
28602864
case 'months':
2861-
if (!calendar) throw new RangeError('a starting point is required for months balancing');
2862-
// balance years down to months
2863-
while (MathAbs(years) > 0) {
2864-
const newRelativeTo = ES.CalendarDateAdd(calendar, relativeTo, oneYear, {});
2865-
const oneYearMonths = ES.CalendarDateUntil(calendar, relativeTo, newRelativeTo, { largestUnit: 'months' })
2866-
.months;
2867-
relativeTo = newRelativeTo;
2868-
months += oneYearMonths;
2869-
years -= sign;
2865+
{
2866+
if (!calendar) throw new RangeError('a starting point is required for months balancing');
2867+
// balance years down to months
2868+
const dateAdd = ES.GetMethod(calendar, 'dateAdd');
2869+
const dateUntil = ES.GetMethod(calendar, 'dateUntil');
2870+
while (MathAbs(years) > 0) {
2871+
const newRelativeTo = ES.CalendarDateAdd(calendar, relativeTo, oneYear, {}, dateAdd);
2872+
const oneYearMonths = ES.CalendarDateUntil(
2873+
calendar,
2874+
relativeTo,
2875+
newRelativeTo,
2876+
{ largestUnit: 'months' },
2877+
dateUntil
2878+
).months;
2879+
relativeTo = newRelativeTo;
2880+
months += oneYearMonths;
2881+
years -= sign;
2882+
}
28702883
}
28712884
break;
28722885
case 'weeks':
@@ -2958,14 +2971,28 @@ export const ES = ObjectAssign({}, ES2020, {
29582971
}
29592972

29602973
// balance months up to years
2961-
newRelativeTo = ES.CalendarDateAdd(calendar, relativeTo, oneYear, {});
2962-
let oneYearMonths = ES.CalendarDateUntil(calendar, relativeTo, newRelativeTo, { largestUnit: 'months' }).months;
2974+
const dateAdd = ES.GetMethod(calendar, 'dateAdd');
2975+
newRelativeTo = ES.CalendarDateAdd(calendar, relativeTo, oneYear, {}, dateAdd);
2976+
const dateUntil = ES.GetMethod(calendar, 'dateUntil');
2977+
let oneYearMonths = ES.CalendarDateUntil(
2978+
calendar,
2979+
relativeTo,
2980+
newRelativeTo,
2981+
{ largestUnit: 'months' },
2982+
dateUntil
2983+
).months;
29632984
while (MathAbs(months) >= MathAbs(oneYearMonths)) {
29642985
months -= oneYearMonths;
29652986
years += sign;
29662987
relativeTo = newRelativeTo;
2967-
newRelativeTo = ES.CalendarDateAdd(calendar, relativeTo, oneYear, {});
2968-
oneYearMonths = ES.CalendarDateUntil(calendar, relativeTo, newRelativeTo, { largestUnit: 'months' }).months;
2988+
newRelativeTo = ES.CalendarDateAdd(calendar, relativeTo, oneYear, {}, dateAdd);
2989+
oneYearMonths = ES.CalendarDateUntil(
2990+
calendar,
2991+
relativeTo,
2992+
newRelativeTo,
2993+
{ largestUnit: 'months' },
2994+
dateUntil
2995+
).months;
29692996
}
29702997
break;
29712998
}
@@ -3527,9 +3554,9 @@ export const ES = ObjectAssign({}, ES2020, {
35273554
);
35283555
const dateDuration1 = new TemporalDuration(y1, mon1, w1, d1, 0, 0, 0, 0, 0, 0);
35293556
const dateDuration2 = new TemporalDuration(y2, mon2, w2, d2, 0, 0, 0, 0, 0, 0);
3530-
const dateAdd = calendar.dateAdd;
3531-
const intermediate = ES.Call(dateAdd, calendar, [datePart, dateDuration1, {}]);
3532-
const end = ES.Call(dateAdd, calendar, [intermediate, dateDuration2, {}]);
3557+
const dateAdd = ES.GetMethod(calendar, 'dateAdd');
3558+
const intermediate = ES.CalendarDateAdd(calendar, datePart, dateDuration1, {}, dateAdd);
3559+
const end = ES.CalendarDateAdd(calendar, intermediate, dateDuration2, {}, dateAdd);
35333560

35343561
const dateLargestUnit = ES.LargerOfTwoTemporalDurationUnits('days', largestUnit);
35353562
({ years, months, weeks, days } = ES.CalendarDateUntil(calendar, datePart, end, {
@@ -4075,18 +4102,20 @@ export const ES = ObjectAssign({}, ES2020, {
40754102

40764103
// convert months and weeks to days by calculating difference(
40774104
// relativeTo + years, relativeTo + { years, months, weeks })
4078-
const yearsLater = ES.CalendarDateAdd(calendar, relativeTo, new TemporalDuration(years), {});
4105+
const yearsDuration = new TemporalDuration(years);
4106+
const dateAdd = ES.GetMethod(calendar, 'dateAdd');
4107+
const yearsLater = ES.CalendarDateAdd(calendar, relativeTo, yearsDuration, {}, dateAdd);
40794108
const yearsMonthsWeeks = new TemporalDuration(years, months, weeks);
4080-
const yearsMonthsWeeksLater = ES.CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, {});
4109+
const yearsMonthsWeeksLater = ES.CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, {}, dateAdd);
40814110
const monthsWeeksInDays = ES.DaysUntil(yearsLater, yearsMonthsWeeksLater);
40824111
relativeTo = yearsLater;
40834112
days += monthsWeeksInDays;
40844113

4085-
const daysLater = ES.CalendarDateAdd(calendar, relativeTo, { days }, {});
4114+
const daysLater = ES.CalendarDateAdd(calendar, relativeTo, { days }, {}, dateAdd);
40864115
const yearsPassed = ES.CalendarDateUntil(calendar, relativeTo, daysLater, { largestUnit: 'years' }).years;
40874116
years += yearsPassed;
40884117
const oldRelativeTo = relativeTo;
4089-
relativeTo = ES.CalendarDateAdd(calendar, relativeTo, { years: yearsPassed }, {});
4118+
relativeTo = ES.CalendarDateAdd(calendar, relativeTo, { years: yearsPassed }, {}, dateAdd);
40904119
const daysPassed = ES.DaysUntil(oldRelativeTo, relativeTo);
40914120
days -= daysPassed;
40924121
const oneYear = new TemporalDuration(days < 0 ? -1 : 1);
@@ -4113,9 +4142,10 @@ export const ES = ObjectAssign({}, ES2020, {
41134142
// convert weeks to days by calculating difference(relativeTo +
41144143
// { years, months }, relativeTo + { years, months, weeks })
41154144
const yearsMonths = new TemporalDuration(years, months);
4116-
const yearsMonthsLater = ES.CalendarDateAdd(calendar, relativeTo, yearsMonths, {});
4145+
const dateAdd = ES.GetMethod(calendar, 'dateAdd');
4146+
const yearsMonthsLater = ES.CalendarDateAdd(calendar, relativeTo, yearsMonths, {}, dateAdd);
41174147
const yearsMonthsWeeks = new TemporalDuration(years, months, weeks);
4118-
const yearsMonthsWeeksLater = ES.CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, {});
4148+
const yearsMonthsWeeksLater = ES.CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, {}, dateAdd);
41194149
const weeksInDays = ES.DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater);
41204150
relativeTo = yearsMonthsLater;
41214151
days += weeksInDays;

0 commit comments

Comments
 (0)