From 2ee9fdd4dde504677ec81f511e2edecd636150c7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 28 Mar 2024 17:39:27 -0400 Subject: [PATCH] Spec text for discards as `void` bindings --- .gitattributes | 3 + .github/workflows/build.yml | 28 +- .github/workflows/deploy.yml | 23 - .github/workflows/pr.yml | 36 ++ .vscode/extensions.json | 6 + .vscode/settings.json | 17 + .vscode/tasks.json | 15 + gulpfile.js | 37 ++ package.json | 20 +- spec.emu | 888 +++++++++++++++++++++++++++++++++-- 10 files changed, 1001 insertions(+), 72 deletions(-) create mode 100644 .gitattributes delete mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 gulpfile.js diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..31e2b43 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +index.html -diff merge=ours +spec.js -diff merge=ours +spec.css -diff merge=ours diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 854640b..4f0e5be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,15 +1,21 @@ -name: Build spec - -on: [pull_request, push] - +name: Publish Spec to gh-pages +on: + push: + branches: [ main ] jobs: build: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: ljharb/actions/node/install@main - name: 'nvm install lts/* && npm install' - with: - node-version: lts/* - - run: npm run build + - uses: actions/checkout@v3 + - uses: ljharb/actions/node/install@main + name: 'nvm install lts/* && npm install' + with: + node-version: lts/* + - run: npm run build + - name: Deploy + uses: JamesIves/github-pages-deploy-action@4.1.4 + with: + branch: gh-pages + folder: build + clean-exclude: | + pr diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 43206c8..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Deploy gh-pages - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - uses: ljharb/actions/node/install@main - name: 'nvm install lts/* && npm install' - with: - node-version: lts/* - - run: npm run build - - uses: JamesIves/github-pages-deploy-action@v4.3.3 - with: - branch: gh-pages - folder: build - clean: true diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..c19f63c --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,36 @@ +name: Publish PR to gh-pages/pr/ +on: + pull_request: + branches: [ main ] +jobs: + build: + runs-on: ubuntu-latest + if: ${{ github.event.number }} + steps: + - uses: actions/checkout@v3 + - uses: ljharb/actions/node/install@main + name: 'nvm install lts/* && npm install' + with: + node-version: lts/* + - run: npm run build + - name: Deploy + uses: JamesIves/github-pages-deploy-action@4.1.4 + with: + branch: gh-pages + folder: build + target-folder: pr/${{ github.event.number }}/ + - id: get-preview-url + name: Get preview url + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + url=(gh api "repos/$GITHUB_REPOSITORY/pages" --jq '.html_url') + echo "preview-url=https://tc39.es/$(basename $GITHUB_REPOSITORY)pr/${{ github.event.number }}" >> "$GITHUB_OUTPUT" + shell: bash + - name: Post Preview Comment + uses: phulsechinmay/rewritable-pr-comment@v0.3.0 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMMENT_IDENTIFIER: tc39_pr_preview_comment + message: | + A preview of this PR can be found at ${{ steps.get-preview-url.outputs.preview-url }}. diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d43d953 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "rbuckton.grammarkdown-vscode", + "rbuckton.ecmarkup-vscode" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8689c86 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "[markdown]": { + "files.trimTrailingWhitespace": false + }, + "[html]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + }, + "[ecmarkup]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + }, + "files.associations": { + // "*.html": "ecmarkup", + "*.emu": "ecmarkup" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..01142c1 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "gulp", + "task": "default", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..56d5e37 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,37 @@ +const del = require("del"); +const path = require("path"); +const gulp = require("gulp"); +const emu = require("gulp-emu"); +const rename = require("gulp-rename"); +const gls = require("gulp-live-server"); + +gulp.task("clean", () => del("build/**/*")); + +gulp.task("build", () => gulp + .src(["spec.emu"]) + .pipe(emu({ + log: require("ecmarkup/lib/utils").logVerbose, + warn: err => { + const file = path.resolve(err.file || "spec.emu"); + const message = `Warning: ${file}:${typeof err.line === "number" ? `${err.line}:${err.column}:` : ""} ${err.message}`; + require("ecmarkup/lib/utils").logWarning(message); + }, + ecma262Biblio: false, + })) + .pipe(rename("index.html")) + .pipe(gulp.dest("build"))); + +gulp.task("watch", () => gulp + .watch(["spec.emu"], gulp.task("build"))); + +gulp.task("start", gulp.parallel("watch", () => { + const server = gls.static("build", 8080); + const promise = server.start(); + (/** @type {import("chokidar").FSWatcher}*/(gulp.watch(["build/**/*"]))) + .on("change", file => { + server.notify({ path: path.resolve(file) }); + }); + return promise; +})); + +gulp.task("default", gulp.task("build")); \ No newline at end of file diff --git a/package.json b/package.json index 842c0cc..f8a7d15 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,25 @@ { "private": true, - "name": "template-for-proposals", + "name": "proposal-discard-binding", "description": "A repository template for ECMAScript proposals.", "scripts": { - "start": "npm run build-loose -- --watch", - "build": "npm run build-loose -- --strict", - "build-loose": "node -e 'fs.mkdirSync(\"build\", { recursive: true })' && ecmarkup --load-biblio @tc39/ecma262-biblio --verbose spec.emu build/index.html --lint-spec" + "build": "gulp build", + "start": "gulp start" }, - "homepage": "https://github.com/tc39/template-for-proposals#readme", + "homepage": "https://github.com/tc39/proposal-discard-binding#readme", "repository": { "type": "git", - "url": "git+https://github.com/tc39/template-for-proposals.git" + "url": "git+https://github.com/tc39/proposal-discard-binding.git" }, - "license": "MIT", + "license": "SEE LICENSE IN https://tc39.es/ecma262/#sec-copyright-and-software-license", "devDependencies": { "@tc39/ecma262-biblio": "^2.1.2571", - "ecmarkup": "^17.0.0" + "del": "^6.0.0", + "ecmarkup": "^18.0.0", + "gulp": "^4.0.2", + "gulp-emu": "^2.2.0", + "gulp-live-server": "0.0.31", + "gulp-rename": "^2.0.0" }, "engines": { "node": ">= 12" diff --git a/spec.emu b/spec.emu index 5d05685..61a214b 100644 --- a/spec.emu +++ b/spec.emu @@ -1,39 +1,867 @@ - -
-title: Proposal Title Goes Here
-stage: -1
-contributors: Your Name(s) Here
+title: Discard Bindings
+status: proposal
+stage: 1
+contributors: Ron Buckton, Ecma International
 
