From f431988a6eb4b02c056af820aa7f3c0d0d973d22 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 18 Jan 2023 20:26:07 -0800 Subject: [PATCH] Normative: Remove support for nested calendar property bags Previously, "nested" calendar property bags were unwrapped up to one level. That is, this object: { calendar: { // ...Temporal.Calendar methods } } would not be considered to implement the Calendar protocol, but would have its calendar property used instead, if it were passed to an API that required a Calendar protocol object. These nested property bags are no longer supported. Discussion: https://github.com/tc39/proposal-temporal/issues/2104#issuecomment-1409549753 See: #2104 --- docs/calendar.md | 1 - polyfill/index.d.ts | 5 ++--- polyfill/lib/ecmascript.mjs | 13 +------------ spec/calendar.html | 8 +------- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/docs/calendar.md b/docs/calendar.md index 105f91796f..025cd03c4f 100644 --- a/docs/calendar.md +++ b/docs/calendar.md @@ -118,7 +118,6 @@ The object must implement all of the `Temporal.Calendar` properties and methods Any object with the required methods will return the correct output from any Temporal property or method. However, most other code will assume that custom calendars act like built-in `Temporal.Calendar` objects. To interoperate with libraries or other code that you didn't write, then you should implement the `fields()`, `mergeFields()`, `toString()`, and `toJSON()` methods as well. -Your object must not have a `calendar` property, so that it can be distinguished in `Temporal.Calendar.from()` from other Temporal objects that have a calendar. The identifier of a custom calendar must consist of one or more components of between 3 and 8 ASCII alphanumeric characters each, separated by dashes, as described in [Unicode Technical Standard 35](https://unicode.org/reports/tr35/tr35.html#Unicode_locale_identifier). diff --git a/polyfill/index.d.ts b/polyfill/index.d.ts index 0ddb0745a0..7afd579a3c 100644 --- a/polyfill/index.d.ts +++ b/polyfill/index.d.ts @@ -614,7 +614,6 @@ export namespace Temporal { export interface CalendarProtocol { id: string; - calendar?: never; year(date: Temporal.PlainDate | Temporal.PlainDateTime | Temporal.PlainYearMonth | PlainDateLike | string): number; month( date: @@ -681,7 +680,7 @@ export namespace Temporal { toJSON?(): string; } - export type CalendarLike = CalendarProtocol | string | { calendar: CalendarProtocol | string }; + export type CalendarLike = CalendarProtocol | string; /** * A `Temporal.Calendar` is a representation of a calendar system. It includes @@ -691,7 +690,7 @@ export namespace Temporal { * * See https://tc39.es/proposal-temporal/docs/calendar.html for more details. */ - export class Calendar implements Omit, 'calendar'> { + export class Calendar implements CalendarProtocol { static from(item: CalendarLike): Temporal.Calendar | CalendarProtocol; constructor(calendarIdentifier: string); readonly id: string; diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index f9a5897c2b..d1865acd9e 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -1850,7 +1850,6 @@ export const ES = ObjectAssign({}, ES2022, { ToTemporalCalendarSlotValue: (calendarLike) => { if (ES.Type(calendarLike) === 'Object') { - if (ES.IsTemporalCalendar(calendarLike)) return calendarLike; if (HasSlot(calendarLike, CALENDAR)) return GetSlot(calendarLike, CALENDAR); if (ES.IsTemporalTime(calendarLike)) { throw new RangeError('Expected a calendar object but received a Temporal.PlainTime'); @@ -1858,17 +1857,7 @@ export const ES = ObjectAssign({}, ES2022, { if (ES.IsTemporalTimeZone(calendarLike)) { throw new RangeError('Expected a calendar object but received a Temporal.TimeZone'); } - if (!('calendar' in calendarLike)) return calendarLike; - calendarLike = calendarLike.calendar; - if (ES.Type(calendarLike) === 'Object') { - if (ES.IsTemporalTime(calendarLike)) { - throw new RangeError('Expected a calendar object as the calendar property but received a Temporal.PlainTime'); - } - if (ES.IsTemporalTimeZone(calendarLike)) { - throw new RangeError('Expected a calendar object as the calendar property but received a Temporal.TimeZone'); - } - if (!('calendar' in calendarLike)) return calendarLike; - } + return calendarLike; } const identifier = ES.ToString(calendarLike); if (ES.IsBuiltinCalendar(identifier)) return ES.ASCIILowercase(identifier); diff --git a/spec/calendar.html b/spec/calendar.html index 42edf0e41c..3cb35464c8 100644 --- a/spec/calendar.html +++ b/spec/calendar.html @@ -497,16 +497,10 @@

1. Assert: IsBuiltinCalendar(_default_) is *true*. 1. Return _default_. 1. If Type(_temporalCalendarLike_) is Object, then - 1. If _temporalCalendarLike_ has an [[InitializedTemporalCalendar]] internal slot, then - 1. Return _temporalCalendarLike_. 1. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then 1. Return _temporalCalendarLike_.[[Calendar]]. 1. If _temporalCalendarLike_ has an [[InitializedTemporalTime]] or [[InitializedTemporalTimeZone]] internal slot, throw a *RangeError* exception. - 1. If ? HasProperty(_temporalCalendarLike_, *"calendar"*) is *false*, return _temporalCalendarLike_. - 1. Set _temporalCalendarLike_ to ? Get(_temporalCalendarLike_, *"calendar"*). - 1. If Type(_temporalCalendarLike_) is Object, then - 1. If _temporalCalendarLike_ has an [[InitializedTemporalTime]] or [[InitializedTemporalTimeZone]] internal slot, throw a *RangeError* exception. - 1. If ? HasProperty(_temporalCalendarLike_, *"calendar"*) is *false*, return _temporalCalendarLike_. + 1. Return _temporalCalendarLike_. 1. Let _identifier_ be ? ToString(_temporalCalendarLike_). 1. Set _identifier_ to ? ParseTemporalCalendarString(_identifier_). 1. If IsBuiltinCalendar(_identifier_) is *false*, throw a *RangeError* exception.