diff --git a/spec.html b/spec.html index 1acba1d27d..6923bcf635 100644 --- a/spec.html +++ b/spec.html @@ -4612,7 +4612,7 @@

The PrivateElement Specification Type

[[Key]] - All + ~field~, ~method~, or ~accessor~ a Private Name @@ -4626,7 +4626,7 @@

The PrivateElement Specification Type

[[Kind]] - All + ~field~, ~method~, or ~accessor~ ~field~, ~method~, or ~accessor~ @@ -4681,16 +4681,55 @@

The PrivateElement Specification Type

- -

The ClassFieldDefinition Record Specification Type

-

The ClassFieldDefinition type is a Record used in the specification of class fields.

-

Values of the ClassFieldDefinition type are Record values whose fields are defined by . Such values are referred to as ClassFieldDefinition Records.

- + +

The DecoratorDefinition Record Specification Type

+

+ The DecoratorDefinition type is a Record used in the specification of + decorators. +

+

+ Values of the DecoratorDefinition type are Record values whose fields + are defined by + . Such + values are referred to as + DecoratorDefinition Records. +

+ + + + + + + + + + + + + + + + + +
Field NameValueMeaning
[[Decorator]]a function object.The decorator function.
[[Receiver]]a Reference Record or an ECMAScript language value + The receiver that the decorator function should be called with. +
+
+
+ + +

The ClassElementDefinition Record Specification Type

+

The ClassElementDefinition type is a Record used in the specification of private and public, static and non-static class fields, methods, and accessors.

+

Values of the ClassElementDefinition type are Record values whose fields are defined by . Such values are referred to as ClassElementDefinition Records.

+ + @@ -4700,7 +4739,10 @@

The ClassFieldDefinition Record Specification Type

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Name + Values of the [[Kind]] field for which it is present + Value
- [[Name]] + [[Key]] + + ~field~, ~method~, ~accessor~, ~getter~, ~setter~ a Private Name, a String, or a Symbol @@ -4711,13 +4753,114 @@

The ClassFieldDefinition Record Specification Type

- [[Initializer]] + [[Kind]] + + ~field~, ~method~, ~accessor~, ~getter~, or ~setter~ + + ~field~, ~method~, ~accessor~, ~getter~, or ~setter~ + + The kind of the element. +
+ [[Value]] + + ~method~ + + an ECMAScript function object + + The function for a method definition. +
+ [[Get]] + + ~accessor~ and ~getter~ + + an ECMAScript function object + + The getter for an accessor definition. +
+ [[Set]] + + ~accessor~ and ~setter~ + + an ECMAScript function object + + The setter for an accessor definition. +
+ [[BackingStorageKey]] + + ~accessor~ + + a Private Name + + A private name for the backing state behind accessors defined with the `accessor` keyword +
+ [[Decorators]] + + ~field~, ~method~, ~accessor~, ~getter~, ~setter~ + + a List of DecoratorDefinition Records or ~empty~ + + The decorators applied to the class element, if any. +
+ [[Initializers]] + + ~field~ and ~accessor~ - an ECMAScript function object or ~empty~ + a List of function objects - The initializer of the field, if any. + The initializers of the field or accessor, if any. +
+ [[ExtraInitializers]] + + ~field~ and ~accessor~ + + a List of function objects + + The extra initializers of the field or accessor, if any.
@@ -6726,27 +6869,61 @@

- +

- DefineField ( + InitializePrivateMethods ( + _O_: an Object, + _elementDefinitions_: a List of ClassElementDefinition Records, + ): either a normal completion containing ~unused~ or an abrupt completion +

+
+
+ + 1. Let _privateMethods_ be a new empty List. + 1. For each element _element_ of _elementDefinitions_, do + 1. If _element_.[[Key]] is a Private Name and _element_.[[Kind]] is ~method~, ~getter~, ~setter~, or ~accessor~, then + 1. If _privateMethods_ contains a PrivateElement _existing_ such that _existing.[[Key]] is _element_.[[Key]], then + 1. Assert: _element_.[[Kind]] is ~getter~ or ~setter~. + 1. Assert: _existing_.[[Kind]] is ~accessor~. + 1. If _element_.[[Get]] is *undefined*, then + 1. Let _combined_ be PrivateElement { [[Key]]: _existing_.[[Key]], [[Kind]]: ~accessor~, [[Get]]: _existing_.[[Get]], [[Set]]: _element_.[[Set]] }. + 1. Else, + 1. Let _combined_ be PrivateElement { [[Key]]: _existing_.[[Key]], [[Kind]]: ~accessor~, [[Get]]: _element_.[[Get]], [[Set]]: _existing_.[[Set]] }. + 1. Replace _existing_ in _privateMethods_ with _combined_. + 1. Else, + 1. If _element_.[[Kind]] is ~getter~ or ~setter~, let _kind_ be ~accessor~. + 1. Else, let _kind_ be _element_.[[Kind]]. + 1. Let _privateElement_ be PrivateElement { [[Key]]: _element_.[[Key]], [[Kind]]: _kind_, [[Value]]: _element_.[[Value]], [[Get]]: _element_.[[Get]], [[Set]]: _element_.[[Set]] }. + 1. Append _privateElement_ to _privateMethods_. + 1. For each element _method_ of _privateMethods_, do + 1. Perform ? PrivateMethodOrAccessorAdd(_O_, _method_). + 1. Return ~unused~. + +
+ + +

+ InitializeFieldOrAccessor ( _receiver_: an Object, - _fieldRecord_: a ClassFieldDefinition Record, - ): either a normal completion containing ~unused~ or a throw completion + _elementRecord_: a ClassElementDefinition Record, + ): either a normal completion containing ~unused~ or an abrupt completion

- 1. Let _fieldName_ be _fieldRecord_.[[Name]]. - 1. Let _initializer_ be _fieldRecord_.[[Initializer]]. - 1. If _initializer_ is not ~empty~, then - 1. Let _initValue_ be ? Call(_initializer_, _receiver_). - 1. Else, - 1. Let _initValue_ be *undefined*. + 1. Assert: _elementRecord_.[[Kind]] is ~field~ or ~accessor~. + 1. If _elementRecord_.[[BackingStorageKey]] is present, let _fieldName_ be _elementRecord_.[[BackingStorageKey]]. + 1. Else, let _fieldName_ be _elementRecord_.[[Key]]. + 1. Let _initValue_ be *undefined*. + 1. For each element _initializer_ of _elementRecord_.[[Initializers]], do + 1. Set _initValue_ to ? Call(_initializer_, _receiver_, « _initValue_ »). 1. If _fieldName_ is a Private Name, then 1. Perform ? PrivateFieldAdd(_receiver_, _fieldName_, _initValue_). 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~.
@@ -6756,17 +6933,18 @@

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