- -

This is an emu-clause

-

This is an algorithm:

- - 1. Let _proposal_ be *undefined*. - 1. If IsAccepted(_proposal_) is *true*, then - 1. Let _stage_ be *0*. - 1. Else, - 1. Let _stage_ be *-1*. - 1. Return ? ToString(_stage_). - + + + +

Introduction

+

See the proposal repository for background material and discussion.

+
+ + +

Syntax-Directed Operations

+ + +

Scope Analysis

+ + +

Static Semantics: BoundNames ( ): a List of Strings

+
+
+ +

*"\*default\*"* is used within this specification as a synthetic name for a module's default export when it does not have another name. An entry in the module's [[Environment]] is created with that name and holds the corresponding value, and resolving the export named *"default"* by calling for the module will return a ResolvedBinding Record whose [[BindingName]] is *"\*default\*"*, which will then resolve in the module's [[Environment]] to the above-mentioned value. This is done only for ease of specification, so that anonymous default exports can be resolved like any other export. This *"\*default\*"* string is never accessible to ECMAScript code or to the module linking algorithm.

+
+ BindingIdentifier : Identifier + + 1. Return a List whose sole element is the StringValue of |Identifier|. + + BindingIdentifier : `yield` + + 1. Return « *"yield"* ». + + BindingIdentifier : `await` + + 1. Return « *"await"* ». + + LexicalDeclaration : LetOrConst BindingList `;` + + 1. Return the BoundNames of |BindingList|. + + + UsingDeclaration : + `using` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + + + 1. Return the BoundNames of |BindingList|. + + BindingList : BindingList `,` LexicalBinding + + 1. Let _names1_ be the BoundNames of |BindingList|. + 1. Let _names2_ be the BoundNames of |LexicalBinding|. + 1. Return the list-concatenation of _names1_ and _names2_. + + LexicalBinding : BindingIdentifier Initializer? + + 1. Return the BoundNames of |BindingIdentifier|. + + LexicalBinding : BindingPattern Initializer + + 1. Return the BoundNames of |BindingPattern|. + + + LexicalBinding : `void` Initializer + + 1. Return a new empty List. + + + VariableDeclarationList : VariableDeclarationList `,` VariableDeclaration + + 1. Let _names1_ be BoundNames of |VariableDeclarationList|. + 1. Let _names2_ be BoundNames of |VariableDeclaration|. + 1. Return the list-concatenation of _names1_ and _names2_. + + VariableDeclaration : BindingIdentifier Initializer? + + 1. Return the BoundNames of |BindingIdentifier|. + + VariableDeclaration : BindingPattern Initializer + + 1. Return the BoundNames of |BindingPattern|. + + + BindingPattern : `void` + + 1. Return a new empty List. + + + ObjectBindingPattern : `{` `}` + + 1. Return a new empty List. + + ObjectBindingPattern : `{` BindingPropertyList `,` BindingRestProperty `}` + + 1. Let _names1_ be BoundNames of |BindingPropertyList|. + 1. Let _names2_ be BoundNames of |BindingRestProperty|. + 1. Return the list-concatenation of _names1_ and _names2_. + + ArrayBindingPattern : `[` Elision? `]` + + 1. Return a new empty List. + + ArrayBindingPattern : `[` Elision? BindingRestElement `]` + + 1. Return the BoundNames of |BindingRestElement|. + + ArrayBindingPattern : `[` BindingElementList `,` Elision? `]` + + 1. Return the BoundNames of |BindingElementList|. + + ArrayBindingPattern : `[` BindingElementList `,` Elision? BindingRestElement `]` + + 1. Let _names1_ be BoundNames of |BindingElementList|. + 1. Let _names2_ be BoundNames of |BindingRestElement|. + 1. Return the list-concatenation of _names1_ and _names2_. + + BindingPropertyList : BindingPropertyList `,` BindingProperty + + 1. Let _names1_ be BoundNames of |BindingPropertyList|. + 1. Let _names2_ be BoundNames of |BindingProperty|. + 1. Return the list-concatenation of _names1_ and _names2_. + + BindingElementList : BindingElementList `,` BindingElisionElement + + 1. Let _names1_ be BoundNames of |BindingElementList|. + 1. Let _names2_ be BoundNames of |BindingElisionElement|. + 1. Return the list-concatenation of _names1_ and _names2_. + + BindingElisionElement : Elision? BindingElement + + 1. Return BoundNames of |BindingElement|. + + BindingProperty : PropertyName `:` BindingElement + + 1. Return the BoundNames of |BindingElement|. + + SingleNameBinding : BindingIdentifier Initializer? + + 1. Return the BoundNames of |BindingIdentifier|. + + BindingElement : BindingPattern Initializer? + + 1. Return the BoundNames of |BindingPattern|. + + ForDeclaration : LetOrConst ForBinding + + 1. Return the BoundNames of |ForBinding|. + + FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` + + 1. Return the BoundNames of |BindingIdentifier|. + + FunctionDeclaration : `function` `(` FormalParameters `)` `{` FunctionBody `}` + + 1. Return « *"\*default\*"* ». + + FormalParameters : [empty] + + 1. Return a new empty List. + + FormalParameters : FormalParameterList `,` FunctionRestParameter + + 1. Let _names1_ be BoundNames of |FormalParameterList|. + 1. Let _names2_ be BoundNames of |FunctionRestParameter|. + 1. Return the list-concatenation of _names1_ and _names2_. + + FormalParameterList : FormalParameterList `,` FormalParameter + + 1. Let _names1_ be BoundNames of |FormalParameterList|. + 1. Let _names2_ be BoundNames of |FormalParameter|. + 1. Return the list-concatenation of _names1_ and _names2_. + + ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList + + 1. Let _formals_ be the |ArrowFormalParameters| that is covered by |CoverParenthesizedExpressionAndArrowParameterList|. + 1. Return the BoundNames of _formals_. + + GeneratorDeclaration : `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}` + + 1. Return the BoundNames of |BindingIdentifier|. + + GeneratorDeclaration : `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}` + + 1. Return « *"\*default\*"* ». + + AsyncGeneratorDeclaration : `async` `function` `*` BindingIdentifier `(` FormalParameters `)` `{` AsyncGeneratorBody `}` + + 1. Return the BoundNames of |BindingIdentifier|. + + AsyncGeneratorDeclaration : `async` `function` `*` `(` FormalParameters `)` `{` AsyncGeneratorBody `}` + + 1. Return « *"\*default\*"* ». + + ClassDeclaration : `class` BindingIdentifier ClassTail + + 1. Return the BoundNames of |BindingIdentifier|. + + ClassDeclaration : `class` ClassTail + + 1. Return « *"\*default\*"* ». + + + AsyncFunctionDeclaration : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}` + + + 1. Return the BoundNames of |BindingIdentifier|. + + + AsyncFunctionDeclaration : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}` + + + 1. Return « *"\*default\*"* ». + + + CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments + + + 1. Let _head_ be the |AsyncArrowHead| that is covered by |CoverCallExpressionAndAsyncArrowHead|. + 1. Return the BoundNames of _head_. + + ImportDeclaration : `import` ImportClause FromClause `;` + + 1. Return the BoundNames of |ImportClause|. + + ImportDeclaration : `import` ModuleSpecifier `;` + + 1. Return a new empty List. + + ImportClause : ImportedDefaultBinding `,` NameSpaceImport + + 1. Let _names1_ be the BoundNames of |ImportedDefaultBinding|. + 1. Let _names2_ be the BoundNames of |NameSpaceImport|. + 1. Return the list-concatenation of _names1_ and _names2_. + + ImportClause : ImportedDefaultBinding `,` NamedImports + + 1. Let _names1_ be the BoundNames of |ImportedDefaultBinding|. + 1. Let _names2_ be the BoundNames of |NamedImports|. + 1. Return the list-concatenation of _names1_ and _names2_. + + NamedImports : `{` `}` + + 1. Return a new empty List. + + ImportsList : ImportsList `,` ImportSpecifier + + 1. Let _names1_ be the BoundNames of |ImportsList|. + 1. Let _names2_ be the BoundNames of |ImportSpecifier|. + 1. Return the list-concatenation of _names1_ and _names2_. + + ImportSpecifier : ModuleExportName `as` ImportedBinding + + 1. Return the BoundNames of |ImportedBinding|. + + + ExportDeclaration : + `export` ExportFromClause FromClause `;` + `export` NamedExports `;` + + + 1. Return a new empty List. + + ExportDeclaration : `export` VariableStatement + + 1. Return the BoundNames of |VariableStatement|. + + ExportDeclaration : `export` Declaration + + 1. Return the BoundNames of |Declaration|. + + ExportDeclaration : `export` `default` HoistableDeclaration + + 1. Let _declarationNames_ be the BoundNames of |HoistableDeclaration|. + 1. If _declarationNames_ does not include the element *"\*default\*"*, append *"\*default\*"* to _declarationNames_. + 1. Return _declarationNames_. + + ExportDeclaration : `export` `default` ClassDeclaration + + 1. Let _declarationNames_ be the BoundNames of |ClassDeclaration|. + 1. If _declarationNames_ does not include the element *"\*default\*"*, append *"\*default\*"* to _declarationNames_. + 1. Return _declarationNames_. + + ExportDeclaration : `export` `default` AssignmentExpression `;` + + 1. Return « *"\*default\*"* ». + +
+
+ + +

Function Name Inference

+ + +

Static Semantics: IsIdentifierRef ( ): a Boolean

+
+
+ PrimaryExpression : IdentifierReference + + 1. Return *true*. + + + PrimaryExpression : + `this` + Literal + ArrayLiteral + ObjectLiteral + FunctionExpression + ClassExpression + GeneratorExpression + AsyncFunctionExpression + AsyncGeneratorExpression + RegularExpressionLiteral + TemplateLiteral + CoverParenthesizedExpressionAndArrowParameterList + + MemberExpression : + MemberExpression `[` Expression `]` + MemberExpression `.` IdentifierName + MemberExpression TemplateLiteral + SuperProperty + MetaProperty + `new` MemberExpression Arguments + MemberExpression `.` PrivateIdentifier + + NewExpression : + `new` NewExpression + + LeftHandSideExpression : + CallExpression + OptionalExpression + + DestructuringAssignmentTarget : + `void` + + + + 1. Return *false*. + +
+
+ + +

Miscellaneous

+ +

+ Runtime Semantics: BindingInitialization ( + _value_: an ECMAScript language value, + _environment_: an Environment Record or *undefined*, + ): either a normal completion containing ~unused~ or an abrupt completion +

+
+
+ +

*undefined* is passed for _environment_ to indicate that a PutValue operation should be used to assign the initialization value. This is the case for `var` statements and formal parameter lists of some non-strict functions (See ). In those cases a lexical binding is hoisted and preinitialized prior to evaluation of its initializer.

+
+ BindingIdentifier : Identifier + + 1. Let _name_ be StringValue of |Identifier|. + 1. Return ? InitializeBoundName(_name_, _value_, _environment_). + + BindingIdentifier : `yield` + + 1. Return ? InitializeBoundName(*"yield"*, _value_, _environment_). + + BindingIdentifier : `await` + + 1. Return ? InitializeBoundName(*"await"*, _value_, _environment_). + + BindingPattern : ObjectBindingPattern + + 1. Perform ? RequireObjectCoercible(_value_). + 1. Return ? BindingInitialization of |ObjectBindingPattern| with arguments _value_ and _environment_. + + BindingPattern : ArrayBindingPattern + + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). + 1. Let _result_ be Completion(IteratorBindingInitialization of |ArrayBindingPattern| with arguments _iteratorRecord_ and _environment_). + 1. If _iteratorRecord_.[[Done]] is *false*, return ? IteratorClose(_iteratorRecord_, _result_). + 1. Return ? _result_. + + + BindingPattern : `void` + + 1. Return ~unused~. + + + ObjectBindingPattern : `{` `}` + + 1. Return ~unused~. + + + ObjectBindingPattern : + `{` BindingPropertyList `}` + `{` BindingPropertyList `,` `}` + + + 1. Perform ? PropertyBindingInitialization of |BindingPropertyList| with arguments _value_ and _environment_. + 1. Return ~unused~. + + ObjectBindingPattern : `{` BindingRestProperty `}` + + 1. Let _excludedNames_ be a new empty List. + 1. Return ? RestBindingInitialization of |BindingRestProperty| with arguments _value_, _environment_, and _excludedNames_. + + ObjectBindingPattern : `{` BindingPropertyList `,` BindingRestProperty `}` + + 1. Let _excludedNames_ be ? PropertyBindingInitialization of |BindingPropertyList| with arguments _value_ and _environment_. + 1. Return ? RestBindingInitialization of |BindingRestProperty| with arguments _value_, _environment_, and _excludedNames_. + +
+
+
+ + +

ECMAScript Language: Expressions

+ + +

Unary Operators

+

Syntax

+ + UnaryExpression[Yield, Await] : + UpdateExpression[?Yield, ?Await] + `delete` UnaryExpression[?Yield, ?Await] + `void` UnaryExpression[?Yield, ?Await] + CoverVoidExpressionAndVoidDiscard[?Yield, ?Await] + `typeof` UnaryExpression[?Yield, ?Await] + `+` UnaryExpression[?Yield, ?Await] + `-` UnaryExpression[?Yield, ?Await] + `~` UnaryExpression[?Yield, ?Await] + `!` UnaryExpression[?Yield, ?Await] + [+Await] CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] #awaitusingcover + + CoverAwaitExpressionAndAwaitUsingDeclarationHead[Yield] : + `await` UnaryExpression[?Yield, +Await] + + + CoverVoidExpressionAndVoidDiscard[Yield, Await] : + `void` UnaryExpression[?Yield, ?Await]? + + + + +

The `void` Operator

+ + +

Supplemental Syntax

+

+ In certain circumstances when processing an instance of the production
+ UnaryExpression : CoverVoidExpressionAndVoidDiscard
+ the interpretation of |CoverVoidExpressionAndVoidDiscard| is refined using the following grammar: +

+ + VoidExpression[Yield, Await] : + `void` UnaryExpression[?Yield, ?Await] + +
+ + +

Runtime Semantics: Evaluation

+ + + UnaryExpression : CoverVoidExpressionAndVoidDiscard + + + 1. Let _voidExpr_ be the |VoidExpression| that is covered by |CoverVoidExpressionAndVoidDiscard|. + 1. Let _expr_ be ? Evaluation of _voidExpr_. + 1. Perform ? GetValue(_expr_). + 1. Return *undefined*. + + + + UnaryExpression : `void` UnaryExpression + VoidExpression : `void` UnaryExpression + + + 1. Let _expr_ be ? Evaluation of |UnaryExpression|. + 1. Perform ? GetValue(_expr_). + 1. Return *undefined*. + + +

GetValue must be called even though its value is not used because it may have observable side-effects.

+
+
+
+
+ + +

Assignment Operators

+ + + +

Destructuring Assignment

+

Supplemental Syntax

+

+ In certain circumstances when processing an instance of the production
+ AssignmentExpression : LeftHandSideExpression `=` AssignmentExpression
+ the interpretation of |LeftHandSideExpression| is refined using the following grammar: +

+ + AssignmentPattern[Yield, Await] : + ObjectAssignmentPattern[?Yield, ?Await] + ArrayAssignmentPattern[?Yield, ?Await] + + ObjectAssignmentPattern[Yield, Await] : + `{` `}` + `{` AssignmentRestProperty[?Yield, ?Await] `}` + `{` AssignmentPropertyList[?Yield, ?Await] `}` + `{` AssignmentPropertyList[?Yield, ?Await] `,` AssignmentRestProperty[?Yield, ?Await]? `}` + + ArrayAssignmentPattern[Yield, Await] : + `[` Elision? AssignmentRestElement[?Yield, ?Await]? `]` + `[` AssignmentElementList[?Yield, ?Await] `]` + `[` AssignmentElementList[?Yield, ?Await] `,` Elision? AssignmentRestElement[?Yield, ?Await]? `]` + + AssignmentRestProperty[Yield, Await] : + `...` DestructuringAssignmentTarget[?Yield, ?Await] + + AssignmentPropertyList[Yield, Await] : + AssignmentProperty[?Yield, ?Await] + AssignmentPropertyList[?Yield, ?Await] `,` AssignmentProperty[?Yield, ?Await] + + AssignmentElementList[Yield, Await] : + AssignmentElisionElement[?Yield, ?Await] + AssignmentElementList[?Yield, ?Await] `,` AssignmentElisionElement[?Yield, ?Await] + + AssignmentElisionElement[Yield, Await] : + Elision? AssignmentElement[?Yield, ?Await] + + AssignmentProperty[Yield, Await] : + IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]? + PropertyName[?Yield, ?Await] `:` AssignmentElement[?Yield, ?Await] + + AssignmentElement[Yield, Await] : + DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]? + + AssignmentRestElement[Yield, Await] : + `...` DestructuringAssignmentTarget[?Yield, ?Await] + + DestructuringAssignmentTarget[Yield, Await] : + LeftHandSideExpression[?Yield, ?Await] + `void` + + + +

Static Semantics: Early Errors

+ AssignmentProperty : IdentifierReference Initializer? +
    +
  • + It is a Syntax Error if AssignmentTargetType of |IdentifierReference| is not ~simple~. +
  • +
+ AssignmentRestProperty : `...` DestructuringAssignmentTarget +
    +
  • + It is a Syntax Error if |DestructuringAssignmentTarget| is either an |ArrayLiteral| or, an |ObjectLiteral|, or `void`. +
  • +
+ DestructuringAssignmentTarget : LeftHandSideExpression +
    +
  • + If |LeftHandSideExpression| is either an |ObjectLiteral| or an |ArrayLiteral|, |LeftHandSideExpression| must cover an |AssignmentPattern|. +
  • +
  • + If |LeftHandSideExpression| is neither an |ObjectLiteral| nor an |ArrayLiteral|, it is a Syntax Error if AssignmentTargetType of |LeftHandSideExpression| is not ~simple~. +
  • +
+
+ + +

+ Runtime Semantics: IteratorDestructuringAssignmentEvaluation ( + _iteratorRecord_: an Iterator Record, + ): either a normal completion containing ~unused~ or an abrupt completion +

+
+
+ AssignmentElementList : AssignmentElisionElement + + 1. Return ? IteratorDestructuringAssignmentEvaluation of |AssignmentElisionElement| with argument _iteratorRecord_. + + AssignmentElementList : AssignmentElementList `,` AssignmentElisionElement + + 1. Perform ? IteratorDestructuringAssignmentEvaluation of |AssignmentElementList| with argument _iteratorRecord_. + 1. Return ? IteratorDestructuringAssignmentEvaluation of |AssignmentElisionElement| with argument _iteratorRecord_. + + AssignmentElisionElement : AssignmentElement + + 1. Return ? IteratorDestructuringAssignmentEvaluation of |AssignmentElement| with argument _iteratorRecord_. + + AssignmentElisionElement : Elision AssignmentElement + + 1. Perform ? IteratorDestructuringAssignmentEvaluation of |Elision| with argument _iteratorRecord_. + 1. Return ? IteratorDestructuringAssignmentEvaluation of |AssignmentElement| with argument _iteratorRecord_. + + Elision : `,` + + 1. If _iteratorRecord_.[[Done]] is *false*, then + 1. Let _next_ be Completion(IteratorStep(_iteratorRecord_)). + 1. If _next_ is an abrupt completion, set _iteratorRecord_.[[Done]] to *true*. + 1. ReturnIfAbrupt(_next_). + 1. If _next_ is *false*, set _iteratorRecord_.[[Done]] to *true*. + 1. Return ~unused~. + + Elision : Elision `,` + + 1. Perform ? IteratorDestructuringAssignmentEvaluation of |Elision| with argument _iteratorRecord_. + 1. If _iteratorRecord_.[[Done]] is *false*, then + 1. Let _next_ be Completion(IteratorStep(_iteratorRecord_)). + 1. If _next_ is an abrupt completion, set _iteratorRecord_.[[Done]] to *true*. + 1. ReturnIfAbrupt(_next_). + 1. If _next_ is *false*, set _iteratorRecord_.[[Done]] to *true*. + 1. Return ~unused~. + + AssignmentElement : DestructuringAssignmentTarget Initializer? + + 1. If |DestructuringAssignmentTarget| is neither an |ObjectLiteral| nor, an |ArrayLiteral|, nor `void`, then + 1. Let _lref_ be ? Evaluation of |DestructuringAssignmentTarget|. + 1. Let _value_ be *undefined*. + 1. If _iteratorRecord_.[[Done]] is *false*, then + 1. Let _next_ be ? IteratorStepValue(_iteratorRecord_). + 1. If _next_ is not ~done~, then + 1. Set _value_ to _next_. + 1. If |Initializer| is present and _value_ is *undefined*, then + 1. If IsAnonymousFunctionDefinition(|Initializer|) is *true* and IsIdentifierRef of |DestructuringAssignmentTarget| is *true*, then + 1. Let _v_ be ? NamedEvaluation of |Initializer| with argument _lref_.[[ReferencedName]]. + 1. Else, + 1. Let _defaultValue_ be ? Evaluation of |Initializer|. + 1. Let _v_ be ? GetValue(_defaultValue_). + 1. Else, + 1. Let _v_ be _value_. + 1. If |DestructuringAssignmentTarget| is either an |ObjectLiteral| or an |ArrayLiteral|, then + 1. Let _nestedAssignmentPattern_ be the |AssignmentPattern| that is covered by |DestructuringAssignmentTarget|. + 1. Return ? DestructuringAssignmentEvaluation of _nestedAssignmentPattern_ with argument _v_. + 1. If |DestructuringAssignmentTarget| is `void`, then + 1. Return ~unused~. + 1. Return ? PutValue(_lref_, _v_). + + +

Left to right evaluation order is maintained by evaluating a |DestructuringAssignmentTarget| that is not a destructuring pattern prior to accessing the iterator or evaluating the |Initializer|.

+
+ AssignmentRestElement : `...` DestructuringAssignmentTarget + + 1. If |DestructuringAssignmentTarget| is neither an |ObjectLiteral| nor, an |ArrayLiteral|, nor `void`, then + 1. Let _lref_ be ? Evaluation of |DestructuringAssignmentTarget|. + 1. Let _A_ be ! ArrayCreate(0). + 1. Let _n_ be 0. + 1. Repeat, while _iteratorRecord_.[[Done]] is *false*, + 1. Let _next_ be ? IteratorStepValue(_iteratorRecord_). + 1. If _next_ is not ~done~, then + 1. Perform ! CreateDataPropertyOrThrow(_A_, ! ToString(𝔽(_n_)), _next_). + 1. Set _n_ to _n_ + 1. + 1. If |DestructuringAssignmentTarget| is neither an |ObjectLiteral| nor an |ArrayLiteral|, then + 1. Return ? PutValue(_lref_, _A_). + 1. Let _nestedAssignmentPattern_ be the |AssignmentPattern| that is covered by |DestructuringAssignmentTarget|. + 1. Return ? DestructuringAssignmentEvaluation of _nestedAssignmentPattern_ with argument _A_. + 1. If |DestructuringAssignmentTarget| is either an |ObjectLiteral| or an |ArrayLiteral|, then + 1. Let _nestedAssignmentPattern_ be the |AssignmentPattern| that is covered by |DestructuringAssignmentTarget|. + 1. Return ? DestructuringAssignmentEvaluation of _nestedAssignmentPattern_ with argument _A_. + 1. If |DestructuringAssignmentTarget| is `void`, then + 1. Return ~unused~. + 1. Return ? PutValue(_lref_, _A_). + +
+ + +

+ Runtime Semantics: KeyedDestructuringAssignmentEvaluation ( + _value_: an ECMAScript language value, + _propertyName_: a property key, + ): either a normal completion containing ~unused~ or an abrupt completion +

+
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer? + + 1. If |DestructuringAssignmentTarget| is neither an |ObjectLiteral| nor an |ArrayLiteral| nor `void`, then + 1. Let _lref_ be ? Evaluation of |DestructuringAssignmentTarget|. + 1. Let _v_ be ? GetV(_value_, _propertyName_). + 1. If |Initializer| is present and _v_ is *undefined*, then + 1. If IsAnonymousFunctionDefinition(|Initializer|) and IsIdentifierRef of |DestructuringAssignmentTarget| are both *true*, then + 1. Let _rhsValue_ be ? NamedEvaluation of |Initializer| with argument _lref_.[[ReferencedName]]. + 1. Else, + 1. Let _defaultValue_ be ? Evaluation of |Initializer|. + 1. Let _rhsValue_ be ? GetValue(_defaultValue_). + 1. Else, + 1. Let _rhsValue_ be _v_. + 1. If |DestructuringAssignmentTarget| is either an |ObjectLiteral| or an |ArrayLiteral|, then + 1. Let _assignmentPattern_ be the |AssignmentPattern| that is covered by |DestructuringAssignmentTarget|. + 1. Return ? DestructuringAssignmentEvaluation of _assignmentPattern_ with argument _rhsValue_. + 1. If |DestructuringAssignmentTarget| is `void`, then + 1. Return ~unused~. + 1. Return ? PutValue(_lref_, _rhsValue_). + +
+
+
- -

- IsAccepted ( - _proposal_: an ECMAScript language value - ): a Boolean -

-
-
description
-
Tells you if the proposal was accepted
-
- - 1. If _proposal_ is not a String, or is not accepted, return *false*. - 1. Return *true*. - + +

ECMAScript Language: Statements and Declarations

+ +

Declarations and the Variable Statement

+ +

Let, Const, Using, and Await Using Declarations

+ +

Syntax

+ + LexicalDeclaration[In, Yield, Await] : + LetOrConst BindingList[?In, ?Yield, ?Await, +Pattern] `;` + UsingDeclaration[?In, ?Yield, ?Await] + [+Await] AwaitUsingDeclaration[?In, ?Yield] + + LetOrConst : + `let` + `const` + + UsingDeclaration[In, Yield, Await] : + `using` [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` + + AwaitUsingDeclaration[In, Yield] : + CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] `;` + + BindingList[In, Yield, Await, Pattern] : + LexicalBinding[?In, ?Yield, ?Await, ?Pattern] + BindingList[?In, ?Yield, ?Await, ?Pattern] `,` LexicalBinding[?In, ?Yield, ?Await, ?Pattern] + + LexicalBinding[In, Yield, Await, Pattern] : + BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]? + [+Pattern] BindingPattern[?Yield, ?Await, ~Void] Initializer[?In, ?Yield, ?Await] + [~Pattern] `void` Initializer[?In, ?Yield, ?Await] + + + +

