├── .gitattributes ├── .gitignore ├── .vscode ├── extensions.json ├── settings.json └── tasks.json ├── spec ├── sec-introduction.html ├── sec-global-environment-records-patch.html ├── sec-object-environment-records-patch.html ├── sec-declarative-environment-records-patch.html ├── sec-getclassenvironment-patch.html ├── sec-makemethod-patch.html ├── sec-static-semantics-static-semantics-assignmenttargettype-patch.html ├── sec-static-semantics-static-semantics-isidentifierref-patch.html ├── sec-static-semantics-static-semantics-isfunctiondefinition-patch.html ├── sec-arrow-function-definitions-static-semantics-contains-patch.html ├── sec-static-semantics-static-semantics-isdestructuring-patch.html ├── sec-newfunctionenvironment-patch.html ├── sec-runtime-semantics-definemethod-patch.html ├── sec-async-function-definitions-PropertyDefinitionEvaluation-patch.html ├── sec-async-arrow-function-definitions-static-semantics-Contains-patch.html ├── sec-static-semantics-static-semantics-contains-patch.html ├── sec-asyncgenerator-definitions-propertydefinitionevaluation-patch.html ├── sec-left-hand-side-expressions-patch.html ├── sec-generator-function-definitions-runtime-semantics-propertydefinitionevaluation-patch.html ├── sec-arrow-function-definitions-runtime-semantics-namedevaluation-patch.html ├── sec-class-keyword-patch.html ├── sec-function-definitions-static-semantics-early-errors-patch.html ├── sec-scripts-static-semantics-early-errors-patch.html ├── sec-async-function-definitions-static-semantics-early-errors-patch.html ├── sec-module-semantics-static-semantics-early-errors-patch.html ├── sec-async-generator-function-definitions-static-semantics-early-errors-patch.html ├── sec-generator-function-definitions-static-semantics-early-errors-patch.html ├── sec-method-definitions-runtime-semantics-propertydefinitionevaluation-patch.html ├── sec-object-initializer-runtime-semantics-propertydefinitionevaluation-patch.html ├── sec-expression-rules-patch.html ├── sec-runtime-semantics-classdefinitionevaluation-patch.html ├── sec-performeval-patch.html ├── sec-the-environment-record-type-hierarchy-patch.html ├── sec-ecmascript-function-objects-patch.html ├── index.html ├── sec-function-environment-records-patch.html └── sec-createdynamicfunction-patch.html ├── .yo-rc.json ├── gulpfile.js ├── package.json ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "rbuckton.grammarkdown-language", 4 | "rbuckton.ecmarkup-vscode" 5 | ] 6 | } -------------------------------------------------------------------------------- /spec/sec-introduction.html: -------------------------------------------------------------------------------- 1 |

This proposal defines new syntax to access static members of the containing lexical `class` declaration.

2 |

See the proposal repository for background material and discussion.

-------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[markdown]": { 3 | "files.trimTrailingWhitespace": false 4 | }, 5 | "files.associations": { 6 | "*.html": "ecmarkup", 7 | "*.emu": "ecmarkup" 8 | }, 9 | "[html]": { "editor.tabSize": 2 }, 10 | "[ecmarkup]": { "editor.tabSize": 2 } 11 | } -------------------------------------------------------------------------------- /spec/sec-global-environment-records-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Global Environment Records

3 | 4 | 5 |

HasClassBinding ( )