- 1. Let _methods_ be the value of _constructor_.[[PrivateMethods]]. - 1. For each PrivateElement _method_ of _methods_, do - 1. Perform ? PrivateMethodOrAccessorAdd(_O_, _method_). - 1. Let _fields_ be the value of _constructor_.[[Fields]]. - 1. For each element _fieldRecord_ of _fields_, do - 1. Perform ? DefineField(_O_, _fieldRecord_). + 1. Let _elements_ be the value of _constructor_.[[Elements]]. + 1. Perform ? InitializePrivateMethods(_O_, _elements_). + 1. For each element _initializer_ of _constructor_.[[Initializers]], do + 1. Perform ? Call(_O_, _initializer_). + 1. For each element _e_ of _elements_, do + 1. If _e_.[[Kind]] is ~field~ or ~accessor~, then + 1. Perform ? InitializeFieldOrAccessor(_O_, _e_). 1. Return ~unused~.
@@ -7328,11 +7506,11 @@

Static Semantics: BoundNames ( ): a List of Strings

1. Return « *"\*default\*"* ». - ClassDeclaration : `class` BindingIdentifier ClassTail + ClassDeclaration : DecoratorList? `class` BindingIdentifier ClassTail 1. Return the BoundNames of |BindingIdentifier|. - ClassDeclaration : `class` ClassTail + ClassDeclaration : DecoratorList? `class` ClassTail 1. Return « *"\*default\*"* ». @@ -7491,8 +7669,8 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

ClassDeclaration : - `class` BindingIdentifier ClassTail - `class` ClassTail + DecoratorList? `class` BindingIdentifier ClassTail + DecoratorList? `class` ClassTail 1. Return *false*. @@ -8909,7 +9087,7 @@

Static Semantics: HasName ( ): a Boolean

CoverCallExpressionAndAsyncArrowHead `=>` AsyncConciseBody ClassExpression : - `class` ClassTail + DecoratorList? `class` ClassTail 1. Return *false*. @@ -8928,7 +9106,7 @@

Static Semantics: HasName ( ): a Boolean

`async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}` ClassExpression : - `class` BindingIdentifier ClassTail + DecoratorList? `class` BindingIdentifier ClassTail 1. Return *true*. @@ -9069,7 +9247,7 @@

Static Semantics: IsFunctionDefinition ( ): a Boolean

`async` `function` BindingIdentifier? `(` FormalParameters `)` `{` AsyncFunctionBody `}` ClassExpression : - `class` BindingIdentifier? ClassTail + DecoratorList? `class` BindingIdentifier? ClassTail 1. Return *true*. @@ -9188,9 +9366,12 @@

1. Return InstantiateAsyncArrowFunctionExpression of |AsyncArrowFunction| with argument _name_. - ClassExpression : `class` ClassTail + ClassExpression : DecoratorList? `class` ClassTail - 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined* and _name_. + 1. If |DecoratorList?| is present, then + 1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined*, _name_, and _decorators_. 1. Set _value_.[[SourceText]] to the source text matched by |ClassExpression|. 1. Return _value_. @@ -9379,6 +9560,22 @@

1. If _inList_ is *true*, return *true*. 1. Return the result of ComputedPropertyContains of |ClassElement| with argument _symbol_. + + ClassElement : + DecoratorList? MethodDefinition + DecoratorList? `static` MethodDefinition + + + 1. Return ComputedPropertyContains of |MethodDefinition| with argument _symbol_. + + + ClassElement : + DecoratorList? FieldDefinition `;` + DecoratorList? `static` FieldDefinition `;` + + + 1. Return ComputedPropertyContains of |FieldDefinition| with argument _symbol_. + ClassElement : ClassStaticBlock 1. Return *false*. @@ -9886,6 +10083,22 @@

Static Semantics: PropName ( ): a String or ~empty~

1. Return PropName of |ClassElementName|. + + ClassElement : + DecoratorList? MethodDefinition + DecoratorList? `static` MethodDefinition + + + 1. Return PropName of |MethodDefinition|. + + + ClassElement : + DecoratorList? FieldDefinition `;` + DecoratorList? `static` FieldDefinition `;` + + + 1. Return PropName of |FieldDefinition|. + ClassElement : ClassStaticBlock 1. Return ~empty~. @@ -13184,24 +13397,24 @@

ECMAScript Function Objects

- [[Fields]] + [[Elements]] - a List of ClassFieldDefinition Records + a List of ClassElementDefinition Records - If the function is a class, this is a list of Records representing the non-static fields and corresponding initializers of the class. + If the function is a class, this is a list of Records representing the non-static elements and corresponding initializers of the class. - [[PrivateMethods]] + [[Initializers]] - a List of PrivateElements + a List of function objects - If the function is a class, this is a list representing the non-static private methods and accessors of the class. + If the function is a class with decorated prototype methods or accessors, this is a list of initializer functions added by the decorators, or ~empty~. @@ -13473,8 +13686,7 @@

1. Set _F_.[[ScriptOrModule]] to GetActiveScriptOrModule(). 1. Set _F_.[[Realm]] to the current Realm Record. 1. Set _F_.[[HomeObject]] to *undefined*. - 1. Set _F_.[[Fields]] to a new empty List. - 1. Set _F_.[[PrivateMethods]] to a new empty List. + 1. Set _F_.[[Elements]] to a new empty List. 1. Set _F_.[[ClassFieldInitializerName]] to ~empty~. 1. Let _len_ be the ExpectedArgumentCount of _ParameterList_. 1. Perform SetFunctionLength(_F_, _len_). @@ -13578,21 +13790,23 @@

DefineMethodProperty ( _homeObject_: an Object, - _key_: a property key or Private Name, - _closure_: a function object, + _methodDefinition_: a ClassElementDefinition Record, _enumerable_: a Boolean, - ): a PrivateElement or ~unused~ + ): either a normal completion containing ~unused~, or an abrupt completion

