diff --git a/spec.html b/spec.html
index 511a46d609..9f9d9ccc20 100644
--- a/spec.html
+++ b/spec.html
@@ -2303,6 +2303,7 @@
The actual semantics of objects, in ECMAScript, are specified via algorithms called internal methods. Each object in an ECMAScript engine is associated with a set of internal methods that defines its runtime behaviour. These internal methods are not part of the ECMAScript language. They are defined by this specification purely for expository purposes. However, each object within an implementation of ECMAScript must behave as specified by the internal methods associated with it. The exact manner in which this is accomplished is determined by the implementation.
Internal method names are polymorphic. This means that different object values may perform different algorithms when a common internal method name is invoked upon them. That actual object upon which an internal method is invoked is the “target” of the invocation. If, at runtime, the implementation of an algorithm attempts to use an internal method of an object that the object does not support, a *TypeError* exception is thrown.
Internal slots correspond to internal state that is associated with objects and used by various ECMAScript specification algorithms. Internal slots are not object properties and they are not inherited. Depending upon the specific internal slot specification, such state may consist of values of any ECMAScript language type or of specific ECMAScript specification type values. Unless explicitly specified otherwise, internal slots are allocated as part of the process of creating an object and may not be dynamically added to an object. Unless specified otherwise, the initial value of an internal slot is the value *undefined*. Various algorithms within this specification create objects that have internal slots. However, the ECMAScript language provides no direct way to associate internal slots with an object.
+ All objects have an internal slot named [[PrivateElements]], which is a List of PrivateElements. This List represents the values of the private fields, methods, and accessors for the object. Initially, it is an empty List.
Internal methods and internal slots are identified within this specification using names enclosed in double square brackets [[ ]].
[[IsClassConstructor]]
@@ -10782,6 +11203,7 @@ PrepareForOrdinaryCall ( _F_, _newTarget_ )
1. Let _localEnv_ be NewFunctionEnvironment(_F_, _newTarget_).
1. Set the LexicalEnvironment of _calleeContext_ to _localEnv_.
1. Set the VariableEnvironment of _calleeContext_ to _localEnv_.
+ 1. Set the PrivateEnvironment of _calleeContext_ to _F_.[[PrivateEnvironment]].
1. If _callerContext_ is not already suspended, suspend _callerContext_.
1. Push _calleeContext_ onto the execution context stack; _calleeContext_ is now the running execution context.
1. NOTE: Any exception objects produced after this point are associated with _calleeRealm_.
@@ -10845,6 +11267,23 @@ Runtime Semantics: EvaluateBody
1. Return ? EvaluateAsyncConciseBody of |AsyncConciseBody| with arguments _functionObject_ and _argumentsList_.
+
+ Initializer :
+ `=` AssignmentExpression
+
+
+ 1. Assert: _argumentsList_ is empty.
+ 1. Assert: _functionObject_.[[ClassFieldInitializerName]] is not ~empty~.
+ 1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true*, then
+ 1. Let _value_ be NamedEvaluation of |Initializer| with argument _functionObject_.[[ClassFieldInitializerName]].
+ 1. Else,
+ 1. Let _rhs_ be the result of evaluating |AssignmentExpression|.
+ 1. Let _value_ be ? GetValue(_rhs_).
+ 1. Return Completion { [[Type]]: ~return~, [[Value]]: _value_, [[Target]]: ~empty~ }.
+
+
+ Even though field initializers constitute a function boundary, calling FunctionDeclarationInstantiation does not have any observable effect and so is omitted.
+
@@ -10868,7 +11307,12 @@ [[Construct]] ( _argumentsList_, _newTarget_ )
1. Let _thisArgument_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%Object.prototype%"*).
1. Let _calleeContext_ be PrepareForOrdinaryCall(_F_, _newTarget_).
1. Assert: _calleeContext_ is now the running execution context.
- 1. If _kind_ is ~base~, perform OrdinaryCallBindThis(_F_, _calleeContext_, _thisArgument_).
+ 1. If _kind_ is ~base~, then
+ 1. Perform OrdinaryCallBindThis(_F_, _calleeContext_, _thisArgument_).
+ 1. Let _initializeResult_ be InitializeInstanceElements(_thisArgument_, _F_).
+ 1. If _initializeResult_ is an abrupt completion, then
+ 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context.
+ 1. Return Completion(_initializeResult_).
1. Let _constructorEnv_ be the LexicalEnvironment of _calleeContext_.
1. Let _result_ be OrdinaryCallEvaluateBody(_F_, _argumentsList_).
1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context.
@@ -10882,8 +11326,8 @@ [[Construct]] ( _argumentsList_, _newTarget_ )
- OrdinaryFunctionCreate ( _functionPrototype_, _sourceText_, _ParameterList_, _Body_, _thisMode_, _Scope_ )
- The abstract operation OrdinaryFunctionCreate takes arguments _functionPrototype_ (an Object), _sourceText_ (a sequence of Unicode code points), _ParameterList_ (a Parse Node), _Body_ (a Parse Node), _thisMode_ (either ~lexical-this~ or ~non-lexical-this~), and _Scope_ (an Environment Record). _sourceText_ is the source text of the syntactic definition of the function to be created. It performs the following steps when called:
+ OrdinaryFunctionCreate ( _functionPrototype_, _sourceText_, _ParameterList_, _Body_, _thisMode_, _Scope_, _PrivateScope_ )
+ The abstract operation OrdinaryFunctionCreate takes arguments _functionPrototype_ (an Object), _sourceText_ (a sequence of Unicode code points), _ParameterList_ (a Parse Node), _Body_ (a Parse Node), _thisMode_ (either ~lexical-this~ or ~non-lexical-this~), _Scope_ (an Environment Record), and _PrivateScope_ (a PrivateEnvironment Record or *null*). _sourceText_ is the source text of the syntactic definition of the function to be created. It performs the following steps when called:
1. Assert: Type(_functionPrototype_) is Object.
1. Let _internalSlotsList_ be the internal slots listed in .
@@ -10899,9 +11343,11 @@ OrdinaryFunctionCreate ( _functionPrototype_, _sourceText_, _ParameterList_,
1. Else, set _F_.[[ThisMode]] to ~global~.
1. Set _F_.[[IsClassConstructor]] to *false*.
1. Set _F_.[[Environment]] to _Scope_.
+ 1. Set _F_.[[PrivateEnvironment]] to _PrivateScope_.
1. Set _F_.[[ScriptOrModule]] to GetActiveScriptOrModule().
1. Set _F_.[[Realm]] to the current Realm Record.
1. Set _F_.[[HomeObject]] to *undefined*.
+ 1. Set _F_.[[ClassFieldInitializerName]] to ~empty~.
1. Let _len_ be the ExpectedArgumentCount of _ParameterList_.
1. Perform ! SetFunctionLength(_F_, _len_).
1. Return _F_.
@@ -10971,17 +11417,31 @@ MakeMethod ( _F_, _homeObject_ )
+
+ DefineMethodProperty ( _key_, _homeObject_, _closure_, _enumerable_ )
+ The abstract operation DefineMethodProperty takes arguments _key_ (a property key or Private Name), _homeObject_ (an Object), _closure_ (a function object), and _enumerable_ (a Boolean). It performs the following steps when called:
+
+ 1. Perform ! SetFunctionName(_closure_, _key_).
+ 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 ~empty~.
+
+
+
SetFunctionName ( _F_, _name_ [ , _prefix_ ] )
- The abstract operation SetFunctionName takes arguments _F_ (a function object) and _name_ (a property key) and optional argument _prefix_ (a String). It adds a *"name"* property to _F_. It performs the following steps when called:
+ The abstract operation SetFunctionName takes arguments _F_ (a function object) and _name_ (a property key or Private Name) and optional argument _prefix_ (a String). It adds a *"name"* property to _F_. It performs the following steps when called:
1. Assert: _F_ is an extensible object that does not have a *"name"* own property.
- 1. Assert: Type(_name_) is either Symbol or String.
- 1. Assert: If _prefix_ is present, then Type(_prefix_) is String.
1. If Type(_name_) is Symbol, then
1. Let _description_ be _name_'s [[Description]] value.
1. If _description_ is *undefined*, set _name_ to the empty String.
1. Else, set _name_ to the string-concatenation of *"["*, _description_, and *"]"*.
+ 1. Else if _name_ is a Private Name, then
+ 1. Set _name_ to _name_.[[Description]].
1. If _F_ has an [[InitialName]] internal slot, then
1. Set _F_.[[InitialName]] to _name_.
1. If _prefix_ is present, then
@@ -11115,9 +11575,10 @@ FunctionDeclarationInstantiation ( _func_, _argumentsList_ )
1. Perform ! _lexEnv_.CreateImmutableBinding(_dn_, *true*).
1. Else,
1. Perform ! _lexEnv_.CreateMutableBinding(_dn_, *false*).
+ 1. Let _privateEnv_ be the PrivateEnvironment of _calleeContext_.
1. For each Parse Node _f_ of _functionsToInitialize_, do
1. Let _fn_ be the sole element of the BoundNames of _f_.
- 1. Let _fo_ be InstantiateFunctionObject of _f_ with argument _lexEnv_.
+ 1. Let _fo_ be InstantiateFunctionObject of _f_ with arguments _lexEnv_ and _privateEnv_.
1. Perform ! _varEnv_.SetMutableBinding(_fn_, _fo_, *false*).
1. Return NormalCompletion(~empty~).
@@ -13315,6 +13776,7 @@ Syntax
CommonToken ::
IdentifierName
+ PrivateIdentifier
Punctuator
NumericLiteral
StringLiteral
@@ -13335,6 +13797,9 @@ Names and Keywords
Two |IdentifierName|s that are canonically equivalent according to the Unicode standard are not equal unless, after replacement of each |UnicodeEscapeSequence|, they are represented by the exact same sequence of code points.
Syntax
+ PrivateIdentifier ::
+ `#` IdentifierName
+
IdentifierName ::
IdentifierStart
IdentifierName IdentifierPart
@@ -14722,6 +15187,13 @@ Static Semantics: StringValue
1. Return the StringValue of |IdentifierName|.
+
+ PrivateIdentifier ::
+ `#` IdentifierName
+
+
+ 1. Return the string-concatenation of 0x0023 (NUMBER SIGN) and the StringValue of |IdentifierName|.
+
@@ -15017,6 +15489,9 @@ Static Semantics: Early Errors
It is a Syntax Error if HasDirectSuper of |MethodDefinition| is *true*.
+
+ It is a Syntax Error if PrivateBoundIdentifiers of |MethodDefinition| is not empty.
+
In addition to describing an actual object initializer the |ObjectLiteral| productions are also used as a cover grammar for |ObjectAssignmentPattern| and may be recognized as part of a |CoverParenthesizedExpressionAndArrowParameterList|. When |ObjectLiteral| appears in a context where |ObjectAssignmentPattern| is required the following Early Error rules are not applied. In addition, they are not applied when initially parsing a |CoverParenthesizedExpressionAndArrowParameterList| or |CoverCallExpressionAndAsyncArrowHead|.
PropertyDefinition : CoverInitializedName
@@ -15136,25 +15611,25 @@ Runtime Semantics: PropertyDefinitionEvaluation
MethodDefinition :
- PropertyName `(` UniqueFormalParameters `)` `{` FunctionBody `}`
- `get` PropertyName `(` `)` `{` FunctionBody `}`
- `set` PropertyName `(` PropertySetParameterList `)` `{` FunctionBody `}`
+ ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}`
+ `get` ClassElementName `(` `)` `{` FunctionBody `}`
+ `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}`
1. Return ? MethodDefinitionEvaluation of |MethodDefinition| with arguments _object_ and _enumerable_.
- GeneratorMethod : `*` PropertyName `(` UniqueFormalParameters `)` `{` GeneratorBody `}`
+ GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}`
1. Return ? MethodDefinitionEvaluation of |GeneratorMethod| with arguments _object_ and _enumerable_.
- AsyncGeneratorMethod : `async` `*` PropertyName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}`
+ AsyncGeneratorMethod : `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}`
1. Return ? MethodDefinitionEvaluation of |AsyncGeneratorMethod| with arguments _object_ and _enumerable_.
- AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+ AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
1. Return ? MethodDefinitionEvaluation of |AsyncMethod| with arguments _object_ and _enumerable_.
@@ -15509,6 +15984,7 @@ Syntax
SuperProperty[?Yield, ?Await]
MetaProperty
`new` MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ MemberExpression[?Yield, ?Await] `.` PrivateIdentifier
SuperProperty[Yield, Await] :
`super` `[` Expression[+In, ?Yield, ?Await] `]`
@@ -15536,6 +16012,7 @@ Syntax
CallExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
CallExpression[?Yield, ?Await] `.` IdentifierName
CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ CallExpression[?Yield, ?Await] `.` PrivateIdentifier
SuperCall[Yield, Await] :
`super` Arguments[?Yield, ?Await]
@@ -15564,10 +16041,12 @@ Syntax
`?.` `[` Expression[+In, ?Yield, ?Await] `]`
`?.` IdentifierName
`?.` TemplateLiteral[?Yield, ?Await, +Tagged]
+ `?.` PrivateIdentifier
OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await]
OptionalChain[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
OptionalChain[?Yield, ?Await] `.` IdentifierName
OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ OptionalChain[?Yield, ?Await] `.` PrivateIdentifier
LeftHandSideExpression[Yield, Await] :
NewExpression[?Yield, ?Await]
@@ -15676,6 +16155,14 @@ Runtime Semantics: Evaluation
1. If the code matched by this |MemberExpression| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*.
1. Return ? EvaluatePropertyAccessWithIdentifierKey(_baseValue_, |IdentifierName|, _strict_).
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 1. Let _baseValue_ be ? GetValue(_baseReference_).
+ 1. Let _bv_ be ? RequireObjectCoercible(_baseValue_).
+ 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 1. Return ! MakePrivateReference(_bv_, _fieldNameString_).
+
CallExpression : CallExpression `[` Expression `]`
1. Let _baseReference_ be the result of evaluating |CallExpression|.
@@ -15690,6 +16177,14 @@ Runtime Semantics: Evaluation
1. If the code matched by this |CallExpression| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*.
1. Return ? EvaluatePropertyAccessWithIdentifierKey(_baseValue_, |IdentifierName|, _strict_).
+ CallExpression : CallExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |CallExpression|.
+ 1. Let _baseValue_ be ? GetValue(_baseReference_).
+ 1. Let _bv_ be ? RequireObjectCoercible(_baseValue_).
+ 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 1. Return ! MakePrivateReference(_bv_, _fieldNameString_).
+
@@ -15839,7 +16334,11 @@ Runtime Semantics: Evaluation
1. If IsConstructor(_func_) is *false*, throw a *TypeError* exception.
1. Let _result_ be ? Construct(_func_, _argList_, _newTarget_).
1. Let _thisER_ be GetThisEnvironment().
- 1. Return ? _thisER_.BindThisValue(_result_).
+ 1. Perform ? _thisER_.BindThisValue(_result_).
+ 1. Let _F_ be _thisER_.[[FunctionObject]].
+ 1. Assert: _F_ is an ECMAScript function object.
+ 1. Perform ? InitializeInstanceElements(_result_, _F_).
+ 1. Return _result_.
@@ -16001,6 +16500,12 @@ Runtime Semantics: ChainEvaluation
1. If the code matched by this |OptionalChain| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*.
1. Return ? EvaluatePropertyAccessWithIdentifierKey(_baseValue_, |IdentifierName|, _strict_).
+ OptionalChain : `?.` PrivateIdentifier
+
+ 1. Let _bv_ be ? RequireObjectCoercible(_baseValue_).
+ 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 1. Return ! MakePrivateReference(_bv_, _fieldNameString_).
+
OptionalChain : OptionalChain Arguments
1. Let _optionalChain_ be |OptionalChain|.
@@ -16026,6 +16531,15 @@ Runtime Semantics: ChainEvaluation
1. If the code matched by this |OptionalChain| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*.
1. Return ? EvaluatePropertyAccessWithIdentifierKey(_newValue_, |IdentifierName|, _strict_).
+ OptionalChain : OptionalChain `.` PrivateIdentifier
+
+ 1. Let _optionalChain_ be |OptionalChain|.
+ 1. Let _newReference_ be ? ChainEvaluation of _optionalChain_ with arguments _baseValue_ and _baseReference_.
+ 1. Let _newValue_ be ? GetValue(_newReference_).
+ 1. Let _nv_ be ? RequireObjectCoercible(_newValue_).
+ 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 1. Return ! MakePrivateReference(_nv_, _fieldNameString_).
+
@@ -16262,7 +16776,7 @@ Static Semantics: Early Errors
UnaryExpression : `delete` UnaryExpression
ClassElement : MethodDefinition
@@ -20564,6 +21108,32 @@ Static Semantics: Early Errors
It is a Syntax Error if PropName of |MethodDefinition| is *"prototype"*.
+
+ ClassElement : FieldDefinition `;`
+
+ - It is a Syntax Error if PropName of |FieldDefinition| is *"constructor"*.
+
+
+ ClassElement : `static` FieldDefinition `;`
+
+ -
+ It is a Syntax Error if PropName of |FieldDefinition| is *"prototype"* or *"constructor"*.
+
+
+
+
+ FieldDefinition :
+ ClassElementName Initializer?
+
+
+ - It is a Syntax Error if |Initializer| is present and ContainsArguments of |Initializer| is *true*.
+ - It is a Syntax Error if |Initializer| is present and |Initializer| Contains |SuperCall| is *true*.
+
+
+ ClassElementName : PrivateIdentifier
+
+ - It is a Syntax Error if StringValue of |PrivateIdentifier| is *"#constructor"*.
+
@@ -20573,7 +21143,12 @@ Static Semantics: ClassElementKind
1. If PropName of |MethodDefinition| is *"constructor"*, return ~ConstructorMethod~.
1. Return ~NonConstructorMethod~.
- ClassElement : `static` MethodDefinition
+
+ ClassElement :
+ `static` MethodDefinition
+ FieldDefinition `;`
+ `static` FieldDefinition `;`
+
1. Return ~NonConstructorMethod~.
@@ -20612,14 +21187,22 @@ Static Semantics: IsStatic
1. Return *true*.
+ ClassElement : FieldDefinition `;`
+
+ 1. Return *false*.
+
+ ClassElement : `static` FieldDefinition `;`
+
+ 1. Return *true*.
+
ClassElement : `;`
1. Return *false*.
-
- Static Semantics: NonConstructorMethodDefinitions
+
+ Static Semantics: NonConstructorElements
ClassElementList : ClassElement
1. If ClassElementKind of |ClassElement| is ~NonConstructorMethod~, then
@@ -20628,7 +21211,7 @@ Static Semantics: NonConstructorMethodDefinitions
ClassElementList : ClassElementList ClassElement
- 1. Let _list_ be NonConstructorMethodDefinitions of |ClassElementList|.
+ 1. Let _list_ be NonConstructorElements of |ClassElementList|.
1. If ClassElementKind of |ClassElement| is ~NonConstructorMethod~, then
1. Append |ClassElement| to the end of _list_.
1. Return _list_.
@@ -20653,20 +21236,273 @@ Static Semantics: PrototypePropertyNameList
+
+ Static Semantics: AllPrivateIdentifiersValid
+ With parameter _names_.
+
+ Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of AllPrivateIdentifiersValid:
+
+ 1. For each child node _child_ of this Parse Node, do
+ 1. If _child_ is an instance of a nonterminal, then
+ 1. If AllPrivateIdentifiersValid of _child_ with argument _names_ is *false*, return *false*.
+ 1. Return *true*.
+
+
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. If _names_ contains the StringValue of |PrivateIdentifier|, then
+ 1. Return AllPrivateIdentifiersValid of |MemberExpression| with argument _names_.
+ 1. Return *false*.
+
+
+ CallExpression : CallExpression `.` PrivateIdentifier
+
+ 1. If _names_ contains the StringValue of |PrivateIdentifier|, then
+ 1. Return AllPrivateIdentifiersValid of |CallExpression| with argument _names_.
+ 1. Return *false*.
+
+
+ OptionalChain : `?.` PrivateIdentifier
+
+ 1. If _names_ contains the StringValue of |PrivateIdentifier|, return *true*.
+ 1. Return *false*.
+
+
+ OptionalChain : OptionalChain `.` PrivateIdentifier
+
+ 1. If _names_ contains the StringValue of |PrivateIdentifier|, then
+ 1. Return AllPrivateIdentifiersValid of |OptionalChain| with argument _names_.
+ 1. Return *false*.
+
+
+ ClassBody : ClassElementList
+
+ 1. Let _newNames_ be a copy of _names_.
+ 1. Append to _newNames_ the elements of PrivateBoundIdentifiers of |ClassBody|.
+ 1. Return AllPrivateIdentifiersValid of |ClassElementList| with argument _newNames_.
+
+
+
+
+ Static Semantics: PrivateBoundIdentifiers
+
+ FieldDefinition : ClassElementName Initializer?
+
+
+ 1. Return PrivateBoundIdentifiers of |ClassElementName|.
+
+
+
+ ClassElementName : PrivateIdentifier
+
+
+ 1. Return a List whose sole element is the StringValue of |PrivateIdentifier|.
+
+
+
+ ClassElementName : PropertyName
+
+ ClassElement : `;`
+
+
+ 1. Return a new empty List.
+
+
+
+ ClassElementList : ClassElementList ClassElement
+
+
+ 1. Let _names_ be PrivateBoundIdentifiers of |ClassElementList|.
+ 1. Append to _names_ the elements of PrivateBoundIdentifiers of |ClassElement|.
+ 1. Return _names_.
+
+
+
+ MethodDefinition :
+ ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}`
+ `get` ClassElementName `(` `)` `{` FunctionBody `}`
+ `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}`
+
+ GeneratorMethod :
+ `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}`
+
+ AsyncMethod :
+ `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncGeneratorMethod :
+ `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}`
+
+
+ 1. Return PrivateBoundIdentifiers of |ClassElementName|.
+
+
+
+
+ Static Semantics: ContainsArguments
+
+ Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of ContainsArguments:
+
+ 1. For each child node _child_ of this Parse Node, do
+ 1. If _child_ is an instance of a nonterminal, then
+ 1. If ContainsArguments of _child_ is *true*, return *true*.
+ 1. Return *false*.
+
+
+
+ IdentifierReference : Identifier
+
+
+ 1. If the StringValue of |Identifier| is *"arguments"*, return *true*.
+ 1. Return *false*.
+
+
+
+ FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}`
+
+ FunctionDeclaration : `function` `(` FormalParameters `)` `{` FunctionBody `}`
+
+ FunctionExpression : `function` BindingIdentifier? `(` FormalParameters `)` `{` FunctionBody `}`
+
+
+ 1. Return *false*.
+
+
+
+ MethodDefinition :
+ ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}`
+ `get` ClassElementName `(` `)` `{` FunctionBody `}`
+ `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}`
+
+
+ 1. Return ContainsArguments of |ClassElementName|.
+
+
+
+ GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}`
+
+
+ 1. Return ContainsArguments of |ClassElementName|.
+
+
+
+ GeneratorDeclaration : `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}`
+
+ GeneratorDeclaration : `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}`
+
+ GeneratorExpression : `function` `*` BindingIdentifier? `(` FormalParameters `)` `{` GeneratorBody `}`
+
+
+ 1. Return *false*.
+
+
+
+ AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+
+
+ 1. Return ContainsArguments of |ClassElementName|.
+
+
+
+ AsyncFunctionDeclaration : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncFunctionDeclaration : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncFunctionExpression : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncFunctionExpression : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+
+ 1. Return *false*.
+
+
+
+
+ Runtime Semantics: ClassFieldDefinitionEvaluation
+
+ With parameter _homeObject_.
+
+
+ FieldDefinition : ClassElementName Initializer?
+
+
+ 1. Let _name_ be the result of evaluating |ClassElementName|.
+ 1. ReturnIfAbrupt(_name_).
+ 1. If |Initializer_opt| is present, then
+ 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 _name_.
+ 1. Else,
+ 1. Let _initializer_ be ~empty~.
+ 1. Return the ClassFieldDefinition Record { [[Name]]: _name_, [[Initializer]]: _initializer_ }.
+
+
+ The function created for _initializer_ is never directly accessible to ECMAScript code.
+
+
+
+
+ Runtime Semantics: ClassElementEvaluation
+ With parameters _object_ and _enumerable_.
+
+
+ ClassElement : FieldDefinition `;`
+
+ ClassElement : `static` FieldDefinition `;`
+
+
+ 1. Return ClassFieldDefinitionEvaluation of |FieldDefinition| with argument _object_.
+
+
+
+ ClassElement : MethodDefinition
+
+ ClassElement : `static` MethodDefinition
+
+
+ 1. Return MethodDefinitionEvaluation of |MethodDefinition| with arguments _object_ and _enumerable_.
+
+
+
+ ClassElement : `;`
+
+
+ 1. Return.
+
+
+
Runtime Semantics: ClassDefinitionEvaluation
With parameters _classBinding_ and _className_.
+
+ For ease of specification, private methods and accessors are included alongside private fields in the [[PrivateElements]] slot of class instances. However, any given object has either all or none of the private methods and accessors defined by a given class. This feature has been designed so that implementations may choose to implement private methods and accessors using a strategy which does not require tracking each method or accessor individually.
+ For example, an implementation could directly associate instance private methods with their corresponding Private Name and track, for each object, which class constructors have run with that object as their `this` value. Looking up an instance private method on an object then consists of checking that the class constructor which defines the method has been used to initialize the object, then returning the method associated with the Private Name.
+ This differs from private fields: because field initializers can throw during class instantiation, an individual object may have some proper subset of the private fields of a given class, and so private fields must in general be tracked individually.
+
ClassTail : ClassHeritage? `{` ClassBody? `}`
1. Let _env_ be the LexicalEnvironment of the running execution context.
1. Let _classScope_ be NewDeclarativeEnvironment(_env_).
1. If _classBinding_ is not *undefined*, then
1. Perform _classScope_.CreateImmutableBinding(_classBinding_, *true*).
+ 1. Let _outerPrivateEnvironment_ be the running execution context's PrivateEnvironment.
+ 1. Let _classPrivateEnvironment_ be NewPrivateEnvironment(_outerPrivateEnvironment_).
+ 1. If |ClassBody_opt| is present, then
+ 1. For each String _dn_ of the PrivateBoundIdentifiers of |ClassBody_opt|, do
+ 1. If _classPrivateEnvironment_.[[Names]] contains a Private Name whose [[Description]] is _dn_, then
+ 1. Assert: This is only possible for getter/setter pairs.
+ 1. Else,
+ 1. Let _name_ be a new Private Name whose [[Description]] value is _dn_.
+ 1. Append _name_ to _classPrivateEnvironment_.[[Names]].
1. If |ClassHeritage_opt| is not present, then
1. Let _protoParent_ be %Object.prototype%.
1. Let _constructorParent_ be %Function.prototype%.
1. Else,
1. Set the running execution context's LexicalEnvironment to _classScope_.
+ 1. NOTE: The running execution context's PrivateEnvironment is _outerPrivateEnvironment_ when evaluating |ClassHeritage|.
1. Let _superclassRef_ be the result of evaluating |ClassHeritage|.
1. Set the running execution context's LexicalEnvironment to _env_.
1. Let _superclass_ be ? GetValue(_superclassRef_).
@@ -20682,6 +21518,7 @@ Runtime Semantics: ClassDefinitionEvaluation
1. If |ClassBody_opt| is not present, let _constructor_ be ~empty~.
1. Else, let _constructor_ be ConstructorMethod of |ClassBody|.
1. Set the running execution context's LexicalEnvironment to _classScope_.
+ 1. Set the running execution context's PrivateEnvironment to _classPrivateEnvironment_.
1. If _constructor_ is ~empty~, then
1. Let _steps_ be the algorithm steps defined in .
1. Let _F_ be ! CreateBuiltinFunction(_steps_, 0, _className_, « [[ConstructorKind]], [[SourceText]] », ~empty~, _constructorParent_).
@@ -20693,19 +21530,52 @@ Runtime Semantics: ClassDefinitionEvaluation
1. Perform ! MakeConstructor(_F_, *false*, _proto_).
1. If |ClassHeritage_opt| is present, set _F_.[[ConstructorKind]] to ~derived~.
1. Perform ! CreateMethodProperty(_proto_, *"constructor"*, _F_).
- 1. If |ClassBody_opt| is not present, let _methods_ be a new empty List.
- 1. Else, let _methods_ be NonConstructorMethodDefinitions of |ClassBody|.
- 1. For each |ClassElement| _m_ of _methods_, do
- 1. If IsStatic of _m_ is *false*, then
- 1. Let _status_ be PropertyDefinitionEvaluation of _m_ with arguments _proto_ and *false*.
+ 1. If |ClassBody_opt| 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 _staticFields_ be a new empty List.
+ 1. For each |ClassElement| _e_ of _elements_, do
+ 1. If IsStatic of _e_ is *false*, then
+ 1. Let _field_ be ClassElementEvaluation of _e_ with arguments _proto_ and *false*.
1. Else,
- 1. Let _status_ be PropertyDefinitionEvaluation of _m_ with arguments _F_ and *false*.
- 1. If _status_ is an abrupt completion, then
+ 1. Let _field_ be ClassElementEvaluation of _e_ with arguments _F_ and *false*.
+ 1. If _field_ is an abrupt completion, then
1. Set the running execution context's LexicalEnvironment to _env_.
- 1. Return Completion(_status_).
+ 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
+ 1. Return Completion(_field_).
+ 1. Set _field_ to _field_.[[Value]].
+ 1. If _field_ is a PrivateElement, then
+ 1. Assert: _field_.[[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 whose [[Key]] is _field_.[[Key]], then
+ 1. Let _existing_ be that PrivateElement.
+ 1. Assert: _field_.[[Kind]] and _existing_.[[Kind]] are both ~accessor~.
+ 1. If _field_.[[Get]] is *undefined*, then
+ 1. Let _combined_ be PrivateElement { [[Key]]: _field_.[[Key]], [[Kind]]: ~accessor~, [[Get]]: _existing_.[[Get]], [[Set]]: _field_.[[Set]] }.
+ 1. Else,
+ 1. Let _combined_ be PrivateElement { [[Key]]: _field_.[[Key]], [[Kind]]: ~accessor~, [[Get]]: _field_.[[Get]], [[Set]]: _existing_.[[Set]] }.
+ 1. Replace _existing_ in _container_ with _combined_.
+ 1. Else,
+ 1. Append _field_ to _container_.
+ 1. Else if _field_ is a ClassFieldDefinition Record, then
+ 1. If IsStatic of _e_ is *false*, append _field_ to _instanceFields_.
+ 1. Else, append _field_ to _staticFields_.
1. Set the running execution context's LexicalEnvironment to _env_.
1. If _classBinding_ is not *undefined*, then
1. Perform _classScope_.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(_method_, _F_).
+ 1. For each element _fieldRecord_ of _staticFields_, do
+ 1. Let _result_ be DefineField(_F_, _fieldRecord_).
+ 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_.
@@ -20773,6 +21643,15 @@ Runtime Semantics: Evaluation
1. Set _value_.[[SourceText]] to the source text matched by |ClassExpression|.
1. Return _value_.
+ ClassElementName : PrivateIdentifier
+
+ 1. Let _privateIdentifier_ be StringValue of |PrivateIdentifier|.
+ 1. Let _privateEnvRec_ be the running execution context's PrivateEnvironment.
+ 1. Let _names_ be _privateEnvRec_.[[Names]].
+ 1. Assert: Exactly one element of _names_ is a Private Name whose [[Description]] is _privateIdentifier_.
+ 1. Let _privateName_ be the Private Name in _names_ whose [[Description]] is _privateIdentifier_.
+ 1. Return _privateName_.
+
@@ -20788,7 +21667,7 @@ Syntax
`async` [no LineTerminator here] `function` BindingIdentifier[~Yield, +Await]? `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
AsyncMethod[Yield, Await] :
- `async` [no LineTerminator here] PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ `async` [no LineTerminator here] ClassElementName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
AsyncFunctionBody :
FunctionBody[~Yield, +Await]
@@ -20817,7 +21696,7 @@ Syntax
Static Semantics: Early Errors
- AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+ AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
@@ -21581,6 +22471,7 @@ ScriptEvaluation ( _scriptRecord_ )
1. Set the ScriptOrModule of _scriptContext_ to _scriptRecord_.
1. Set the VariableEnvironment of _scriptContext_ to _globalEnv_.
1. Set the LexicalEnvironment of _scriptContext_ to _globalEnv_.
+ 1. Set the PrivateEnvironment of _scriptContext_ to *null*.
1. Suspend the currently running execution context.
1. Push _scriptContext_ onto the execution context stack; _scriptContext_ is now the running execution context.
1. Let _scriptBody_ be _scriptRecord_.[[ECMAScriptCode]].
@@ -21643,6 +22534,7 @@ GlobalDeclarationInstantiation ( _script_, _env_ )
1. NOTE: No abnormal terminations occur after this algorithm step if the global object is an ordinary object. However, if the global object is a Proxy exotic object it may exhibit behaviours that cause abnormal terminations in some of the following steps.
1. [id="step-globaldeclarationinstantiation-web-compat-insertion-point"] NOTE: Annex adds additional steps at this point.
1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _script_.
+ 1. Let _privateEnv_ be *null*.
1. For each element _d_ of _lexDeclarations_, do
1. NOTE: Lexically declared names are only instantiated here but not initialized.
1. For each element _dn_ of the BoundNames of _d_, do
@@ -21652,7 +22544,7 @@ GlobalDeclarationInstantiation ( _script_, _env_ )
1. Perform ? _env_.CreateMutableBinding(_dn_, *false*).
1. For each Parse Node _f_ of _functionsToInitialize_, do
1. Let _fn_ be the sole element of the BoundNames of _f_.
- 1. Let _fo_ be InstantiateFunctionObject of _f_ with argument _env_.
+ 1. Let _fo_ be InstantiateFunctionObject of _f_ with arguments _env_ and _privateEnv_.
1. Perform ? _env_.CreateGlobalFunctionBinding(_fn_, _fo_, *false*).
1. For each String _vn_ of _declaredVarNames_, do
1. Perform ? _env_.CreateGlobalVarBinding(_vn_, *false*).
@@ -21719,6 +22611,9 @@ Static Semantics: Early Errors
It is a Syntax Error if ContainsUndefinedContinueTarget of |ModuleItemList| with arguments « » and « » is *true*.
+
+ It is a Syntax Error if AllPrivateIdentifiersValid of |ModuleItemList| with argument « » is *false*.
+
The duplicate ExportedNames rule implies that multiple `export default` |ExportDeclaration| items within a |ModuleBody| is a Syntax Error. Additional error conditions relating to conflicting or duplicate declarations are checked during module linking prior to evaluation of a |Module|. If any such errors are detected the |Module| is not evaluated.
@@ -22833,6 +23728,7 @@ InitializeEnvironment ( ) Concrete Method
1. Set the ScriptOrModule of _moduleContext_ to _module_.
1. Set the VariableEnvironment of _moduleContext_ to _module_.[[Environment]].
1. Set the LexicalEnvironment of _moduleContext_ to _module_.[[Environment]].
+ 1. Set the PrivateEnvironment of _moduleContext_ to *null*.
1. Set _module_.[[Context]] to _moduleContext_.
1. Push _moduleContext_ onto the execution context stack; _moduleContext_ is now the running execution context.
1. Let _code_ be _module_.[[ECMAScriptCode]].
@@ -22845,6 +23741,7 @@ InitializeEnvironment ( ) Concrete Method
1. Call _env_.InitializeBinding(_dn_, *undefined*).
1. Append _dn_ to _declaredVarNames_.
1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _code_.
+ 1. Let _privateEnv_ be *null*.
1. For each element _d_ of _lexDeclarations_, do
1. For each element _dn_ of the BoundNames of _d_, do
1. If IsConstantDeclaration of _d_ is *true*, then
@@ -22852,7 +23749,7 @@ InitializeEnvironment ( ) Concrete Method
1. Else,
1. Perform ! _env_.CreateMutableBinding(_dn_, *false*).
1. If _d_ is a |FunctionDeclaration|, a |GeneratorDeclaration|, an |AsyncFunctionDeclaration|, or an |AsyncGeneratorDeclaration|, then
- 1. Let _fo_ be InstantiateFunctionObject of _d_ with argument _env_.
+ 1. Let _fo_ be InstantiateFunctionObject of _d_ with arguments _env_ and _privateEnv_.
1. Call _env_.InitializeBinding(_dn_, _fo_).
1. Remove _moduleContext_ from the execution context stack.
1. Return NormalCompletion(~empty~).
@@ -23667,6 +24564,7 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. Let _inFunction_ be *false*.
1. Let _inMethod_ be *false*.
1. Let _inDerivedConstructor_ be *false*.
+ 1. Let _inClassFieldInitializer_ be *false*.
1. If _direct_ is *true*, then
1. Let _thisEnvRec_ be ! GetThisEnvironment().
1. If _thisEnvRec_ is a function Environment Record, then
@@ -23674,6 +24572,8 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. Set _inFunction_ to *true*.
1. Set _inMethod_ to _thisEnvRec_.HasSuperBinding().
1. If _F_.[[ConstructorKind]] is ~derived~, set _inDerivedConstructor_ to *true*.
+ 1. Let _classFieldIntializerName_ be _F_.[[ClassFieldInitializerName]].
+ 1. If _classFieldIntializerName_ is not ~empty~, set _inClassFieldInitializer_ to *true*.
1. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
1. Let _script_ be ParseText(! StringToCodePoints(_x_), |Script|).
1. If _script_ is a List of errors, throw a *SyntaxError* exception.
@@ -23682,6 +24582,7 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. If _inFunction_ is *false*, and _body_ Contains |NewTarget|, throw a *SyntaxError* exception.
1. If _inMethod_ is *false*, and _body_ Contains |SuperProperty|, throw a *SyntaxError* exception.
1. If _inDerivedConstructor_ is *false*, and _body_ Contains |SuperCall|, throw a *SyntaxError* exception.
+ 1. If _inClassFieldInitializer_ is *true*, and ContainsArguments of _body_ is *true*, throw a *SyntaxError* exception.
1. If _strictCaller_ is *true*, let _strictEval_ be *true*.
1. Else, let _strictEval_ be IsStrict of _script_.
1. Let _runningContext_ be the running execution context.
@@ -23689,9 +24590,11 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. If _direct_ is *true*, then
1. Let _lexEnv_ be NewDeclarativeEnvironment(_runningContext_'s LexicalEnvironment).
1. Let _varEnv_ be _runningContext_'s VariableEnvironment.
+ 1. Let _privateEnv_ be _runningContext_'s PrivateEnvironment.
1. Else,
1. Let _lexEnv_ be NewDeclarativeEnvironment(_evalRealm_.[[GlobalEnv]]).
1. Let _varEnv_ be _evalRealm_.[[GlobalEnv]].
+ 1. Let _privateEnv_ be *null*.
1. If _strictEval_ is *true*, set _varEnv_ to _lexEnv_.
1. If _runningContext_ is not already suspended, suspend _runningContext_.
1. Let _evalContext_ be a new ECMAScript code execution context.
@@ -23700,8 +24603,9 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. Set _evalContext_'s ScriptOrModule to _runningContext_'s ScriptOrModule.
1. Set _evalContext_'s VariableEnvironment to _varEnv_.
1. Set _evalContext_'s LexicalEnvironment to _lexEnv_.
+ 1. Set _evalContext_'s PrivateEnvironment to _privateEnv_.
1. Push _evalContext_ onto the execution context stack; _evalContext_ is now the running execution context.
- 1. Let _result_ be EvalDeclarationInstantiation(_body_, _varEnv_, _lexEnv_, _strictEval_).
+ 1. Let _result_ be EvalDeclarationInstantiation(_body_, _varEnv_, _lexEnv_, _privateEnv_, _strictEval_).
1. If _result_.[[Type]] is ~normal~, then
1. Set _result_ to the result of evaluating _body_.
1. If _result_.[[Type]] is ~normal~ and _result_.[[Value]] is ~empty~, then
@@ -23722,8 +24626,8 @@ HostEnsureCanCompileStrings ( _callerRealm_, _calleeRealm_ )
- EvalDeclarationInstantiation ( _body_, _varEnv_, _lexEnv_, _strict_ )
- The abstract operation EvalDeclarationInstantiation takes arguments _body_, _varEnv_, _lexEnv_, and _strict_. It performs the following steps when called:
+ EvalDeclarationInstantiation ( _body_, _varEnv_, _lexEnv_, _privateEnv_, _strict_ )
+ The abstract operation EvalDeclarationInstantiation takes arguments _body_, _varEnv_, _lexEnv_, _privateEnv_, and _strict_. It performs the following steps when called:
|