6 | 7 | 1. Return *false*. 8 | 9 |
10 | 11 |
-------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "gulp", 8 | "task": "build", 9 | "group": { 10 | "kind": "build", 11 | "isDefault": true 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /spec/sec-object-environment-records-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Object Environment Records

3 | 4 | 5 |

HasClassBinding ( )

6 |

Regular object Environment Records do not provide a `class` binding.

7 | 8 | 1. Return *false*. 9 | 10 |
11 |
-------------------------------------------------------------------------------- /spec/sec-declarative-environment-records-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Declarative Environment Records

3 | 4 | 5 |

HasClassBinding ( )

6 |

Regular declarative Environment Records do not provide a `class` binding.

7 | 8 | 1. Return *false*. 9 | 10 |
11 |
-------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-ecmascript-proposal": { 3 | "promptValues": { 4 | "hasChampion": true, 5 | "championName": "Ron Buckton", 6 | "championGithub": "rbuckton", 7 | "spec": "https://rbuckton.github.io/proposal-class-access-expressions", 8 | "stage": "0", 9 | "sections": [ 10 | "syntax", 11 | "semantics", 12 | "examples", 13 | "grammar", 14 | "references" 15 | ], 16 | "build": "gulp", 17 | "vscode": true 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /spec/sec-getclassenvironment-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

GetClassEnvironment ( )

3 |

The abstract operation GetClassEnvironment takes no arguments. It finds the Environment Record that currently supplies the binding of the keyword `class` for a |ClassProperty|. It performs the following steps when called:

4 | 5 | 1. Let _env_ be GetThisEnvironment(). 6 | 1. Let _exists_ be _env_.HasClassBinding(). 7 | 1. If _exists_ is *true*, return _env_. 8 | 1. Return *undefined*. 9 | 10 |
11 | -------------------------------------------------------------------------------- /spec/sec-makemethod-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

MakeMethod ( _F_, _homeObject_, _classObject_ )

3 |

The abstract operation MakeMethod takes arguments _F_ and _homeObject_, _homeObject_, and _classObject_. It configures _F_ as a method. It performs the following steps when called:

4 | 5 | 1. Assert: _F_ is an ECMAScript function object. 6 | 1. Assert: Type(_homeObject_) is Object. 7 | 1. Assert: Type(_classObject_) is either Object or Undefined. 8 | 1. Set _F_.[[HomeObject]] to _homeObject_. 9 | 1. Set _F_.[[InitialClassObject]] to _classObject_. 10 | 1. Return NormalCompletion(*undefined*). 11 | 12 |
-------------------------------------------------------------------------------- /spec/sec-static-semantics-static-semantics-assignmenttargettype-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: AssignmentTargetType

3 | 4 | 5 | CallExpression : 6 | CallExpression `[` Expression `]` 7 | CallExpression `.` IdentifierName 8 | 9 | MemberExpression : 10 | MemberExpression `[` Expression `]` 11 | MemberExpression `.` IdentifierName 12 | SuperProperty 13 | ClassProperty 14 | 15 | 16 | 1. Return ~simple~. 17 | 18 |
-------------------------------------------------------------------------------- /spec/sec-static-semantics-static-semantics-isidentifierref-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: IsIdentifierRef

3 | 4 | 5 | MemberExpression : 6 | MemberExpression `[` Expression `]` 7 | MemberExpression `.` IdentifierName 8 | MemberExpression TemplateLiteral 9 | SuperProperty 10 | ClassProperty 11 | MetaProperty 12 | `new` MemberExpression Arguments 13 | 14 | NewExpression : 15 | `new` NewExpression 16 | 17 | LeftHandSideExpression : 18 | CallExpression 19 | OptionalExpression 20 | 21 | 22 | 1. Return *false*. 23 | 24 |
-------------------------------------------------------------------------------- /spec/sec-static-semantics-static-semantics-isfunctiondefinition-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: IsFunctionDefinition

3 | 4 | 5 | MemberExpression : 6 | MemberExpression `[` Expression `]` 7 | MemberExpression `.` IdentifierName 8 | MemberExpression TemplateLiteral 9 | SuperProperty 10 | ClassProperty 11 | MetaProperty 12 | `new` MemberExpression Arguments 13 | 14 | NewExpression : 15 | `new` NewExpression 16 | 17 | LeftHandSideExpression : 18 | CallExpression 19 | OptionalExpression 20 | 21 | 22 | 1. Return *false*. 23 | 24 |
25 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const del = require("del"); 2 | const gulp = require("gulp"); 3 | const emu = require("gulp-emu"); 4 | const gls = require("gulp-live-server"); 5 | const spawn = require("child_process").spawn; 6 | 7 | const clean = () => del("docs/**/*"); 8 | gulp.task("clean", clean); 9 | 10 | const build = () => gulp 11 | .src(["spec/index.html"]) 12 | .pipe(emu()) 13 | .pipe(gulp.dest("docs")); 14 | gulp.task("build", build); 15 | 16 | const watch = () => gulp 17 | .watch(["spec/**/*"], build); 18 | gulp.task("watch", watch); 19 | 20 | const serve = () => { 21 | const server = gls.static("docs", 8080); 22 | const promise = server.start(); 23 | gulp.watch(["docs/**/*"], file => server.notify(file)); 24 | return promise; 25 | }; 26 | gulp.task("start", gulp.parallel(watch, serve)); 27 | gulp.task("default", build); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proposal-class-access-expressions", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "ECMAScript 'class'-property access expressions", 6 | "homepage": "https://github.com/tc39/proposal-class-access-expressions#readme", 7 | "author": { 8 | "name": "Ron Buckton", 9 | "email": "ron.buckton@microsoft.com" 10 | }, 11 | "keywords": [ 12 | "javascript", 13 | "ecmascript" 14 | ], 15 | "scripts": { 16 | "build": "gulp build", 17 | "start": "gulp start" 18 | }, 19 | "license": "SEE LICENSE IN https://tc39.github.io/ecma262/#sec-copyright-and-software-license", 20 | "devDependencies": { 21 | "del": "^5.1.0", 22 | "ecmarkup": "^4.1.2", 23 | "gulp": "^4.0.2", 24 | "gulp-emu": "^1.3.2", 25 | "gulp-live-server": "0.0.31" 26 | }, 27 | "repository": "tc39/proposal-class-access-expressions" 28 | } 29 | -------------------------------------------------------------------------------- /spec/sec-arrow-function-definitions-static-semantics-contains-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Contains

3 |

With parameter _symbol_.

4 | 5 | ArrowFunction : ArrowParameters `=>` ConciseBody 6 | 7 | 1. If _symbol_ is not one of |NewTarget|, |SuperProperty|, |SuperCall|, |ClassProperty|, `super`, `class` or `this`, return *false*. 8 | 1. If |ArrowParameters| Contains _symbol_ is *true*, return *true*. 9 | 1. Return |ConciseBody| Contains _symbol_. 10 | 11 | 12 |

Normally, Contains does not look inside most function forms. However, Contains is used to detect `new.target`, `this`, and `super`, `super` and `class`-property usage within an |ArrowFunction|.

13 |
14 |
15 | -------------------------------------------------------------------------------- /spec/sec-static-semantics-static-semantics-isdestructuring-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: IsDestructuring

3 | 4 | MemberExpression : PrimaryExpression 5 | 6 | 1. If |PrimaryExpression| is either an |ObjectLiteral| or an |ArrayLiteral|, return *true*. 7 | 1. Return *false*. 8 | 9 | 10 | MemberExpression : 11 | MemberExpression `[` Expression `]` 12 | MemberExpression `.` IdentifierName 13 | MemberExpression TemplateLiteral 14 | SuperProperty 15 | ClassProperty 16 | MetaProperty 17 | `new` MemberExpression Arguments 18 | 19 | NewExpression : 20 | `new` NewExpression 21 | 22 | LeftHandSideExpression : 23 | CallExpression 24 | OptionalExpression 25 | 26 | 27 | 1. Return *false*. 28 | 29 |
-------------------------------------------------------------------------------- /spec/sec-newfunctionenvironment-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

NewFunctionEnvironment ( _F_, _newTarget_ )

3 |

The abstract operation NewFunctionEnvironment takes arguments _F_ and _newTarget_. It performs the following steps when called:

4 | 5 | 1. Assert: _F_ is an ECMAScript function. 6 | 1. Assert: Type(_newTarget_) is Undefined or Object. 7 | 1. Let _env_ be a new function Environment Record containing no bindings. 8 | 1. Set _env_.[[FunctionObject]] to _F_. 9 | 1. If _F_.[[ThisMode]] is ~lexical~, set _env_.[[ThisBindingStatus]] to ~lexical~. 10 | 1. Else, set _env_.[[ThisBindingStatus]] to ~uninitialized~. 11 | 1. Let _home_ be _F_.[[HomeObject]]. 12 | 1. Set _env_.[[HomeObject]] to _home_. 13 | 1. Let _classObject_ be _F_.[[InitialClassObject]]. 14 | 1. Set _env_.[[InitialClassObject]] to _classObject_. 15 | 1. Set _env_.[[NewTarget]] to _newTarget_. 16 | 1. Set _env_.[[OuterEnv]] to _F_.[[Environment]]. 17 | 1. Return _env_. 18 | 19 |
20 | -------------------------------------------------------------------------------- /spec/sec-runtime-semantics-definemethod-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: DefineMethod

3 |

With parameter _object_ and optional parameter _functionPrototype_parameters _functionPrototype_ and _classObject_.

4 | MethodDefinition : PropertyName `(` UniqueFormalParameters `)` `{` FunctionBody `}` 5 | 6 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 7 | 1. ReturnIfAbrupt(_propKey_). 8 | 1. Let _scope_ be the running execution context's LexicalEnvironment. 9 | 1. If _functionPrototype_ is present, then 10 | 1. Let _prototype_ be _functionPrototype_. 11 | 1. Else, 12 | 1. Let _prototype_ be %Function.prototype%. 13 | 1. Let _sourceText_ be the source text matched by |MethodDefinition|. 14 | 1. Let _closure_ be OrdinaryFunctionCreate(_prototype_, _sourceText_, |UniqueFormalParameters|, |FunctionBody|, ~non-lexical-this~, _scope_). 15 | 1. Perform MakeMethod(_closure_, _object_, _classObject_). 16 | 1. Return the Record { [[Key]]: _propKey_, [[Closure]]: _closure_ }. 17 | 18 |
-------------------------------------------------------------------------------- /spec/sec-async-function-definitions-PropertyDefinitionEvaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: PropertyDefinitionEvaluation

3 |

With parameters _object_ and _enumerable_, _enumerable_, and optional parameter _classObject_.

4 | 5 | AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` 6 | 7 | 8 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 9 | 1. ReturnIfAbrupt(_propKey_). 10 | 1. Let _scope_ be the LexicalEnvironment of the running execution context. 11 | 1. Let _sourceText_ be the source text matched by |AsyncMethod|. 12 | 1. Let _closure_ be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, _sourceText_, |UniqueFormalParameters|, |AsyncFunctionBody|, ~non-lexical-this~, _scope_). 13 | 1. Perform ! MakeMethod(_closure_, _object_, _classObject_). 14 | 1. Perform ! SetFunctionName(_closure_, _propKey_). 15 | 1. Let _desc_ be the PropertyDescriptor { [[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. 16 | 1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). 17 | 18 |
-------------------------------------------------------------------------------- /spec/sec-async-arrow-function-definitions-static-semantics-Contains-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Contains

3 |

With parameter _symbol_.

4 | 5 | AsyncArrowFunction : `async` AsyncArrowBindingIdentifier `=>` AsyncConciseBody 6 | 7 | 8 | 1. If _symbol_ is not one of |NewTarget|, |SuperProperty|, |SuperCall|, |ClassProperty|, `super`, `class`, or `this`, return *false*. 9 | 1. Return |AsyncConciseBody| Contains _symbol_. 10 | 11 | 12 | AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead `=>` AsyncConciseBody 13 | 14 | 15 | 1. If _symbol_ is not one of |NewTarget|, |SuperProperty|, |SuperCall|, |ClassProperty|, `super`, `class`, or `this`, return *false*. 16 | 1. Let _head_ be CoveredAsyncArrowHead of |CoverCallExpressionAndAsyncArrowHead|. 17 | 1. If _head_ Contains _symbol_ is *true*, return *true*. 18 | 1. Return |AsyncConciseBody| Contains _symbol_. 19 | 20 | Normally, Contains does not look inside most function forms. However, Contains is used to detect `new.target`, `this`, and `super`, `super`, and `class`-property usage within an AsyncArrowFunction. 21 |
22 | -------------------------------------------------------------------------------- /spec/sec-static-semantics-static-semantics-contains-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Contains

3 |

With parameter _symbol_.

4 | 5 | MemberExpression : MemberExpression `.` IdentifierName 6 | 7 | 1. If |MemberExpression| Contains _symbol_ is *true*, return *true*. 8 | 1. Return *false*. 9 | 10 | SuperProperty : `super` `.` IdentifierName 11 | 12 | 1. If _symbol_ is the |ReservedWord| `super`, return *true*. 13 | 1. Return *false*. 14 | 15 | ClassProperty : `class` `.` IdentifierName 16 | 17 | 1. If _symbol_ is the |ReservedWord| `class`, return *true*. 18 | 1. Return *false*. 19 | 20 | CallExpression : CallExpression `.` IdentifierName 21 | 22 | 1. If |CallExpression| Contains _symbol_ is *true*, return *true*. 23 | 1. Return *false*. 24 | 25 | OptionalChain : `?.` IdentifierName 26 | 27 | 1. Return *false*. 28 | 29 | OptionalChain : OptionalChain `.` IdentifierName 30 | 31 | 1. If |OptionalChain| Contains _symbol_ is *true*, return *true*. 32 | 1. Return *false*. 33 | 34 |
35 | -------------------------------------------------------------------------------- /spec/sec-asyncgenerator-definitions-propertydefinitionevaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: PropertyDefinitionEvaluation

3 |

With parameter _object_ and _enumerable_, _enumerable_, and optional parameter _classObject_.

4 | 5 | AsyncGeneratorMethod : `async` `*` PropertyName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` 6 | 7 | 8 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 9 | 1. ReturnIfAbrupt(_propKey_). 10 | 1. Let _scope_ be the running execution context's LexicalEnvironment. 11 | 1. Let _sourceText_ be the source text matched by |AsyncGeneratorMethod|. 12 | 1. Let _closure_ be ! OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, _sourceText_, |UniqueFormalParameters|, |AsyncGeneratorBody|, ~non-lexical-this~, _scope_). 13 | 1. Perform ! MakeMethod(_closure_, _object_, _classObject_). 14 | 1. Perform ! SetFunctionName(_closure_, _propKey_). 15 | 1. Let _prototype_ be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%). 16 | 1. Perform ! DefinePropertyOrThrow(_closure_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). 17 | 1. Let _desc_ be PropertyDescriptor { [[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. 18 | 1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). 19 | 20 |
-------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Ron Buckton, Ecma International 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /spec/sec-left-hand-side-expressions-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Left-Hand-Side Expressions

3 |

Syntax

4 | 5 | MemberExpression[Yield, Await] : 6 | PrimaryExpression[?Yield, ?Await] 7 | MemberExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]` 8 | MemberExpression[?Yield, ?Await] `.` IdentifierName 9 | MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] 10 | SuperProperty[?Yield, ?Await] 11 | ClassProperty[?Yield, ?Await] 12 | MetaProperty 13 | `new` MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] 14 | 15 | 16 | ClassProperty[Yield, Await] : 17 | `class` `[` Expression[+In, ?Yield, ?Await] `]` 18 | `class` `.` IdentifierName 19 | `class` `.` PrivateIdentifier 20 | 21 | 22 | 23 |

Static Semantics

24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 |
33 | -------------------------------------------------------------------------------- /spec/sec-generator-function-definitions-runtime-semantics-propertydefinitionevaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: PropertyDefinitionEvaluation

3 |

With parameters _object_ and _enumerable_, _enumerable_, and optional parameter _classObject_.

4 | 5 | GeneratorMethod : `*` PropertyName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` 6 | 7 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 8 | 1. ReturnIfAbrupt(_propKey_). 9 | 1. Let _scope_ be the running execution context's LexicalEnvironment. 10 | 1. Let _sourceText_ be the source text matched by |GeneratorMethod|. 11 | 1. Let _closure_ be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, _sourceText_, |UniqueFormalParameters|, |GeneratorBody|, ~non-lexical-this~, _scope_). 12 | 1. Perform MakeMethod(_closure_, _object_, _classObject_). 13 | 1. Perform SetFunctionName(_closure_, _propKey_). 14 | 1. Let _prototype_ be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%). 15 | 1. Perform DefinePropertyOrThrow(_closure_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). 16 | 1. Let _desc_ be the PropertyDescriptor { [[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. 17 | 1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). 18 | 19 |
-------------------------------------------------------------------------------- /spec/sec-arrow-function-definitions-runtime-semantics-namedevaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: NamedEvaluation