1. Assert: _homeObject_ is an ordinary, extensible object with no non-configurable properties. - 1. If _key_ is a Private Name, then - 1. Return PrivateElement { [[Key]]: _key_, [[Kind]]: ~method~, [[Value]]: _closure_ }. - 1. Else, - 1. Let _desc_ be the PropertyDescriptor { [[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. - 1. Perform ! DefinePropertyOrThrow(_homeObject_, _key_, _desc_). - 1. Return ~unused~. + 1. Assert: _methodDefinition_.[[Kind]] is ~method~, ~getter~, ~setter~, or ~accessor~. + 1. Let _key_ be _methodDefinition_.[[Key]]. + 1. If _key_ is not a Private Name, then + 1. Let _desc_ be the PropertyDescriptor { [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. + 1. If _methodDefinition_.[[Kind]] is ~getter~ or ~accessor~, set _desc_.[[Get]] to _methodDefinition_.[[Get]]. + 1. If _methodDefinition_.[[Kind]] is ~setter~ or ~accessor~, set _desc_.[[Set]] to _methodDefinition_.[[Set]]. + 1. If _methodDefinition_.[[Kind]] is ~method~, set _desc_.[[Value]] to _methodDefinition_.[[Value]]. + 1. Perform ? DefinePropertyOrThrow(_homeObject_, _key_, _desc_). + 1. Return ~unused~. @@ -18618,7 +18832,8 @@

PropertyDefinition : MethodDefinition - 1. Perform ? MethodDefinitionEvaluation of |MethodDefinition| with arguments _object_ and *true*. + 1. Let _methodDefinition_ be ? MethodDefinitionEvaluation of |MethodDefinition| with argument _object_. + 1. Perform ? DefineMethodProperty(_object_, _methodDefinition_, *true*). 1. Return ~unused~. @@ -23805,8 +24020,7 @@

Runtime Semantics: MethodDefinitionEvaluation ( _object_: an Object, - _enumerable_: a Boolean, - ): either a normal completion containing either a PrivateElement or ~unused~, or an abrupt completion + ): either a normal completion containing a ClassElementDefinition Record, or an abrupt completion

@@ -23814,7 +24028,7 @@

1. Let _methodDef_ be ? DefineMethod of |MethodDefinition| with argument _object_. 1. Perform SetFunctionName(_methodDef_.[[Closure]], _methodDef_.[[Key]]). - 1. Return DefineMethodProperty(_object_, _methodDef_.[[Key]], _methodDef_.[[Closure]], _enumerable_). + 1. Return ClassElementDefinition Record { [[Key]]: _methodDef_.[[Key]], [[Kind]]: ~method~, [[Value]]: _methodDef_.[[Closure]], [[Decorators]]: ~empty~ }. MethodDefinition : `get` ClassElementName `(` `)` `{` FunctionBody `}` @@ -23826,12 +24040,7 @@

1. Let _closure_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, _formalParameterList_, |FunctionBody|, ~non-lexical-this~, _env_, _privateEnv_). 1. Perform MakeMethod(_closure_, _object_). 1. Perform SetFunctionName(_closure_, _propKey_, *"get"*). - 1. If _propKey_ is a Private Name, then - 1. Return PrivateElement { [[Key]]: _propKey_, [[Kind]]: ~accessor~, [[Get]]: _closure_, [[Set]]: *undefined* }. - 1. Else, - 1. Let _desc_ be the PropertyDescriptor { [[Get]]: _closure_, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. - 1. Perform ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). - 1. Return ~unused~. + 1. Return ClassElementDefinition Record { [[Key]]: _propKey_, [[Kind]]: ~getter~, [[Get]]: _closure_, [[Decorators]]: ~empty~ }. MethodDefinition : `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}` @@ -23842,12 +24051,7 @@

1. Let _closure_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, |PropertySetParameterList|, |FunctionBody|, ~non-lexical-this~, _env_, _privateEnv_). 1. Perform MakeMethod(_closure_, _object_). 1. Perform SetFunctionName(_closure_, _propKey_, *"set"*). - 1. If _propKey_ is a Private Name, then - 1. Return PrivateElement { [[Key]]: _propKey_, [[Kind]]: ~accessor~, [[Get]]: *undefined*, [[Set]]: _closure_ }. - 1. Else, - 1. Let _desc_ be the PropertyDescriptor { [[Set]]: _closure_, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. - 1. Perform ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). - 1. Return ~unused~. + 1. Return ClassElementDefinition Record { [[Key]]: _propKey_, [[Kind]]: ~setter~, [[Set]]: _closure_, [[Decorators]]: ~empty~ }. GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` @@ -23860,7 +24064,7 @@

1. Perform SetFunctionName(_closure_, _propKey_). 1. Let _prototype_ be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%). 1. Perform ! DefinePropertyOrThrow(_closure_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). - 1. Return DefineMethodProperty(_object_, _propKey_, _closure_, _enumerable_). + 1. Return ClassElementDefinition Record { [[Key]]: _propKey_, [[Kind]]: ~method~, [[Value]]: _closure_, [[Decorators]]: ~empty~ }. AsyncGeneratorMethod : `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` @@ -23875,7 +24079,7 @@

1. Perform SetFunctionName(_closure_, _propKey_). 1. Let _prototype_ be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%). 1. Perform ! DefinePropertyOrThrow(_closure_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). - 1. Return DefineMethodProperty(_object_, _propKey_, _closure_, _enumerable_). + 1. Return ClassElementDefinition Record { [[Key]]: _propKey_, [[Kind]]: ~method~, [[Value]]: _closure_, [[Decorators]]: ~empty~ }. AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` @@ -23888,7 +24092,7 @@

1. Let _closure_ be OrdinaryFunctionCreate(%AsyncFunction.prototype%, _sourceText_, |UniqueFormalParameters|, |AsyncFunctionBody|, ~non-lexical-this~, _env_, _privateEnv_). 1. Perform MakeMethod(_closure_, _object_). 1. Perform SetFunctionName(_closure_, _propKey_). - 1. Return DefineMethodProperty(_object_, _propKey_, _closure_, _enumerable_). + 1. Return ClassElementDefinition Record { [[Key]]: _propKey_, [[Kind]]: ~method~, [[Value]]: _closure_, [[Decorators]]: ~empty~ }. @@ -24320,16 +24524,277 @@

Runtime Semantics: Evaluation

+ +

Decorators

+

Syntax

+ + DecoratorList[Yield, Await] : + DecoratorList[?Yield, ?Await]? Decorator[?Yield, ?Await] + + Decorator[Yield, Await] : + `@` DecoratorMemberExpression[?Yield, ?Await] + `@` DecoratorParenthesizedExpression[?Yield, ?Await] + `@` DecoratorCallExpression[?Yield, ?Await] + + DecoratorMemberExpression[Yield, Await] : + IdentifierReference[?Yield, ?Await] + DecoratorMemberExpression[?Yield, ?Await] `.` IdentifierName + DecoratorMemberExpression[?Yield, ?Await] `.` PrivateIdentifier + + DecoratorParenthesizedExpression[Yield, Await] : + `(` Expression[+In, ?Yield, ?Await] `)` + + DecoratorCallExpression[Yield, Await] : + DecoratorMemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] + + + +

Runtime Semantics: DecoratorEvaluation ( ): either a normal completion containing a DecoratorDefinition Record or an abrupt completion

+
+
+ Decorator : `@` DecoratorMemberExpression + + 1. Let _expr_ be the |MemberExpression| that is covered by |DecoratorMemberExpression|. + 1. Let _ref_ be ? Evaluation of _expr_. + 1. Let _value_ be ? GetValue(_ref_). + 1. Return DecoratorDefinition Record { [[Decorator]]: _value_, [[Receiver]]: _ref_ }. + + Decorator : `@` DecoratorCallExpression + + 1. Let _expr_ be the |CallMemberExpression| that is covered by |DecoratorCallExpression|. + 1. Let _ref_ be ? Evaluation of _expr_. + 1. Let _value_ be ? GetValue(_ref_). + 1. Return DecoratorDefinition Record { [[Decorator]]: _value_, [[Receiver]]: _ref_ }. + + Decorator : `@` DecoratorParenthesizedExpression + + 1. Let _expr_ be the |MemberExpression| that is covered by |DecoratorParenthesizedExpression|. + 1. Let _ref_ be ? Evaluation of _expr_. + 1. Let _value_ be ? GetValue(_ref_). + 1. Return DecoratorDefinition Record { [[Decorator]]: _value_, [[Receiver]]: _ref_ }. + +
+ + +

Runtime Semantics: DecoratorListEvaluation ( ): either a normal completion containing a List of DecoratorDefinition Records or an abrupt completion

+
+
+ DecoratorList : DecoratorList? Decorator + + 1. If |DecoratorList| is present, then + 1. Let _leftValue_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, + 1. Let _leftValue_ be a new empty List. + 1. Let _rightValue_ be ? DecoratorEvaluation of |Decorator|. + 1. Prepend _rightValue_ to _leftValue_. + 1. Return _leftValue_. + +
+ + +

+ CreateDecoratorAccessObject ( + _kind_: ~field~, ~method~, ~accessor~, ~getter~, or ~setter~, + _name_: either a String, a Symbol, or a Private Name, + ): an Object +

+
+
description
+
Returns an object with appropriate accessor functions for the value, for use in a decorator context object.
+
+ + 1. Let _accessObj_ be OrdinaryObjectCreate(%Object.prototype%). + 1. If _kind_ is ~field~, ~method~, ~accessor~, or ~getter~, then + 1. Let _getterClosure_ be a new Abstract Closure with parameters (_obj_) that captures _name_ and performs the following steps when called: + 1. If _obj_ is not an Object, throw a *TypeError* exception. + 1. If _name_ is either a String or a Symbol, return ? Get(_obj_, _name_). + 1. Else, return ? PrivateGet(_name_, _obj_). + 1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 1, *""*, « »). + 1. Perform ! CreateDataPropertyOrThrow(_accessObj_, *"get"*, _getter_). + 1. If _kind_ is ~field~, ~accessor~, or ~setter~, then + 1. Let _setterClosure_ be a new Abstract Closure with parameters (_obj_, _value_) that captures _name_ and performs the following steps when called: + 1. If _obj_ is not an Object, throw a *TypeError* exception. + 1. If _name_ is either a String or a Symbol, perform ? Set(_obj_, _name_, _value_, *true*). + 1. Else, perform ? PrivateSet(_name_, _obj_, _value_). + 1. Return *undefined*. + 1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 2, *""*, « »). + 1. Perform ! CreateDataPropertyOrThrow(_accessObj_, *"set"*, _setter_). + 1. Let _hasClosure_ be a new Abstract Closure with parameters (_obj_) that captures _name_ and performs the following steps when called: + 1. If _obj_ is not an Object, throw a *TypeError* exception. + 1. If _name_ is either a String or a Symbol, return ? HasProperty(_obj_, _name_). + 1. If PrivateElementFind(_obj_, _name_) is not ~empty~, return *true*. + 1. Return *false*. + 1. Let _has_ be CreateBuiltinFunction(_hasClosure_, 1, *""*, « »). + 1. Perform ! CreateDataPropertyOrThrow(_accessObj_, *"has"*, _has_). + 1. Return _accessObj_. + +
+ + +

