deps: update Acorn to v8.4.1

We can remove the Acorn plugins as their features are now supported
by default.

PR-URL: https://github.com/nodejs/node/pull/39166
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
Michaël Zasso 2021-06-27 09:50:24 +02:00
parent 30e878b603
commit 8630b39376
No known key found for this signature in database
GPG Key ID: 770F7A9A5AE15600
43 changed files with 847 additions and 1025 deletions

25
LICENSE
View File

@ -55,30 +55,7 @@ The externally maintained libraries used by Node.js are:
"""
MIT License
Copyright (C) 2012-2018 by various contributors (see AUTHORS)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
- Acorn plugins, located at deps/acorn-plugins, is licensed as follows:
"""
Copyright (C) 2017-2018 by Adrian Heine
Copyright (C) 2012-2020 by various contributors (see AUTHORS)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,28 +0,0 @@
## 0.3.1 (2019-02-09)
* Restore compatibility with acorn-private-methods
## 0.3.0 (2019-02-09)
* Require acorn >= 6.1.0
## 0.2.1 (2018-11-06)
* Adapt to changes in acorn 6.0.3
## 0.2.0 (2018-09-14)
* Update to new acorn 6 interface
* Change license to MIT
## 0.1.2 (2018-01-26)
* Don't accept whitespace between hash and private name
## 0.1.1 (2018-01-17)
* Correctly parse all fields named `async`
## 0.1.0 (2018-01-13)
Initial release

View File

@ -1,19 +0,0 @@
Copyright (C) 2017-2018 by Adrian Heine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,21 +0,0 @@
# Class fields support for Acorn
[![NPM version](https://img.shields.io/npm/v/acorn-class-fields.svg)](https://www.npmjs.org/package/acorn-class-fields)
This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
It implements support for class fields as defined in the stage 3 proposal [Class field declarations for JavaScript](https://github.com/tc39/proposal-class-fields). The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180).
## Usage
This module provides a plugin that can be used to extend the Acorn `Parser` class:
```javascript
const {Parser} = require('acorn');
const classFields = require('acorn-class-fields');
Parser.extend(classFields).parse('class X { x = 0 }');
```
## License
This plugin is released under an [MIT License](./LICENSE).

View File

@ -1,59 +0,0 @@
"use strict"
const acorn = require('internal/deps/acorn/acorn/dist/acorn')
const tt = acorn.tokTypes
const privateClassElements = require('internal/deps/acorn-plugins/acorn-private-class-elements/index')
function maybeParseFieldValue(field) {
if (this.eat(tt.eq)) {
const oldInFieldValue = this._inFieldValue
this._inFieldValue = true
field.value = this.parseExpression()
this._inFieldValue = oldInFieldValue
} else field.value = null
}
module.exports = function(Parser) {
Parser = privateClassElements(Parser)
return class extends Parser {
// Parse fields
parseClassElement(_constructorAllowsSuper) {
if (this.options.ecmaVersion >= 8 && (this.type == tt.name || this.type == this.privateNameToken || this.type == tt.bracketL || this.type == tt.string)) {
const branch = this._branch()
if (branch.type == tt.bracketL) {
let count = 0
do {
if (branch.eat(tt.bracketL)) ++count
else if (branch.eat(tt.bracketR)) --count
else branch.next()
} while (count > 0)
} else branch.next()
if (branch.type == tt.eq || branch.canInsertSemicolon() || branch.type == tt.semi) {
const node = this.startNode()
if (this.type == this.privateNameToken) {
this.parsePrivateClassElementName(node)
} else {
this.parsePropertyName(node)
}
if ((node.key.type === "Identifier" && node.key.name === "constructor") ||
(node.key.type === "Literal" && node.key.value === "constructor")) {
this.raise(node.key.start, "Classes may not have a field called constructor")
}
maybeParseFieldValue.call(this, node)
this.finishNode(node, "FieldDefinition")
this.semicolon()
return node
}
}
return super.parseClassElement.apply(this, arguments)
}
// Prohibit arguments in class field initializers
parseIdent(liberal, isBinding) {
const ident = super.parseIdent(liberal, isBinding)
if (this._inFieldValue && ident.name == "arguments") this.raise(ident.start, "A class field initializer may not contain arguments")
return ident
}
}
}

View File

@ -1,36 +0,0 @@
{
"name": "acorn-class-fields",
"description": "Support for class fields in acorn",
"homepage": "https://github.com/acornjs/acorn-class-fields",
"contributors": [
"Adrian Heine <mail@adrianheine.de>"
],
"engines": {
"node": ">=4.8.2"
},
"repository": {
"type": "git",
"url": "https://github.com/acornjs/acorn-class-fields"
},
"license": "MIT",
"scripts": {
"test": "mocha",
"test:test262": "node run_test262.js",
"lint": "eslint -c .eslintrc.json ."
},
"peerDependencies": {
"acorn": "^6.0.0"
},
"version": "0.3.1",
"devDependencies": {
"acorn": "^6.1.0",
"eslint": "^5.13.0",
"eslint-plugin-node": "^8.0.1",
"mocha": "^5.2.0",
"test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d",
"test262-parser-runner": "^0.5.0"
},
"dependencies": {
"acorn-private-class-elements": "^0.1.1"
}
}

View File

@ -1,11 +0,0 @@
## 0.2.0 (2020-03-07)
* Mark as compatible with acorn v7
## 0.1.1 (2019-02-09)
* Add \_branch() method
## 0.1.0 (2019-02-09)
Initial release

View File

@ -1,19 +0,0 @@
Copyright (C) 2017-2018 by Adrian Heine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,11 +0,0 @@
# Helpers for supporting private class methods and fields for Acorn
[![NPM version](https://img.shields.io/npm/v/acorn-private-class-elements.svg)](https://www.npmjs.org/package/acorn-private-class-elements)
This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
It provides helpers for implementing support for private class elements. The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180).
## License
This plugin is released under an [MIT License](./LICENSE).

View File

@ -1,123 +0,0 @@
"use strict"
const acorn = require('internal/deps/acorn/acorn/dist/acorn')
if (acorn.version.indexOf("6.") != 0 && acorn.version.indexOf("6.0.") == 0 && acorn.version.indexOf("7.") != 0) {
throw new Error(`acorn-private-class-elements requires acorn@^6.1.0 or acorn@7.0.0, not ${acorn.version}`)
}
const tt = acorn.tokTypes
const TokenType = acorn.TokenType
module.exports = function(Parser) {
// Only load this plugin once.
if (Parser.prototype.parsePrivateName) {
return Parser
}
// Make sure `Parser` comes from the same acorn as our `tt`,
// otherwise the comparisons fail.
let cur = Parser
while (cur && cur !== acorn.Parser) {
cur = cur.__proto__
}
if (cur !== acorn.Parser) {
throw new Error("acorn-private-class-elements does not support mixing different acorn copies")
}
Parser = class extends Parser {
_branch() {
this.__branch = this.__branch || new Parser({ecmaVersion: this.options.ecmaVersion}, this.input)
this.__branch.end = this.end
this.__branch.pos = this.pos
this.__branch.type = this.type
this.__branch.value = this.value
this.__branch.containsEsc = this.containsEsc
return this.__branch
}
parsePrivateClassElementName(element) {
element.computed = false
element.key = this.parsePrivateName()
if (element.key.name == "constructor") this.raise(element.key.start, "Classes may not have a private element named constructor")
const accept = {get: "set", set: "get"}[element.kind]
const privateBoundNames = this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1]
if (Object.prototype.hasOwnProperty.call(privateBoundNames, element.key.name) && privateBoundNames[element.key.name] !== accept) {
this.raise(element.start, "Duplicate private element")
}
privateBoundNames[element.key.name] = element.kind || true
delete this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1][element.key.name]
return element.key
}
parsePrivateName() {
const node = this.startNode()
node.name = this.value
this.next()
this.finishNode(node, "PrivateName")
if (this.options.allowReserved == "never") this.checkUnreserved(node)
return node
}
// Parse # token
getTokenFromCode(code) {
if (code === 35) {
++this.pos
const word = this.readWord1()
return this.finishToken(this.privateNameToken, word)
}
return super.getTokenFromCode(code)
}
// Manage stacks and check for undeclared private names
parseClass(node, isStatement) {
this._privateBoundNamesStack = this._privateBoundNamesStack || []
const privateBoundNames = Object.create(this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1] || null)
this._privateBoundNamesStack.push(privateBoundNames)
this._unresolvedPrivateNamesStack = this._unresolvedPrivateNamesStack || []
const unresolvedPrivateNames = Object.create(null)
this._unresolvedPrivateNamesStack.push(unresolvedPrivateNames)
const _return = super.parseClass(node, isStatement)
this._privateBoundNamesStack.pop()
this._unresolvedPrivateNamesStack.pop()
if (!this._unresolvedPrivateNamesStack.length) {
const names = Object.keys(unresolvedPrivateNames)
if (names.length) {
names.sort((n1, n2) => unresolvedPrivateNames[n1] - unresolvedPrivateNames[n2])
this.raise(unresolvedPrivateNames[names[0]], "Usage of undeclared private name")
}
} else Object.assign(this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1], unresolvedPrivateNames)
return _return
}
// Parse private element access
parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow) {
if (!this.eat(tt.dot)) {
return super.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow)
}
let node = this.startNodeAt(startPos, startLoc)
node.object = base
node.computed = false
if (this.type == this.privateNameToken) {
node.property = this.parsePrivateName()
if (!this._privateBoundNamesStack.length || !this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1][node.property.name]) {
this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1][node.property.name] = node.property.start
}
} else {
node.property = this.parseIdent(true)
}
return this.finishNode(node, "MemberExpression")
}
// Prohibit delete of private class elements
parseMaybeUnary(refDestructuringErrors, sawUnary) {
const _return = super.parseMaybeUnary(refDestructuringErrors, sawUnary)
if (_return.operator == "delete") {
if (_return.argument.type == "MemberExpression" && _return.argument.property.type == "PrivateName") {
this.raise(_return.start, "Private elements may not be deleted")
}
}
return _return
}
}
Parser.prototype.privateNameToken = new TokenType("privateName")
return Parser
}

View File