3 |

With parameter _name_.

4 | ArrowFunction : ArrowParameters `=>` ConciseBody 5 | 6 | 1. Let _scope_ be the LexicalEnvironment of the running execution context. 7 | 1. Let _sourceText_ be the source text matched by |ArrowFunction|. 8 | 1. Let _parameters_ be CoveredFormalsList of |ArrowParameters|. 9 | 1. [id="step-arrowfunction-evaluation-functioncreate"] Let _closure_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, _parameters_, |ConciseBody|, ~lexical-this~, _scope_). 10 | 1. Perform SetFunctionName(_closure_, _name_). 11 | 1. Return _closure_. 12 | 13 | 14 |

An |ArrowFunction| does not define local bindings for `arguments`, `super`, `class`, `this`, or `new.target`. Any reference to `arguments`, `super`, `class`, `this`, or `new.target` within an |ArrowFunction| must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function. Even though an |ArrowFunction| may contain references to `super`, the function object created in step is not made into a method by performing MakeMethod. An |ArrowFunction| that references `super` or `class` is always contained within a non-|ArrowFunction| and the necessary state to implement `super` or `class` is accessible via the _scope_ that is captured by the function object of the |ArrowFunction|.

15 |
16 |
-------------------------------------------------------------------------------- /spec/sec-class-keyword-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

The `class` keyword

3 | 4 | 5 |

Runtime Semantics: Evaluation

6 | 7 | ClassProperty : `class` `[` Expression `]` 8 | 9 | 1. Let _env_ be GetClassEnvironment(). 10 | 1. If _env_ is *undefined* throw a *TypeError* exception. 11 | 1. Let _classObject_ be ? _env_.GetClassBinding(). 12 | 1. If _classObject_ is *undefined* throw a *TypeError* exception. 13 | 1. If the code matched by this |ClassProperty| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*. 14 | 1. Return ? EvaluatePropertyAccessWithExpressionKey(_classObject_, |Expression|, _strict_). 15 | 16 | 17 | ClassProperty : `class` `.` IdentifierName 18 | 19 | 1. Let _env_ be GetClassEnvironment(). 20 | 1. If _env_ is *undefined* throw a *TypeError* exception. 21 | 1. Let _classObject_ be ? _env_.GetClassBinding(). 22 | 1. If _classObject_ is *undefined* throw a *TypeError* exception. 23 | 1. If the code matched by this |ClassProperty| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*. 24 | 1. Return ? EvaluatePropertyAccessWithIdentifierKey(_classObject_, |IdentifierName|, _strict_). 25 | 26 | 27 | ClassProperty : `class` `.` PrivateIdentifier 28 | 29 | 1. Let _env_ be GetClassEnvironment(). 30 | 1. If _env_ is *undefined* throw a *TypeError* exception. 31 | 1. Let _classObject_ be ? _env_.GetClassBinding(). 32 | 1. If _classObject_ is *undefined* throw a *TypeError* exception. 33 | 1. Return ? MakePrivateReference(_classObject_, |PrivateIdentifier|). 34 | 35 |
36 |
-------------------------------------------------------------------------------- /spec/sec-function-definitions-static-semantics-early-errors-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Early Errors