+ CreateAddInitializerFunction ( + _initializers_: a List of ECMAScript function objects, + _decorationState_: a Record with a field [[Finished]] (a Boolean), + ): a function object +

+
+
description
+
Creates a function for a decorator's context object which can be used to add an extra initializer to the class.
+
+ + 1. Let _addInitializerClosure_ be a new Abstract Closure with parameters (_initializer_) that captures _initializers_ and _decorationState_ and performs the following steps when called: + 1. If _decorationState_.[[Finished]] is *true*, throw a *TypeError* exception. + 1. If IsCallable(_initializer_) is *false*, throw a *TypeError* exception. + 1. Append _initializer_ to _initializers_. + 1. Return *undefined*. + 1. Return CreateBuiltinFunction(_addInitializerClosure_, 1, *"addInitializer"*, « »). + +
+ + +

+ CreateDecoratorContextObject ( + _kind_: ~class~, ~field~, ~method~, ~accessor~, ~getter~, or ~setter~, + _name_: a String, a Symbol, or a Private Name, + _initializers_: a List of function objects, + _decorationState_: a Record with a field [[Finished]] (a Boolean), + optional _isStatic_: a Boolean, + ): an Object +

+
+
description
+
It returns a context object which is passed as the second argument to decorators of the given class element.
+
+ + 1. Let _contextObj_ be OrdinaryObjectCreate(%Object.prototype%). + 1. If _kind_ is ~method~, let _kindStr_ be *"method"*. + 1. Else if _kind_ is ~getter~, let _kindStr_ be *"getter"*. + 1. Else if _kind_ is ~setter~, let _kindStr_ be *"setter"*. + 1. Else if _kind_ is ~accessor~, let _kindStr_ be *"accessor"*. + 1. Else if _kind_ is ~field~, let _kindStr_ be *"field"*. + 1. Else, + 1. Assert: _kind_ is ~class~. + 1. Let _kindStr_ be *"class"*. + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"kind"*, _kindStr_). + 1. If _kind_ is not ~class~, then + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"access"*, CreateDecoratorAccessObject(_kind_, _name_)). + 1. If _isStatic_ is present, perform ! CreateDataPropertyOrThrow(_contextObj_, *"static"*, _isStatic_). + 1. If _name_ is a Private Name, then + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"private"*, *true*). + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"name"*, _name_.[[Description]]). + 1. Else, + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"private"*, *false*). + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"name"*, _name_). + 1. Else, + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"name"*, _name_). + 1. Let _addInitializer_ be CreateAddInitializerFunction(_initializers_, _decorationState_). + 1. Perform ! CreateDataPropertyOrThrow(_contextObj_, *"addInitializer"*, _addInitializer_). + 1. Return _contextObj_. + +
+ + +

+ ApplyDecoratorsToElementDefinition ( + _homeObject_: an Object, + _elementRecord_: a ClassElementDefinition Record, + _extraInitializers_: a List of function objects, + _isStatic_: a Boolean, + ): either a normal completion containing ~unused~, or an abrupt completion +

