Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call field and accessor extra initializer after field/accessor definition on the instance #12

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -4657,14 +4657,9 @@ <h1>The DecoratorDefinition Record Specification Type</h1>
are defined by
<emu-xref href="#table-decoratordefinition-fields"></emu-xref>. Such
values are referred to as
<dfn variants="DecoratorDefinition Record"
>DecoratorDefinition Records</dfn
>.
<dfn variants="DecoratorDefinition Record">DecoratorDefinition Records</dfn>.
</p>
<emu-table
id="table-decoratordefinition-fields"
caption="DecoratorDefinition Record Fields"
>
<emu-table id="table-decoratordefinition-fields" caption="DecoratorDefinition Record Fields">
<table>
<tr>
<th>Field Name</th>
Expand Down Expand Up @@ -4819,6 +4814,20 @@ <h1>The ClassElementDefinition Record Specification Type</h1>
The initializers of the field or accessor, if any.
</td>
</tr>
<tr>
<td>
[[ExtraInitializers]]
</td>
<td>
~field~ and ~accessor~
</td>
<td>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR doesn't seem to include the algorithm steps that add entries to this list, so it will always be empty.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[[ExtraInitializers]] are passed into ApplyDecoratorsToElementDefinition, which then creates a context object which adds the initializers there. The logic there is a bit funky, I think I can clean it up at some point so that decorators always use [[ExtraInitializers]] and we don't have the
_staticMethodExtraInitializers_ and _instanceMethodExtraInitializers_, those were from a bit of an earlier draft before there was much distinction between extra initializers

a List of function objects
</td>
<td>
The extra initializers of the field or accessor, if any.
</td>
</tr>
</table>
</emu-table>
</emu-clause>
Expand Down Expand Up @@ -6880,6 +6889,8 @@ <h1>
1. Else,
1. Assert: IsPropertyKey(_fieldName_) is *true*.
1. Perform ? CreateDataPropertyOrThrow(_receiver_, _fieldName_, _initValue_).
1. For each element _initializer_ of _elementRecord_.[[ExtraInitializers]], do
1. Perform ? Call(_initializer_, _receiver_).
1. Return ~unused~.
</emu-alg>
</emu-clause>
Expand All @@ -6889,7 +6900,7 @@ <h1>
InitializeInstanceElements (
_O_: an Object,
_constructor_: an ECMAScript function object,
): either a normal completion containing ~unused~ or a throw completion
): either a normal completion containing ~unused~ or an abrupt completion
</h1>
<dl class="header">
</dl>
Expand Down Expand Up @@ -25031,10 +25042,11 @@ <h1>
<emu-alg>
1. Let _name_ be ? Evaluation of |ClassElementName|.
1. Let _initializers_ be a new empty List.
1. Let _extraInitializers_ be a new empty List.
1. If |Initializer?| is present, then
1. Let _initializer_ be CreateFieldInitializerFunction(_homeObject_, _name_, |Initializer|).
1. Append _initializer_ to _initializers_.
1. Return ClassElementDefinition Record { [[Key]]: _name_, [[Kind]]: ~field~, [[Initializers]]: _initializers_, [[Decorators]]: ~empty~ }.
1. Return ClassElementDefinition Record { [[Key]]: _name_, [[Kind]]: ~field~, [[Initializers]]: _initializers_, [[ExtraInitializers]]: _extraInitializers_, [[Decorators]]: ~empty~ }.
</emu-alg>
<emu-grammar>
FieldDefinition : `accessor` ClassElementName Initializer?
Expand All @@ -25047,13 +25059,14 @@ <h1>
1. Let _getter_ be MakeAutoAccessorGetter(_homeObject_, _name_, _privateStateName_).
1. Let _setter_ be MakeAutoAccessorSetter(_homeObject_, _name_, _privateStateName_).
1. Let _initializers_ be a new empty List.
1. Let _extraInitializers_ be a new empty List.
1. If |Initializer?| is present, then
1. Let _initializer_ be CreateFieldInitializerFunction(_homeObject_, _name_, |Initializer|).
1. Append _initializer_ to _initializers_.
1. If _name_ is not a Private Name, then
1. Let _desc_ be the PropertyDescriptor { [[Get]]: _getter_, [[Set]]: _setter_, [[Enumerable]]: *true*, [[Configurable]]: *true* }.
1. Perform ? DefinePropertyOrThrow(_homeObject_, _name_, _desc_).
1. Return ClassElementDefinition Record { [[Key]]: _name_, [[Kind]]: ~accessor~, [[Get]]: _getter_, [[Set]]: _setter_, [[BackingStorageKey]]: _privateStateName_, [[Initializers]]: _initializers_, [[Decorators]]: ~empty~ }.
1. Return ClassElementDefinition Record { [[Key]]: _name_, [[Kind]]: ~accessor~, [[Get]]: _getter_, [[Set]]: _setter_, [[BackingStorageKey]]: _privateStateName_, [[Initializers]]: _initializers_, [[ExtraInitializers]]: _extraInitializers_, [[Decorators]]: ~empty~ }.
</emu-alg>
<emu-note>
The function created for _initializer_ is never directly accessible to ECMAScript code.
Expand Down Expand Up @@ -25238,34 +25251,36 @@ <h1>
1. Assert: _element_ is a ClassStaticBlockDefinition Record.
1. Append _element_ to _staticElements_.
1. Set the running execution context's LexicalEnvironment to _env_.
1. Let _instanceExtraInitializers_ be a new empty List.
1. Let _staticExtraInitializers_ be a new empty List.
1. Let _instanceMethodExtraInitializers_ be a new empty List.
1. Let _staticMethodExtraInitializers_ be a new empty List.
1. For each element _e_ of _staticElements_, do
1. If _e_ is a ClassElementDefinition Record and _e_.[[Kind]] is not ~field~, then
1. Let _result_ be Completion(ApplyDecoratorsAndDefineMethod(_F_, _e_, _staticExtraInitializers_, *true*)).
1. If _e_.[[Kind]] is ~accessor~, let _extraInitializers_ be _e_.[[ExtraInitializers]]; otherwise, let _extraInitializers_ be _staticMethodExtraInitializers_.
1. Let _result_ be Completion(ApplyDecoratorsAndDefineMethod(_F_, _e_, _extraInitializers_, *true*)).
1. If _result_ is an abrupt completion, then
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
1. Return ? _result_.
1. For each element _e_ of _instanceElements_, do
Copy link

