Skip to content

Commit

Permalink
Post-adjustment: Make calendar method lookups unconditional
Browse files Browse the repository at this point in the history
This is to address a belated review comment from Richard on #2519. For
each operation in which we need to observably look up calendar methods,
make those lookups unconditional for every method that might be called.

See: #2724
  • Loading branch information
ptomato committed Nov 14, 2023
1 parent 8ce1f54 commit c80df40
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 210 deletions.
41 changes: 3 additions & 38 deletions polyfill/lib/duration.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -329,35 +329,7 @@ export class Duration {
let calendarRec;
if (zonedRelativeTo || plainRelativeTo) {
const calendar = GetSlot(zonedRelativeTo ?? plainRelativeTo, CALENDAR);
calendarRec = new CalendarMethodRecord(calendar);
if (
years !== 0 ||
months !== 0 ||
weeks !== 0 ||
largestUnit === 'year' ||
largestUnit === 'month' ||
largestUnit === 'week' ||
smallestUnit === 'year' ||
smallestUnit === 'month' ||
smallestUnit === 'week'
) {
calendarRec.lookup('dateAdd');
}
if (
largestUnit === 'year' ||
(largestUnit === 'month' && years !== 0) ||
smallestUnit === 'year' ||
// Edge condition in AdjustRoundedDurationDays:
(zonedRelativeTo &&
!roundingGranularityIsNoop &&
smallestUnit !== 'year' &&
smallestUnit !== 'month' &&
smallestUnit !== 'week' &&
smallestUnit !== 'day' &&
(largestUnit === 'year' || largestUnit === 'month' || largestUnit === 'week'))
) {
calendarRec.lookup('dateUntil');
}
calendarRec = new CalendarMethodRecord(calendar, ['dateAdd', 'dateUntil']);
}

({ years, months, weeks, days } = ES.UnbalanceDateDurationRelative(
Expand Down Expand Up @@ -500,13 +472,7 @@ export class Duration {
calendar = GetSlot(plainRelativeTo, CALENDAR);
}
if (calendar) {
calendarRec = new CalendarMethodRecord(calendar);
if (years !== 0 || months !== 0 || weeks !== 0 || unit === 'year' || unit === 'month' || unit === 'week') {
calendarRec.lookup('dateAdd');
}
if (unit === 'year' || (unit === 'month' && years !== 0)) {
calendarRec.lookup('dateUntil');
}
calendarRec = new CalendarMethodRecord(calendar, ['dateAdd', 'dateUntil']);
}

// Convert larger units down to days
Expand Down Expand Up @@ -760,8 +726,7 @@ export class Duration {

let calendarRec;
if (zonedRelativeTo || plainRelativeTo) {
calendarRec = new CalendarMethodRecord(GetSlot(zonedRelativeTo ?? plainRelativeTo, CALENDAR));
if (calendarUnitsPresent) calendarRec.lookup('dateAdd');
calendarRec = new CalendarMethodRecord(GetSlot(zonedRelativeTo ?? plainRelativeTo, CALENDAR), ['dateAdd']);
}

if (zonedRelativeTo && (calendarUnitsPresent || d1 != 0 || d2 !== 0)) {
Expand Down
107 changes: 20 additions & 87 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4302,25 +4302,7 @@ export function DifferenceTemporalPlainDate(operation, plainDate, other, options
return new Duration();
}

const calendarRec = new CalendarMethodRecord(calendar);
const roundingIsNoop = settings.smallestUnit === 'day' && settings.roundingIncrement === 1;
if (
settings.smallestUnit === 'year' ||
settings.smallestUnit === 'month' ||
settings.smallestUnit === 'week' ||
(!roundingIsNoop &&
(settings.largestUnit === 'year' || settings.largestUnit === 'month' || settings.largestUnit === 'week'))
) {
calendarRec.lookup('dateAdd');
}
if (
settings.largestUnit === 'year' ||
settings.largestUnit === 'month' ||
settings.largestUnit === 'week' ||
settings.smallestUnit === 'year'
) {
calendarRec.lookup('dateUntil');
}
const calendarRec = new CalendarMethodRecord(calendar, ['dateAdd', 'dateUntil']);

resolvedOptions.largestUnit = settings.largestUnit;
const untilResult = DifferenceDate(calendarRec, plainDate, other, resolvedOptions);
Expand All @@ -4329,6 +4311,7 @@ export function DifferenceTemporalPlainDate(operation, plainDate, other, options
let weeks = GetSlot(untilResult, WEEKS);
let days = GetSlot(untilResult, DAYS);

const roundingIsNoop = settings.smallestUnit === 'day' && settings.roundingIncrement === 1;
if (!roundingIsNoop) {
({ years, months, weeks, days } = RoundDuration(
years,
Expand Down Expand Up @@ -4388,25 +4371,7 @@ export function DifferenceTemporalPlainDateTime(operation, plainDateTime, other,
return new Duration();
}

const calendarRec = new CalendarMethodRecord(calendar);
const roundingIsNoop = settings.smallestUnit === 'nanosecond' && settings.roundingIncrement === 1;
if (
settings.smallestUnit === 'year' ||
settings.smallestUnit === 'month' ||
settings.smallestUnit === 'week' ||
(!datePartsIdentical &&
!roundingIsNoop &&
(settings.largestUnit === 'year' || settings.largestUnit === 'month' || settings.largestUnit === 'week'))
) {
calendarRec.lookup('dateAdd');
}
if (
(!datePartsIdentical &&
(settings.largestUnit === 'year' || settings.largestUnit === 'month' || settings.largestUnit === 'week')) ||
settings.smallestUnit === 'year'
) {
calendarRec.lookup('dateUntil');
}
const calendarRec = new CalendarMethodRecord(calendar, ['dateAdd', 'dateUntil']);

let { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } =
DifferenceISODateTime(
Expand All @@ -4433,6 +4398,7 @@ export function DifferenceTemporalPlainDateTime(operation, plainDateTime, other,
resolvedOptions
);

const roundingIsNoop = settings.smallestUnit === 'nanosecond' && settings.roundingIncrement === 1;
if (!roundingIsNoop) {
const relativeTo = TemporalDateTimeToDate(plainDateTime);
({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = RoundDuration(
Expand Down Expand Up @@ -4570,13 +4536,7 @@ export function DifferenceTemporalPlainYearMonth(operation, yearMonth, other, op
return new Duration();
}

const calendarRec = new CalendarMethodRecord(calendar);
if (settings.smallestUnit !== 'month' || settings.roundingIncrement !== 1) {
calendarRec.lookup('dateAdd');
}
calendarRec.lookup('dateFromFields');
calendarRec.lookup('dateUntil');
calendarRec.lookup('fields');
const calendarRec = new CalendarMethodRecord(calendar, ['dateAdd', 'dateFromFields', 'dateUntil', 'fields']);

const fieldNames = CalendarFields(calendarRec, ['monthCode', 'year']);
const thisFields = PrepareTemporalFields(yearMonth, fieldNames, []);
Expand Down Expand Up @@ -4765,7 +4725,7 @@ export function AddISODate(year, month, day, years, months, weeks, days, overflo
}

export function AddDate(calendarRec, plainDate, duration, options = undefined) {
// dateAdd must be looked up if years, months, weeks != 0
// dateAdd must be looked up
const years = GetSlot(duration, YEARS);
const months = GetSlot(duration, MONTHS);
const weeks = GetSlot(duration, WEEKS);
Expand Down Expand Up @@ -5174,31 +5134,10 @@ export function AddDurationToOrSubtractDurationFromDuration(operation, duration,

let calendarRec;
if (plainRelativeTo || zonedRelativeTo) {
calendarRec = new CalendarMethodRecord(GetSlot(zonedRelativeTo ?? plainRelativeTo, CALENDAR));
if (
GetSlot(duration, YEARS) !== 0 ||
GetSlot(duration, MONTHS) !== 0 ||
GetSlot(duration, WEEKS) !== 0 ||
years !== 0 ||
months !== 0 ||
weeks !== 0
) {
calendarRec.lookup('dateAdd');
if (
years !== 0 ||
months !== 0 ||
weeks !== 0 ||
days !== 0 ||
hours !== 0 ||
minutes !== 0 ||
seconds !== 0 ||
milliseconds !== 0 ||
microseconds !== 0 ||
nanoseconds !== 0
) {
calendarRec.lookup('dateUntil');
}
}
calendarRec = new CalendarMethodRecord(GetSlot(zonedRelativeTo ?? plainRelativeTo, CALENDAR), [
'dateAdd',
'dateUntil'
]);
}

({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = AddDuration(
Expand Down Expand Up @@ -5258,10 +5197,7 @@ export function AddDurationToOrSubtractDurationFromPlainDateTime(operation, date
ToTemporalDurationRecord(durationLike);
options = GetOptionsObject(options);

const calendarRec = new CalendarMethodRecord(GetSlot(dateTime, CALENDAR));
if (years !== 0 || months !== 0 || weeks !== 0) {
calendarRec.lookup('dateAdd');
}
const calendarRec = new CalendarMethodRecord(GetSlot(dateTime, CALENDAR), ['dateAdd']);

const { year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = AddDateTime(
GetSlot(dateTime, ISO_YEAR),
Expand Down Expand Up @@ -5350,14 +5286,14 @@ export function AddDurationToOrSubtractDurationFromPlainYearMonth(operation, yea
({ days } = BalanceTimeDuration(days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 'day'));
const sign = DurationSign(years, months, weeks, days, 0, 0, 0, 0, 0, 0);

const calendarRec = new CalendarMethodRecord(GetSlot(yearMonth, CALENDAR));
if (sign < 0 || years !== 0 || months !== 0 || weeks !== 0) {
calendarRec.lookup('dateAdd');
}
calendarRec.lookup('dateFromFields');
if (sign < 0) calendarRec.lookup('day');
calendarRec.lookup('fields');
calendarRec.lookup('yearMonthFromFields');
const calendarRec = new CalendarMethodRecord(GetSlot(yearMonth, CALENDAR), [
'dateAdd',
'dateFromFields',
'day',
'fields',
'yearMonthFromFields'
]);

const fieldNames = CalendarFields(calendarRec, ['monthCode', 'year']);
const fields = PrepareTemporalFields(yearMonth, fieldNames, []);
const fieldsCopy = SnapshotOwnProperties(fields, null);
Expand Down Expand Up @@ -5404,10 +5340,7 @@ export function AddDurationToOrSubtractDurationFromZonedDateTime(operation, zone
'getOffsetNanosecondsFor',
'getPossibleInstantsFor'
]);
const calendarRec = new CalendarMethodRecord(GetSlot(zonedDateTime, CALENDAR));
if (years !== 0 || months !== 0 || weeks !== 0) {
calendarRec.lookup('dateAdd');
}
const calendarRec = new CalendarMethodRecord(GetSlot(zonedDateTime, CALENDAR), ['dateAdd']);
const epochNanoseconds = AddZonedDateTime(
GetSlot(zonedDateTime, INSTANT),
timeZoneRec,
Expand Down
15 changes: 2 additions & 13 deletions polyfill/lib/plaindate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ import {
ISO_NANOSECOND,
CALENDAR,
EPOCHNANOSECONDS,
MONTHS,
WEEKS,
YEARS,
GetSlot
} from './slots.mjs';

Expand Down Expand Up @@ -122,11 +119,7 @@ export class PlainDate {
const duration = ES.ToTemporalDuration(temporalDurationLike);
options = ES.GetOptionsObject(options);

const calendarRec = new CalendarMethodRecord(GetSlot(this, CALENDAR));
if (GetSlot(duration, YEARS) !== 0 || GetSlot(duration, MONTHS) !== 0 || GetSlot(duration, WEEKS) !== 0) {
calendarRec.lookup('dateAdd');
}

const calendarRec = new CalendarMethodRecord(GetSlot(this, CALENDAR), ['dateAdd']);
return ES.AddDate(calendarRec, this, duration, options);
}
subtract(temporalDurationLike, options = undefined) {
Expand All @@ -135,11 +128,7 @@ export class PlainDate {
const duration = ES.CreateNegatedTemporalDuration(ES.ToTemporalDuration(temporalDurationLike));
options = ES.GetOptionsObject(options);

const calendarRec = new CalendarMethodRecord(GetSlot(this, CALENDAR));
if (GetSlot(duration, YEARS) !== 0 || GetSlot(duration, MONTHS) !== 0 || GetSlot(duration, WEEKS) !== 0) {
calendarRec.lookup('dateAdd');
}

const calendarRec = new CalendarMethodRecord(GetSlot(this, CALENDAR), ['dateAdd']);
return ES.AddDate(calendarRec, this, duration, options);
}
until(other, options = undefined) {
Expand Down
34 changes: 4 additions & 30 deletions spec/duration.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ <h1>Temporal.Duration.compare ( _one_, _two_ [ , _options_ ] )</h1>
1. Let _calendarRec_ be *undefined*.
1. If _zonedRelativeTo_ is not *undefined* or _plainRelativeTo_ is not *undefined*, then
1. If _zonedRelativeTo_ is not *undefined*, let _calendar_ be _zonedRelativeTo_.[[Calendar]]; else let _calendar_ be _plainRelativeTo_.[[Calendar]].
1. Set _calendarRec_ to ! CreateCalendarMethodsRecord(_calendar_, « »).
1. If _calendarUnitsPresent_ is *true*, then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateAdd~).
1. Set _calendarRec_ to ? CreateCalendarMethodsRecord(_calendar_, « ~dateAdd~ »).
1. If _zonedRelativeTo_ is not *undefined*, and either _calendarUnitsPresent_ is *true*, or _one_.[[Days]] &ne; 0, or _two_.[[Days]] &ne; 0, then
1. Let _instant_ be ! CreateTemporalInstant(_zonedRelativeTo_.[[Nanoseconds]]).
1. Let _precalculatedPlainDateTime_ be ? GetPlainDateTimeFor(_timeZoneRec_, _instant_, _calendarRec_.[[Receiver]]).
Expand Down Expand Up @@ -475,23 +473,7 @@ <h1>Temporal.Duration.prototype.round ( _roundTo_ )</h1>
1. Let _calendarRec_ be *undefined*.
1. If _zonedRelativeTo_ is not *undefined* or _plainRelativeTo_ is not *undefined*, then
1. If _zonedRelativeTo_ is not *undefined*, let _calendar_ be _zonedRelativeTo_.[[Calendar]]; else let _calendar_ be _plainRelativeTo_.[[Calendar]].
1. Set _calendarRec_ to ! CreateCalendarMethodsRecord(_calendar_, « »).
1. If _largestUnit_ is *"year"*, or _largestUnit_ is *"month"*, or _largestUnit_ is *"week"*, let _largestUnitIsCalendarUnit_ be *true*; else let _largestUnitIsCalendarUnit_ be *false*.
1. If _smallestUnit_ is *"year"*, or _smallestUnit_ is *"month"*, or _smallestUnit_ is *"week"*, let _smallestUnitIsCalendarUnit_ be *true*; else let _smallestUnitIsCalendarUnit_ be *false*.
1. If _duration_.[[Years]] &ne; 0, or _duration_.[[Months]] &ne; 0, or _duration_.[[Weeks]] &ne; 0, or _largestUnitIsCalendarUnit_ is *true*, or _smallestUnitIsCalendarUnit_ is *true*; then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateAdd~).
1. Let _dateUntilMayBeCalled_ be *false*.
1. If _largestUnit_ is *"year"*, set _dateUntilMayBeCalled_ to *true*.
1. If _largestUnit_ is *"month"* and _duration_.[[Years]] &ne; 0, set _dateUntilMayBeCalled_ to *true*.
1. If _smallestUnit_ is *"year"*, set _dateUntilMayBeCalled_ to *true*.
1. Let _dateUntilMayBeCalledInAdjustDurationEdgeCase_ be *true*.
1. If _zonedRelativeTo_ is *undefined*, set _dateUntilMayBeCalledInAdjustDurationEdgeCase_ to *false*.
1. If _roundingGranularityIsNoop_ is *true*, set _dateUntilMayBeCalledInAdjustDurationEdgeCase_ to *false*.
1. If _smallestUnitIsCalendarUnit_ is *true*, set _dateUntilMayBeCalledInAdjustDurationEdgeCase_ to *false*.
1. If _largestUnitIsCalendarUnit_ is *false*, set _dateUntilMayBeCalledInAdjustDurationEdgeCase_ to *false*.
1. If _dateUntilMayBeCalledInAdjustDurationEdgeCase_ is *true*, set _dateUntilMayBeCalled_ to *true*.
1. If _dateUntilMayBeCalled_ is *true*, then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateUntil~).
1. Set _calendarRec_ to ? CreateCalendarMethodsRecord(_calendar_, « ~dateAdd~, ~dateUntil~ »).
1. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _plainRelativeTo_, _calendarRec_).
1. Let _roundRecord_ be ? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _plainRelativeTo_, _calendarRec_, _zonedRelativeTo_, _timeZoneRec_, _precalculatedPlainDateTime_).
1. Let _roundResult_ be _roundRecord_.[[DurationRecord]].
Expand Down Expand Up @@ -536,11 +518,7 @@ <h1>Temporal.Duration.prototype.total ( _totalOf_ )</h1>
1. Let _calendarRec_ be *undefined*.
1. If _zonedRelativeTo_ is not *undefined* and _plainRelativeTo_ is not *undefined*, then
1. If _zonedRelativeTo_ is not *undefined*, let _calendar_ be _zonedRelativeTo_.[[Calendar]]; else let _calendar_ be _plainRelativeTo_.[[Calendar]].
1. Set _calendarRec_ to ! CreateCalendarMethodsRecord(_calendar_, « »).
1. If _duration_.[[Years]] &ne; 0, or _duration_.[[Months]] &ne; 0, or _duration_.[[Weeks]] &ne; 0, or _unit_ is *"year"*, or _unit_ is *"month"*, or _unit_ is *"week"*, then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateAdd~).
1. If _unit_ is *"year"*, or _unit_ is *"month"* and _duration_.[[Years]] &ne; 0, then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateUntil~).
1. Set _calendarRec_ to ? CreateCalendarMethodsRecord(_calendar_, « ~dateAdd~, ~dateUntil~ »).
1. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _unit_, _plainRelativeTo_, _calendarRec_).
1. If _zonedRelativeTo_ is not *undefined*, then
1. Let _intermediate_ be ? MoveRelativeZonedDateTime(_zonedRelativeTo_, _calendarRec_, _timeZoneRec_, _unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], 0, _precalculatedPlainDateTime_).
Expand Down Expand Up @@ -2030,11 +2008,7 @@ <h1>
1. Let _calendarRec_ be *undefined*.
1. If _zonedRelativeTo_ is not *undefined* and _plainRelativeTo_ is not *undefined*, then
1. If _zonedRelativeTo_ is not *undefined*, let _calendar_ be _zonedRelativeTo_.[[Calendar]]; else let _calendar_ be _plainRelativeTo_.[[Calendar]].
1. Set _calendarRec_ to ! CreateCalendarMethodsRecord(_calendar_, « »).
1. If _duration_.[[Years]] &ne; 0, or _duration_.[[Months]] &ne; 0, or _duration_.[[Weeks]] &ne; 0, or _other_.[[Years]] &ne; 0, or _other_.[[Months]] &ne; 0, or _other_.[[Weeks]] &ne; 0, then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateAdd~).
1. If _other_.[[Years]] &ne; 0, or _other_.[[Months]] &ne; 0, or _other_.[[Weeks]] &ne; 0, or _other_.[[Days]] &ne; 0, or _other_.[[Hours]] &ne; 0, or _other_.[[Minutes]] &ne; 0, or _other_.[[Seconds]] &ne; 0, or _other_.[[Milliseconds]] &ne; 0, or _other_.[[Microseconds]] &ne; 0, or _other_.[[Nanoseconds]] &ne; 0, then
1. Perform ? CalendarMethodsRecordLookup(_calendarRec_, ~dateUntil~).
1. Set _calendarRec_ to ? CreateCalendarMethodsRecord(_calendar_, « ~dateAdd~, ~dateUntil~ »).
1. Let _result_ be ? AddDuration(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _sign_ &times; _other_.[[Years]], _sign_ &times; _other_.[[Months]], _sign_ &times; _other_.[[Weeks]], _sign_ &times; _other_.[[Days]], _sign_ &times; _other_.[[Hours]], _sign_ &times; _other_.[[Minutes]], _sign_ &times; _other_.[[Seconds]], _sign_ &times; _other_.[[Milliseconds]], _sign_ &times; _other_.[[Microseconds]], _sign_ &times; _other_.[[Nanoseconds]], _plainRelativeTo_, _calendarRec_, _zonedRelativeTo_, _timeZoneRec_).
1. Return ! CreateTemporalDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _result_.[[Hours]], _result_.[[Minutes]], _result_.[[Seconds]], _result_.[[Milliseconds]], _result_.[[Microseconds]], _result_.[[Nanoseconds]]).
</emu-alg>
Expand Down
Loading

0 comments on commit c80df40

Please sign in to comment.