+
+
description
+
Applies the decorators stored on an ClassElementDefinition to the value of the definition.
+
+ + 1. Let _decorators_ be _elementRecord_.[[Decorators]]. + 1. If _decorators_ is ~empty~, return ~unused~. + 1. Let _key_ be _elementRecord_.[[Key]]. + 1. Let _kind_ be _elementRecord_.[[Kind]]. + 1. For each element _decoratorRecord_ of _decorators_, do + 1. Let _decorator_ be _decoratorRecord_.[[Decorator]]. + 1. Let _decoratorReceiver_ be _decoratorRecord_.[[Receiver]]. + 1. Let _decorationState_ be the Record { [[Finished]]: *false* }. + 1. Let _context_ be CreateDecoratorContextObject(_kind_, _key_, _extraInitializers_, _decorationState_, _isStatic_). + 1. Let _value_ be *undefined*. + 1. If _kind_ is ~method~, set _value_ to _elementRecord_.[[Value]]. + 1. Else if _kind_ is ~getter~, set _value_ to _elementRecord_.[[Get]]. + 1. Else if _kind_ is ~setter~, set _value_ to _elementRecord_.[[Set]]. + 1. Else if _kind_ is ~accessor~, then + 1. Set _value_ to OrdinaryObjectCreate(%Object.prototype%). + 1. Perform ! CreateDataPropertyOrThrow(_value_, *"get"*, _elementRecord_.[[Get]]). + 1. Perform ! CreateDataPropertyOrThrow(_value_, *"set"*, _elementRecord_.[[Set]]). + 1. Let _newValue_ be ? Call(_decorator_, _decoratorReceiver_, « _value_, _context_ »). + 1. Set _decorationState_.[[Finished]] to *true*. + 1. If _kind_ is ~field~, then + 1. If IsCallable(_newValue_) is *true*, prepend _newValue_ to _elementRecord_.[[Initializers]]. + 1. Else if _newValue_ is not *undefined*, throw a *TypeError* exception. + 1. Else if _kind_ is ~accessor~, then + 1. If _newValue_ is an Object, then + 1. Let _newGetter_ be ? Get(_newValue_, *"get"*). + 1. If IsCallable(_newGetter_) is *true*, set _elementRecord_.[[Get]] to _newGetter_. + 1. Else if _newGetter_ is not *undefined*, throw a *TypeError* exception. + 1. Let _newSetter_ be ? Get(_newValue_, *"set"*). + 1. If IsCallable(_newSetter_) is *true*, set _elementRecord_.[[Set]] to _newSetter_. + 1. Else if _newSetter_ is not *undefined*, throw a *TypeError* exception. + 1. Let _initializer_ be ? Get(_newValue_, *"init"*). + 1. If IsCallable(_initializer_) is *true*, prepend _initializer_ to _elementRecord_.[[Initializers]]. + 1. Else if _initializer_ is not *undefined*, throw a *TypeError* exception. + 1. Else if _newValue_ is not *undefined*, throw a *TypeError* exception. + 1. Else, + 1. If IsCallable(_newValue_) is *true*, then + 1. If _kind_ is ~getter~, then + 1. Set _elementRecord_.[[Get]] to _newValue_. + 1. Else if _kind_ is ~setter~, then + 1. Set _elementRecord_.[[Set]] to _newValue_. + 1. Else, + 1. Set _elementRecord_.[[Value]] to _newValue_. + 1. Else if _newValue_ is not *undefined*, throw a *TypeError* exception. + 1. Set _elementRecord_.[[Decorators]] to ~empty~. + 1. Return ~unused~. + +
+ + +

+ ApplyDecoratorsToClassDefinition ( + _classDef_: a function object, + _decorators_: a List of DecoratorDefinition Records, + _className_: a property key or a Private Name, + _extraInitializers_: a List of function objects, + ): either a normal completion containing a function object, or an abrupt completion +

+
+
description
+
Applies the passed decorators to the passed class definition.
+
+ + 1. For each element _decoratorRecord_ of _decorators_, do + 1. Let _decorator_ be _decoratorRecord_.[[Decorator]]. + 1. Let _decoratorReceiver_ be _decoratorRecord_.[[Receiver]]. + 1. Let _decorationState_ be the Record { [[Finished]]: *false* }. + 1. Let _context_ be CreateDecoratorContextObject(~class~, _className_, _extraInitializers_, _decorationState_). + 1. Let _newDef_ be ? Call(_decorator_, _decoratorReceiver_, « _classDef_, _context_ »). + 1. Set _decorationState_.[[Finished]] to *true*. + 1. If IsCallable(_newDef_) is *true*, then + 1. Set _classDef_ to _newDef_. + 1. Else if _newDef_ is not *undefined*, then + 1. Throw a *TypeError* exception. + 1. Return _classDef_. + +
+
+

Class Definitions

Syntax

ClassDeclaration[Yield, Await, Default] : - `class` BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] - [+Default] `class` ClassTail[?Yield, ?Await] + DecoratorList[?Yield, ?Await]? `class` BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] + [+Default] DecoratorList[?Yield, ?Await]? `class` ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : - `class` BindingIdentifier[?Yield, ?Await]? ClassTail[?Yield, ?Await] + DecoratorList[?Yield, ?Await]? `class` BindingIdentifier[?Yield, ?Await]? ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]? `{` ClassBody[?Yield, ?Await]? `}` @@ -24345,15 +24810,16 @@

Syntax

ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : - MethodDefinition[?Yield, ?Await] - `static` MethodDefinition[?Yield, ?Await] - FieldDefinition[?Yield, ?Await] `;` - `static` FieldDefinition[?Yield, ?Await] `;` + DecoratorList[?Yield, ?Await]? MethodDefinition[?Yield, ?Await] + DecoratorList[?Yield, ?Await]? `static` MethodDefinition[?Yield, ?Await] + DecoratorList[?Yield, ?Await]? FieldDefinition[?Yield, ?Await] `;` + DecoratorList[?Yield, ?Await]? `static` FieldDefinition[?Yield, ?Await] `;` ClassStaticBlock `;` FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]? + `accessor` [no LineTerminator here] ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]? ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] @@ -24394,7 +24860,7 @@

Static Semantics: Early Errors

It is a Syntax Error if PrivateBoundIdentifiers of |ClassElementList| contains any duplicate entries, unless the name is used once for a getter and once for a setter and in no other entries, and the getter and setter are either both static or both non-static. - ClassElement : MethodDefinition + ClassElement : DecoratorList? MethodDefinition
  • It is a Syntax Error if PropName of |MethodDefinition| is not *"constructor"* and HasDirectSuper of |MethodDefinition| is *true*. @@ -24403,7 +24869,7 @@

    Static Semantics: Early Errors

    It is a Syntax Error if PropName of |MethodDefinition| is *"constructor"* and SpecialMethod of |MethodDefinition| is *true*.
- ClassElement : `static` MethodDefinition + ClassElement : DecoratorList? `static` MethodDefinition
  • It is a Syntax Error if HasDirectSuper of |MethodDefinition| is *true*. @@ -24413,12 +24879,12 @@

    Static Semantics: Early Errors

- ClassElement : FieldDefinition `;` + ClassElement : DecoratorList? FieldDefinition `;`
  • It is a Syntax Error if PropName of |FieldDefinition| is *"constructor"*.
