Skip to content

Commit

Permalink
Fast-path conversion of a Temporal object to Temporal.Calendar
Browse files Browse the repository at this point in the history
If passing a Temporal object with a [[Calendar]] internal slot where a
calendar is expected, then read that slot instead of doing a Get on the
"calendar" property.
(The Get operation was also not consistently done throughout the existing
spec text, so fix that as well. This means the CalendarFrom operation
becomes redundant, so remove it.)

See: #1428
  • Loading branch information
ptomato committed Apr 13, 2021
1 parent 7badec0 commit ba1b1fa
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 38 deletions.
2 changes: 1 addition & 1 deletion polyfill/lib/calendar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export class Calendar {
return ES.ToString(this);
}
static from(item) {
return ES.CalendarFrom(item);
return ES.ToTemporalCalendar(item);
}
}

Expand Down
34 changes: 14 additions & 20 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1501,24 +1501,6 @@ export const ES = ObjectAssign({}, ES2020, {
const TemporalCalendar = GetIntrinsic('%Temporal.Calendar%');
return new TemporalCalendar('iso8601');
},
CalendarFrom: (item) => {
if (ES.Type(item) === 'Object') {
if (!('calendar' in item)) return item;
item = item.calendar;
if (ES.Type(item) === 'Object' && !('calendar' in item)) return item;
}
const stringIdent = ES.ToString(item);
const TemporalCalendar = GetIntrinsic('%Temporal.Calendar%');
if (IsBuiltinCalendar(stringIdent)) return new TemporalCalendar(stringIdent);
let calendar;
try {
({ calendar } = ES.ParseISODateTime(stringIdent, { zoneRequired: false }));
} catch {
throw new RangeError(`Invalid calendar: ${stringIdent}`);
}
if (!calendar) calendar = 'iso8601';
return new TemporalCalendar(calendar);
},
CalendarFields: (calendar, fieldNames) => {
const fields = ES.GetMethod(calendar, 'fields');
if (fields !== undefined) fieldNames = ES.Call(fields, calendar, [fieldNames]);
Expand Down Expand Up @@ -1624,10 +1606,22 @@ export const ES = ObjectAssign({}, ES2020, {

ToTemporalCalendar: (calendarLike) => {
if (ES.Type(calendarLike) === 'Object') {
return calendarLike;
if (HasSlot(calendarLike, CALENDAR)) return GetSlot(calendarLike, CALENDAR);
if (!('calendar' in calendarLike)) return calendarLike;
calendarLike = calendarLike.calendar;
if (ES.Type(calendarLike) === 'Object' && !('calendar' in calendarLike)) return calendarLike;
}
const identifier = ES.ToString(calendarLike);
return ES.CalendarFrom(identifier);
const TemporalCalendar = GetIntrinsic('%Temporal.Calendar%');
if (IsBuiltinCalendar(identifier)) return new TemporalCalendar(identifier);
let calendar;
try {
({ calendar } = ES.ParseISODateTime(identifier, { zoneRequired: false }));
} catch {
throw new RangeError(`Invalid calendar: ${identifier}`);
}
if (!calendar) calendar = 'iso8601';
return new TemporalCalendar(calendar);
},
CalendarCompare: (one, two) => {
const cal1 = ES.ToString(one);
Expand Down
26 changes: 9 additions & 17 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,15 @@ <h1>CalendarInLeapYear ( _calendar_, _dateLike_ )</h1>
<h1>ToTemporalCalendar ( _temporalCalendarLike_ )</h1>
<emu-alg>
1. If Type(_temporalCalendarLike_) is Object, then
1. Return _temporalCalendarLike_.
1. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalTime]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
1. Return _temporalCalendarLike_.[[Calendar]].
1. If ? HasProperty(_item_, *"calendar"*) is *false*, return _item_.
1. Set _item_ to ? Get(_item_, *"calendar"*).
1. If Type(_item_) is Object and ? HasProperty(_item_, *"calendar"*) is *false*, return _item_.
1. Let _identifier_ be ? ToString(_temporalCalendarLike_).
1. Return ? CalendarFrom(_identifier_, %Temporal.Calendar%).
1. If ! IsBuiltinCalendar(_identifier_) is *false*, then
1. Let _identifier_ be ? ParseTemporalCalendarString(_identifier_).
1. Return ? CreateTemporalCalendar(_identifier_).
</emu-alg>
</emu-clause>

Expand Down Expand Up @@ -268,20 +274,6 @@ <h1>GetOptionalTemporalCalendar ( _item_ )</h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-calendarfrom" aoid="CalendarFrom">
<h1>CalendarFrom ( _identifier_ )</h1>
<emu-alg>
1. If Type(_item_) is Object, then
1. If ? HasProperty(_item_, *"calendar"*) is *false*, return _item_.
1. Set _item_ to ? Get(_item_, *"calendar"*).
1. If Type(_item_) is Object and ? HasProperty(_item_, *"calendar"*) is *false*, return _item_.
1. Let _string_ be ? ToString(_item_).
1. If ! IsBuiltinCalendar(_string_) is *false*, then
1. Let _string_ be ? ParseTemporalCalendarString(_string_).
1. Return ? CreateTemporalCalendar(_string_).
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-datefromfields" aoid="DateFromFields">
<h1>DateFromFields ( _calendar_, _fields_, _options_ )</h1>
<emu-alg>
Expand Down Expand Up @@ -656,7 +648,7 @@ <h1>Temporal.Calendar.from ( _item_ )</h1>
The following steps are taken:
</p>
<emu-alg>
1. Return ? CalendarFrom(_item_).
1. Return ? ToTemporalCalendar(_item_).
</emu-alg>
</emu-clause>
</emu-clause>
Expand Down

0 comments on commit ba1b1fa

Please sign in to comment.