Skip to content

Commit

Permalink
Normative: Remove the ECMA-402 PrepareTemporalFields override
Browse files Browse the repository at this point in the history
"era" and "eraYear" are still checked in alphabetical order along with other fields
when the calendar specifies their relevance,
but ensuring both-or-neither and consistency between the pair and "year"
is no longer part of the operation (although it remains part of CalendarResolveFields
along with similar checks for "month" and "monthCode").

Fixes #2465
  • Loading branch information
gibson042 committed Feb 18, 2023
1 parent 0779b5a commit 7d1666d
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 81 deletions.
51 changes: 41 additions & 10 deletions spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,7 @@ <h1>
_fields_: an Object,
_fieldNames_: a List of property names,
_requiredFields_: ~partial~ or a List of property names,
optional _extraFieldDescriptors_: a List of Calendar Field Descriptor Records
): either a normal completion containing an Object, or an abrupt completion
</h1>
<dl class="header">
Expand All @@ -1669,11 +1670,18 @@ <h1>
The returned Object has a null prototype, and an own data property for each element of _fieldNames_ that corresponds with a non-*undefined* property of the same name on _fields_ used as the input for relevant conversion.
When _requiredFields_ is ~partial~, this operation throws if none of the properties are present with a non-*undefined* value.
When _requiredFields_ is a List, this operation throws if any of the properties named by it are absent or undefined, and otherwise substitutes a relevant default for any absent or undefined non-required property (ensuring that the returned object has a property for each element of _fieldNames_).
When _extraFieldDescriptors_ is present, its contents are treated as an extension of <emu-xref href="#table-temporal-field-requirements"></emu-xref>.
</dd>
</dl>
<emu-alg>
1. Let _result_ be OrdinaryObjectCreate(*null*).
1. Let _any_ be *false*.
1. If _extraFieldDescriptors_ is present, then
1. For each Calendar Field Descriptor Record _desc_ of _extraFieldDescriptors_, do
1. Assert: _fieldNames_ does not contain _desc_.[[Property]].
1. Append _desc_.[[Property]] to _fieldNames_.
1. If _desc_.[[Required]] is *true* and _requiredFields_ is a List, then
1. Append _desc_.[[Property]] to _requiredFields_.
1. Let _sortedFieldNames_ be SortStringListByCodeUnit(_fieldNames_).
1. For each property name _property_ of _sortedFieldNames_, do
1. Let _value_ be ? Get(_fields_, _property_).
Expand All @@ -1690,6 +1698,9 @@ <h1>
1. Else,
1. Assert: _Conversion_ is ~ToString~.
1. Set _value_ to ? ToString(_value_).
1. Else if _extraFieldDescriptors_ is present and _extraFieldDescriptors_ contains a Calendar Field Descriptor Record _desc_ such that _desc_.[[Property]] is _property_, then
1. Let _converter_ be _desc_.[[Conversion]].
1. Set _value_ to ? _converter_(_value_).
1. Perform ! CreateDataPropertyOrThrow(_result_, _property_, _value_).
1. Else if _requiredFields_ is a List, then
1. If _requiredFields_ contains _property_, then
Expand Down Expand Up @@ -1767,16 +1778,6 @@ <h1>
<td>~ToString~</td>
<td>*undefined*</td>
</tr>
<tr>
<td>*"era"*</td>
<td>~ToString~</td>
<td>*undefined*</td>
</tr>
<tr>
<td>*"eraYear"*</td>
<td>~ToIntegerWithTruncation~</td>
<td>*undefined*</td>
</tr>
<tr>
<td>*"timeZone"*</td>
<td></td>
Expand All @@ -1785,6 +1786,36 @@ <h1>
</tbody>
</table>
</emu-table>

<emu-clause id="sec-temporal-calendar-field-descriptor-record">
<h1>Calendar Field Descriptor Record</h1>
<p>A <dfn variants="Calendar Field Descriptor Records">Calendar Field Descriptor Record</dfn> is a Record value used to describe a calendar-specific field for use in creating and interacting with instances of Temporal types.</p>
<p>Calendar Field Descriptor Records have the fields listed in <emu-xref href="#table-temporal-calendar-field-descriptor-record"></emu-xref>.</p>
<emu-table id="table-temporal-calendar-field-descriptor-record" caption="Calendar Field Descriptor Record Fields">
<table>
<tr>
<th>Field Name</th>
<th>Value</th>
<th>Meaning</th>
</tr>
<tr>
<td>[[Property]]</td>
<td>a String</td>
<td>The property name associated with the field, analogous to the Property column of <emu-xref href="#table-temporal-field-requirements"></emu-xref>.</td>
</tr>
<tr>
<td>[[Conversion]]</td>
<td>an Abstract Closure accepting a single ECMAScript language value and returning either a normal completion containing an ECMAScript language value representing purely static data or a throw completion.</td>
<td>The means by which purported values are coerced to a static representation of the correct type (or rejected if that fails), analogous to steps indicated by the Conversion column of <emu-xref href="#table-temporal-field-requirements"></emu-xref>.</td>
</tr>
<tr>
<td>[[Required]]</td>
<td>a Boolean</td>
<td>Whether PrepareTemporalFields should consider the field as required when not accepting partial data.</td>
</tr>
</table>
</emu-table>
</emu-clause>
</emu-clause>