@JLHwung JLHwung Jan 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If _e._[[Kind]] is ~accessor~, we should pass in _e_.[[ExtraInitializers]] instead of _staticMethodExtraInitializers_.

Ditto for the _instanceMethodExtraInitializers_ in the next instance elements scan.

1. If _e_.[[Kind]] is not ~field~, then
1. Let _result_ be Completion(ApplyDecoratorsAndDefineMethod(_proto_, _e_, _instanceExtraInitializers_, *true*)).
1. If _e_.[[Kind]] is ~accessor~, let _extraInitializers_ be _e_.[[ExtraInitializers]]; otherwise, let _extraInitializers_ be _instanceMethodExtraInitializers_.
1. Let _result_ be Completion(ApplyDecoratorsAndDefineMethod(_proto_, _e_, _extraInitializers_, *false*)).
1. If _result_ is an abrupt completion, then
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
1. Return ? _result_.
1. For each element _e_ of _staticElements_, do
1. If _e_.[[Kind]] is ~field~, then
1. Let _result_ be Completion(ApplyDecoratorsToElementDefinition(_F_, _e_, _staticExtraInitializers_, *true*)).
1. Let _result_ be Completion(ApplyDecoratorsToElementDefinition(_F_, _e_, _e_.[[ExtraInitializers]], *true*)).
1. If _result_ is an abrupt completion, then
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
1. Return ? _result_.
1. For each element _e_ of _instanceElements_, do
1. If _e_.[[Kind]] is ~field~, then
1. Let _result_ be Completion(ApplyDecoratorsToElementDefinition(_proto_, _e_, _instanceExtraInitializers_, *false*)).
1. Let _result_ be Completion(ApplyDecoratorsToElementDefinition(_proto_, _e_, _e_.[[ExtraInitializers]], *false*)).
1. If _result_ is an abrupt completion, then
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
1. Return ? _result_.
1. Set _F_.[[Elements]] to _instanceElements_.
1. Set _F_.[[Initializers]] to _instanceExtraInitializers_.
1. Set _F_.[[Initializers]] to _instanceMethodExtraInitializers_.
1. Perform ? InitializePrivateMethods(_F_, _staticElements_).
1. Let _classExtraInitializers_ be a new empty List.
1. Let _newF_ be Completion(ApplyDecoratorsToClassDefinition(_F_, _decorators_, _className_, _classExtraInitializers_)).
Expand All @@ -25275,7 +25290,7 @@ <h1>
1. Set _F_ to _newF_.[[Value]].
1. If _classBinding_ is not *undefined*, then
1. Perform _classEnv_.InitializeBinding(_classBinding_, _F_).
1. For each element _initializer_ of _staticExtraInitializers_, do
1. For each element _initializer_ of _staticMethodExtraInitializers_, do
1. Let _result_ be Completion(Call(_initializer_, _F_)).
1. If _result_ is an abrupt completion, then
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
Expand Down
Loading