- ClassElement : `static` FieldDefinition `;` + ClassElement : DecoratorList? `static` FieldDefinition `;`
  • It is a Syntax Error if PropName of |FieldDefinition| is either *"prototype"* or *"constructor"*. @@ -24428,6 +24894,7 @@

    Static Semantics: Early Errors

    FieldDefinition : ClassElementName Initializer? + `accessor` ClassElementName Initializer?
    • It is a Syntax Error if |Initializer| is present and ContainsArguments of |Initializer| is *true*.
    • @@ -24472,16 +24939,16 @@

      Static Semantics: Early Errors

      Static Semantics: ClassElementKind ( ): ~constructor-method~, ~non-constructor-method~, or ~empty~

      - ClassElement : MethodDefinition + ClassElement : DecoratorList? MethodDefinition 1. If PropName of |MethodDefinition| is *"constructor"*, return ~constructor-method~. 1. Return ~non-constructor-method~. ClassElement : - `static` MethodDefinition - FieldDefinition `;` - `static` FieldDefinition `;` + DecoratorList? `static` MethodDefinition + DecoratorList? FieldDefinition `;` + DecoratorList? `static` FieldDefinition `;` 1. Return ~non-constructor-method~. @@ -24521,19 +24988,19 @@

      Static Semantics: ConstructorMethod ( ): a |ClassElement| Parse Node or ~emp

      Static Semantics: IsStatic ( ): a Boolean

      - ClassElement : MethodDefinition + ClassElement : DecoratorList? MethodDefinition 1. Return *false*. - ClassElement : `static` MethodDefinition + ClassElement : DecoratorList? `static` MethodDefinition 1. Return *true*. - ClassElement : FieldDefinition `;` + ClassElement : DecoratorList? FieldDefinition `;` 1. Return *false*. - ClassElement : `static` FieldDefinition `;` + ClassElement : DecoratorList? `static` FieldDefinition `;` 1. Return *true*. @@ -24662,6 +25129,23 @@

      Static Semantics: PrivateBoundIdentifiers ( ): a List of Strings

      1. Return a List whose sole element is the StringValue of |PrivateIdentifier|.
      + + ClassElement : + DecoratorList? MethodDefinition + DecoratorList? `static` MethodDefinition + + + 1. Return PrivateBoundIdentifiers of |MethodDefinition|. + + + ClassElement : + DecoratorList? FieldDefinition `;` + DecoratorList? `static` FieldDefinition `;` + + + 1. Return PrivateBoundIdentifiers of |FieldDefinition|. + + ClassElementName : PropertyName @@ -24777,11 +25261,106 @@

      Static Semantics: ContainsArguments ( ): a Boolean

      + +

      Static Semantics: Method Decorators

      + + ClassElement : DecoratorList? MethodDefinition + +
        +
      • + It is a Syntax Error if |DecoratorList| is present and PropName of |MethodDefinition| is `"constructor"`. +
      • +
      +
      + + +

      + ApplyDecoratorsAndDefineMethod ( + _homeObject_: an Object, + _methodDefinition_: a ClassElementDefinition Record, + _extraInitializers_: a List of function objects, + _isStatic_: a Boolean, + ): either a normal completion containing ~unused~, or an abrupt completion +

      +
      +
      + + 1. Perform ? ApplyDecoratorsToElementDefinition(_homeObject_, _methodDefinition_, _extraInitializers_, _isStatic_). + 1. Perform ? DefineMethodProperty(_homeObject_, _methodDefinition_, _isStatic_). + 1. Return ~unused~. + +
      + + +

      + CreateFieldInitializerFunction ( + _homeObject_: an Object, + _propName_: a property key or Private Name, + _Initializer_: a Parse Node, + ): a function object +

      +
      +
      + + 1. Let _formalParameterList_ be an instance of the production FormalParameters : [empty]. + 1. Let _scope_ be the LexicalEnvironment of the running execution context. + 1. Let _privateScope_ be the running execution context's PrivateEnvironment. + 1. Let _sourceText_ be the empty sequence of Unicode code points. + 1. Let _initializer_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, _formalParameterList_, _Initializer_, ~non-lexical-this~, _scope_, _privateScope_). + 1. Perform MakeMethod(_initializer_, _homeObject_). + 1. Set _initializer_.[[ClassFieldInitializerName]] to _propName_. + 1. Return _initializer_. + +
      + + +

      + MakeAutoAccessorGetter ( + _homeObject_: an Object, + _name_: a property key or Private Name, + _privateStateName_: a Private Name, + ): a function object +

      +
      +
      + + 1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _privateStateName_ and performs the following steps when called: + 1. Let _o_ be the *this* value. + 1. Return ? PrivateGet(_privateStateName_, _o_). + 1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 0, *"get"*, « »). + 1. Perform SetFunctionName(_getter_, _name_, *"get"*). + 1. Perform MakeMethod(_getter_, _homeObject_). + 1. Return _getter_. + +
      + + +

      + MakeAutoAccessorSetter ( + _homeObject_: an Object, + _name_: a property key or Private Name, + _privateStateName_: a Private Name, + ): a function object +

      +
      +
      + + 1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _privateStateName_ and performs the following steps when called: + 1. Let _o_ be the *this* value. + 1. Perform ? PrivateSet(_privateStateName_, _o_, _value_). + 1. Return *undefined*. + 1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 1, *"set"*, « »). + 1. Perform SetFunctionName(_setter_, _name_, *"set"*). + 1. Perform MakeMethod(_setter_, _homeObject_). + 1. Return _setter_. + +
      +

      Runtime Semantics: ClassFieldDefinitionEvaluation ( _homeObject_: an Object, - ): either a normal completion containing a ClassFieldDefinition Record or an abrupt completion + ): either a normal completion containing a ClassElementDefinition Record or an abrupt completion

      @@ -24790,17 +25369,32 @@

      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 _formalParameterList_ be an instance of the production FormalParameters : [empty]. - 1. Let _env_ be the LexicalEnvironment of the running execution context. - 1. Let _privateEnv_ be the running execution context's PrivateEnvironment. - 1. Let _sourceText_ be the empty sequence of Unicode code points. - 1. Let _initializer_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, _formalParameterList_, |Initializer|, ~non-lexical-this~, _env_, _privateEnv_). - 1. Perform MakeMethod(_initializer_, _homeObject_). - 1. Set _initializer_.[[ClassFieldInitializerName]] to _name_. - 1. Else, - 1. Let _initializer_ be ~empty~. - 1. Return the ClassFieldDefinition Record { [[Name]]: _name_, [[Initializer]]: _initializer_ }. + 1. Let _initializer_ be CreateFieldInitializerFunction(_homeObject_, _name_, |Initializer|). + 1. Append _initializer_ to _initializers_. + 1. Return ClassElementDefinition Record { [[Key]]: _name_, [[Kind]]: ~field~, [[Initializers]]: _initializers_, [[ExtraInitializers]]: _extraInitializers_, [[Decorators]]: ~empty~ }. + + + FieldDefinition : `accessor` ClassElementName Initializer? + + + 1. Let _name_ be the result of evaluating |ClassElementName|. + 1. ReturnIfAbrupt(_name_). + 1. Let _privateStateDesc_ be the string-concatenation of _name_ and *" accessor storage"*. + 1. Let _privateStateName_ be a new Private Name whose [[Description]] is _privateStateDesc_. + 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_, [[ExtraInitializers]]: _extraInitializers_, [[Decorators]]: ~empty~ }. The function created for _initializer_ is never directly accessible to ECMAScript code. @@ -24847,27 +25441,34 @@

      Runtime Semantics: ClassElementEvaluation ( _object_: an Object, - ): either a normal completion containing either a ClassFieldDefinition Record, a ClassStaticBlockDefinition Record, a PrivateElement, or ~unused~, or an abrupt completion + ): either a normal completion containing either a ClassElementDefinition Record, a ClassStaticBlockDefinition Record, or ~unused~, or an abrupt completion

      - ClassElement : - FieldDefinition `;` - `static` FieldDefinition `;` + DecoratorList? FieldDefinition `;` + DecoratorList? `static` FieldDefinition `;` - 1. Return ? ClassFieldDefinitionEvaluation of |FieldDefinition| with argument _object_. + 1. If |DecoratorList?| is present, let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Let _fieldDefinition_ be ? ClassFieldDefinitionEvaluation of |FieldDefinition| with argument _object_. + 1. Set _fieldDefinition_.[[Decorators]] to _decorators_. + 1. Return _fieldDefinition_. ClassElement : - MethodDefinition - `static` MethodDefinition + DecoratorList? MethodDefinition + DecoratorList? `static` MethodDefinition - 1. Return ? MethodDefinitionEvaluation of |MethodDefinition| with arguments _object_ and *false*. + 1. If |DecoratorList?| is present, let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Let _methodDefinition_ be ? MethodDefinitionEvaluation of |MethodDefinition| with argument _object_. + 1. Set _methodDefinition_.[[Decorators]] to _decorators_. + 1. Return _methodDefinition_. ClassElement : ClassStaticBlock @@ -24888,6 +25489,7 @@

      Runtime Semantics: ClassDefinitionEvaluation ( _classBinding_: a String or *undefined*, _className_: a property key or a Private Name, + _decorators_: a List of DecoratorDefinition Records, ): either a normal completion containing a function object or an abrupt completion

      @@ -24961,103 +25563,142 @@

      1. Perform CreateMethodProperty(_proto_, *"constructor"*, _F_). 1. If |ClassBody?| is not present, let _elements_ be a new empty List. 1. Else, let _elements_ be NonConstructorElements of |ClassBody|. - 1. Let _instancePrivateMethods_ be a new empty List. - 1. Let _staticPrivateMethods_ be a new empty List. - 1. Let _instanceFields_ be a new empty List. + 1. Let _instanceElements_ be a new empty List. 1. Let _staticElements_ be a new empty List. 1. For each |ClassElement| _e_ of _elements_, do - 1. If IsStatic of _e_ is *false*, then - 1. Let _element_ be Completion(ClassElementEvaluation of _e_ with argument _proto_). - 1. Else, - 1. Let _element_ be Completion(ClassElementEvaluation of _e_ with argument _F_). - 1. If _element_ is an abrupt completion, then + 1. If IsStatic of _e_ is *false*, let _result_ be Completion(ClassElementEvaluation of _e_ with argument _proto_). + 1. Else, let _result_ be Completion(ClassElementEvaluation of _e_ with argument _F_). + 1. If _result_ is an abrupt completion, then 1. Set the running execution context's LexicalEnvironment to _env_. 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _element_. - 1. Set _element_ to ! _element_. - 1. If _element_ is a PrivateElement, then - 1. Assert: _element_.[[Kind]] is either ~method~ or ~accessor~. - 1. If IsStatic of _e_ is *false*, let _container_ be _instancePrivateMethods_. - 1. Else, let _container_ be _staticPrivateMethods_. - 1. If _container_ contains a PrivateElement _pe_ such that _pe_.[[Key]] is _element_.[[Key]], then - 1. Assert: _element_.[[Kind]] and _pe_.[[Kind]] are both ~accessor~. - 1. If _element_.[[Get]] is *undefined*, then - 1. Let _combined_ be PrivateElement { [[Key]]: _element_.[[Key]], [[Kind]]: ~accessor~, [[Get]]: _pe_.[[Get]], [[Set]]: _element_.[[Set]] }. - 1. Else, - 1. Let _combined_ be PrivateElement { [[Key]]: _element_.[[Key]], [[Kind]]: ~accessor~, [[Get]]: _element_.[[Get]], [[Set]]: _pe_.[[Set]] }. - 1. Replace _pe_ in _container_ with _combined_. - 1. Else, - 1. Append _element_ to _container_. - 1. Else if _element_ is a ClassFieldDefinition Record, then - 1. If IsStatic of _e_ is *false*, append _element_ to _instanceFields_. + 1. Return ? _result_. + 1. Let _element_ be ! _result_. + 1. If _element_ is a ClassElementDefinition Record, then + 1. If IsStatic of _e_ is *false*, append _element_ to _instanceElements_. 1. Else, append _element_ to _staticElements_. - 1. Else if _element_ is a ClassStaticBlockDefinition Record, then + 1. Else, + 1. Assert: _element_ is a ClassStaticBlockDefinition Record. 1. Append _element_ to _staticElements_. 1. Set the running execution context's LexicalEnvironment to _env_. + 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. 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 + 1. If _e_.[[Kind]] is not ~field~, then + 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_, _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_, _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 _instanceMethodExtraInitializers_. + 1. Perform ? InitializePrivateMethods(_F_, _staticElements_). + 1. Let _classExtraInitializers_ be a new empty List. + 1. Let _newF_ be Completion(ApplyDecoratorsToClassDefinition(_F_, _decorators_, _className_, _classExtraInitializers_)). + 1. If _newF_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _result_. + 1. Set _F_ to _newF_.[[Value]]. 1. If _classBinding_ is not *undefined*, then - 1. Perform ! _classEnv_.InitializeBinding(_classBinding_, _F_). - 1. Set _F_.[[PrivateMethods]] to _instancePrivateMethods_. - 1. Set _F_.[[Fields]] to _instanceFields_. - 1. For each PrivateElement _method_ of _staticPrivateMethods_, do - 1. Perform ! PrivateMethodOrAccessorAdd(_F_, _method_). + 1. Perform _classEnv_.InitializeBinding(_classBinding_, _F_). + 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_. + 1. Return ? _result_. 1. For each element _elementRecord_ of _staticElements_, do - 1. If _elementRecord_ is a ClassFieldDefinition Record, then - 1. Let _result_ be Completion(DefineField(_F_, _elementRecord_)). - 1. Else, - 1. Assert: _elementRecord_ is a ClassStaticBlockDefinition Record. + 1. If _elementRecord_ is a ClassElementDefinition Record and _elementRecord_.[[Kind]] is ~field~ or ~accessor~, then + 1. Let _result_ be Completion(InitializeFieldOrAccessor(_F_, _elementRecord_)). + 1. Else if _elementRecord_ is a ClassStaticBlockDefinition Record, then 1. Let _result_ be Completion(Call(_elementRecord_.[[BodyFunction]], _F_)). 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 _initializer_ of _classExtraInitializers_, 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_. + 1. Return ? _result_. 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. 1. Return _F_. -

      Runtime Semantics: BindingClassDeclarationEvaluation ( ): either a normal completion containing a function object or an abrupt completion

      +

      + Runtime Semantics: BindingClassDeclarationEvaluation ( + _decorators_: a List of DecoratorDefinition Records, + ): either a normal completion containing a function object or an abrupt completion +

      - ClassDeclaration : `class` BindingIdentifier ClassTail + ClassDeclaration : DecoratorList? `class` BindingIdentifier ClassTail 1. Let _className_ be StringValue of |BindingIdentifier|. - 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments _className_ and _className_. + 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments _className_, _className_, and _decorators_. 1. Set _value_.[[SourceText]] to the source text matched by |ClassDeclaration|. 1. Let _env_ be the running execution context's LexicalEnvironment. 1. Perform ? InitializeBoundName(_className_, _value_, _env_). 1. Return _value_. - ClassDeclaration : `class` ClassTail + ClassDeclaration : DecoratorList? `class` ClassTail - 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined* and *"default"*. + 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined*, *"default"*, and _decorators_. 1. Set _value_.[[SourceText]] to the source text matched by |ClassDeclaration|. 1. Return _value_. -

      ClassDeclaration : `class` ClassTail only occurs as part of an |ExportDeclaration| and establishing its binding is handled as part of the evaluation action for that production. See .

      +

      ClassDeclaration : DecoratorList? `class` ClassTail only occurs as part of an |ExportDeclaration| and establishing its binding is handled as part of the evaluation action for that production. See .

      Runtime Semantics: Evaluation

      - ClassDeclaration : `class` BindingIdentifier ClassTail + ClassDeclaration : DecoratorList? `class` BindingIdentifier ClassTail - 1. Perform ? BindingClassDeclarationEvaluation of this |ClassDeclaration|. + 1. If |DecoratorList?| is present, then + 1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Perform ? BindingClassDeclarationEvaluation of this |ClassDeclaration| with argument _decorators_. 1. Return ~empty~. -

      ClassDeclaration : `class` ClassTail only occurs as part of an |ExportDeclaration| and is never directly evaluated.

      +

      ClassDeclaration : DecoratorList? `class` ClassTail only occurs as part of an |ExportDeclaration| and is never directly evaluated.

      - ClassExpression : `class` ClassTail + ClassExpression : DecoratorList? `class` ClassTail - 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined* and *""*. + 1. If |DecoratorList?| is present, then + 1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined*, *""*, and _decorators_. 1. Set _value_.[[SourceText]] to the source text matched by |ClassExpression|. 1. Return _value_. - ClassExpression : `class` BindingIdentifier ClassTail + ClassExpression : DecoratorList? `class` BindingIdentifier ClassTail 1. Let _className_ be StringValue of |BindingIdentifier|. - 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments _className_ and _className_. + 1. If |DecoratorList?| is present, then + 1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments _className_, _className_, and _decorators_. 1. Set _value_.[[SourceText]] to the source text matched by |ClassExpression|. 1. Return _value_. @@ -28409,10 +29050,10 @@

      Syntax

      `export` ExportFromClause FromClause `;` `export` NamedExports `;` `export` VariableStatement[~Yield, +Await] - `export` Declaration[~Yield, +Await] + DecoratorList[~Yield, +Await]? `export` Declaration[~Yield, +Await] `export` `default` HoistableDeclaration[~Yield, +Await, +Default] - `export` `default` ClassDeclaration[~Yield, +Await, +Default] - `export` `default` [lookahead ∉ { `function`, `async` [no LineTerminator here] `function`, `class` }] AssignmentExpression[+In, ~Yield, +Await] `;` + DecoratorList[~Yield, +Await]? `export` `default` ClassDeclaration[~Yield, +Await, +Default] + `export` `default` [lookahead ∉ { `function`, `async` [no LineTerminator here] `function`, `class`, `@` }] AssignmentExpression[+In, ~Yield, +Await] `;` ExportFromClause : `*` @@ -28447,6 +29088,21 @@

      Static Semantics: Early Errors

      The above rule means that each ReferencedBindings of |NamedExports| is treated as an |IdentifierReference|.

      + ExportDeclaration : DecoratorList? `export` Declaration +
        +
      • + It is a Syntax Error if |DecoratorList| is present and |Declaration| is not |ClassDeclaration|. +
      • +
      • + It is a Syntax Error if |DecoratorList| is present, |Declaration| is a |ClassDeclaration|, and the |DecoratorList| of that |ClassDeclaration| is present. +
      • +
      + ExportDeclaration : DecoratorList? `export` `default` ClassDeclaration +
        +
      • + It is a Syntax Error if |DecoratorList| is present and the |DecoratorList| of |ClassDeclaration| is present. +
      • +
      @@ -28761,17 +29417,26 @@

      Runtime Semantics: Evaluation

      1. Return ? Evaluation of |VariableStatement|. - ExportDeclaration : `export` Declaration + ExportDeclaration : DecoratorList? `export` Declaration - 1. Return ? Evaluation of |Declaration|. + 1. If |DecoratorList| is present, then + 1. Assert: |Declaration| is a |ClassDeclaration| and the |DecoratorList| of that |ClassDeclaration| is not present. + 1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Perform ? BindingClassDeclarationEvaluation of |Declaration| with argument _decorators_. + 1. Return ~empty~. + 1. Else, + 1. Return ? Evaluation of |Declaration|. ExportDeclaration : `export` `default` HoistableDeclaration 1. Return ? Evaluation of |HoistableDeclaration|. - ExportDeclaration : `export` `default` ClassDeclaration + ExportDeclaration : DecoratorList? `export` `default` ClassDeclaration - 1. Let _value_ be ? BindingClassDeclarationEvaluation of |ClassDeclaration|. + 1. If |DecoratorList| is present, then + 1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. + 1. Else, let _decorators_ be a new empty List. + 1. Let _value_ be ? BindingClassDeclarationEvaluation of |ClassDeclaration| with argument _decorators_. 1. Let _className_ be the sole element of BoundNames of |ClassDeclaration|. 1. If _className_ is *"\*default\*"*, then 1. Let _env_ be the running execution context's LexicalEnvironment. @@ -49552,6 +50217,11 @@

      Functions and Classes

      + + + + +