<emu-clause id="sec-temporal-getdifferencesettings" type="abstract operation">
Expand Down
88 changes: 17 additions & 71 deletions spec/intl.html
Original file line number Diff line number Diff line change
Expand Up @@ -1701,16 +1701,16 @@ <h1>
</emu-note>
</emu-clause>

<emu-clause id="sec-temporal-calendardatefields" type="abstract operation">
<emu-clause id="sec-temporal-calendarfielddescriptors" type="abstract operation">
<h1>
CalendarDateFields (
CalendarFieldDescriptors (
_calendar_: a String,
_fields_: a List of Strings,
): a List of Strings
_type_: ~date~, ~year-month~, or ~month-day~,
): a List of Calendar Field Descriptor Records
</h1>
<dl class="header">
<dt>description</dt>
<dd>It interprets _fields_ as the names of fields (<emu-xref href="#table-temporal-field-requirements"></emu-xref>) necessary for a given operation and returns a new List by appending the names of additional calendar-specific fields that are relevant for the built-in calendar identified by _calendar_. For example, *"era"* and *"eraYear"* are appended when _calendar_ is *"gregory"* or *"japanese"*.</dd>
<dd>It characterizes calendar-specific fields that are relevant for values of the provided _type_ in the built-in calendar identified by _calendar_. For example, *"era"* (with ToString conversion) and *"eraYear"* (with ToIntegerWithTruncation conversion) are returned when _calendar_ is *"gregory"* or *"japanese"* and _type_ is ~date~ or ~year-month~.</dd>
</dl>
</emu-clause>

Expand Down Expand Up @@ -1825,8 +1825,8 @@ <h1>Temporal.Calendar.prototype.dateFromFields ( _fields_ [ , _options_ ] )</h1>
1. If _calendar_.[[Identifier]] is *"iso8601"*, then
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _relevantFieldNames_, « *"year"*, *"day"* »).
1. Else,
1. Let _fieldNames_ be CalendarDateFields(_calendar_.[[Identifier]], _relevantFieldNames_).
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _fieldNames_, « »).
1. Let _calendarRelevantFieldDescriptors_ be CalendarFieldDescriptors(_calendar_.[[Identifier]], ~date~).
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _relevantFieldNames_, « », _calendarRelevantFieldDescriptors_).
1. Let _overflow_ be ? ToTemporalOverflow(_options_).
1. If _calendar_.[[Identifier]] is *"iso8601"*, then
1. Perform ? ISOResolveMonth(_fields_).
Expand All @@ -1853,8 +1853,8 @@ <h1>Temporal.Calendar.prototype.yearMonthFromFields ( _fields_ [ , _options_ ] )
1. If _calendar_.[[Identifier]] is *"iso8601"*, then
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _relevantFieldNames_, « *"year"* »).
1. Else,
1. Let _fieldNames_ be CalendarDateFields(_calendar_.[[Identifier]], _relevantFieldNames_).
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _fieldNames_, « »).
1. Let _calendarRelevantFieldDescriptors_ be CalendarFieldDescriptors(_calendar_.[[Identifier]], ~year-month~).
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _relevantFieldNames_, « », _calendarRelevantFieldDescriptors_).
1. Let _firstDayIndex_ be the 1-based index of the first day of the month described by _fields_ (i.e., 1 unless the month's first day is skipped by this calendar.)
1. Perform ! CreateDataPropertyOrThrow(_fields_, *"day"*, 𝔽(_firstDayIndex_)).
1. Let _overflow_ be ? ToTemporalOverflow(_options_).
Expand Down Expand Up @@ -1884,8 +1884,8 @@ <h1>Temporal.Calendar.prototype.monthDayFromFields ( _fields_ [ , _options_ ] )<
1. If _calendar_.[[Identifier]] is *"iso8601"*, then
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _relevantFieldNames_, « *"day"* »).
1. Else,
1. Let _fieldNames_ be CalendarDateFields(_calendar_.[[Identifier]], _relevantFieldNames_).
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _fieldNames_, « »).
1. Let _calendarRelevantFieldDescriptors_ be CalendarFieldDescriptors(_calendar_.[[Identifier]], ~month-day~).
1. Set _fields_ to ? PrepareTemporalFields(_fields_, _relevantFieldNames_, « », _calendarRelevantFieldDescriptors_).
1. Let _overflow_ be ? ToTemporalOverflow(_options_).
1. If _calendar_.[[Identifier]] is *"iso8601"*, then
1. Perform ? ISOResolveMonth(_fields_).
Expand Down Expand Up @@ -2252,10 +2252,12 @@ <h1>Temporal.Calendar.prototype.fields ( _fields_ )</h1>
1. Let _completion_ be ThrowCompletion(a newly created *RangeError* object).
1. Return ? IteratorClose(_iteratorRecord_, _completion_).
1. Append _nextValue_ to the end of the List _fieldNames_.
1. If _calendar_.[[Identifier]] is *"iso8601"*, then
1. Let _result_ be _fieldNames_.
1. Else,
1. Let _result_ be CalendarDateFields(_calendar_.[[Identifier]], _fieldNames_).
1. Let _result_ be _fieldNames_.
1. If _calendar_.[[Identifier]] is not *"iso8601"*, then
1. NOTE: Every built-in calendar preserves all input field names in output.
1. Let _extraFieldDescriptors_ be CalendarFieldDescriptors(_calendar_.[[Identifier]], ~date~).
1. For each Calendar Field Descriptor Record _desc_ of _extraFieldDescriptors_, do
1. Append _desc_.[[Property]] to _result_.
1. Return CreateArrayFromList(_result_).
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -2539,61 +2541,5 @@ <h1>get Temporal.ZonedDateTime.prototype.eraYear</h1>
</emu-clause>
</emu-clause>
</ins>