3 | 4 | FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` 5 | 6 | FunctionDeclaration : `function` `(` FormalParameters `)` `{` FunctionBody `}` 7 | 8 | FunctionExpression : `function` BindingIdentifier? `(` FormalParameters `)` `{` FunctionBody `}` 9 | 10 | 42 |
-------------------------------------------------------------------------------- /spec/sec-scripts-static-semantics-early-errors-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Early Errors

3 | Script : ScriptBody 4 | 12 | ScriptBody : StatementList 13 | 33 |
-------------------------------------------------------------------------------- /spec/sec-async-function-definitions-static-semantics-early-errors-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Early Errors

3 | 4 | AsyncFunctionDeclaration : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}` 5 | 6 | AsyncFunctionDeclaration : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}` 7 | 8 | AsyncFunctionExpression : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}` 9 | 10 | AsyncFunctionExpression : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}` 11 | 12 | 25 |
26 | -------------------------------------------------------------------------------- /spec/sec-module-semantics-static-semantics-early-errors-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Early Errors

3 | ModuleBody : ModuleItemList 4 | 36 | 37 |

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.

38 |
39 |
40 | -------------------------------------------------------------------------------- /spec/sec-async-generator-function-definitions-static-semantics-early-errors-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Early Errors

3 | 4 | AsyncGeneratorDeclaration : `async` `function` `*` BindingIdentifier `(` FormalParameters `)` `{` AsyncGeneratorBody `}` 5 | 6 | AsyncGeneratorDeclaration : `async` `function` `*` `(` FormalParameters `)` `{` AsyncGeneratorBody `}` 7 | 8 | AsyncGeneratorExpression : `async` `function` `*` BindingIdentifier? `(` FormalParameters `)` `{` AsyncGeneratorBody `}` 9 | 10 | 24 |
-------------------------------------------------------------------------------- /spec/sec-generator-function-definitions-static-semantics-early-errors-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Static Semantics: Early Errors

3 | 4 | GeneratorDeclaration : `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}` 5 | 6 | GeneratorDeclaration : `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}` 7 | 8 | GeneratorExpression : `function` `*` BindingIdentifier? `(` FormalParameters `)` `{` GeneratorBody `}` 9 | 10 | 45 |
46 | -------------------------------------------------------------------------------- /spec/sec-method-definitions-runtime-semantics-propertydefinitionevaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: PropertyDefinitionEvaluation

3 |

With parameters _object_ and _enumerable_, _enumerable_, and optional parameter _classObject_.

4 | 5 | MethodDefinition : PropertyName `(` UniqueFormalParameters `)` `{` FunctionBody `}` 6 | 7 | 1. Let _methodDef_ be ? DefineMethod of |MethodDefinition| with argument _object_arguments _object_, *undefined*, and _classObject_. 8 | 1. Perform SetFunctionName(_methodDef_.[[Closure]], _methodDef_.[[Key]]). 9 | 1. Let _desc_ be the PropertyDescriptor { [[Value]]: _methodDef_.[[Closure]], [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. 10 | 1. Return ? DefinePropertyOrThrow(_object_, _methodDef_.[[Key]], _desc_). 11 | 12 | MethodDefinition : `get` PropertyName `(` `)` `{` FunctionBody `}` 13 | 14 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 15 | 1. ReturnIfAbrupt(_propKey_). 16 | 1. Let _scope_ be the running execution context's LexicalEnvironment. 17 | 1. Let _sourceText_ be the source text matched by |MethodDefinition|. 18 | 1. Let _formalParameterList_ be an instance of the production FormalParameters : [empty]. 19 | 1. Let _closure_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, _formalParameterList_, |FunctionBody|, ~non-lexical-this~, _scope_). 20 | 1. Perform MakeMethod(_closure_, _object_, _classObject_). 21 | 1. Perform SetFunctionName(_closure_, _propKey_, *"get"*). 22 | 1. Let _desc_ be the PropertyDescriptor { [[Get]]: _closure_, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. 23 | 1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). 24 | 25 | MethodDefinition : `set` PropertyName `(` PropertySetParameterList `)` `{` FunctionBody `}` 26 | 27 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 28 | 1. ReturnIfAbrupt(_propKey_). 29 | 1. Let _scope_ be the running execution context's LexicalEnvironment. 30 | 1. Let _sourceText_ be the source text matched by |MethodDefinition|. 31 | 1. Let _closure_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, |PropertySetParameterList|, |FunctionBody|, ~non-lexical-this~, _scope_). 32 | 1. Perform MakeMethod(_closure_, _object_, _classObject_). 33 | 1. Perform SetFunctionName(_closure_, _propKey_, *"set"*). 34 | 1. Let _desc_ be the PropertyDescriptor { [[Set]]: _closure_, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. 35 | 1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_). 36 | 37 |
38 | -------------------------------------------------------------------------------- /spec/sec-object-initializer-runtime-semantics-propertydefinitionevaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: PropertyDefinitionEvaluation

3 |

With parameters _object_ and _enumerable_, _enumerable_, and optional parameter _classObject_.

4 | 5 | PropertyDefinitionList : PropertyDefinitionList `,` PropertyDefinition 6 | 7 | 1. Assert: _classObject_ is not present or Type(_classObject_) is Undefined. 8 | 1. Perform ? PropertyDefinitionEvaluation of |PropertyDefinitionList| with arguments _object_ and _enumerable_. 9 | 1. Return the result of performing PropertyDefinitionEvaluation of |PropertyDefinition| with arguments _object_ and _enumerable_. 10 | 11 | PropertyDefinition : `...` AssignmentExpression 12 | 13 | 1. Assert: _classObject_ is not present or Type(_classObject_) is Undefined. 14 | 1. Let _exprValue_ be the result of evaluating |AssignmentExpression|. 15 | 1. Let _fromValue_ be ? GetValue(_exprValue_). 16 | 1. Let _excludedNames_ be a new empty List. 17 | 1. Return ? CopyDataProperties(_object_, _fromValue_, _excludedNames_). 18 | 19 | PropertyDefinition : IdentifierReference 20 | 21 | 1. Assert: _classObject_ is not present or Type(_classObject_) is Undefined. 22 | 1. Let _propName_ be StringValue of |IdentifierReference|. 23 | 1. Let _exprValue_ be the result of evaluating |IdentifierReference|. 24 | 1. Let _propValue_ be ? GetValue(_exprValue_). 25 | 1. Assert: _enumerable_ is *true*. 26 | 1. Assert: _object_ is an ordinary, extensible object with no non-configurable properties. 27 | 1. Return ! CreateDataPropertyOrThrow(_object_, _propName_, _propValue_). 28 | 29 | PropertyDefinition : PropertyName `:` AssignmentExpression 30 | 31 | 1. Assert: _classObject_ is not present or Type(_classObject_) is Undefined. 32 | 1. Let _propKey_ be the result of evaluating |PropertyName|. 33 | 1. ReturnIfAbrupt(_propKey_). 34 | 1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true*, then 35 | 1. Let _propValue_ be NamedEvaluation of |AssignmentExpression| with argument _propKey_. 36 | 1. Else, 37 | 1. Let _exprValueRef_ be the result of evaluating |AssignmentExpression|. 38 | 1. Let _propValue_ be ? GetValue(_exprValueRef_). 39 | 1. Assert: _enumerable_ is *true*. 40 | 1. Assert: _object_ is an ordinary, extensible object with no non-configurable properties. 41 | 1. Return ! CreateDataPropertyOrThrow(_object_, _propKey_, _propValue_). 42 | 43 | 44 |

An alternative semantics for this production is given in .

45 |
46 |
-------------------------------------------------------------------------------- /spec/sec-expression-rules-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Expression Rules

3 | 4 |

A potential tail position call that is immediately followed by return GetValue of the call result is also a possible tail position call. Function calls cannot return reference values, so such a GetValue operation will always return the same value as the actual function call result.

5 |
6 | 7 | AssignmentExpression : 8 | YieldExpression 9 | ArrowFunction 10 | AsyncArrowFunction 11 | LeftHandSideExpression `=` AssignmentExpression 12 | LeftHandSideExpression AssignmentOperator AssignmentExpression 13 | LeftHandSideExpression `&&=` AssignmentExpression 14 | LeftHandSideExpression `||=` AssignmentExpression 15 | LeftHandSideExpression `??=` AssignmentExpression 16 | 17 | BitwiseANDExpression : BitwiseANDExpression `&` EqualityExpression 18 | 19 | BitwiseXORExpression : BitwiseXORExpression `^` BitwiseANDExpression 20 | 21 | BitwiseORExpression : BitwiseORExpression `|` BitwiseXORExpression 22 | 23 | EqualityExpression : 24 | EqualityExpression `==` RelationalExpression 25 | EqualityExpression `!=` RelationalExpression 26 | EqualityExpression `===` RelationalExpression 27 | EqualityExpression `!==` RelationalExpression 28 | 29 | RelationalExpression : 30 | RelationalExpression `<` ShiftExpression 31 | RelationalExpression `>` ShiftExpression 32 | RelationalExpression `<=` ShiftExpression 33 | RelationalExpression `>=` ShiftExpression 34 | RelationalExpression `instanceof` ShiftExpression 35 | RelationalExpression `in` ShiftExpression 36 | 37 | ShiftExpression : 38 | ShiftExpression `<<` AdditiveExpression 39 | ShiftExpression `>>` AdditiveExpression 40 | ShiftExpression `>>>` AdditiveExpression 41 | 42 | AdditiveExpression : 43 | AdditiveExpression `+` MultiplicativeExpression 44 | AdditiveExpression `-` MultiplicativeExpression 45 | 46 | MultiplicativeExpression : 47 | MultiplicativeExpression MultiplicativeOperator ExponentiationExpression 48 | 49 | ExponentiationExpression : 50 | UpdateExpression `**` ExponentiationExpression 51 | 52 | UpdateExpression : 53 | LeftHandSideExpression `++` 54 | LeftHandSideExpression `--` 55 | `++` UnaryExpression 56 | `--` UnaryExpression 57 | 58 | UnaryExpression : 59 | `delete` UnaryExpression 60 | `void` UnaryExpression 61 | `typeof` UnaryExpression 62 | `+` UnaryExpression 63 | `-` UnaryExpression 64 | `~` UnaryExpression 65 | `!` UnaryExpression 66 | AwaitExpression 67 | 68 | CallExpression : 69 | SuperCall 70 | CallExpression `[` Expression `]` 71 | CallExpression `.` IdentifierName 72 | 73 | NewExpression : `new` NewExpression 74 | 75 | MemberExpression : 76 | MemberExpression `[` Expression `]` 77 | MemberExpression `.` IdentifierName 78 | SuperProperty 79 | ClassProperty 80 | MetaProperty 81 | `new` MemberExpression Arguments 82 | 83 | PrimaryExpression : 84 | `this` 85 | IdentifierReference 86 | Literal 87 | ArrayLiteral 88 | ObjectLiteral 89 | FunctionExpression 90 | ClassExpression 91 | GeneratorExpression 92 | AsyncFunctionExpression 93 | AsyncGeneratorExpression 94 | RegularExpressionLiteral 95 | TemplateLiteral 96 | 97 | 98 | 1. Return *false*. 99 | 100 |
101 | -------------------------------------------------------------------------------- /spec/sec-runtime-semantics-classdefinitionevaluation-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: ClassDefinitionEvaluation

3 |

With parameters _classBinding_ and _className_.

4 | ClassTail : ClassHeritage? `{` ClassBody? `}` 5 | 6 | 1. Let _env_ be the LexicalEnvironment of the running execution context. 7 | 1. Let _classScope_ be NewDeclarativeEnvironment(_env_). 8 | 1. If _classBinding_ is not *undefined*, then 9 | 1. Perform _classScope_.CreateImmutableBinding(_classBinding_, *true*). 10 | 1. If |ClassHeritage_opt| is not present, then 11 | 1. Let _protoParent_ be %Object.prototype%. 12 | 1. Let _constructorParent_ be %Function.prototype%. 13 | 1. Else, 14 | 1. Set the running execution context's LexicalEnvironment to _classScope_. 15 | 1. Let _superclassRef_ be the result of evaluating |ClassHeritage|. 16 | 1. Set the running execution context's LexicalEnvironment to _env_. 17 | 1. Let _superclass_ be ? GetValue(_superclassRef_). 18 | 1. If _superclass_ is *null*, then 19 | 1. Let _protoParent_ be *null*. 20 | 1. Let _constructorParent_ be %Function.prototype%. 21 | 1. Else if IsConstructor(_superclass_) is *false*, throw a *TypeError* exception. 22 | 1. Else, 23 | 1. Let _protoParent_ be ? Get(_superclass_, *"prototype"*). 24 | 1. If Type(_protoParent_) is neither Object nor Null, throw a *TypeError* exception. 25 | 1. Let _constructorParent_ be _superclass_. 26 | 1. Let _proto_ be ! OrdinaryObjectCreate(_protoParent_). 27 | 1. If |ClassBody_opt| is not present, let _constructor_ be ~empty~. 28 | 1. Else, let _constructor_ be ConstructorMethod of |ClassBody|. 29 | 1. If _constructor_ is ~empty~, then 30 | 1. If |ClassHeritage_opt| is present, then 31 | 1. Set _constructor_ to the result of parsing the source text 32 |
constructor(...args) { super(...args); }
33 | using the syntactic grammar with the goal symbol |MethodDefinition[~Yield, ~Await]|. 34 | 1. Else, 35 | 1. Set _constructor_ to the result of parsing the source text 36 |
constructor() {}
37 | using the syntactic grammar with the goal symbol |MethodDefinition[~Yield, ~Await]|. 38 | 1. Set the running execution context's LexicalEnvironment to _classScope_. 39 | 1. Let _constructorInfo_ be ! DefineMethod of _constructor_ with arguments _proto_ and _constructorParent_. 40 | 1. Let _F_ be _constructorInfo_.[[Closure]]. 41 | 1. Perform SetFunctionName(_F_, _className_). 42 | 1. Perform MakeConstructor(_F_, *false*, _proto_). 43 | 1. If |ClassHeritage_opt| is present, set _F_.[[ConstructorKind]] to ~derived~. 44 | 1. Set _F_.[[InitialClassObject]] to _F_. 45 | 1. Perform MakeClassConstructor(_F_). 46 | 1. Perform CreateMethodProperty(_proto_, *"constructor"*, _F_). 47 | 1. If |ClassBody_opt| is not present, let _methods_ be a new empty List. 48 | 1. Else, let _methods_ be NonConstructorMethodDefinitions of |ClassBody|. 49 | 1. For each |ClassElement| _m_ of _methods_, do 50 | 1. If IsStatic of _m_ is *false*, then 51 | 1. Let _status_ be PropertyDefinitionEvaluation of _m_ with arguments _proto_ and *false*, *false*, and _F_. 52 | 1. Else, 53 | 1. Let _status_ be PropertyDefinitionEvaluation of _m_ with arguments _F_ and *false*, *false*, and _F_. 54 | 1. If _status_ is an abrupt completion, then 55 | 1. Set the running execution context's LexicalEnvironment to _env_. 56 | 1. Return Completion(_status_). 57 | 1. Set the running execution context's LexicalEnvironment to _env_. 58 | 1. If _classBinding_ is not *undefined*, then 59 | 1. Perform _classScope_.InitializeBinding(_classBinding_, _F_). 60 | 1. Return _F_. 61 |
62 |
63 | -------------------------------------------------------------------------------- /spec/sec-performeval-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )

3 |

The abstract operation PerformEval takes arguments _x_, _callerRealm_, _strictCaller_, and _direct_. It performs the following steps when called:

4 | 5 | 1. Assert: If _direct_ is *false*, then _strictCaller_ is also *false*. 6 | 1. If Type(_x_) is not String, return _x_. 7 | 1. Let _evalRealm_ be the current Realm Record. 8 | 1. Perform ? HostEnsureCanCompileStrings(_callerRealm_, _evalRealm_). 9 | 1. Let _inFunction_ be *false*. 10 | 1. Let _inMethod_ be *false*. 11 | 1. Let _inDerivedConstructor_ be *false*. 12 | 1. If _direct_ is *true*, then 13 | 1. Let _thisEnvRec_ be ! GetThisEnvironment(). 14 | 1. If _thisEnvRec_ is a function Environment Record, then 15 | 1. Let _F_ be _thisEnvRec_.[[FunctionObject]]. 16 | 1. Set _inFunction_ to *true*. 17 | 1. Set _inMethod_ to _thisEnvRec_.HasSuperBinding(). 18 | 1. If _F_.[[ConstructorKind]] is ~derived~, set _inDerivedConstructor_ to *true*. 19 | 1. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection: 20 | 1. Let _script_ be the ECMAScript code that is the result of parsing ! StringToCodePoints(_x_), for the goal symbol |Script|. If the parse fails, throw a *SyntaxError* exception. If any early errors are detected, throw a *SyntaxError* exception (but see also clause ). 21 | 1. If _script_ Contains |ScriptBody| is *false*, return *undefined*. 22 | 1. Let _body_ be the |ScriptBody| of _script_. 23 | 1. If _inFunction_ is *false*, and _body_ Contains |NewTarget|, throw a *SyntaxError* exception. 24 | 1. If _inMethod_ is *false*, and _body_ Contains |SuperProperty|, throw a *SyntaxError* exception. 25 | 1. If _inMethod_ is *false*, and _body_ Contains |ClassProperty|, throw a *SyntaxError* exception. 26 | 1. If _inDerivedConstructor_ is *false*, and _body_ Contains |SuperCall|, throw a *SyntaxError* exception. 27 | 1. If _strictCaller_ is *true*, let _strictEval_ be *true*. 28 | 1. Else, let _strictEval_ be IsStrict of _script_. 29 | 1. Let _runningContext_ be the running execution context. 30 | 1. NOTE: If _direct_ is *true*, _runningContext_ will be the execution context that performed the direct eval. If _direct_ is *false*, _runningContext_ will be the execution context for the invocation of the `eval` function. 31 | 1. If _direct_ is *true*, then 32 | 1. Let _lexEnv_ be NewDeclarativeEnvironment(_runningContext_'s LexicalEnvironment). 33 | 1. Let _varEnv_ be _runningContext_'s VariableEnvironment. 34 | 1. Else, 35 | 1. Let _lexEnv_ be NewDeclarativeEnvironment(_evalRealm_.[[GlobalEnv]]). 36 | 1. Let _varEnv_ be _evalRealm_.[[GlobalEnv]]. 37 | 1. If _strictEval_ is *true*, set _varEnv_ to _lexEnv_. 38 | 1. If _runningContext_ is not already suspended, suspend _runningContext_. 39 | 1. Let _evalContext_ be a new ECMAScript code execution context. 40 | 1. Set _evalContext_'s Function to *null*. 41 | 1. Set _evalContext_'s Realm to _evalRealm_. 42 | 1. Set _evalContext_'s ScriptOrModule to _runningContext_'s ScriptOrModule. 43 | 1. Set _evalContext_'s VariableEnvironment to _varEnv_. 44 | 1. Set _evalContext_'s LexicalEnvironment to _lexEnv_. 45 | 1. Push _evalContext_ onto the execution context stack; _evalContext_ is now the running execution context. 46 | 1. Let _result_ be EvalDeclarationInstantiation(_body_, _varEnv_, _lexEnv_, _strictEval_). 47 | 1. If _result_.[[Type]] is ~normal~, then 48 | 1. Set _result_ to the result of evaluating _body_. 49 | 1. If _result_.[[Type]] is ~normal~ and _result_.[[Value]] is ~empty~, then 50 | 1. Set _result_ to NormalCompletion(*undefined*). 51 | 1. Suspend _evalContext_ and remove it from the execution context stack. 52 | 1. Resume the context that is now on the top of the execution context stack as the running execution context. 53 | 1. Return Completion(_result_). 54 | 55 | 56 |

The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if the calling context is evaluating formal parameter initializers or if either the code of the calling context or the eval code is strict mode code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code. Bindings introduced by `let`, `const`, or `class` declarations are always instantiated in a new LexicalEnvironment.

57 |
58 |
59 | -------------------------------------------------------------------------------- /spec/sec-the-environment-record-type-hierarchy-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

The Environment Record Type Hierarchy

3 | 4 |

The Environment Record abstract class includes the abstract specification methods defined in . These abstract methods have distinct concrete algorithms for each of the concrete subclasses.

5 | 6 | 7 | 8 | 9 | 12 | 15 | 16 | 17 | 20 | 23 | 24 | 25 | 28 | 31 | 32 | 33 | 36 | 39 | 40 | 41 | 44 | 47 | 48 | 49 | 52 | 55 | 56 | 57 | 60 | 63 | 64 | 65 | 68 | 71 | 72 | 73 | 76 | 79 | 80 | 81 | 84 | 87 | 88 | 89 | 92 | 95 | 96 | 97 | 100 | 103 | 104 | 105 |
10 | Method 11 | 13 | Purpose 14 |
18 | HasBinding(N) 19 | 21 | Determine if an Environment Record has a binding for the String value _N_. Return *true* if it does and *false* if it does not. 22 |
26 | CreateMutableBinding(N, D) 27 | 29 | Create a new but uninitialized mutable binding in an Environment Record. The String value _N_ is the text of the bound name. If the Boolean argument _D_ is *true* the binding may be subsequently deleted. 30 |
34 | CreateImmutableBinding(N, S) 35 | 37 | Create a new but uninitialized immutable binding in an Environment Record. The String value _N_ is the text of the bound name. If _S_ is *true* then attempts to set it after it has been initialized will always throw an exception, regardless of the strict mode setting of operations that reference that binding. 38 |
42 | InitializeBinding(N, V) 43 | 45 | Set the value of an already existing but uninitialized binding in an Environment Record. The String value _N_ is the text of the bound name. _V_ is the value for the binding and is a value of any ECMAScript language type. 46 |
50 | SetMutableBinding(N, V, S) 51 | 53 | Set the value of an already existing mutable binding in an Environment Record. The String value _N_ is the text of the bound name. _V_ is the value for the binding and may be a value of any ECMAScript language type. _S_ is a Boolean flag. If _S_ is *true* and the binding cannot be set throw a *TypeError* exception. 54 |
58 | GetBindingValue(N, S) 59 | 61 | Returns the value of an already existing binding from an Environment Record. The String value _N_ is the text of the bound name. _S_ is used to identify references originating in strict mode code or that otherwise require strict mode reference semantics. If _S_ is *true* and the binding does not exist throw a *ReferenceError* exception. If the binding exists but is uninitialized a *ReferenceError* is thrown, regardless of the value of _S_. 62 |
66 | DeleteBinding(N) 67 | 69 | Delete a binding from an Environment Record. The String value _N_ is the text of the bound name. If a binding for _N_ exists, remove the binding and return *true*. If the binding exists but cannot be removed return *false*. If the binding does not exist return *true*. 70 |
74 | HasThisBinding() 75 | 77 | Determine if an Environment Record establishes a `this` binding. Return *true* if it does and *false* if it does not. 78 |
82 | HasSuperBinding() 83 | 85 | Determine if an Environment Record establishes a `super` method binding. Return *true* if it does and *false* if it does not. 86 |
90 | HasClassBinding() 91 | 93 | Determine if an Environment Record establishes a `class` binding. Return *true* if it does and *false* if it does not. 94 |
98 | WithBaseObject() 99 | 101 | If this Environment Record is associated with a `with` statement, return the with object. Otherwise, return *undefined*. 102 |
106 |
107 | 108 | 109 | 110 | 111 |
-------------------------------------------------------------------------------- /spec/sec-ecmascript-function-objects-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

ECMAScript Function Objects

3 |

ECMAScript function objects encapsulate parameterized ECMAScript code closed over a lexical environment and support the dynamic evaluation of that code. An ECMAScript function object is an ordinary object and has the same internal slots and the same internal methods as other ordinary objects. The code of an ECMAScript function object may be either strict mode code () or non-strict code. An ECMAScript function object whose code is strict mode code is called a strict function. One whose code is not strict mode code is called a non-strict function.

4 |

In addition to [[Extensible]] and [[Prototype]], ECMAScript function objects also have the internal slots listed in .

5 | 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 23 | 26 | 29 | 30 | 31 | 34 | 37 | 40 | 41 | 42 | 45 | 48 | 51 | 52 | 53 | 56 | 59 | 62 | 63 | 64 | 67 | 70 | 73 | 74 | 75 | 78 | 81 | 84 | 85 | 86 | 89 | 92 | 95 | 96 | 97 | 100 | 103 | 106 | 107 | 108 | 111 | 114 | 117 | 118 | 119 | 122 | 125 | 128 | 129 | 130 | 133 | 136 | 139 | 140 | 141 | 144 | 147 | 150 | 151 | 152 |
10 | Internal Slot 11 | 13 | Type 14 | 16 | Description 17 |
21 | [[Environment]] 22 | 24 | Environment Record 25 | 27 | The Environment Record that the function was closed over. Used as the outer environment when evaluating the code of the function. 28 |
32 | [[FormalParameters]] 33 | 35 | Parse Node 36 | 38 | The root parse node of the source text that defines the function's formal parameter list. 39 |
43 | [[ECMAScriptCode]] 44 | 46 | Parse Node 47 | 49 | The root parse node of the source text that defines the function's body. 50 |
54 | [[ConstructorKind]] 55 | 57 | ~base~ | ~derived~ 58 | 60 | Whether or not the function is a derived class constructor. 61 |
65 | [[Realm]] 66 | 68 | Realm Record 69 | 71 | The realm in which the function was created and which provides any intrinsic objects that are accessed when evaluating the function. 72 |
76 | [[ScriptOrModule]] 77 | 79 | Script Record or Module Record 80 | 82 | The script or module in which the function was created. 83 |
87 | [[ThisMode]] 88 | 90 | ~lexical~ | ~strict~ | ~global~ 91 | 93 | Defines how `this` references are interpreted within the formal parameters and code body of the function. ~lexical~ means that `this` refers to the *this* value of a lexically enclosing function. ~strict~ means that the *this* value is used exactly as provided by an invocation of the function. ~global~ means that a *this* value of *undefined* or *null* is interpreted as a reference to the global object, and any other *this* value is first passed to ToObject. 94 |
98 | [[Strict]] 99 | 101 | Boolean 102 | 104 | *true* if this is a strict function, *false* if this is a non-strict function. 105 |
109 | [[HomeObject]] 110 | 112 | Object 113 | 115 | If the function uses `super`, this is the object whose [[GetPrototypeOf]] provides the object where `super` property lookups begin. 116 |
120 | [[InitialClassObject]] 121 | 123 | Object | *undefined* 124 | 126 | If the function has `class` property access, this is the function object where `class` property lookups begin. 127 |
131 | [[SourceText]] 132 | 134 | sequence of Unicode code points 135 | 137 | The source text that defines the function. 138 |
142 | [[IsClassConstructor]] 143 | 145 | Boolean 146 | 148 | Indicates whether the function is a class constructor. (If *true*, invoking the function's [[Call]] will immediately throw a *TypeError* exception.) 149 |
153 |
154 | 155 |
-------------------------------------------------------------------------------- /spec/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
  6 | title: ECMAScript 'class'-property access expressions
  7 | stage: 1
  8 | contributors: Ron Buckton, Ecma International
  9 | 
10 | 11 | 12 |

Introduction

13 | 14 |
15 | 16 | 17 |

Executable Code and Execution Contexts

18 | 19 |

Environment Records

20 | 21 | 22 |

Environment Record Operations

23 | 24 |
25 |
26 | 27 |

Execution Contexts

28 | 29 |
30 |
31 | 32 | 33 |

Ordinary and Exotic Object Behaviors

34 | 35 |
36 | 37 | 38 |

ECMAScript Language: Expressions

39 | 40 |

Primary Expression

41 | 42 |

Object Initializer

43 | 44 |
45 |
46 | 47 |
48 | 49 | 50 |

ECMAScript Language: Functions and Classes

51 | 52 |

Function Definitions

53 | 54 |
55 | 56 |

Arrow Function Definitions

57 | 58 | 59 |
60 | 61 |

Method Definitions

62 | 63 | 64 |
65 | 66 |

Generator Function Definitions

67 | 68 | 69 |
70 | 71 |

Async Generator Function Definitions

72 | 73 | 74 |
75 | 76 |

Class Definitions

77 | 78 |
79 | 80 |

Async Function Definitions

81 | 82 | 83 |
84 | 85 |

Async Arrow Function Definitions

86 | 87 |
88 | 89 |

Tail Position Calls

90 | 91 |

Static Semantics: HasCallInTailPosition

92 | 93 |
94 |
95 |
96 | 97 | 98 |

ECMAScript Language: Scripts and Modules

99 | 100 |

Scripts

101 | 102 |
103 | 104 |

modules

105 | 106 |

Module Semantics

107 | 108 |
109 |
110 |
111 | 112 | 113 |

The Global Object

114 | 115 |

Function Properties of the Global Object

116 | 117 |

eval ( _x_ )

118 | 119 |
120 |
121 |
122 | 123 | 124 |

Fundamental Objects

125 | 126 |

Function Objects

127 | 128 |

The Function Constructor

129 | 130 |

Function ( _p1_, _p2_, ..., _pn_, _body_ )

131 | 132 |
133 |
134 |
135 |
-------------------------------------------------------------------------------- /spec/sec-function-environment-records-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Function Environment Records

3 |

A function Environment Record is a declarative Environment Record that is used to represent the top-level scope of a function and, if the function is not an |ArrowFunction|, provides a `this` binding. If a function is not an |ArrowFunction| function and references `super`, its function Environment Record also contains the state that is used to perform `super` method invocations from within the function. If a function is not an |ArrowFunction| function and references `class`, its function Environment Record also contains the state that is used to perform `class` property acccess from within the function.

4 |

Function Environment Records have the additional state fields listed in .

5 | 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 23 | 26 | 29 | 30 | 31 | 34 | 37 | 40 | 41 | 42 | 45 | 48 | 51 | 52 | 53 | 56 | 59 | 62 | 63 | 64 | 67 | 70 | 73 | 74 | 75 | 78 | 81 | 84 | 85 | 86 |
10 | Field Name 11 | 13 | Value 14 | 16 | Meaning 17 |
21 | [[ThisValue]] 22 | 24 | Any 25 | 27 | This is the *this* value used for this invocation of the function. 28 |
32 | [[ThisBindingStatus]] 33 | 35 | ~lexical~ | ~initialized~ | ~uninitialized~ 36 | 38 | If the value is ~lexical~, this is an |ArrowFunction| and does not have a local *this* value. 39 |
43 | [[FunctionObject]] 44 | 46 | Object 47 | 49 | The function object whose invocation caused this Environment Record to be created. 50 |
54 | [[HomeObject]] 55 | 57 | Object | *undefined* 58 | 60 | If the associated function has `super` property accesses and is not an |ArrowFunction|, [[HomeObject]] is the object that the function is bound to as a method. The default value for [[HomeObject]] is *undefined*. 61 |
65 | [[InitialClassObject]] 66 | 68 | Object | *undefined* 69 | 71 | If the associated function has `class` property access and is not an |ArrowFunction|, [[InitialClassObject]] is the class constructor function object that the function was initially bound to as a method. The default value for [[InitialClassObject]] is *undefined*. 72 |
76 | [[NewTarget]] 77 | 79 | Object | *undefined* 80 | 82 | If this Environment Record was created by the [[Construct]] internal method, [[NewTarget]] is the value of the [[Construct]] _newTarget_ parameter. Otherwise, its value is *undefined*. 83 |
87 |
88 |

Function Environment Records support all of the declarative Environment Record methods listed in and share the same specifications for all of those methods except for HasThisBinding and HasSuperBinding, HasSuperBinding, and HasClassBinding. In addition, function Environment Records support the methods listed in :

89 | 90 | 91 | 92 | 93 | 96 | 99 | 100 | 101 | 104 | 107 | 108 | 109 | 112 | 115 | 116 | 117 | 120 | 123 | 124 | 125 | 128 | 131 | 132 | 133 |
94 | Method 95 | 97 | Purpose 98 |
102 | BindThisValue(V) 103 | 105 | Set the [[ThisValue]] and record that it has been initialized. 106 |
110 | GetThisBinding() 111 | 113 | Return the value of this Environment Record's `this` binding. Throws a *ReferenceError* if the `this` binding has not been initialized. 114 |
118 | GetSuperBase() 119 | 121 | Return the object that is the base for `super` property accesses bound in this Environment Record. The object is derived from this Environment Record's [[HomeObject]] field. The value *undefined* indicates that `super` property accesses will produce runtime errors. 122 |
126 | GetClassBinding() 127 | 129 | Return the object that is the base for `class` property accesses bound in this Environment Record. The object is derived from this Environment Record's [[InitialClassObject]] field. The value *undefined* indicates that `class` property accesses will produce runtime errors. 130 |
134 |
135 |

The behaviour of the additional concrete specification methods for function Environment Records is defined by the following algorithms:

136 | 137 | 138 |

HasClassBinding ( )

139 | 140 | 1. Let _envRec_ be the function Environment Record for which the method was invoked. 141 | 1. If _envRec_.[[ThisBindingStatus]] is ~lexical~, return *false*. 142 | 1. If _envRec_.[[InitialClassObject]] has the value *undefined*, return *false*; otherwise, return *true*. 143 | 144 |
145 | 146 | 147 |

GetClassBinding ( )

148 | 149 | 1. Let _envRec_ be the function Environment Record for which the method was invoked. 150 | 1. Let _classObject_ be _envRec_.[[InitialClassObject]]. 151 | 1. If _classObject_ has the value *undefined*, return *undefined*. 152 | 1. Assert: Type(_classObject_) is Object. 153 | 1. Return ? _classObject_. 154 | 155 |
156 |
157 | -------------------------------------------------------------------------------- /spec/sec-createdynamicfunction-patch.html: -------------------------------------------------------------------------------- 1 | 2 |

Runtime Semantics: CreateDynamicFunction ( _constructor_, _newTarget_, _kind_, _args_ )

3 |

The abstract operation CreateDynamicFunction takes arguments _constructor_ (a constructor), _newTarget_ (a constructor), _kind_ (either ~normal~, ~generator~, ~async~, or ~asyncGenerator~), and _args_ (a List of ECMAScript language values). _constructor_ is the constructor function that is performing this action. _newTarget_ is the constructor that `new` was initially applied to. _args_ is the argument values that were passed to _constructor_. It performs the following steps when called:

4 | 5 | 1. Assert: The execution context stack has at least two elements. 6 | 1. Let _callerContext_ be the second to top element of the execution context stack. 7 | 1. Let _callerRealm_ be _callerContext_'s Realm. 8 | 1. Let _calleeRealm_ be the current Realm Record. 9 | 1. Perform ? HostEnsureCanCompileStrings(_callerRealm_, _calleeRealm_). 10 | 1. If _newTarget_ is *undefined*, set _newTarget_ to _constructor_. 11 | 1. If _kind_ is ~normal~, then 12 | 1. Let _goal_ be the grammar symbol |FunctionBody[~Yield, ~Await]|. 13 | 1. Let _parameterGoal_ be the grammar symbol |FormalParameters[~Yield, ~Await]|. 14 | 1. Let _fallbackProto_ be *"%Function.prototype%"*. 15 | 1. Else if _kind_ is ~generator~, then 16 | 1. Let _goal_ be the grammar symbol |GeneratorBody|. 17 | 1. Let _parameterGoal_ be the grammar symbol |FormalParameters[+Yield, ~Await]|. 18 | 1. Let _fallbackProto_ be *"%GeneratorFunction.prototype%"*. 19 | 1. Else if _kind_ is ~async~, then 20 | 1. Let _goal_ be the grammar symbol |AsyncFunctionBody|. 21 | 1. Let _parameterGoal_ be the grammar symbol |FormalParameters[~Yield, +Await]|. 22 | 1. Let _fallbackProto_ be *"%AsyncFunction.prototype%"*. 23 | 1. Else, 24 | 1. Assert: _kind_ is ~asyncGenerator~. 25 | 1. Let _goal_ be the grammar symbol |AsyncGeneratorBody|. 26 | 1. Let _parameterGoal_ be the grammar symbol |FormalParameters[+Yield, +Await]|. 27 | 1. Let _fallbackProto_ be *"%AsyncGeneratorFunction.prototype%"*. 28 | 1. Let _argCount_ be the number of elements in _args_. 29 | 1. Let _P_ be the empty String. 30 | 1. If _argCount_ = 0, let _bodyArg_ be the empty String. 31 | 1. Else if _argCount_ = 1, let _bodyArg_ be _args_[0]. 32 | 1. Else, 33 | 1. Assert: _argCount_ > 1. 34 | 1. Let _firstArg_ be _args_[0]. 35 | 1. Set _P_ to ? ToString(_firstArg_). 36 | 1. Let _k_ be 1. 37 | 1. Repeat, while _k_ < _argCount_ - 1, 38 | 1. Let _nextArg_ be _args_[_k_]. 39 | 1. Let _nextArgString_ be ? ToString(_nextArg_). 40 | 1. Set _P_ to the string-concatenation of _P_, *","* (a comma), and _nextArgString_. 41 | 1. Set _k_ to _k_ + 1. 42 | 1. Let _bodyArg_ be _args_[_k_]. 43 | 1. Let _bodyString_ be the string-concatenation of 0x000A (LINE FEED), ? ToString(_bodyArg_), and 0x000A (LINE FEED). 44 | 1. Let _prefix_ be the prefix associated with _kind_ in . 45 | 1. Let _sourceString_ be the string-concatenation of _prefix_, *" anonymous("*, _P_, 0x000A (LINE FEED), *") {"*, _bodyString_, and *"}"*. 46 | 1. Let _sourceText_ be ! StringToCodePoints(_sourceString_). 47 | 1. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection: 48 | 1. Let _parameters_ be the result of parsing ! StringToCodePoints(_P_), using _parameterGoal_ as the goal symbol. Throw a *SyntaxError* exception if the parse fails. 49 | 1. Let _body_ be the result of parsing ! StringToCodePoints(_bodyString_), using _goal_ as the goal symbol. Throw a *SyntaxError* exception if the parse fails. 50 | 1. Let _strict_ be ContainsUseStrict of _body_. 51 | 1. If any static semantics errors are detected for _parameters_ or _body_, throw a *SyntaxError* exception. If _strict_ is *true*, the Early Error rules for UniqueFormalParameters : FormalParameters are applied. 52 | 1. If _strict_ is *true* and IsSimpleParameterList of _parameters_ is *false*, throw a *SyntaxError* exception. 53 | 1. If any element of the BoundNames of _parameters_ also occurs in the LexicallyDeclaredNames of _body_, throw a *SyntaxError* exception. 54 | 1. If _body_ Contains |SuperCall| is *true*, throw a *SyntaxError* exception. 55 | 1. If _parameters_ Contains |SuperCall| is *true*, throw a *SyntaxError* exception. 56 | 1. If _body_ Contains |SuperProperty| is *true*, throw a *SyntaxError* exception. 57 | 1. If _body_ Contains |ClassProperty| is *true*, throw a *SyntaxError* exception. 58 | 1. If _parameters_ Contains |SuperProperty| is *true*, throw a *SyntaxError* exception. 59 | 1. If _parameters_ Contains |ClassProperty| is *true*, throw a *SyntaxError* exception. 60 | 1. If _kind_ is ~generator~ or ~asyncGenerator~, then 61 | 1. If _parameters_ Contains |YieldExpression| is *true*, throw a *SyntaxError* exception. 62 | 1. If _kind_ is ~async~ or ~asyncGenerator~, then 63 | 1. If _parameters_ Contains |AwaitExpression| is *true*, throw a *SyntaxError* exception. 64 | 1. If _strict_ is *true*, then 65 | 1. If BoundNames of _parameters_ contains any duplicate elements, throw a *SyntaxError* exception. 66 | 1. Let _proto_ be ? GetPrototypeFromConstructor(_newTarget_, _fallbackProto_). 67 | 1. Let _realmF_ be the current Realm Record. 68 | 1. Let _scope_ be _realmF_.[[GlobalEnv]]. 69 | 1. Let _F_ be ! OrdinaryFunctionCreate(_proto_, _sourceText_, _parameters_, _body_, ~non-lexical-this~, _scope_). 70 | 1. Perform SetFunctionName(_F_, *"anonymous"*). 71 | 1. If _kind_ is ~generator~, then 72 | 1. Let _prototype_ be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%). 73 | 1. Perform DefinePropertyOrThrow(_F_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). 74 | 1. Else if _kind_ is ~asyncGenerator~, then 75 | 1. Let _prototype_ be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%). 76 | 1. Perform DefinePropertyOrThrow(_F_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). 77 | 1. Else if _kind_ is ~normal~, perform MakeConstructor(_F_). 78 | 1. NOTE: Functions whose _kind_ is ~async~ are not constructible and do not have a [[Construct]] internal method or a *"prototype"* property. 79 | 1. Return _F_. 80 | 81 | 82 |

CreateDynamicFunction defines a *"prototype"* property on any function it creates whose _kind_ is not ~async~ to provide for the possibility that the function will be used as a constructor.

83 |
84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
KindPrefix
~normal~*"function"*
~generator~*"function\*"*
~async~*"async function"*
~asyncGenerator~*"async function\*"*
95 |
96 |
-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # ECMAScript class property access expressions 3 | 4 | Class access expressions seek to simplify access to static members of a class as well as provide 5 | access to static members of a class when that class is unnamed: 6 | 7 | ```js 8 | class C { 9 | static f() { ... } 10 | 11 | g() { 12 | class.f(); 13 | } 14 | } 15 | ``` 16 | 17 | * [Stage 0 Presentation](https://docs.google.com/presentation/d/1VXqGgxq_a0byLuc9yl4jSLR6GlopjvhU_Z0OpZnk6l0/edit?usp=sharing) 18 | 19 | 20 | 21 | 22 | ## Status 23 | 24 | **Stage:** 1 25 | **Champion:** Ron Buckton (@rbuckton) 26 | 27 | _For detailed status of this proposal see [TODO](#todo), below._ 28 | 29 | 30 | 31 | ## Authors 32 | 33 | * Ron Buckton (@rbuckton) 34 | 35 | 36 | 37 | 44 | 45 | 46 | 47 | # Motivations 48 | 49 | Today, ECMAScript developers can write classes with static members that can be accessed in one of 50 | two ways: 51 | 52 | - Via the class name: 53 | ```js 54 | class C { 55 | static x() {} 56 | y() { C.x(); } 57 | } 58 | ``` 59 | - Via `this` in a static member: 60 | ```js 61 | class C { 62 | static x() {} 63 | static y() { this.x(); } 64 | } 65 | ``` 66 | 67 | However, there is no easy mechanism to access class statics in a class that has no name: 68 | 69 | ```js 70 | export default class { 71 | static x() { } 72 | y() { 73 | this.constructor.x(); // Not actually guaranteed to be the correct `x`. 74 | } 75 | } 76 | 77 | 78 | const x = class { 79 | static x() { } 80 | y() { 81 | this.constructor.x(); // Not actually guaranteed to be the correct `x`. 82 | } 83 | } 84 | ``` 85 | 86 | It’s not guaranteed to be the correct `x` in the above examples, because you could be 87 | accessing an overridden member of a subclass. 88 | 89 | Also, with current proposal for private static fields and methods, its very easy to 90 | run into errors at runtime when using `this` in a static method: 91 | 92 | ```js 93 | class C { 94 | static #x() {} 95 | static y() { this.#x(); } 96 | } 97 | class D extends C {} 98 | D.y(); // TypeError 99 | ``` 100 | 101 | 102 | 103 | 104 | # Syntax 105 | 106 | ```js 107 | // from a non-static method 108 | class C { 109 | static f() { } 110 | g() { 111 | class.f(); 112 | class["f"](); 113 | } 114 | } 115 | 116 | // from a static method 117 | class C { 118 | static f() { } 119 | static g() { 120 | class.f(); 121 | class["f"](); 122 | } 123 | } 124 | 125 | // with static private members 126 | class C { 127 | static #f() {} 128 | static g() { 129 | class.#f(); 130 | } 131 | } 132 | ``` 133 | 134 | 135 | 136 | # Semantics 137 | 138 | - Function Environment Records have a new field in Table 15: 139 | > | Field Name | Value | Meaning | 140 | > |:-|:-|:-| 141 | > | \[\[InitialClassObject]] | Object \| **undefined** | If the associated function has `class` property access and is not an _ArrowFunction_, \[\[InitialClassObject]] is the class that the function is bound to as a method. The default value for \[\[InitialClassObject]] is **undefined**. | 142 | - Function Environment Records have a new method in Table 16: 143 | > | Method | Purpose | 144 | > |:-|:-| 145 | > | GetClassBinding() | Return the object that is the base for `class` property access bound in this Environment Record. | 146 | - ECMAScript Function Objects have a new internal slot in Table 27: 147 | > | Interanl Slot | Type | Description | 148 | > |:-|:-|:-| 149 | > | \[\[InitialClassObject]] | Object \| **undefined** | If the function has `class` property access, this is the object where `class` property lookups begin. | 150 | - During ClassDefinitionEvaluation, the class constructor (F) is set as the \[\[InitialClassObject]] on the method. 151 | - During NewFunctionEnvironment, the \[\[InitialClassObject]] is copied from the method (F) to envRec.\[\[InitialClassObject]]. 152 | - Arrow functions use the \[\[InitialClassObject]] of their containing lexical environment (similar to `super` and `this`). 153 | - When evaluating ``ClassProperty: `class` `.` IdentifierName`` we return a new Reference with the following properties: 154 | - The referenced name component is the StringValue of _IdentifierName_. 155 | - The base value component is the \[\[InitialClassObject]] of GetThisEnvironment(). 156 | - When evaluating ``ClassProperty: `class` `[` Expression `]` `` we return a new Reference with the following properties: 157 | - The referenced name component is the result of calling ?ToPropertyKey on the result of calling GetValue on the result of evaluating _Expression_. 158 | - The base value component is the \[\[InitialClassObject]] of GetThisEnvironment(). 159 | - When evaluating ``ClassProperty: `class` `.` PrivateIdentifier`` we perform the following steps: 160 | 1. Let `fieldNameString` be the StringValue of _PrivateIdentifier_. 161 | 2. Let `bv` be the \[\[InitialClassObject]] of GetThisEnvironment(). 162 | 3. Return ?[MakePrivateReference](https://tc39.es/proposal-class-fields/#sec-makeprivatereference)( `bv`, `fieldNameString` ) 163 | - `class` bindings are only available in the following declarations: 164 | - A method of a class. 165 | - An accessor of a class. 166 | - A field initializer of a class. 167 | - The constructor of a class. 168 | - A class's `static` intialization block (see http://github.com/tc39/proposal-class-static-block) 169 | - An *ArrowFunction* in any of these declarations. 170 | - `class` bindings are *not* valid in any of the following declarations: 171 | - A *FunctionDeclaration* or *FunctionExpression*. 172 | - A method of an object literal. 173 | - An accessor of an object literal. 174 | - Any execution context not nested within a lexical `class` declaration, including module or global scope. 175 | - *NOTE:* This aligns with the behavior of `super`. 176 | 177 | 178 | 179 | 180 | ## Examples 181 | 182 | ### Property Access 183 | 184 | In class methods or the class constructor, getting the value of `class.x` always refers to the value of the property `x` on the 185 | containing lexical class: 186 | 187 | ```js 188 | class Base { 189 | static f() { 190 | console.log(`this: ${this.name}, class: ${class.name})`); 191 | } 192 | } 193 | class Sub extends Base { 194 | } 195 | 196 | Base.f(); // this: Base, class: Base 197 | Sub.f(); // this: Sub, class: Base 198 | Base.f.call({ name: "Other" }); // this: Other, class: Base 199 | ``` 200 | 201 | This behavior provides the following benefits: 202 | 203 | - Able to reference static members of the containing lexical class without needing to repeat the class name. 204 | - Able to reference static members of an anonymous class declaration or expression: 205 | ```js 206 | export default class { 207 | static f() { ... } 208 | g() { class.f(); } 209 | } 210 | ``` 211 | 212 | ### Property Assignment 213 | 214 | In class methods or the class constructor, setting the value of `class.x` always updates the value of the property `x` on the 215 | containing lexical class: 216 | 217 | ```js 218 | function print(F) { 219 | const { name, x, y } = F; 220 | const hasX = F.hasOwnProperty("x") ? "own" : "inherited"; 221 | const hasY = F.hasOwnProperty("y") ? "own" : "inherited"; 222 | console.log(`${name}.x: ${x} (${hasX}), ${name}.y: ${y} (${hasY})`); 223 | } 224 | 225 | class Base { 226 | static f() { 227 | this.x++; 228 | class.y++; 229 | } 230 | } 231 | 232 | Base.x = 0; 233 | Base.y = 0; 234 | 235 | class Sub extends Base { 236 | } 237 | 238 | print(Base); // Base.x: 0 (own), Base.y: 0 (own) 239 | print(Sub); // Sub.x: 0 (inherited), Sub.y: 0 (inherited) 240 | 241 | Base.f(); 242 | 243 | print(Base); // Base.x: 1 (own), Base.y: 1 (own) 244 | print(Sub); // Sub.x: 1 (inherited), Sub.y: 1 (inherited) 245 | 246 | Sub.f(); 247 | 248 | print(Base); // Base.x: 1 (own), Base.y: 2 (own) 249 | print(Sub); // Sub.x: 2 (own), Sub.y: 2 (inherited) 250 | 251 | Base.f(); 252 | 253 | print(Base); // Base.x: 2 (own), Base.y: 3 (own) 254 | print(Sub); // Sub.x: 2 (own), Sub.y: 3 (inherited) 255 | ``` 256 | 257 | This behavior provides the following benefits: 258 | 259 | - Assignments always occur on the current lexical class, which should be unsurprising to users. 260 | 261 | ### Method Invocation 262 | 263 | Invoking `class.x()` in a method, an initializer, or in the constructor uses the value of containing lexical class as the receiver: 264 | 265 | ```js 266 | class Base { 267 | static f() { 268 | console.log(`this.name: ${this.name}, class.name: ${class.name})`); 269 | } 270 | static g() { 271 | class.f(); 272 | } 273 | h() { 274 | class.f(); 275 | } 276 | } 277 | class Sub extends Base { 278 | } 279 | 280 | Base.g(); // this: Base, class: Base 281 | Sub.g(); // this: Sub, class: Base 282 | Base.g.call({ name: "Other" }); // this: Other, class: Base 283 | 284 | let b = new Base(); 285 | let s = new Sub(); 286 | b.h(); // this: Base, class: Base 287 | s.h(); // this: Sub, class: Base 288 | b.h.call({ name: "Other" }); // this: Other, class: Base 289 | ``` 290 | 291 | ### Invalid usage 292 | 293 | ```js 294 | class C { 295 | static x = 1; 296 | constructor() { 297 | function f() { 298 | return class.x; // function has no access to `class.` 299 | } 300 | f(); // throws TypeError 301 | 302 | const obj = { 303 | method() { 304 | return class.x; // method of object literal has no access to `class`. 305 | } 306 | }; 307 | obj.method(); // throws TypeError 308 | } 309 | } 310 | ``` 311 | 312 | 313 | 314 | 315 | 320 | 321 | 322 | 323 | # Grammar 324 | 325 | ```grammarkdown 326 | MemberExpression[Yield, Await] : 327 | ClassProperty[?Yield, ?Await] 328 | 329 | ClassProperty[Yield, Await] : 330 | `class` `[` Expression[+In, ?Yield, ?Await] `]` 331 | `class` `.` IdentifierName 332 | `class` `.` PrivateIdentifier 333 | ``` 334 | 335 | 336 | # Relationship to Other Proposals 337 | 338 | ## Class Fields 339 | 340 | This proposal can easily align with the current class fields proposal, providing easier access to static fields without unexpected behavior: 341 | 342 | ```js 343 | class Base { 344 | static counter = 0; 345 | id = class.counter++; // `Base` is used as `this` 346 | } 347 | 348 | class Sub extends Base { 349 | } 350 | 351 | console.log(new Base().id); // 0 352 | console.log(new Sub().id); // 1 353 | console.log(Base.counter); // 2 354 | console.log(Sub.counter); // 2 355 | ``` 356 | 357 | 358 | ## Class Private Fields 359 | 360 | In addition to private methods, this proposal can also align with the current proposals for class private fields, providing 361 | access to class static private state without introducing TypeErrors due to incorrect `this`: 362 | 363 | ```js 364 | class Base { 365 | static #counter = 0; 366 | static increment() { 367 | return class.#counter++; 368 | } 369 | } 370 | 371 | class Sub extends Base { 372 | } 373 | 374 | console.log(Base.increment()); // 0 375 | console.log(Sub.increment()); // 1 376 | console.log(Base.increment()); // 2 377 | ``` 378 | 379 | ## Class Private Methods 380 | 381 | One of the benefits of `class` access expressions is that they guarantee the correct reference is used when accessing static private members. Special care must be taken, however, when invoking private and non-private static methods using `class` access expressions, as the `this` binding within the invoked method will be the lexical class declaration: 382 | 383 | ```js 384 | class Base { 385 | static #counter = 0; 386 | static #increment() { 387 | class.#counter++; 388 | this.printCounter(); 389 | } 390 | static doIncrement() { 391 | class.#increment(); 392 | } 393 | static printCounter() { 394 | console.log(class.#counter); 395 | } 396 | } 397 | class Sub extends Base { 398 | static printCounter() { 399 | console.log("Custom Counter"); 400 | super.printCounter(); 401 | } 402 | } 403 | 404 | Base.doIncrement(); // prints: 1 405 | Sub.doIncrement(); // prints: 2 406 | ``` 407 | 408 | In the example above, `Sub`'s overriden `printCounter` is never invoked. Such method calls would need to be rewritten: 409 | 410 | ```js 411 | // option 1: 412 | class Base { 413 | ... 414 | static #increment() { 415 | ... 416 | } 417 | static doIncrement() { 418 | class.#increment.call(this); 419 | } 420 | } 421 | 422 | // option 2: 423 | class Base { 424 | ... 425 | static #increment(C) { 426 | ... 427 | C.printCounter(); 428 | } 429 | ... 430 | static doIncrement() { 431 | class.#increment(this); 432 | } 433 | } 434 | ``` 435 | 436 | This is due to the fact that `class.` in this example is essentially a substitute for `Base.`, therefore `Base` becomes the receiver in these method calls. 437 | 438 | 439 | 440 | 447 | 448 | 449 | 450 | 457 | 458 | 459 | 460 | # TODO 461 | 462 | The following is a high-level list of tasks to progress through each stage of the [TC39 proposal process](https://tc39.github.io/process-document/): 463 | 464 | ### Stage 1 Entrance Criteria 465 | 466 | * [x] Identified a "[champion][Champion]" who will advance the addition. 467 | * [x] [Prose][Prose] outlining the problem or need and the general shape of a solution. 468 | * [x] Illustrative [examples][Examples] of usage. 469 | * [x] High-level [API][API]. 470 | 471 | ### Stage 2 Entrance Criteria 472 | 473 | * [x] [Initial specification text][Specification]. 474 | * [ ] [Transpiler support][Transpiler] (_Optional_). 475 | 476 | ### Stage 3 Entrance Criteria 477 | 478 | * [ ] [Complete specification text][Specification]. 479 | * [ ] Designated reviewers have [signed off][Stage3ReviewerSignOff] on the current spec text. 480 | * [ ] The ECMAScript editor has [signed off][Stage3EditorSignOff] on the current spec text. 481 | 482 | ### Stage 4 Entrance Criteria 483 | 484 | * [ ] [Test262](https://github.com/tc39/test262) acceptance tests have been written for mainline usage scenarios and [merged][Test262PullRequest]. 485 | * [ ] Two compatible implementations which pass the acceptance tests: [\[1\]][Implementation1], [\[2\]][Implementation2]. 486 | * [ ] A [pull request][Ecma262PullRequest] has been sent to tc39/ecma262 with the integrated spec text. 487 | * [ ] The ECMAScript editor has signed off on the [pull request][Ecma262PullRequest]. 488 | 489 | 490 | 491 | 492 | [Process]: https://tc39.github.io/process-document/ 493 | [Proposals]: https://github.com/tc39/proposals/ 494 | [Grammarkdown]: http://github.com/rbuckton/grammarkdown#readme 495 | [Champion]: #status 496 | [Prose]: #motivations 497 | [Examples]: #examples 498 | [API]: #api 499 | [Specification]: https://tc39.es/proposal-class-access-expressions 500 | 501 | 502 | [Transpiler]: #todo 503 | [Stage3ReviewerSignOff]: #todo 504 | [Stage3EditorSignOff]: #todo 505 | [Test262PullRequest]: #todo 506 | [Implementation1]: #todo 507 | [Implementation2]: #todo 508 | [Ecma262PullRequest]: #todo 509 | 510 | --------------------------------------------------------------------------------