@ -1,30 +0,0 @@
{
"name": "acorn-private-class-elements",
"description": "Helpers for supporting private class methods and fields in acorn",
"homepage": "https://github.com/acornjs/acorn-private-class-elements",
"contributors": [
"Adrian Heine <mail@adrianheine.de>"
],
"engines": {
"node": ">=4.8.2"
},
"repository": {
"type": "git",
"url": "https://github.com/acornjs/acorn-private-class-elements"
},
"license": "MIT",
"scripts": {
"test": "mocha",
"lint": "eslint -c .eslintrc.json ."
},
"peerDependencies": {
"acorn": "^6.1.0 || ^7.0.0"
},
"version": "0.2.0",
"devDependencies": {
"acorn": "^7.0.0",
"eslint": "^6.8.0",
"eslint-plugin-node": "^11.0.0",
"mocha": "^7.1.0"
}
}

View File

@ -1,29 +0,0 @@
## 0.3.0 (2019-02-09)
* Require acorn >= 6.1.0
## 0.2.3 (2019-02-09)
* Forbid binding await in async arrow function's parameter list
## 0.2.2 (2019-01-30)
* Fix parsing of chained subscripts
## 0.2.1 (2018-11-06)
* Adapt to changes in acorn 6.0.3
## 0.2.0 (2018-09-14)
* Update to new acorn 6 interface
* Change license to MIT
* Don't allow direct super() calls in private methods
## 0.1.1 (2018-02-09)
* Don't accept whitespace between hash and private name
## 0.1.0 (2018-01-13)
Initial release

View File