<ins class="block">
<emu-clause id="sec-abstracts">
<h1>Abstract Operations</h1>

<emu-clause id="sup-temporal-preparetemporalfields" type="abstract operation">
<h1>
PrepareTemporalFields (
_fields_: an Object,
_fieldNames_: a List of property names,
_requiredFields_: ~partial~ or a List of property names,
): either a normal completion containing an Object, or an abrupt completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>This definition supersedes the definition provided in <emu-xref href="#sec-temporal-preparetemporalfields"></emu-xref>.</dd>
<dt>redefinition</dt>
<dd>true</dd>
</dl>
<emu-alg>
1. Let _result_ be OrdinaryObjectCreate(*null*).
1. Let _any_ be *false*.
1. For each property name _property_ of _fieldNames_, do
1. Let _value_ be ? Get(_fields_, _property_).
1. If _value_ is not *undefined*, then
1. Set _any_ to *true*.
1. If _property_ is in the Property column of <emu-xref href="#table-temporal-field-requirements"></emu-xref> and there is a Conversion value in the same row, then
1. Let _Conversion_ be the Conversion value of the same row.
1. If _Conversion_ is ~ToIntegerWithTruncation~, then
1. Set _value_ to ? ToIntegerWithTruncation(_value_).
1. Set _value_ to 𝔽(_value_).
1. Else if _Conversion_ is ~ToPositiveIntegerWithTruncation~, then
1. Set _value_ to ? ToPositiveIntegerWithTruncation(_value_).
1. Set _value_ to 𝔽(_value_).
1. Else,
1. Assert: _Conversion_ is ~ToString~.
1. Set _value_ to ? ToString(_value_).
1. Perform ! CreateDataPropertyOrThrow(_result_, _property_, _value_).
1. Else if _requiredFields_ is a List, then
1. If _requiredFields_ contains _property_, then
1. Throw a *TypeError* exception.
1. If _property_ is in the Property column of <emu-xref href="#table-temporal-field-requirements"></emu-xref>, then
1. Set _value_ to the corresponding Default value of the same row.
1. Perform ! CreateDataPropertyOrThrow(_result_, _property_, _value_).
1. If _requiredFields_ is ~partial~ and _any_ is *false*, then
1. Throw a *TypeError* exception.
1. If _requiredFields_ is not ~partial~, then
1. Let _era_ be ? Get(_result_, *"era"*).
1. Let _eraYear_ be ? Get(_result_, *"eraYear"*).
1. If _era_ is *undefined* and _eraYear_ is not *undefined*, or if _era_ is not *undefined* and _eraYear_ is *undefined*, then
1. Throw a *RangeError* exception.
1. Return _result_.
</emu-alg>
</emu-clause>
</emu-clause>
</ins>
</emu-clause>
</emu-clause>

0 comments on commit 7d1666d

Please sign in to comment.