+ Runtime Semantics: BindingEvaluation ( + _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~, + ): either a normal completion containing ~unused~ or an abrupt completion +

+
+
+ BindingList : BindingList `,` LexicalBinding + + 1. Perform ? BindingEvaluation of |BindingList| with argument _hint_. + 1. Return ? BindingEvaluation of |LexicalBinding| with argument _hint_. + + LexicalBinding : BindingIdentifier + + 1. Assert: _hint_ is ~normal~. + 1. Let _lhs_ be ! ResolveBinding(StringValue of |BindingIdentifier|). + 1. Perform ! InitializeReferencedBinding(_lhs_, *undefined*, ~normal~). + 1. Return ~unused~. + + +

A static semantics rule ensures that this form of |LexicalBinding| never occurs in a `const`, `using`, or `await using` declaration.

+
+ LexicalBinding : BindingIdentifier Initializer + + 1. Let _bindingId_ be StringValue of |BindingIdentifier|. + 1. Let _lhs_ be ! ResolveBinding(_bindingId_). + 1. If IsAnonymousFunctionDefinition(|Initializer|) is *true*, then + 1. Let _value_ be ? NamedEvaluation of |Initializer| with argument _bindingId_. + 1. Else, + 1. Let _rhs_ be ? Evaluation of |Initializer|. + 1. Let _value_ be ? GetValue(_rhs_). + 1. Perform ? InitializeReferencedBinding(_lhs_, _value_, _hint_). + 1. Return ~unused~. + + + LexicalBinding : `void` Initializer + + 1. Assert: _hint_ is not ~normal~. + 1. Let _env_ be the running execution context's LexicalEnvironment. + 1. Assert: _env_ is an Environment Record. + 1. Let _rhs_ be ? Evaluation of |Initializer|. + 1. Let _value_ be ? GetValue(_rhs_). + 1. Perform ? AddDisposableResource(_env_.[[DisposeCapability]], _value_, _hint_). + 1. Return ~unused~. + + + LexicalBinding : BindingPattern Initializer + + 1. Assert: _hint_ is ~normal~. + 1. Let _rhs_ be ? Evaluation of |Initializer|. + 1. Let _value_ be ? GetValue(_rhs_). + 1. Let _env_ be the running execution context's LexicalEnvironment. + 1. Return ? BindingInitialization of |BindingPattern| with arguments _value_ and _env_. + +
+
+ + +