@ -1,19 +0,0 @@
Copyright (C) 2017-2018 by Adrian Heine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,21 +0,0 @@
# Private methods and getter/setters support for Acorn
[![NPM version](https://img.shields.io/npm/v/acorn-private-methods.svg)](https://www.npmjs.org/package/acorn-private-methods)
This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
It implements support for private methods, getters and setters as defined in the stage 3 proposal [Private methods and getter/setters for JavaScript classes](https://github.com/tc39/proposal-private-methods). The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180).
## Usage
This module provides a plugin that can be used to extend the Acorn `Parser` class:
```javascript
const {Parser} = require('acorn');
const privateMethods = require('acorn-private-methods');
Parser.extend(privateMethods).parse('class X { #a() {} }');
```
## License
This plugin is released under an [MIT License](./LICENSE).

View File

@ -1,25 +0,0 @@
"use strict"
const privateClassElements = require('internal/deps/acorn-plugins/acorn-private-class-elements/index')
module.exports = function(Parser) {
const ExtendedParser = privateClassElements(Parser)
return class extends ExtendedParser {
// Parse private methods
parseClassElement(_constructorAllowsSuper) {
const oldInClassMemberName = this._inClassMemberName
this._inClassMemberName = true
const result = super.parseClassElement.apply(this, arguments)
this._inClassMemberName = oldInClassMemberName
return result
}
parsePropertyName(prop) {
const isPrivate = this.options.ecmaVersion >= 8 && this._inClassMemberName && this.type == this.privateNameToken
this._inClassMemberName = false
if (!isPrivate) return super.parsePropertyName(prop)
return this.parsePrivateClassElementName(prop)
}
}
}

View File

@ -1,36 +0,0 @@
{
"name": "acorn-private-methods",
"description": "Support for private methods in acorn",
"homepage": "https://github.com/acornjs/acorn-private-methods",
"contributors": [
"Adrian Heine <mail@adrianheine.de>"
],
"engines": {
"node": ">=4.8.2"
},
"repository": {
"type": "git",
"url": "https://github.com/acornjs/acorn-private-methods"
},
"license": "MIT",
"scripts": {
"test": "mocha",
"test:test262": "node run_test262.js",
"lint": "eslint -c .eslintrc.json ."
},
"peerDependencies": {
"acorn": "^6.1.0"
},
"dependencies": {
"acorn-private-class-elements": "^0.1.0"
},
"version": "0.3.0",
"devDependencies": {
"acorn": "^6.1.0",
"eslint": "^5.13.0",
"eslint-plugin-node": "^8.0.1",
"mocha": "^5.2.0",
"test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d",
"test262-parser-runner": "^0.5.0"
}
}

View File

@ -1,11 +0,0 @@
## 0.2.0 (2019-02-09)
* Require acorn >= 6.1.0
## 0.1.1 (2018-11-06)
* Adapt to changes in acorn 6.0.3
## 0.1.0 (2018-09-14)
Initial release

View File

@ -1,19 +0,0 @@
Copyright (C) 2017-2018 by Adrian Heine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,21 +0,0 @@
# Static class features support for Acorn
[![NPM version](https://img.shields.io/npm/v/acorn-class-fields.svg)](https://www.npmjs.org/package/acorn-static-class-features)
This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
It implements support for static class features as defined in the stage 3 proposal [Static class features](https://github.com/tc39/proposal-static-class-features). The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180).
## Usage
This module provides a plugin that can be used to extend the Acorn `Parser` class:
```javascript
const {Parser} = require('acorn');
const staticClassFeatures = require('acorn-static-class-features');
Parser.extend(staticClassFeatures).parse('class X { static x = 0 }');
```
## License
This plugin is released under an [MIT License](./LICENSE).

View File

@ -1,126 +0,0 @@
"use strict"
const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g
const acorn = require('internal/deps/acorn/acorn/dist/acorn')
const tt = acorn.tokTypes
function maybeParseFieldValue(field) {
if (this.eat(tt.eq)) {
const oldInFieldValue = this._inStaticFieldValue
this._inStaticFieldValue = true
field.value = this.parseExpression()
this._inStaticFieldValue = oldInFieldValue
} else field.value = null
}
const privateClassElements = require("internal/deps/acorn-plugins/acorn-private-class-elements/index")
module.exports = function(Parser) {
const ExtendedParser = privateClassElements(Parser)
return class extends ExtendedParser {
// Parse private fields
parseClassElement(_constructorAllowsSuper) {
if (this.eat(tt.semi)) return null
const node = this.startNode()
const tryContextual = (k, noLineBreak) => {
if (typeof noLineBreak == "undefined") noLineBreak = false
const start = this.start, startLoc = this.startLoc
if (!this.eatContextual(k)) return false
if (this.type !== tt.parenL && (!noLineBreak || !this.canInsertSemicolon())) return true
if (node.key) this.unexpected()
node.computed = false
node.key = this.startNodeAt(start, startLoc)
node.key.name = k
this.finishNode(node.key, "Identifier")
return false
}
node.static = tryContextual("static")
if (!node.static) return super.parseClassElement.apply(this, arguments)
let isGenerator = this.eat(tt.star)
let isAsync = false
if (!isGenerator) {
// Special-case for `async`, since `parseClassMember` currently looks
// for `(` to determine whether `async` is a method name
if (this.options.ecmaVersion >= 8 && this.isContextual("async")) {
skipWhiteSpace.lastIndex = this.pos
let skip = skipWhiteSpace.exec(this.input)
let next = this.input.charAt(this.pos + skip[0].length)
if (next === ";" || next === "=") {
node.key = this.parseIdent(true)
node.computed = false
maybeParseFieldValue.call(this, node)
this.finishNode(node, "FieldDefinition")
this.semicolon()
return node
} else if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
isAsync = true
isGenerator = this.options.ecmaVersion >= 9 && this.eat(tt.star)
}
} else if (tryContextual("get")) {
node.kind = "get"
} else if (tryContextual("set")) {
node.kind = "set"
}
}
if (this.type === this.privateNameToken) {
this.parsePrivateClassElementName(node)
if (this.type !== tt.parenL) {
if (node.key.name === "prototype") {
this.raise(node.key.start, "Classes may not have a private static property named prototype")
}
maybeParseFieldValue.call(this, node)
this.finishNode(node, "FieldDefinition")
this.semicolon()
return node
}
} else if (!node.key) {
this.parsePropertyName(node)
if ((node.key.name || node.key.value) === "prototype" && !node.computed) {
this.raise(node.key.start, "Classes may not have a static property named prototype")
}
}
if (!node.kind) node.kind = "method"
this.parseClassMethod(node, isGenerator, isAsync)
if (!node.kind && (node.key.name || node.key.value) === "constructor" && !node.computed) {
this.raise(node.key.start, "Classes may not have a static field named constructor")
}
if (node.kind === "get" && node.value.params.length !== 0) {
this.raiseRecoverable(node.value.start, "getter should have no params")
}
if (node.kind === "set" && node.value.params.length !== 1) {
this.raiseRecoverable(node.value.start, "setter should have exactly one param")
}
if (node.kind === "set" && node.value.params[0].type === "RestElement") {
this.raiseRecoverable(node.value.params[0].start, "Setter cannot use rest params")
}
return node
}
// Parse public static fields
parseClassMethod(method, isGenerator, isAsync, _allowsDirectSuper) {
if (isGenerator || isAsync || method.kind != "method" || !method.static || this.options.ecmaVersion < 8 || this.type == tt.parenL) {
return super.parseClassMethod.apply(this, arguments)
}
maybeParseFieldValue.call(this, method)
delete method.kind
method = this.finishNode(method, "FieldDefinition")
this.semicolon()
return method
}
// Prohibit arguments in class field initializers
parseIdent(liberal, isBinding) {
const ident = super.parseIdent(liberal, isBinding)
if (this._inStaticFieldValue && ident.name == "arguments") this.raise(ident.start, "A static class field initializer may not contain arguments")
return ident
}
}
}

View File

@ -1,36 +0,0 @@
{
"name": "acorn-static-class-features",
"description": "Support for static class features in acorn",
"homepage": "https://github.com/acornjs/acorn-static-class-features",
"contributors": [
"Adrian Heine <mail@adrianheine.de>"
],
"engines": {
"node": ">=4.8.2"
},
"repository": {
"type": "git",
"url": "https://github.com/acornjs/acorn-static-class-features"
},
"license": "MIT",
"scripts": {
"test": "mocha",
"test:test262": "node run_test262.js",
"lint": "eslint -c .eslintrc.json ."
},
"peerDependencies": {
"acorn": "^6.1.0"
},
"version": "0.2.0",
"devDependencies": {
"acorn": "^6.1.0",
"eslint": "^5.13.0",
"eslint-plugin-node": "^8.0.1",
"mocha": "^5.2.0",
"test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d",
"test262-parser-runner": "^0.5.0"
},
"dependencies": {
"acorn-private-class-elements": "^0.1.1"
}
}

View File

@ -1,3 +1,21 @@
## 8.1.0 (2021-04-24)
### New features
Support node types for class fields and private methods.
## 8.0.2 (2021-01-25)
### Bug fixes
Adjust package.json to work with Node 12.16.0 and 13.0-13.6.
## 8.0.0 (2021-01-05)
### Bug fixes
Fix a bug where `full` and `fullAncestor` would skip nodes with overridden types.
## 8.0.0 (2020-08-12)
### New features

View File

@ -1,6 +1,6 @@
MIT License
Copyright (C) 2012-2018 by various contributors (see AUTHORS)
Copyright (C) 2012-2020 by various contributors (see AUTHORS)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -72,11 +72,15 @@
// A full walk triggers the callback on each node
function full(node, callback, baseVisitor, state, override) {
if (!baseVisitor) { baseVisitor = base
; }(function c(node, st, override) {
if (!baseVisitor) { baseVisitor = base; }
var last
;(function c(node, st, override) {
var type = override || node.type;
baseVisitor[type](node, st, c);
if (!override) { callback(node, st, type); }
if (last !== node) {
callback(node, st, type);
last = node;
}
})(node, state, override);
}
@ -84,13 +88,16 @@
// the callback on each node
function fullAncestor(node, callback, baseVisitor, state) {
if (!baseVisitor) { baseVisitor = base; }
var ancestors = []
var ancestors = [], last
;(function c(node, st, override) {
var type = override || node.type;
var isNew = node !== ancestors[ancestors.length - 1];
if (isNew) { ancestors.push(node); }
baseVisitor[type](node, st, c);
if (!override) { callback(node, st || ancestors, ancestors, type); }
if (last !== node) {
callback(node, st || ancestors, ancestors, type);
last = node;
}
if (isNew) { ancestors.pop(); }
})(node, state);
}
@ -168,17 +175,10 @@
return max
}
// Fallback to an Object.create polyfill for older environments.
var create = Object.create || function(proto) {
function Ctor() {}
Ctor.prototype = proto;
return new Ctor
};
// Used to create a custom walker. Will fill in all missing node
// type properties with the defaults.
function make(funcs, baseVisitor) {
var visitor = create(baseVisitor || base);
var visitor = Object.create(baseVisitor || base);
for (var type in funcs) { visitor[type] = funcs[type]; }
return visitor
}
@ -421,7 +421,7 @@
base.ImportExpression = function (node, st, c) {
c(node.source, st, "Expression");
};
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore;
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore;
base.TaggedTemplateExpression = function (node, st, c) {
c(node.tag, st, "Expression");
@ -441,9 +441,9 @@
c(elt, st);
}
};
base.MethodDefinition = base.Property = function (node, st, c) {
base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) {
if (node.computed) { c(node.key, st, "Expression"); }
c(node.value, st, "Expression");
if (node.value) { c(node.value, st, "Expression"); }
};
exports.ancestor = ancestor;

File diff suppressed because one or more lines are too long

View File

@ -66,11 +66,15 @@ var Found = function Found(node, state) { this.node = node; this.state = state;
// A full walk triggers the callback on each node
function full(node, callback, baseVisitor, state, override) {
if (!baseVisitor) { baseVisitor = base
; }(function c(node, st, override) {
if (!baseVisitor) { baseVisitor = base; }
var last
;(function c(node, st, override) {
var type = override || node.type;
baseVisitor[type](node, st, c);
if (!override) { callback(node, st, type); }
if (last !== node) {
callback(node, st, type);
last = node;
}
})(node, state, override);
}
@ -78,13 +82,16 @@ function full(node, callback, baseVisitor, state, override) {
// the callback on each node
function fullAncestor(node, callback, baseVisitor, state) {
if (!baseVisitor) { baseVisitor = base; }
var ancestors = []
var ancestors = [], last
;(function c(node, st, override) {
var type = override || node.type;
var isNew = node !== ancestors[ancestors.length - 1];
if (isNew) { ancestors.push(node); }
baseVisitor[type](node, st, c);
if (!override) { callback(node, st || ancestors, ancestors, type); }
if (last !== node) {
callback(node, st || ancestors, ancestors, type);
last = node;
}
if (isNew) { ancestors.pop(); }
})(node, state);
}
@ -162,17 +169,10 @@ function findNodeBefore(node, pos, test, baseVisitor, state) {
return max
}
// Fallback to an Object.create polyfill for older environments.
var create = Object.create || function(proto) {
function Ctor() {}
Ctor.prototype = proto;
return new Ctor
};
// Used to create a custom walker. Will fill in all missing node
// type properties with the defaults.
function make(funcs, baseVisitor) {
var visitor = create(baseVisitor || base);
var visitor = Object.create(baseVisitor || base);
for (var type in funcs) { visitor[type] = funcs[type]; }
return visitor
}
@ -415,7 +415,7 @@ base.ImportDeclaration = function (node, st, c) {
base.ImportExpression = function (node, st, c) {
c(node.source, st, "Expression");
};
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore;
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore;
base.TaggedTemplateExpression = function (node, st, c) {
c(node.tag, st, "Expression");
@ -435,9 +435,9 @@ base.ClassBody = function (node, st, c) {
c(elt, st);
}
};
base.MethodDefinition = base.Property = function (node, st, c) {
base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) {
if (node.computed) { c(node.key, st, "Expression"); }
c(node.value, st, "Expression");
if (node.value) { c(node.value, st, "Expression"); }
};
export { ancestor, base, findNodeAfter, findNodeAround, findNodeAt, findNodeBefore, full, fullAncestor, make, recursive, simple };

File diff suppressed because one or more lines are too long

View File

@ -6,10 +6,17 @@
"types": "dist/walk.d.ts",
"module": "dist/walk.mjs",
"exports": {
"import": "./dist/walk.mjs",
"require": "./dist/walk.js"
".": [
{
"import": "./dist/walk.mjs",
"require": "./dist/walk.js",
"default": "./dist/walk.js"
},
"./dist/walk.js"
],
"./package.json": "./package.json"
},
"version": "8.0.0",
"version": "8.1.0",
"engines": {"node": ">=0.4.0"},
"maintainers": [
{

View File

@ -1,3 +1,79 @@
## 8.4.1 (2021-06-24)
### Bug fixes
Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources.
## 8.4.0 (2021-06-11)
### New features
A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context.
## 8.3.0 (2021-05-31)
### New features
Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher.
Add support for the `p` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag.
## 8.2.4 (2021-05-04)
### Bug fixes
Fix spec conformity in corner case 'for await (async of ...)'.
## 8.2.3 (2021-05-04)
### Bug fixes
Fix an issue where the library couldn't parse 'for (async of ...)'.
Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances.
## 8.2.2 (2021-04-29)
### Bug fixes
Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield.
## 8.2.1 (2021-04-24)
### Bug fixes
Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse.
## 8.2.0 (2021-04-24)
### New features
Add support for ES2022 class fields and private methods.
## 8.1.1 (2021-04-12)
### Various
Stop shipping source maps in the NPM package.
## 8.1.0 (2021-03-09)
### Bug fixes
Fix a spurious error in nested destructuring arrays.
### New features
Expose `allowAwaitOutsideFunction` in CLI interface.
Make `allowImportExportAnywhere` also apply to `import.meta`.
## 8.0.5 (2021-01-25)
### Bug fixes
Adjust package.json to work with Node 12.16.0 and 13.0-13.6.
## 8.0.4 (2020-10-05)
### Bug fixes

View File

@ -1,6 +1,6 @@
MIT License
Copyright (C) 2012-2018 by various contributors (see AUTHORS)
Copyright (C) 2012-2020 by various contributors (see AUTHORS)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -54,9 +54,10 @@ required):
- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be
either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019),
11 (2020), or 12 (2021, partial support), or `"latest"` (the latest
the library supports). This influences support for strict mode, the
set of reserved words, and support for new syntax features.
11 (2020), 12 (2021, partial support), 13 (2022, partial support)
or `"latest"` (the latest the library supports). This influences
support for strict mode, the set of reserved words, and support
for new syntax features.
**NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
implemented by Acorn. Other proposed new features must be
@ -90,13 +91,19 @@ required):
- **allowImportExportEverywhere**: By default, `import` and `export`
declarations can only appear at a program's top level. Setting this
option to `true` allows them anywhere where a statement is allowed.
- **allowAwaitOutsideFunction**: By default, `await` expressions can
only appear inside `async` functions. Setting this option to
option to `true` allows them anywhere where a statement is allowed,
and also allows `import.meta` expressions to appear in scripts
(when `sourceType` is not `"module"`).
- **allowAwaitOutsideFunction**: If `false`, `await` expressions can
only appear inside `async` functions. Defaults to `true` for
`ecmaVersion` 2022 and later, `false` for lower versions. Setting this option to
`true` allows to have top-level `await` expressions. They are
still not allowed in non-`async` functions, though.
- **allowSuperOutsideMethod**: By default, `super` outside a method
raises an error. Set this to `true` to accept such code.
- **allowHashBang**: When this is enabled (off by default), if the
code starts with the characters `#!` (as in a shellscript), the
first line will be treated as a comment.
@ -250,6 +257,9 @@ options:
- `--allow-hash-bang`: If the code starts with the characters #! (as
in a shellscript), the first line will be treated as a comment.
- `--allow-await-outside-function`: Allows top-level `await` expressions.
See the `allowAwaitOutsideFunction` option for more information.
- `--compact`: No whitespace is used in the AST output.
- `--silent`: Do not output the AST, just return the exit status.

View File

@ -12,7 +12,7 @@ declare namespace acorn {
}
interface Options {
ecmaVersion: 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 'latest'
ecmaVersion: 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 'latest'
sourceType?: 'script' | 'module'
onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
@ -20,6 +20,7 @@ declare namespace acorn {
allowReturnOutsideFunction?: boolean
allowImportExportEverywhere?: boolean
allowAwaitOutsideFunction?: boolean
allowSuperOutsideMethod?: boolean
allowHashBang?: boolean
locations?: boolean
onToken?: ((token: Token) => any) | Token[]
@ -88,6 +89,7 @@ declare namespace acorn {
regexp: TokenType
string: TokenType
name: TokenType
privateId: TokenType
eof: TokenType
bracketL: TokenType
bracketR: TokenType

View File

@ -152,6 +152,7 @@
regexp: new TokenType("regexp", startsExpr),
string: new TokenType("string", startsExpr),
name: new TokenType("name", startsExpr),
privateId: new TokenType("privateId", startsExpr),
eof: new TokenType("eof"),
// Punctuation token types.
@ -320,9 +321,10 @@
var defaultOptions = {
// `ecmaVersion` indicates the ECMAScript version to parse. Must be
// either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10
// (2019), 11 (2020), 12 (2021), or `"latest"` (the latest version
// the library supports). This influences support for strict mode,
// the set of reserved words, and support for new syntax features.
// (2019), 11 (2020), 12 (2021), 13 (2022), or `"latest"` (the
// latest version the library supports). This influences support
// for strict mode, the set of reserved words, and support for
// new syntax features.
ecmaVersion: null,
// `sourceType` indicates the mode the code should be parsed in.
// Can be either `"script"` or `"module"`. This influences global
@ -346,11 +348,16 @@
// error.
allowReturnOutsideFunction: false,
// When enabled, import/export statements are not constrained to
// appearing at the top of the program.
// appearing at the top of the program, and an import.meta expression
// in a script isn't considered an error.
allowImportExportEverywhere: false,
// By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.
// When enabled, await identifiers are allowed to appear at the top-level scope,
// but they are still not allowed in non-async functions.
allowAwaitOutsideFunction: false,
allowAwaitOutsideFunction: null,
// When enabled, super identifiers are not constrained to
// appearing in methods and do not raise an error when they appear elsewhere.
allowSuperOutsideMethod: null,
// When enabled, hashbang directive in the beginning of file
// is allowed and treated as a line comment.
allowHashBang: false,
@ -537,13 +544,14 @@
// Used to signify the start of a potential arrow function
this.potentialArrowAt = -1;
this.potentialArrowInForAwait = false;
// Positions to delayed-check that yield/await does not exist in default parameters.
this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
// Labels in scope.
this.labels = [];
// Thus-far undefined exports.
this.undefinedExports = {};
this.undefinedExports = Object.create(null);
// If enabled, skip leading hashbang line.
if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
@ -555,9 +563,14 @@
// For RegExp validation
this.regexpState = null;
// The stack of private names.
// Each element has two properties: 'declared' and 'used'.
// When it exited from the outermost class definition, all used private names must be declared.
this.privateNameStack = [];
};
var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },inNonArrowFunction: { configurable: true } };
var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },inNonArrowFunction: { configurable: true } };
Parser.prototype.parse = function parse () {
var node = this.options.program || this.startNode();
@ -566,12 +579,30 @@
};
prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 };
prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit };
prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit };
prototypeAccessors.canAwait.get = function () {
for (var i = this.scopeStack.length - 1; i >= 0; i--) {
var scope = this.scopeStack[i];
if (scope.inClassFieldInit) { return false }
if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 }
}
return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
};
prototypeAccessors.allowSuper.get = function () {
var ref = this.currentThisScope();
var flags = ref.flags;
var inClassFieldInit = ref.inClassFieldInit;
return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod
};
prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
prototypeAccessors.inNonArrowFunction.get = function () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 };
prototypeAccessors.inNonArrowFunction.get = function () {
var ref = this.currentThisScope();
var flags = ref.flags;
var inClassFieldInit = ref.inClassFieldInit;
return (flags & SCOPE_FUNCTION) > 0 || inClassFieldInit
};
Parser.extend = function extend () {
var plugins = [], len = arguments.length;
@ -757,7 +788,7 @@
// to its body instead of creating a new node.
pp$1.parseTopLevel = function(node) {
var exports = {};
var exports = Object.create(null);
if (!node.body) { node.body = []; }
while (this.type !== types.eof) {
var stmt = this.parseStatement(null, true, exports);
@ -787,13 +818,14 @@
// Statement) is allowed here. If context is not empty then only a Statement
// is allowed. However, `let [` is an explicit negative lookahead for
// ExpressionStatement, so special-case it first.
if (nextCh === 91) { return true } // '['
if (nextCh === 91 || nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '[', '/', astral
if (context) { return false }
if (nextCh === 123) { return true } // '{'
if (isIdentifierStart(nextCh, true)) {
var pos = next + 1;
while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }
if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
var ident = this.input.slice(next, pos);
if (!keywordRelationalOperator.test(ident)) { return true }
}
@ -809,10 +841,11 @@
skipWhiteSpace.lastIndex = this.pos;
var skip = skipWhiteSpace.exec(this.input);
var next = this.pos + skip[0].length;
var next = this.pos + skip[0].length, after;
return !lineBreak.test(this.input.slice(this.pos, next)) &&
this.input.slice(next, next + 8) === "function" &&
(next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
(next + 8 === this.input.length ||
!(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))
};
// Parse a single statement.
@ -952,7 +985,7 @@
pp$1.parseForStatement = function(node) {
this.next();
var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1;
this.labels.push(loopLabel);
this.enterScope(0);
this.expect(types.parenL);
@ -978,7 +1011,7 @@
return this.parseFor(node, init$1)
}
var refDestructuringErrors = new DestructuringErrors;
var init = this.parseExpression(true, refDestructuringErrors);
var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors);
if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
if (this.options.ecmaVersion >= 9) {
if (this.type === types._in) {
@ -1324,6 +1357,7 @@
this.parseClassId(node, isStatement);
this.parseClassSuper(node);
var privateNameMap = this.enterClassBody();
var classBody = this.startNode();
var hadConstructor = false;
classBody.body = [];
@ -1335,77 +1369,154 @@
if (element.type === "MethodDefinition" && element.kind === "constructor") {
if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
hadConstructor = true;
} else if (element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) {
this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared"));
}
}
}
this.strict = oldStrict;
this.next();
node.body = this.finishNode(classBody, "ClassBody");
this.exitClassBody();
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
};
pp$1.parseClassElement = function(constructorAllowsSuper) {
var this$1 = this;
if (this.eat(types.semi)) { return null }
var method = this.startNode();
var tryContextual = function (k, noLineBreak) {
if ( noLineBreak === void 0 ) noLineBreak = false;
var start = this$1.start, startLoc = this$1.startLoc;
if (!this$1.eatContextual(k)) { return false }
if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
if (method.key) { this$1.unexpected(); }
method.computed = false;
method.key = this$1.startNodeAt(start, startLoc);
method.key.name = k;
this$1.finishNode(method.key, "Identifier");
return false
};
method.kind = "method";
method.static = tryContextual("static");
var isGenerator = this.eat(types.star);
var ecmaVersion = this.options.ecmaVersion;
var node = this.startNode();
var keyName = "";
var isGenerator = false;
var isAsync = false;
if (!isGenerator) {
if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
isAsync = true;
isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
} else if (tryContextual("get")) {
method.kind = "get";
} else if (tryContextual("set")) {
method.kind = "set";
var kind = "method";
// Parse modifiers
node.static = false;
if (this.eatContextual("static")) {
if (this.isClassElementNameStart() || this.type === types.star) {
node.static = true;
} else {
keyName = "static";
}
}
if (!method.key) { this.parsePropertyName(method); }
var key = method.key;
var allowsDirectSuper = false;
if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
key.type === "Literal" && key.value === "constructor")) {
if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
method.kind = "constructor";
allowsDirectSuper = constructorAllowsSuper;
} else if (method.static && key.type === "Identifier" && key.name === "prototype") {
this.raise(key.start, "Classes may not have a static property named prototype");
if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
if ((this.isClassElementNameStart() || this.type === types.star) && !this.canInsertSemicolon()) {
isAsync = true;
} else {
keyName = "async";
}
}
if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types.star)) {
isGenerator = true;
}
if (!keyName && !isAsync && !isGenerator) {
var lastValue = this.value;
if (this.eatContextual("get") || this.eatContextual("set")) {
if (this.isClassElementNameStart()) {
kind = lastValue;
} else {
keyName = lastValue;
}
}
}
// Parse element name
if (keyName) {
// 'async', 'get', 'set', or 'static' were not a keyword contextually.
// The last token is any of those. Make it the element name.
node.computed = false;
node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);
node.key.name = keyName;
this.finishNode(node.key, "Identifier");
} else {
this.parseClassElementName(node);
}
// Parse element value
if (ecmaVersion < 13 || this.type === types.parenL || kind !== "method" || isGenerator || isAsync) {
var isConstructor = !node.static && checkKeyName(node, "constructor");
var allowsDirectSuper = isConstructor && constructorAllowsSuper;
// Couldn't move this check into the 'parseClassMethod' method for backward compatibility.
if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); }
node.kind = isConstructor ? "constructor" : kind;
this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);
} else {
this.parseClassField(node);
}
return node
};
pp$1.isClassElementNameStart = function() {
return (
this.type === types.name ||
this.type === types.privateId ||
this.type === types.num ||
this.type === types.string ||
this.type === types.bracketL ||
this.type.keyword
)
};
pp$1.parseClassElementName = function(element) {
if (this.type === types.privateId) {
if (this.value === "constructor") {
this.raise(this.start, "Classes can't have an element named '#constructor'");
}
element.computed = false;
element.key = this.parsePrivateIdent();
} else {
this.parsePropertyName(element);
}
this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper);
if (method.kind === "get" && method.value.params.length !== 0)
{ this.raiseRecoverable(method.value.start, "getter should have no params"); }
if (method.kind === "set" && method.value.params.length !== 1)
{ this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
if (method.kind === "set" && method.value.params[0].type === "RestElement")
{ this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
return method
};
pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
// Check key and flags
var key = method.key;
if (method.kind === "constructor") {
if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
} else if (method.static && checkKeyName(method, "prototype")) {
this.raise(key.start, "Classes may not have a static property named prototype");
}
// Parse value
var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
// Check value
if (method.kind === "get" && value.params.length !== 0)
{ this.raiseRecoverable(value.start, "getter should have no params"); }
if (method.kind === "set" && value.params.length !== 1)
{ this.raiseRecoverable(value.start, "setter should have exactly one param"); }
if (method.kind === "set" && value.params[0].type === "RestElement")
{ this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); }
return this.finishNode(method, "MethodDefinition")
};
pp$1.parseClassField = function(field) {
if (checkKeyName(field, "constructor")) {
this.raise(field.key.start, "Classes can't have a field named 'constructor'");
} else if (field.static && checkKeyName(field, "prototype")) {
this.raise(field.key.start, "Classes can't have a static field named 'prototype'");
}
if (this.eat(types.eq)) {
// To raise SyntaxError if 'arguments' exists in the initializer.
var scope = this.currentThisScope();
var inClassFieldInit = scope.inClassFieldInit;
scope.inClassFieldInit = true;
field.value = this.parseMaybeAssign();
scope.inClassFieldInit = inClassFieldInit;
} else {
field.value = null;
}
this.semicolon();
return this.finishNode(field, "PropertyDefinition")
};
pp$1.parseClassId = function(node, isStatement) {
if (this.type === types.name) {
node.id = this.parseIdent();
@ -1422,6 +1533,65 @@
node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
};
pp$1.enterClassBody = function() {
var element = {declared: Object.create(null), used: []};
this.privateNameStack.push(element);
return element.declared
};
pp$1.exitClassBody = function() {
var ref = this.privateNameStack.pop();
var declared = ref.declared;
var used = ref.used;
var len = this.privateNameStack.length;
var parent = len === 0 ? null : this.privateNameStack[len - 1];
for (var i = 0; i < used.length; ++i) {
var id = used[i];
if (!has(declared, id.name)) {
if (parent) {
parent.used.push(id);
} else {
this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class"));
}
}
}
};
function isPrivateNameConflicted(privateNameMap, element) {
var name = element.key.name;
var curr = privateNameMap[name];
var next = "true";
if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) {
next = (element.static ? "s" : "i") + element.kind;
}
// `class { get #a(){}; static set #a(_){} }` is also conflict.
if (
curr === "iget" && next === "iset" ||
curr === "iset" && next === "iget" ||
curr === "sget" && next === "sset" ||
curr === "sset" && next === "sget"
) {
privateNameMap[name] = "true";
return false
} else if (!curr) {
privateNameMap[name] = next;
return false
} else {
return true
}
}
function checkKeyName(node, name) {
var computed = node.computed;
var key = node.key;
return !computed && (
key.type === "Identifier" && key.name === name ||
key.type === "Literal" && key.value === name
)
}
// Parses module export declaration.
pp$1.parseExport = function(node, exports) {
@ -2040,13 +2210,13 @@
// and object pattern might appear (so it's possible to raise
// delayed syntax error at correct position).
pp$3.parseExpression = function(noIn, refDestructuringErrors) {
pp$3.parseExpression = function(forInit, refDestructuringErrors) {
var startPos = this.start, startLoc = this.startLoc;
var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
if (this.type === types.comma) {
var node = this.startNodeAt(startPos, startLoc);
node.expressions = [expr];
while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); }
while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
return this.finishNode(node, "SequenceExpression")
}
return expr
@ -2055,9 +2225,9 @@
// Parse an assignment expression. This includes applications of
// operators like `+=`.
pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
pp$3.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
if (this.isContextual("yield")) {
if (this.inGenerator) { return this.parseYield(noIn) }
if (this.inGenerator) { return this.parseYield(forInit) }
// The tokenizer will assume an expression is allowed after
// `yield`, but this isn't that kind of yield
else { this.exprAllowed = false; }
@ -2074,9 +2244,11 @@
}
var startPos = this.start, startLoc = this.startLoc;
if (this.type === types.parenL || this.type === types.name)
{ this.potentialArrowAt = this.start; }
var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
if (this.type === types.parenL || this.type === types.name) {
this.potentialArrowAt = this.start;
this.potentialArrowInForAwait = forInit === "await";
}
var left = this.parseMaybeConditional(forInit, refDestructuringErrors);
if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
if (this.type.isAssign) {
var node = this.startNodeAt(startPos, startLoc);
@ -2094,7 +2266,7 @@
{ this.checkLValSimple(left); }
node.left = left;
this.next();
node.right = this.parseMaybeAssign(noIn);
node.right = this.parseMaybeAssign(forInit);
return this.finishNode(node, "AssignmentExpression")
} else {
if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
@ -2106,16 +2278,16 @@
// Parse a ternary conditional (`?:`) operator.
pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
pp$3.parseMaybeConditional = function(forInit, refDestructuringErrors) {
var startPos = this.start, startLoc = this.startLoc;
var expr = this.parseExprOps(noIn, refDestructuringErrors);
var expr = this.parseExprOps(forInit, refDestructuringErrors);
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
if (this.eat(types.question)) {
var node = this.startNodeAt(startPos, startLoc);
node.test = expr;
node.consequent = this.parseMaybeAssign();
this.expect(types.colon);
node.alternate = this.parseMaybeAssign(noIn);
node.alternate = this.parseMaybeAssign(forInit);
return this.finishNode(node, "ConditionalExpression")
}
return expr
@ -2123,11 +2295,11 @@
// Start the precedence parser.
pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
pp$3.parseExprOps = function(forInit, refDestructuringErrors) {
var startPos = this.start, startLoc = this.startLoc;
var expr = this.parseMaybeUnary(refDestructuringErrors, false);
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)
};
// Parse binary operators with the operator precedence parsing
@ -2136,9 +2308,9 @@
// defer further parser to one of its callers when it encounters an
// operator that has a lower precedence than the set it is parsing.
pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {
var prec = this.type.binop;
if (prec != null && (!noIn || this.type !== types._in)) {
if (prec != null && (!forInit || this.type !== types._in)) {
if (prec > minPrec) {
var logical = this.type === types.logicalOR || this.type === types.logicalAND;
var coalesce = this.type === types.coalesce;
@ -2150,12 +2322,12 @@
var op = this.value;
this.next();
var startPos = this.start, startLoc = this.startLoc;
var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, forInit);
var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) {
this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
}
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)
}
}
return left
@ -2171,9 +2343,9 @@
// Parse unary operators, both prefix and postfix.
pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec) {
var startPos = this.start, startLoc = this.startLoc, expr;
if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
if (this.isContextual("await") && this.canAwait) {
expr = this.parseAwait();
sawUnary = true;
} else if (this.type.prefix) {
@ -2181,12 +2353,14 @@
node.operator = this.value;
node.prefix = true;
this.next();
node.argument = this.parseMaybeUnary(null, true);
node.argument = this.parseMaybeUnary(null, true, update);
this.checkExpressionErrors(refDestructuringErrors, true);
if (update) { this.checkLValSimple(node.argument); }
else if (this.strict && node.operator === "delete" &&
node.argument.type === "Identifier")
{ this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
else if (node.operator === "delete" && isPrivateFieldAccess(node.argument))
{ this.raiseRecoverable(node.start, "Private fields can not be deleted"); }
else { sawUnary = true; }
expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
} else {
@ -2203,12 +2377,23 @@
}
}
if (!sawUnary && this.eat(types.starstar))
{ return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
else
{ return expr }
if (!incDec && this.eat(types.starstar)) {
if (sawUnary)
{ this.unexpected(this.lastTokStart); }
else
{ return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
} else {
return expr
}
};
function isPrivateFieldAccess(node) {
return (
node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" ||
node.type === "ChainExpression" && isPrivateFieldAccess(node.expression)
)
}
// Parse call, dot, and `[]`-subscript expressions.
pp$3.parseExprSubscripts = function(refDestructuringErrors) {
@ -2220,6 +2405,7 @@
if (refDestructuringErrors && result.type === "MemberExpression") {
if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }
}
return result
};
@ -2256,9 +2442,15 @@
if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) {
var node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never");
if (computed) {
node.property = this.parseExpression();
this.expect(types.bracketR);
} else if (this.type === types.privateId && base.type !== "Super") {
node.property = this.parsePrivateIdent();
} else {
node.property = this.parseIdent(this.options.allowReserved !== "never");
}
node.computed = !!computed;
if (computed) { this.expect(types.bracketR); }
if (optionalSupported) {
node.optional = optional;
}
@ -2344,7 +2536,8 @@
if (canBeArrow && !this.canInsertSemicolon()) {
if (this.eat(types.arrow))
{ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc &&
(!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) {
id = this.parseIdent(false);
if (this.canInsertSemicolon() || !this.eat(types.arrow))
{ this.unexpected(); }
@ -2462,7 +2655,7 @@
{ this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
if (containsEsc)
{ this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
if (this.options.sourceType !== "module")
if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere)
{ this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
return this.finishNode(node, "MetaProperty")
@ -2883,7 +3076,7 @@
// or "arguments" and duplicate parameters.
pp$3.checkParams = function(node, allowDuplicates) {
var nameHash = {};
var nameHash = Object.create(null);
for (var i = 0, list = node.params; i < list.length; i += 1)
{
var param = list[i];
@ -2930,6 +3123,8 @@
{ this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
if (this.inAsync && name === "await")
{ this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
if (this.currentThisScope().inClassFieldInit && name === "arguments")
{ this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); }
if (this.keywords.test(name))
{ this.raise(start, ("Unexpected keyword '" + name + "'")); }
if (this.options.ecmaVersion < 6 &&
@ -2974,9 +3169,29 @@
return node
};
pp$3.parsePrivateIdent = function() {
var node = this.startNode();
if (this.type === types.privateId) {
node.name = this.value;
} else {
this.unexpected();
}
this.next();
this.finishNode(node, "PrivateIdentifier");
// For validating existence
if (this.privateNameStack.length === 0) {
this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class"));
} else {
this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
}
return node
};
// Parses yield expression inside generator.
pp$3.parseYield = function(noIn) {
pp$3.parseYield = function(forInit) {
if (!this.yieldPos) { this.yieldPos = this.start; }
var node = this.startNode();
@ -2986,7 +3201,7 @@
node.argument = null;
} else {
node.delegate = this.eat(types.star);
node.argument = this.parseMaybeAssign(noIn);
node.argument = this.parseMaybeAssign(forInit);
}
return this.finishNode(node, "YieldExpression")
};
@ -3034,6 +3249,8 @@
this.lexical = [];
// A list of lexically-declared FunctionDeclaration names in the current lexical scope
this.functions = [];
// A switch to disallow the identifier reference 'arguments'
this.inClassFieldInit = false;
};
// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
@ -3365,7 +3582,7 @@
var RegExpValidationState = function RegExpValidationState(parser) {
this.parser = parser;
this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "");
this.unicodeProperties = data[parser.options.ecmaVersion >= 12 ? 12 : parser.options.ecmaVersion];
this.source = "";
this.flags = "";
@ -4510,9 +4727,9 @@
pp$9.fullCharCodeAtPos = function() {
var code = this.input.charCodeAt(this.pos);
if (code <= 0xd7ff || code >= 0xe000) { return code }
if (code <= 0xd7ff || code >= 0xdc00) { return code }
var next = this.input.charCodeAt(this.pos + 1);
return (code << 10) + next - 0x35fdc00
return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00
};
pp$9.skipBlockComment = function() {
@ -4731,6 +4948,20 @@
return this.finishOp(types.question, 1)
};
pp$9.readToken_numberSign = function() { // '#'
var ecmaVersion = this.options.ecmaVersion;
var code = 35; // '#'
if (ecmaVersion >= 13) {
++this.pos;
code = this.fullCharCodeAtPos();
if (isIdentifierStart(code, true) || code === 92 /* '\' */) {
return this.finishToken(types.privateId, this.readWord1())
}
}
this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
};
pp$9.getTokenFromCode = function(code) {
switch (code) {
// The interpretation of a dot depends on whether it is followed
@ -4802,6 +5033,9 @@
case 126: // '~'
return this.finishOp(types.prefix, 1)
case 35: // '#'
return this.readToken_numberSign()
}
this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
@ -5213,7 +5447,7 @@
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
var version = "8.0.4";
var version = "8.4.1";
Parser.acorn = {
Parser: Parser,
@ -5289,4 +5523,3 @@
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=acorn.js.map

File diff suppressed because one or more lines are too long

View File

@ -146,6 +146,7 @@ var types = {
regexp: new TokenType("regexp", startsExpr),
string: new TokenType("string", startsExpr),
name: new TokenType("name", startsExpr),
privateId: new TokenType("privateId", startsExpr),
eof: new TokenType("eof"),
// Punctuation token types.
@ -314,9 +315,10 @@ function getLineInfo(input, offset) {
var defaultOptions = {
// `ecmaVersion` indicates the ECMAScript version to parse. Must be
// either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10
// (2019), 11 (2020), 12 (2021), or `"latest"` (the latest version
// the library supports). This influences support for strict mode,
// the set of reserved words, and support for new syntax features.
// (2019), 11 (2020), 12 (2021), 13 (2022), or `"latest"` (the
// latest version the library supports). This influences support
// for strict mode, the set of reserved words, and support for
// new syntax features.
ecmaVersion: null,
// `sourceType` indicates the mode the code should be parsed in.
// Can be either `"script"` or `"module"`. This influences global
@ -340,11 +342,16 @@ var defaultOptions = {
// error.
allowReturnOutsideFunction: false,
// When enabled, import/export statements are not constrained to
// appearing at the top of the program.
// appearing at the top of the program, and an import.meta expression
// in a script isn't considered an error.
allowImportExportEverywhere: false,
// By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.
// When enabled, await identifiers are allowed to appear at the top-level scope,
// but they are still not allowed in non-async functions.
allowAwaitOutsideFunction: false,
allowAwaitOutsideFunction: null,
// When enabled, super identifiers are not constrained to
// appearing in methods and do not raise an error when they appear elsewhere.
allowSuperOutsideMethod: null,
// When enabled, hashbang directive in the beginning of file
// is allowed and treated as a line comment.
allowHashBang: false,
@ -531,13 +538,14 @@ var Parser = function Parser(options, input, startPos) {
// Used to signify the start of a potential arrow function
this.potentialArrowAt = -1;
this.potentialArrowInForAwait = false;
// Positions to delayed-check that yield/await does not exist in default parameters.
this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
// Labels in scope.
this.labels = [];
// Thus-far undefined exports.
this.undefinedExports = {};
this.undefinedExports = Object.create(null);
// If enabled, skip leading hashbang line.
if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
@ -549,9 +557,14 @@ var Parser = function Parser(options, input, startPos) {
// For RegExp validation
this.regexpState = null;
// The stack of private names.
// Each element has two properties: 'declared' and 'used'.
// When it exited from the outermost class definition, all used private names must be declared.
this.privateNameStack = [];
};
var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },inNonArrowFunction: { configurable: true } };
var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },inNonArrowFunction: { configurable: true } };
Parser.prototype.parse = function parse () {
var node = this.options.program || this.startNode();
@ -560,12 +573,30 @@ Parser.prototype.parse = function parse () {
};
prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 };
prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit };
prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit };
prototypeAccessors.canAwait.get = function () {
for (var i = this.scopeStack.length - 1; i >= 0; i--) {
var scope = this.scopeStack[i];
if (scope.inClassFieldInit) { return false }
if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 }
}
return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
};
prototypeAccessors.allowSuper.get = function () {
var ref = this.currentThisScope();
var flags = ref.flags;
var inClassFieldInit = ref.inClassFieldInit;
return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod
};
prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
prototypeAccessors.inNonArrowFunction.get = function () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 };
prototypeAccessors.inNonArrowFunction.get = function () {
var ref = this.currentThisScope();
var flags = ref.flags;
var inClassFieldInit = ref.inClassFieldInit;
return (flags & SCOPE_FUNCTION) > 0 || inClassFieldInit
};
Parser.extend = function extend () {
var plugins = [], len = arguments.length;
@ -751,7 +782,7 @@ var pp$1 = Parser.prototype;
// to its body instead of creating a new node.
pp$1.parseTopLevel = function(node) {
var exports = {};
var exports = Object.create(null);
if (!node.body) { node.body = []; }
while (this.type !== types.eof) {
var stmt = this.parseStatement(null, true, exports);
@ -781,13 +812,14 @@ pp$1.isLet = function(context) {
// Statement) is allowed here. If context is not empty then only a Statement
// is allowed. However, `let [` is an explicit negative lookahead for
// ExpressionStatement, so special-case it first.
if (nextCh === 91) { return true } // '['
if (nextCh === 91 || nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '[', '/', astral
if (context) { return false }
if (nextCh === 123) { return true } // '{'
if (isIdentifierStart(nextCh, true)) {
var pos = next + 1;
while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }
if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
var ident = this.input.slice(next, pos);
if (!keywordRelationalOperator.test(ident)) { return true }
}
@ -803,10 +835,11 @@ pp$1.isAsyncFunction = function() {
skipWhiteSpace.lastIndex = this.pos;
var skip = skipWhiteSpace.exec(this.input);
var next = this.pos + skip[0].length;
var next = this.pos + skip[0].length, after;
return !lineBreak.test(this.input.slice(this.pos, next)) &&
this.input.slice(next, next + 8) === "function" &&
(next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
(next + 8 === this.input.length ||
!(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))
};
// Parse a single statement.
@ -946,7 +979,7 @@ pp$1.parseDoStatement = function(node) {
pp$1.parseForStatement = function(node) {
this.next();
var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1;
this.labels.push(loopLabel);
this.enterScope(0);
this.expect(types.parenL);
@ -972,7 +1005,7 @@ pp$1.parseForStatement = function(node) {
return this.parseFor(node, init$1)
}
var refDestructuringErrors = new DestructuringErrors;
var init = this.parseExpression(true, refDestructuringErrors);
var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors);
if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
if (this.options.ecmaVersion >= 9) {
if (this.type === types._in) {
@ -1318,6 +1351,7 @@ pp$1.parseClass = function(node, isStatement) {
this.parseClassId(node, isStatement);
this.parseClassSuper(node);
var privateNameMap = this.enterClassBody();
var classBody = this.startNode();
var hadConstructor = false;
classBody.body = [];
@ -1329,77 +1363,154 @@ pp$1.parseClass = function(node, isStatement) {
if (element.type === "MethodDefinition" && element.kind === "constructor") {
if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
hadConstructor = true;
} else if (element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) {
this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared"));
}
}
}
this.strict = oldStrict;
this.next();
node.body = this.finishNode(classBody, "ClassBody");
this.exitClassBody();
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
};
pp$1.parseClassElement = function(constructorAllowsSuper) {
var this$1 = this;
if (this.eat(types.semi)) { return null }
var method = this.startNode();
var tryContextual = function (k, noLineBreak) {
if ( noLineBreak === void 0 ) noLineBreak = false;
var start = this$1.start, startLoc = this$1.startLoc;
if (!this$1.eatContextual(k)) { return false }
if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
if (method.key) { this$1.unexpected(); }
method.computed = false;
method.key = this$1.startNodeAt(start, startLoc);
method.key.name = k;
this$1.finishNode(method.key, "Identifier");
return false
};
method.kind = "method";
method.static = tryContextual("static");
var isGenerator = this.eat(types.star);
var ecmaVersion = this.options.ecmaVersion;
var node = this.startNode();
var keyName = "";
var isGenerator = false;
var isAsync = false;
if (!isGenerator) {
if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
isAsync = true;
isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
} else if (tryContextual("get")) {
method.kind = "get";
} else if (tryContextual("set")) {
method.kind = "set";
var kind = "method";
// Parse modifiers
node.static = false;
if (this.eatContextual("static")) {
if (this.isClassElementNameStart() || this.type === types.star) {
node.static = true;
} else {
keyName = "static";
}
}
if (!method.key) { this.parsePropertyName(method); }
var key = method.key;
var allowsDirectSuper = false;
if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
key.type === "Literal" && key.value === "constructor")) {
if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
method.kind = "constructor";
allowsDirectSuper = constructorAllowsSuper;
} else if (method.static && key.type === "Identifier" && key.name === "prototype") {
this.raise(key.start, "Classes may not have a static property named prototype");
if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
if ((this.isClassElementNameStart() || this.type === types.star) && !this.canInsertSemicolon()) {
isAsync = true;
} else {
keyName = "async";
}
}
if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types.star)) {
isGenerator = true;
}
if (!keyName && !isAsync && !isGenerator) {
var lastValue = this.value;
if (this.eatContextual("get") || this.eatContextual("set")) {
if (this.isClassElementNameStart()) {
kind = lastValue;
} else {
keyName = lastValue;
}
}
}
// Parse element name
if (keyName) {
// 'async', 'get', 'set', or 'static' were not a keyword contextually.
// The last token is any of those. Make it the element name.
node.computed = false;
node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);
node.key.name = keyName;
this.finishNode(node.key, "Identifier");
} else {
this.parseClassElementName(node);
}
// Parse element value
if (ecmaVersion < 13 || this.type === types.parenL || kind !== "method" || isGenerator || isAsync) {
var isConstructor = !node.static && checkKeyName(node, "constructor");
var allowsDirectSuper = isConstructor && constructorAllowsSuper;
// Couldn't move this check into the 'parseClassMethod' method for backward compatibility.
if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); }
node.kind = isConstructor ? "constructor" : kind;
this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);
} else {
this.parseClassField(node);
}
return node
};
pp$1.isClassElementNameStart = function() {
return (
this.type === types.name ||
this.type === types.privateId ||
this.type === types.num ||
this.type === types.string ||
this.type === types.bracketL ||
this.type.keyword
)
};
pp$1.parseClassElementName = function(element) {
if (this.type === types.privateId) {
if (this.value === "constructor") {
this.raise(this.start, "Classes can't have an element named '#constructor'");
}
element.computed = false;
element.key = this.parsePrivateIdent();
} else {
this.parsePropertyName(element);
}
this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper);
if (method.kind === "get" && method.value.params.length !== 0)
{ this.raiseRecoverable(method.value.start, "getter should have no params"); }
if (method.kind === "set" && method.value.params.length !== 1)
{ this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
if (method.kind === "set" && method.value.params[0].type === "RestElement")
{ this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
return method
};
pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
// Check key and flags
var key = method.key;
if (method.kind === "constructor") {
if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
} else if (method.static && checkKeyName(method, "prototype")) {
this.raise(key.start, "Classes may not have a static property named prototype");
}
// Parse value
var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
// Check value
if (method.kind === "get" && value.params.length !== 0)
{ this.raiseRecoverable(value.start, "getter should have no params"); }
if (method.kind === "set" && value.params.length !== 1)
{ this.raiseRecoverable(value.start, "setter should have exactly one param"); }
if (method.kind === "set" && value.params[0].type === "RestElement")
{ this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); }
return this.finishNode(method, "MethodDefinition")
};
pp$1.parseClassField = function(field) {
if (checkKeyName(field, "constructor")) {
this.raise(field.key.start, "Classes can't have a field named 'constructor'");
} else if (field.static && checkKeyName(field, "prototype")) {
this.raise(field.key.start, "Classes can't have a static field named 'prototype'");
}
if (this.eat(types.eq)) {
// To raise SyntaxError if 'arguments' exists in the initializer.
var scope = this.currentThisScope();
var inClassFieldInit = scope.inClassFieldInit;
scope.inClassFieldInit = true;
field.value = this.parseMaybeAssign();
scope.inClassFieldInit = inClassFieldInit;
} else {
field.value = null;
}
this.semicolon();
return this.finishNode(field, "PropertyDefinition")
};
pp$1.parseClassId = function(node, isStatement) {
if (this.type === types.name) {
node.id = this.parseIdent();
@ -1416,6 +1527,65 @@ pp$1.parseClassSuper = function(node) {
node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
};
pp$1.enterClassBody = function() {
var element = {declared: Object.create(null), used: []};
this.privateNameStack.push(element);
return element.declared
};
pp$1.exitClassBody = function() {
var ref = this.privateNameStack.pop();
var declared = ref.declared;
var used = ref.used;
var len = this.privateNameStack.length;
var parent = len === 0 ? null : this.privateNameStack[len - 1];
for (var i = 0; i < used.length; ++i) {
var id = used[i];
if (!has(declared, id.name)) {
if (parent) {
parent.used.push(id);
} else {
this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class"));
}
}
}
};
function isPrivateNameConflicted(privateNameMap, element) {
var name = element.key.name;
var curr = privateNameMap[name];
var next = "true";
if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) {
next = (element.static ? "s" : "i") + element.kind;
}
// `class { get #a(){}; static set #a(_){} }` is also conflict.
if (
curr === "iget" && next === "iset" ||
curr === "iset" && next === "iget" ||
curr === "sget" && next === "sset" ||
curr === "sset" && next === "sget"
) {
privateNameMap[name] = "true";
return false
} else if (!curr) {
privateNameMap[name] = next;
return false
} else {
return true
}
}
function checkKeyName(node, name) {
var computed = node.computed;
var key = node.key;
return !computed && (
key.type === "Identifier" && key.name === name ||
key.type === "Literal" && key.value === name
)
}
// Parses module export declaration.
pp$1.parseExport = function(node, exports) {
@ -2034,13 +2204,13 @@ pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {
// and object pattern might appear (so it's possible to raise
// delayed syntax error at correct position).
pp$3.parseExpression = function(noIn, refDestructuringErrors) {
pp$3.parseExpression = function(forInit, refDestructuringErrors) {
var startPos = this.start, startLoc = this.startLoc;
var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
if (this.type === types.comma) {
var node = this.startNodeAt(startPos, startLoc);
node.expressions = [expr];
while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); }
while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
return this.finishNode(node, "SequenceExpression")
}
return expr
@ -2049,9 +2219,9 @@ pp$3.parseExpression = function(noIn, refDestructuringErrors) {
// Parse an assignment expression. This includes applications of
// operators like `+=`.
pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
pp$3.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
if (this.isContextual("yield")) {
if (this.inGenerator) { return this.parseYield(noIn) }
if (this.inGenerator) { return this.parseYield(forInit) }
// The tokenizer will assume an expression is allowed after
// `yield`, but this isn't that kind of yield
else { this.exprAllowed = false; }
@ -2068,9 +2238,11 @@ pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
}
var startPos = this.start, startLoc = this.startLoc;
if (this.type === types.parenL || this.type === types.name)
{ this.potentialArrowAt = this.start; }
var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
if (this.type === types.parenL || this.type === types.name) {
this.potentialArrowAt = this.start;
this.potentialArrowInForAwait = forInit === "await";
}
var left = this.parseMaybeConditional(forInit, refDestructuringErrors);
if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
if (this.type.isAssign) {
var node = this.startNodeAt(startPos, startLoc);
@ -2088,7 +2260,7 @@ pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
{ this.checkLValSimple(left); }
node.left = left;
this.next();
node.right = this.parseMaybeAssign(noIn);
node.right = this.parseMaybeAssign(forInit);
return this.finishNode(node, "AssignmentExpression")
} else {
if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
@ -2100,16 +2272,16 @@ pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
// Parse a ternary conditional (`?:`) operator.
pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
pp$3.parseMaybeConditional = function(forInit, refDestructuringErrors) {
var startPos = this.start, startLoc = this.startLoc;
var expr = this.parseExprOps(noIn, refDestructuringErrors);
var expr = this.parseExprOps(forInit, refDestructuringErrors);
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
if (this.eat(types.question)) {
var node = this.startNodeAt(startPos, startLoc);
node.test = expr;
node.consequent = this.parseMaybeAssign();
this.expect(types.colon);
node.alternate = this.parseMaybeAssign(noIn);
node.alternate = this.parseMaybeAssign(forInit);
return this.finishNode(node, "ConditionalExpression")
}
return expr
@ -2117,11 +2289,11 @@ pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
// Start the precedence parser.
pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
pp$3.parseExprOps = function(forInit, refDestructuringErrors) {
var startPos = this.start, startLoc = this.startLoc;
var expr = this.parseMaybeUnary(refDestructuringErrors, false);
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)
};
// Parse binary operators with the operator precedence parsing
@ -2130,9 +2302,9 @@ pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
// defer further parser to one of its callers when it encounters an
// operator that has a lower precedence than the set it is parsing.
pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {
var prec = this.type.binop;
if (prec != null && (!noIn || this.type !== types._in)) {
if (prec != null && (!forInit || this.type !== types._in)) {
if (prec > minPrec) {
var logical = this.type === types.logicalOR || this.type === types.logicalAND;
var coalesce = this.type === types.coalesce;
@ -2144,12 +2316,12 @@ pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
var op = this.value;
this.next();
var startPos = this.start, startLoc = this.startLoc;
var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, forInit);
var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) {
this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
}
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)
}
}
return left
@ -2165,9 +2337,9 @@ pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
// Parse unary operators, both prefix and postfix.
pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec) {
var startPos = this.start, startLoc = this.startLoc, expr;
if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
if (this.isContextual("await") && this.canAwait) {
expr = this.parseAwait();
sawUnary = true;
} else if (this.type.prefix) {
@ -2175,12 +2347,14 @@ pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
node.operator = this.value;
node.prefix = true;
this.next();
node.argument = this.parseMaybeUnary(null, true);
node.argument = this.parseMaybeUnary(null, true, update);
this.checkExpressionErrors(refDestructuringErrors, true);
if (update) { this.checkLValSimple(node.argument); }
else if (this.strict && node.operator === "delete" &&
node.argument.type === "Identifier")
{ this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
else if (node.operator === "delete" && isPrivateFieldAccess(node.argument))
{ this.raiseRecoverable(node.start, "Private fields can not be deleted"); }
else { sawUnary = true; }
expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
} else {
@ -2197,12 +2371,23 @@ pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
}
}
if (!sawUnary && this.eat(types.starstar))
{ return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
else
{ return expr }
if (!incDec && this.eat(types.starstar)) {
if (sawUnary)
{ this.unexpected(this.lastTokStart); }
else
{ return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
} else {
return expr
}
};
function isPrivateFieldAccess(node) {
return (
node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" ||
node.type === "ChainExpression" && isPrivateFieldAccess(node.expression)
)
}
// Parse call, dot, and `[]`-subscript expressions.
pp$3.parseExprSubscripts = function(refDestructuringErrors) {
@ -2214,6 +2399,7 @@ pp$3.parseExprSubscripts = function(refDestructuringErrors) {
if (refDestructuringErrors && result.type === "MemberExpression") {
if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }
}
return result
};
@ -2250,9 +2436,15 @@ pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArro
if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) {
var node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never");
if (computed) {
node.property = this.parseExpression();
this.expect(types.bracketR);
} else if (this.type === types.privateId && base.type !== "Super") {
node.property = this.parsePrivateIdent();
} else {
node.property = this.parseIdent(this.options.allowReserved !== "never");
}
node.computed = !!computed;
if (computed) { this.expect(types.bracketR); }
if (optionalSupported) {
node.optional = optional;
}
@ -2338,7 +2530,8 @@ pp$3.parseExprAtom = function(refDestructuringErrors) {
if (canBeArrow && !this.canInsertSemicolon()) {
if (this.eat(types.arrow))
{ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc &&
(!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) {
id = this.parseIdent(false);
if (this.canInsertSemicolon() || !this.eat(types.arrow))
{ this.unexpected(); }
@ -2456,7 +2649,7 @@ pp$3.parseImportMeta = function(node) {
{ this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
if (containsEsc)
{ this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
if (this.options.sourceType !== "module")
if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere)
{ this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
return this.finishNode(node, "MetaProperty")
@ -2877,7 +3070,7 @@ pp$3.isSimpleParamList = function(params) {
// or "arguments" and duplicate parameters.
pp$3.checkParams = function(node, allowDuplicates) {
var nameHash = {};
var nameHash = Object.create(null);
for (var i = 0, list = node.params; i < list.length; i += 1)
{
var param = list[i];
@ -2924,6 +3117,8 @@ pp$3.checkUnreserved = function(ref) {
{ this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
if (this.inAsync && name === "await")
{ this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
if (this.currentThisScope().inClassFieldInit && name === "arguments")
{ this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); }
if (this.keywords.test(name))
{ this.raise(start, ("Unexpected keyword '" + name + "'")); }
if (this.options.ecmaVersion < 6 &&
@ -2968,9 +3163,29 @@ pp$3.parseIdent = function(liberal, isBinding) {
return node
};
pp$3.parsePrivateIdent = function() {
var node = this.startNode();
if (this.type === types.privateId) {
node.name = this.value;
} else {
this.unexpected();
}
this.next();
this.finishNode(node, "PrivateIdentifier");
// For validating existence
if (this.privateNameStack.length === 0) {
this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class"));
} else {
this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
}
return node
};
// Parses yield expression inside generator.
pp$3.parseYield = function(noIn) {
pp$3.parseYield = function(forInit) {
if (!this.yieldPos) { this.yieldPos = this.start; }
var node = this.startNode();
@ -2980,7 +3195,7 @@ pp$3.parseYield = function(noIn) {
node.argument = null;
} else {
node.delegate = this.eat(types.star);
node.argument = this.parseMaybeAssign(noIn);
node.argument = this.parseMaybeAssign(forInit);
}
return this.finishNode(node, "YieldExpression")
};
@ -3028,6 +3243,8 @@ var Scope = function Scope(flags) {
this.lexical = [];
// A list of lexically-declared FunctionDeclaration names in the current lexical scope
this.functions = [];
// A switch to disallow the identifier reference 'arguments'
this.inClassFieldInit = false;
};
// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
@ -3359,7 +3576,7 @@ var pp$8 = Parser.prototype;
var RegExpValidationState = function RegExpValidationState(parser) {
this.parser = parser;
this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "");
this.unicodeProperties = data[parser.options.ecmaVersion >= 12 ? 12 : parser.options.ecmaVersion];
this.source = "";
this.flags = "";
@ -4504,9 +4721,9 @@ pp$9.readToken = function(code) {
pp$9.fullCharCodeAtPos = function() {
var code = this.input.charCodeAt(this.pos);
if (code <= 0xd7ff || code >= 0xe000) { return code }
if (code <= 0xd7ff || code >= 0xdc00) { return code }
var next = this.input.charCodeAt(this.pos + 1);
return (code << 10) + next - 0x35fdc00
return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00
};
pp$9.skipBlockComment = function() {
@ -4725,6 +4942,20 @@ pp$9.readToken_question = function() { // '?'
return this.finishOp(types.question, 1)
};
pp$9.readToken_numberSign = function() { // '#'
var ecmaVersion = this.options.ecmaVersion;
var code = 35; // '#'
if (ecmaVersion >= 13) {
++this.pos;
code = this.fullCharCodeAtPos();
if (isIdentifierStart(code, true) || code === 92 /* '\' */) {
return this.finishToken(types.privateId, this.readWord1())
}
}
this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
};
pp$9.getTokenFromCode = function(code) {
switch (code) {
// The interpretation of a dot depends on whether it is followed
@ -4796,6 +5027,9 @@ pp$9.getTokenFromCode = function(code) {
case 126: // '~'
return this.finishOp(types.prefix, 1)
case 35: // '#'
return this.readToken_numberSign()
}
this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
@ -5207,7 +5441,7 @@ pp$9.readWord = function() {
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
var version = "8.0.4";
var version = "8.4.1";
Parser.acorn = {
Parser: Parser,
@ -5258,4 +5492,3 @@ function tokenizer(input, options) {
}
export { Node, Parser, Position, SourceLocation, TokContext, Token, TokenType, defaultOptions, getLineInfo, isIdentifierChar, isIdentifierStart, isNewLine, keywords$1 as keywordTypes, lineBreak, lineBreakG, nonASCIIwhitespace, parse, parseExpressionAt, types$1 as tokContexts, types as tokTypes, tokenizer, version };
//# sourceMappingURL=acorn.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@ var options = {};
function help(status) {
var print = (status === 0) ? console.log : console.error;
print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|...|--ecma2015|--ecma2016|--ecma2017|--ecma2018|...]");
print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]");
print(" [--tokenize] [--locations] [---allow-hash-bang] [--allow-await-outside-function] [--compact] [--silent] [--module] [--help] [--] [infile]");
process.exit(status);
}
@ -20,6 +20,7 @@ for (var i = 2; i < process.argv.length; ++i) {
else if (arg === "--" && !infile && i + 2 === process.argv.length) { forceFile = infile = process.argv[++i]; }
else if (arg === "--locations") { options.locations = true; }
else if (arg === "--allow-hash-bang") { options.allowHashBang = true; }
else if (arg === "--allow-await-outside-function") { options.allowAwaitOutsideFunction = true; }
else if (arg === "--silent") { silent = true; }
else if (arg === "--compact") { compact = true; }
else if (arg === "--help") { help(0); }

View File

@ -6,10 +6,17 @@
"types": "dist/acorn.d.ts",
"module": "dist/acorn.mjs",
"exports": {
"import": "./dist/acorn.mjs",
"require": "./dist/acorn.js"
".": [
{
"import": "./dist/acorn.mjs",
"require": "./dist/acorn.js",
"default": "./dist/acorn.js"
},
"./dist/acorn.js"
],
"./package.json": "./package.json"
},
"version": "8.0.4",
"version": "8.4.1",
"engines": {"node": ">=0.4.0"},
"maintainers": [
{

View File

@ -243,21 +243,9 @@ function getCode(fd, line, column) {
function parseCode(code, offset) {
// Lazy load acorn.
if (parseExpressionAt === undefined) {
const acorn = require('internal/deps/acorn/acorn/dist/acorn');
const privateMethods =
require('internal/deps/acorn-plugins/acorn-private-methods/index');
const classFields =
require('internal/deps/acorn-plugins/acorn-class-fields/index');
const staticClassFeatures =
require('internal/deps/acorn-plugins/acorn-static-class-features/index');
const Parser = require('internal/deps/acorn/acorn/dist/acorn').Parser;
({ findNodeAround } = require('internal/deps/acorn/acorn-walk/dist/walk'));
const Parser = acorn.Parser.extend(
privateMethods,
classFields,
staticClassFeatures
);
parseExpressionAt = FunctionPrototypeBind(Parser.parseExpressionAt, Parser);
}
let node;

View File

@ -10,20 +10,8 @@ const {
ObjectKeys,
} = primordials;
const acorn = require('internal/deps/acorn/acorn/dist/acorn');
const parser = require('internal/deps/acorn/acorn/dist/acorn').Parser;
const walk = require('internal/deps/acorn/acorn-walk/dist/walk');
const privateMethods =
require('internal/deps/acorn-plugins/acorn-private-methods/index');
const classFields =
require('internal/deps/acorn-plugins/acorn-class-fields/index');
const staticClassFeatures =
require('internal/deps/acorn-plugins/acorn-static-class-features/index');
const parser = acorn.Parser.extend(
privateMethods,
classFields,
staticClassFeatures
);
const noop = FunctionPrototype;
const visitorsWithoutAncestors = {

View File

@ -23,12 +23,6 @@ const {
const { tokTypes: tt, Parser: AcornParser } =
require('internal/deps/acorn/acorn/dist/acorn');
const privateMethods =
require('internal/deps/acorn-plugins/acorn-private-methods/index');
const classFields =
require('internal/deps/acorn-plugins/acorn-class-fields/index');
const staticClassFeatures =
require('internal/deps/acorn-plugins/acorn-static-class-features/index');
const { sendInspectorCommand } = require('internal/util/inspector');
@ -98,9 +92,6 @@ function isRecoverableError(e, code) {
//
const RecoverableParser = AcornParser
.extend(
privateMethods,
classFields,
staticClassFeatures,
(Parser) => {
return class extends Parser {
// eslint-disable-next-line no-useless-constructor

View File

@ -49,10 +49,6 @@
'deps/v8/tools/tickprocessor-driver.mjs',
'deps/acorn/acorn/dist/acorn.js',
'deps/acorn/acorn-walk/dist/walk.js',
'deps/acorn-plugins/acorn-class-fields/index.js',
'deps/acorn-plugins/acorn-private-class-elements/index.js',
'deps/acorn-plugins/acorn-private-methods/index.js',
'deps/acorn-plugins/acorn-static-class-features/index.js',
'deps/cjs-module-lexer/lexer.js',
'deps/cjs-module-lexer/dist/lexer.js',
],

View File

@ -30,7 +30,6 @@ fi
# Dependencies bundled in distributions
addlicense "Acorn" "deps/acorn" "$(cat "${rootdir}"/deps/acorn/acorn/LICENSE)"
addlicense "Acorn plugins" "deps/acorn-plugins" "$(cat "${rootdir}"/deps/acorn-plugins/acorn-class-fields/LICENSE)"
addlicense "c-ares" "deps/cares" "$(tail -n +3 "${rootdir}"/deps/cares/LICENSE.md)"
addlicense "cjs-module-lexer" "deps/cjs-module-lexer" "$(cat "${rootdir}"/deps/cjs-module-lexer/LICENSE)"
if [ -f "${rootdir}/deps/icu/LICENSE" ]; then