Variable Statement

+

Syntax

+ + VariableStatement[Yield, Await] : + `var` VariableDeclarationList[+In, ?Yield, ?Await] `;` + + VariableDeclarationList[In, Yield, Await] : + VariableDeclaration[?In, ?Yield, ?Await] + VariableDeclarationList[?In, ?Yield, ?Await] `,` VariableDeclaration[?In, ?Yield, ?Await] + + VariableDeclaration[In, Yield, Await] : + BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]? + BindingPattern[?Yield, ?Await, ~Void] Initializer[?In, ?Yield, ?Await] + +
+ + +

Destructuring Binding Patterns

+

Syntax

+ + BindingPattern[Yield, Await, Void] : + ObjectBindingPattern[?Yield, ?Await] + ArrayBindingPattern[?Yield, ?Await] + [+Void] `void` + + ObjectBindingPattern[Yield, Await] : + `{` `}` + `{` BindingRestProperty[?Yield, ?Await] `}` + `{` BindingPropertyList[?Yield, ?Await] `}` + `{` BindingPropertyList[?Yield, ?Await] `,` BindingRestProperty[?Yield, ?Await]? `}` + + ArrayBindingPattern[Yield, Await] : + `[` Elision? BindingRestElement[?Yield, ?Await]? `]` + `[` BindingElementList[?Yield, ?Await] `]` + `[` BindingElementList[?Yield, ?Await] `,` Elision? BindingRestElement[?Yield, ?Await]? `]` + + BindingRestProperty[Yield, Await] : + `...` BindingIdentifier[?Yield, ?Await] + + BindingPropertyList[Yield, Await] : + BindingProperty[?Yield, ?Await] + BindingPropertyList[?Yield, ?Await] `,` BindingProperty[?Yield, ?Await] + + BindingElementList[Yield, Await] : + BindingElisionElement[?Yield, ?Await] + BindingElementList[?Yield, ?Await] `,` BindingElisionElement[?Yield, ?Await] + + BindingElisionElement[Yield, Await] : + Elision? BindingElement[?Yield, ?Await] + + BindingProperty[Yield, Await] : + SingleNameBinding[?Yield, ?Await] + PropertyName[?Yield, ?Await] `:` BindingElement[?Yield, ?Await] + + BindingElement[Yield, Await] : + SingleNameBinding[?Yield, ?Await] + BindingPattern[?Yield, ?Await, +Void] Initializer[+In, ?Yield, ?Await]? + + SingleNameBinding[Yield, Await] : + BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]? + + BindingRestElement[Yield, Await] : + `...` BindingIdentifier[?Yield, ?Await] + `...` BindingPattern[?Yield, ?Await, +Void] + +
+