diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..77155769c --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock = false \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 27e8b8282..731ec895e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,14 +3,12 @@ sudo: false cache: npm matrix: include: - - node_js: '0.12' - - node_js: '4' - - node_js: '5' - node_js: '6' - - node_js: '7' - - node_js: '8' - node_js: '8' + - node_js: '10' + - node_js: '10' env: TEST_SUITE=test262 + - node_js: '12' script: > if [ "$TEST_SUITE" != "test262" ]; then npm test diff --git a/acorn-loose/CHANGELOG.md b/acorn-loose/CHANGELOG.md index 014309bf7..495184ece 100644 --- a/acorn-loose/CHANGELOG.md +++ b/acorn-loose/CHANGELOG.md @@ -1,3 +1,11 @@ +## 6.1.0 (2019-07-04) + +## New features + +Support bigint syntax. + +Support dynamic import. + ## 6.0.0 (2018-09-14) ### Breaking changes diff --git a/acorn-loose/package.json b/acorn-loose/package.json index 08f564edf..5adabfc9e 100644 --- a/acorn-loose/package.json +++ b/acorn-loose/package.json @@ -4,10 +4,10 @@ "homepage": "https://github.com/acornjs/acorn", "main": "dist/acorn-loose.js", "module": "dist/acorn-loose.mjs", - "version": "6.0.0", + "version": "6.1.0", "engines": {"node": ">=0.4.0"}, "dependencies": { - "acorn": "^6.0.0" + "acorn": "^6.2.0" }, "maintainers": [ { diff --git a/acorn-loose/rollup.config.js b/acorn-loose/rollup.config.js index e5cbc30e5..32f6d8a8c 100644 --- a/acorn-loose/rollup.config.js +++ b/acorn-loose/rollup.config.js @@ -1,16 +1,25 @@ import buble from "rollup-plugin-buble" export default { - entry: "./acorn-loose/src/index.js", - moduleName: "acorn.loose", + input: "./acorn-loose/src/index.js", + output: [ + { + file: "acorn-loose/dist/acorn-loose.js", + format: "umd", + name: "acorn.loose", + sourceMap: true, + external: ["acorn"], + globals: {acorn: "acorn"} + }, + { + file: "acorn-loose/dist/acorn-loose.mjs", + format: "es", + sourceMap: true, + external: ["acorn"], + globals: {acorn: "acorn"} + } + ], plugins: [ buble({transforms: {dangerousForOf: true}}) - ], - sourceMap: true, - targets: [ - {dest: "acorn-loose/dist/acorn-loose.js", format: "umd"}, - {dest: "acorn-loose/dist/acorn-loose.mjs", format: "es"} - ], - external: ["acorn"], - globals: {acorn: "acorn"} + ] } diff --git a/acorn-loose/src/expression.js b/acorn-loose/src/expression.js index d5dba4e99..fe338d960 100644 --- a/acorn-loose/src/expression.js +++ b/acorn-loose/src/expression.js @@ -244,6 +244,7 @@ lp.parseExprAtom = function() { node = this.startNode() node.value = this.tok.value node.raw = this.input.slice(this.tok.start, this.tok.end) + if (this.tok.type === tt.num && node.raw.charCodeAt(node.raw.length - 1) === 110) node.bigint = node.raw.slice(0, -1) this.next() return this.finishNode(node, "Literal") @@ -295,11 +296,24 @@ lp.parseExprAtom = function() { case tt.backQuote: return this.parseTemplate() + case tt._import: + if (this.options.ecmaVersion > 10) { + return this.parseDynamicImport() + } else { + return this.dummyIdent() + } + default: return this.dummyIdent() } } +lp.parseDynamicImport = function() { + const node = this.startNode() + this.next() + return this.finishNode(node, "Import") +} + lp.parseNew = function() { let node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart let meta = this.parseIdent(true) diff --git a/acorn-loose/src/statement.js b/acorn-loose/src/statement.js index c3701f7e0..a5b574044 100644 --- a/acorn-loose/src/statement.js +++ b/acorn-loose/src/statement.js @@ -10,9 +10,7 @@ lp.parseTopLevel = function() { while (this.tok.type !== tt.eof) node.body.push(this.parseStatement()) this.toks.adaptDirectivePrologue(node.body) this.last = this.tok - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType - } + node.sourceType = this.options.sourceType return this.finishNode(node, "Program") } @@ -178,6 +176,12 @@ lp.parseStatement = function() { return this.parseClass(true) case tt._import: + if (this.options.ecmaVersion > 10 && this.lookAhead(1).type === tt.parenL) { + node.expression = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ExpressionStatement") + } + return this.parseImport() case tt._export: diff --git a/acorn-walk/CHANGELOG.md b/acorn-walk/CHANGELOG.md index 525950b51..c02dbd7dd 100644 --- a/acorn-walk/CHANGELOG.md +++ b/acorn-walk/CHANGELOG.md @@ -1,3 +1,9 @@ +## 6.2.0 (2017-07-04) + +### New features + +Add support for `Import` nodes. + ## 6.1.0 (2018-09-28) ### New features diff --git a/acorn-walk/package.json b/acorn-walk/package.json index aee3f2584..239e6c729 100644 --- a/acorn-walk/package.json +++ b/acorn-walk/package.json @@ -4,7 +4,7 @@ "homepage": "https://github.com/acornjs/acorn", "main": "dist/walk.js", "module": "dist/walk.mjs", - "version": "6.1.1", + "version": "6.2.0", "engines": {"node": ">=0.4.0"}, "maintainers": [ { diff --git a/acorn-walk/rollup.config.js b/acorn-walk/rollup.config.js index 2588b1cd8..36f906469 100644 --- a/acorn-walk/rollup.config.js +++ b/acorn-walk/rollup.config.js @@ -1,14 +1,21 @@ import buble from "rollup-plugin-buble" export default { - entry: "acorn-walk/src/index.js", - moduleName: "acorn.walk", + input: "acorn-walk/src/index.js", + output: [ + { + file: "acorn-walk/dist/walk.js", + format: "umd", + name: "acorn.walk", + sourceMap: true + }, + { + file: "acorn-walk/dist/walk.mjs", + format: "es", + sourceMap: true + } + ], plugins: [ buble({transforms: {dangerousForOf: true}}) - ], - sourceMap: true, - targets: [ - {dest: "acorn-walk/dist/walk.js", format: "umd"}, - {dest: "acorn-walk/dist/walk.mjs", format: "es"} ] } diff --git a/acorn-walk/src/index.js b/acorn-walk/src/index.js index 25f5166f1..fb341507d 100644 --- a/acorn-walk/src/index.js +++ b/acorn-walk/src/index.js @@ -360,7 +360,7 @@ base.ImportDeclaration = (node, st, c) => { c(spec, st) 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.Literal = base.Import = ignore base.TaggedTemplateExpression = (node, st, c) => { c(node.tag, st, "Expression") diff --git a/acorn/CHANGELOG.md b/acorn/CHANGELOG.md index 1c8f79cd7..1438da677 100644 --- a/acorn/CHANGELOG.md +++ b/acorn/CHANGELOG.md @@ -1,3 +1,39 @@ +## 6.4.0 (2019-11-26) + +### New features + +Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on. + +## 6.3.0 (2019-08-12) + +### New features + +`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard. + +## 6.2.1 (2019-07-21) + +### Bug fixes + +Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such. + +Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances. + +## 6.2.0 (2019-07-04) + +### Bug fixes + +Improve valid assignment checking in `for`/`in` and `for`/`of` loops. + +Disallow binding `let` in patterns. + +### New features + +Support bigint syntax with `ecmaVersion` >= 10. + +Support dynamic `import` syntax with `ecmaVersion` >= 10. + +Upgrade to Unicode version 12. + ## 6.1.1 (2019-02-27) ### Bug fixes diff --git a/acorn/README.md b/acorn/README.md index 3e5f58d95..bcf85ccba 100644 --- a/acorn/README.md +++ b/acorn/README.md @@ -54,7 +54,7 @@ an object containing any of these fields: - **ecmaVersion**: Indicates the ECMAScript version to parse. Must be either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018) or 10 (2019, partial support). This influences support for strict mode, the set of - reserved words, and support for new syntax features. Default is 7. + reserved words, and support for new syntax features. Default is 9. **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being implemented by Acorn. Other proposed new features can be implemented @@ -64,6 +64,9 @@ an object containing any of these fields: either `"script"` or `"module"`. This influences global strict mode and parsing of `import` and `export` declarations. + **NOTE**: If set to `"module"`, then static `import` / `export` syntax + will be valid, even if `ecmaVersion` is less than 6. + - **onInsertedSemicolon**: If given a callback, that callback will be called whenever a missing semicolon is inserted by the parser. The callback will be given the character offset of the point where the @@ -260,10 +263,7 @@ The utility spits out the syntax tree as JSON data. Plugins for ECMAScript proposals: - [`acorn-stage3`](https://github.com/acornjs/acorn-stage3): Parse most stage 3 proposals, bundling: - - [`acorn-async-iteration`](https://github.com/acornjs/acorn-async-iteration): Parse [async iteration proposal](https://github.com/tc39/proposal-async-iteration) - - [`acorn-bigint`](https://github.com/acornjs/acorn-bigint): Parse [BigInt proposal](https://github.com/tc39/proposal-bigint) - [`acorn-class-fields`](https://github.com/acornjs/acorn-class-fields): Parse [class fields proposal](https://github.com/tc39/proposal-class-fields) - - [`acorn-dynamic-import`](https://github.com/kesne/acorn-dynamic-import): Parse [import() proposal](https://github.com/tc39/proposal-dynamic-import) - [`acorn-import-meta`](https://github.com/acornjs/acorn-import-meta): Parse [import.meta proposal](https://github.com/tc39/proposal-import-meta) - [`acorn-numeric-separator`](https://github.com/acornjs/acorn-numeric-separator): Parse [numeric separator proposal](https://github.com/tc39/proposal-numeric-separator) - [`acorn-private-methods`](https://github.com/acornjs/acorn-private-methods): parse [private methods, getters and setters proposal](https://github.com/tc39/proposal-private-methods)n diff --git a/acorn/dist/acorn.d.ts b/acorn/dist/acorn.d.ts index c6f9841b8..c68e23912 100644 --- a/acorn/dist/acorn.d.ts +++ b/acorn/dist/acorn.d.ts @@ -16,7 +16,7 @@ declare namespace acorn { sourceType?: 'script' | 'module' onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void - allowReserved?: boolean + allowReserved?: boolean | 'never' allowReturnOutsideFunction?: boolean allowImportExportEverywhere?: boolean allowAwaitOutsideFunction?: boolean @@ -36,14 +36,14 @@ declare namespace acorn { class Parser { constructor(options: Options, input: string, startPos?: number) - parse(): Node - static parse(input: string, options?: Options): Node - static parseExpressionAt(input: string, pos: number, options?: Options): Node - static tokenizer(input: string, options?: Options): { + parse(this: Parser): Node + static parse(this: typeof Parser, input: string, options?: Options): Node + static parseExpressionAt(this: typeof Parser, input: string, pos: number, options?: Options): Node + static tokenizer(this: typeof Parser, input: string, options?: Options): { getToken(): Token [Symbol.iterator](): Iterator } - static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser + static extend(this: typeof Parser, ...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser } interface Position { line: number; column: number; offset: number } diff --git a/acorn/package.json b/acorn/package.json index 808d1dac1..318bed138 100644 --- a/acorn/package.json +++ b/acorn/package.json @@ -4,7 +4,7 @@ "homepage": "https://github.com/acornjs/acorn", "main": "dist/acorn.js", "module": "dist/acorn.mjs", - "version": "6.1.1", + "version": "6.4.1", "engines": {"node": ">=0.4.0"}, "maintainers": [ { diff --git a/acorn/rollup.config.bin.js b/acorn/rollup.config.bin.js index 19234cb3b..8a082b069 100644 --- a/acorn/rollup.config.bin.js +++ b/acorn/rollup.config.bin.js @@ -1,10 +1,12 @@ import buble from "rollup-plugin-buble" export default { - entry: "acorn/src/bin/acorn.js", - dest: "acorn/dist/bin.js", - format: "cjs", - external: ["fs", "path", "acorn"], - paths: {acorn: "./acorn.js"}, + input: "acorn/src/bin/acorn.js", + output: { + file: "acorn/dist/bin.js", + format: "cjs", + paths: {acorn: "./acorn.js"}, + external: ["fs", "path", "acorn"] + }, plugins: [buble()] } diff --git a/acorn/rollup.config.js b/acorn/rollup.config.js index 79dac8ef5..0705d4cbc 100644 --- a/acorn/rollup.config.js +++ b/acorn/rollup.config.js @@ -1,14 +1,21 @@ import buble from "rollup-plugin-buble" export default { - entry: "acorn/src/index.js", - moduleName: "acorn", + input: "acorn/src/index.js", + output: [ + { + file: "acorn/dist/acorn.js", + format: "umd", + name: "acorn", + sourceMap: true + }, + { + file: "acorn/dist/acorn.mjs", + format: "es", + sourceMap: true + } + ], plugins: [ buble({transforms: {dangerousForOf: true}}) - ], - sourceMap: true, - targets: [ - {dest: "acorn/dist/acorn.js", format: "umd"}, - {dest: "acorn/dist/acorn.mjs", format: "es"} ] } diff --git a/acorn/src/.eslintrc b/acorn/src/.eslintrc index ea6fbdfb6..181c1b369 100644 --- a/acorn/src/.eslintrc +++ b/acorn/src/.eslintrc @@ -25,7 +25,8 @@ "space-before-function-paren": ["error", "never"] }, "globals": { - "Packages": false + "Packages": false, + "BigInt": false }, "plugins": [ "import" diff --git a/acorn/src/bin/acorn.js b/acorn/src/bin/acorn.js index 2aa4139b0..9a6712c87 100644 --- a/acorn/src/bin/acorn.js +++ b/acorn/src/bin/acorn.js @@ -46,7 +46,7 @@ function run(code) { } while (token.type !== acorn.tokTypes.eof) } } catch (e) { - console.error(e.message) + console.error(infile && infile !== "-" ? e.message.replace(/\(\d+:\d+\)$/, m => m.slice(0, 1) + infile + " " + m.slice(1)) : e.message) process.exit(1) } if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)) diff --git a/acorn/src/expression.js b/acorn/src/expression.js index 97c3fe6b9..b338141e8 100644 --- a/acorn/src/expression.js +++ b/acorn/src/expression.js @@ -272,7 +272,7 @@ pp.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow) if (computed || this.eat(tt.dot)) { let node = this.startNodeAt(startPos, startLoc) node.object = base - node.property = computed ? this.parseExpression() : this.parseIdent(true) + node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never") node.computed = !!computed if (computed) this.expect(tt.bracketR) base = this.finishNode(node, "MemberExpression") @@ -281,7 +281,7 @@ pp.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow) this.yieldPos = 0 this.awaitPos = 0 this.awaitIdentPos = 0 - let exprList = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors) + let exprList = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8 && base.type !== "Import", false, refDestructuringErrors) if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { this.checkPatternErrors(refDestructuringErrors, false) this.checkYieldAwaitInDefaultParams() @@ -299,6 +299,16 @@ pp.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow) let node = this.startNodeAt(startPos, startLoc) node.callee = base node.arguments = exprList + if (node.callee.type === "Import") { + if (node.arguments.length !== 1) { + this.raise(node.start, "import() requires exactly one argument") + } + + const importArg = node.arguments[0] + if (importArg && importArg.type === "SpreadElement") { + this.raise(importArg.start, "... is not allowed in import()") + } + } base = this.finishNode(node, "CallExpression") } else if (this.type === tt.backQuote) { let node = this.startNodeAt(startPos, startLoc) @@ -409,15 +419,32 @@ pp.parseExprAtom = function(refDestructuringErrors) { case tt.backQuote: return this.parseTemplate() + case tt._import: + if (this.options.ecmaVersion > 10) { + return this.parseDynamicImport() + } else { + return this.unexpected() + } + default: this.unexpected() } } +pp.parseDynamicImport = function() { + const node = this.startNode() + this.next() + if (this.type !== tt.parenL) { + this.unexpected() + } + return this.finishNode(node, "Import") +} + pp.parseLiteral = function(value) { let node = this.startNode() node.value = value node.raw = this.input.slice(this.start, this.end) + if (node.raw.charCodeAt(node.raw.length - 1) === 110) node.bigint = node.raw.slice(0, -1) this.next() return this.finishNode(node, "Literal") } @@ -522,7 +549,10 @@ pp.parseNew = function() { } let startPos = this.start, startLoc = this.startLoc node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) - if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false) + if (this.options.ecmaVersion > 10 && node.callee.type === "Import") { + this.raise(node.callee.start, "Cannot use new with import(...)") + } + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8 && node.callee.type !== "Import", false) else node.arguments = empty return this.finishNode(node, "NewExpression") } @@ -704,7 +734,7 @@ pp.parsePropertyName = function(prop) { prop.computed = false } } - return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") } // Initialize empty function node. @@ -872,7 +902,6 @@ pp.checkUnreserved = function({start, end, name}) { pp.parseIdent = function(liberal, isBinding) { let node = this.startNode() - if (liberal && this.options.allowReserved === "never") liberal = false if (this.type === tt.name) { node.name = this.value } else if (this.type.keyword) { diff --git a/acorn/src/identifier.js b/acorn/src/identifier.js index 2e6464d98..339066260 100644 --- a/acorn/src/identifier.js +++ b/acorn/src/identifier.js @@ -14,6 +14,7 @@ const ecma5AndLessKeywords = "break case catch continue debugger default do else export const keywords = { 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", 6: ecma5AndLessKeywords + " const class extends export import super" } @@ -26,9 +27,8 @@ export const keywordRelationalOperator = /^in(stanceof)?$/ // are only applied when a character is found to actually have a // code point above 128. // Generated by `bin/generate-identifier-regex.js`. - -let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" -let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" +let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7c6\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab67\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") @@ -42,10 +42,10 @@ nonASCIIidentifierStartChars = nonASCIIidentifierChars = null // generated by bin/generate-identifier-regex.js // eslint-disable-next-line comma-spacing -const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541] +const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,155,22,13,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,0,33,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,0,161,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,754,9486,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541] // eslint-disable-next-line comma-spacing -const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] +const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,232,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,792487,239] // This has a complexity linear to the value of the code. The // assumption is that looking up astral identifier characters is diff --git a/acorn/src/index.js b/acorn/src/index.js index 510648e5f..506a989dd 100644 --- a/acorn/src/index.js +++ b/acorn/src/index.js @@ -22,17 +22,58 @@ import "./expression" import "./location" import "./scope" -export {Parser} from "./state" -export {defaultOptions} from "./options" -export {Position, SourceLocation, getLineInfo} from "./locutil" -export {Node} from "./node" -export {TokenType, types as tokTypes, keywords as keywordTypes} from "./tokentype" -export {TokContext, types as tokContexts} from "./tokencontext" -export {isIdentifierChar, isIdentifierStart} from "./identifier" -export {Token} from "./tokenize" -export {isNewLine, lineBreak, lineBreakG, nonASCIIwhitespace} from "./whitespace" - -export const version = "6.1.1" +import {defaultOptions} from "./options" +import {Position, SourceLocation, getLineInfo} from "./locutil" +import {Node} from "./node" +import {TokenType, types as tokTypes, keywords as keywordTypes} from "./tokentype" +import {TokContext, types as tokContexts} from "./tokencontext" +import {isIdentifierChar, isIdentifierStart} from "./identifier" +import {Token} from "./tokenize" +import {isNewLine, lineBreak, lineBreakG, nonASCIIwhitespace} from "./whitespace" + +export const version = "6.4.0" +export { + Parser, + defaultOptions, + Position, + SourceLocation, + getLineInfo, + Node, + TokenType, + tokTypes, + keywordTypes, + TokContext, + tokContexts, + isIdentifierChar, + isIdentifierStart, + Token, + isNewLine, + lineBreak, + lineBreakG, + nonASCIIwhitespace +} + +Parser.acorn = { + Parser, + version, + defaultOptions, + Position, + SourceLocation, + getLineInfo, + Node, + TokenType, + tokTypes, + keywordTypes, + TokContext, + tokContexts, + isIdentifierChar, + isIdentifierStart, + Token, + isNewLine, + lineBreak, + lineBreakG, + nonASCIIwhitespace +} // The main exported interface (under `self.acorn` when in the // browser) is a `parse` function that takes a code string and diff --git a/acorn/src/lval.js b/acorn/src/lval.js index dbd220f93..8ad4b2639 100644 --- a/acorn/src/lval.js +++ b/acorn/src/lval.js @@ -1,7 +1,7 @@ import {types as tt} from "./tokentype" import {Parser} from "./state" import {has} from "./util" -import {BIND_NONE, BIND_OUTSIDE} from "./scopeflags" +import {BIND_NONE, BIND_OUTSIDE, BIND_LEXICAL} from "./scopeflags" const pp = Parser.prototype @@ -189,6 +189,8 @@ pp.parseMaybeDefault = function(startPos, startLoc, left) { pp.checkLVal = function(expr, bindingType = BIND_NONE, checkClashes) { switch (expr.type) { case "Identifier": + if (bindingType === BIND_LEXICAL && expr.name === "let") + this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name") if (this.strict && this.reservedWordsStrictBind.test(expr.name)) this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode") if (checkClashes) { diff --git a/acorn/src/regexp.js b/acorn/src/regexp.js index 00a4dc244..2fe832b4b 100644 --- a/acorn/src/regexp.js +++ b/acorn/src/regexp.js @@ -9,7 +9,7 @@ export class RegExpValidationState { constructor(parser) { this.parser = parser this.validFlags = `gim${parser.options.ecmaVersion >= 6 ? "uy" : ""}${parser.options.ecmaVersion >= 9 ? "s" : ""}` - this.unicodeProperties = UNICODE_PROPERTY_VALUES[parser.options.ecmaVersion >= 10 ? 10 : parser.options.ecmaVersion] + this.unicodeProperties = UNICODE_PROPERTY_VALUES[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion] this.source = "" this.flags = "" this.start = 0 @@ -50,7 +50,8 @@ export class RegExpValidationState { if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { return c } - return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00 + const next = s.charCodeAt(i + 1) + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c } nextIndex(i) { @@ -59,8 +60,9 @@ export class RegExpValidationState { if (i >= l) { return l } - const c = s.charCodeAt(i) - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + let c = s.charCodeAt(i), next + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { return i + 1 } return i + 2 diff --git a/acorn/src/state.js b/acorn/src/state.js index dce754fb8..eb4e0e120 100644 --- a/acorn/src/state.js +++ b/acorn/src/state.js @@ -9,9 +9,9 @@ export class Parser { constructor(options, input, startPos) { this.options = options = getOptions(options) this.sourceFile = options.sourceFile - this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]) let reserved = "" - if (!options.allowReserved) { + if (options.allowReserved !== true) { for (let v = options.ecmaVersion;; v--) if (reserved = reservedWords[v]) break if (options.sourceType === "module") reserved += " await" diff --git a/acorn/src/statement.js b/acorn/src/statement.js index 23a903840..8cadb5118 100644 --- a/acorn/src/statement.js +++ b/acorn/src/statement.js @@ -27,9 +27,7 @@ pp.parseTopLevel = function(node) { this.raiseRecoverable(this.undefinedExports[name].start, `Export '${name}' is not defined`) this.adaptDirectivePrologue(node.body) this.next() - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType - } + node.sourceType = this.options.sourceType return this.finishNode(node, "Program") } @@ -120,6 +118,14 @@ pp.parseStatement = function(context, topLevel, exports) { case tt.semi: return this.parseEmptyStatement(node) case tt._export: case tt._import: + if (this.options.ecmaVersion > 10 && starttype === tt._import) { + skipWhiteSpace.lastIndex = this.pos + let skip = skipWhiteSpace.exec(this.input) + let next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 40) // '(' + return this.parseExpressionStatement(node, this.parseExpression()) + } + if (!this.options.allowImportExportEverywhere) { if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level") @@ -215,8 +221,7 @@ pp.parseForStatement = function(node) { this.next() this.parseVar(init, true, kind) this.finishNode(init, "VariableDeclaration") - if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1 && - !(kind !== "var" && init.declarations[0].init)) { + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { if (this.options.ecmaVersion >= 9) { if (this.type === tt._in) { if (awaitAt > -1) this.unexpected(awaitAt) @@ -446,21 +451,36 @@ pp.parseFor = function(node, init) { // same from parser's perspective. pp.parseForIn = function(node, init) { - let type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + const isForIn = this.type === tt._in this.next() - if (type === "ForInStatement") { - if (init.type === "AssignmentPattern" || - (init.type === "VariableDeclaration" && init.declarations[0].init != null && - (this.strict || init.declarations[0].id.type !== "Identifier"))) - this.raise(init.start, "Invalid assignment in for-in loop head") + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + `${ + isForIn ? "for-in" : "for-of" + } loop variable declaration may not have an initializer` + ) + } else if (init.type === "AssignmentPattern") { + this.raise(init.start, "Invalid left-hand side in for-loop") } node.left = init - node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign() + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign() this.expect(tt.parenR) node.body = this.parseStatement("for") this.exitScope() this.labels.pop() - return this.finishNode(node, type) + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") } // Parse a list of variable declarations. @@ -487,9 +507,6 @@ pp.parseVar = function(node, isFor, kind) { } pp.parseVarId = function(decl, kind) { - if ((kind === "const" || kind === "let") && this.isContextual("let")) { - this.raiseRecoverable(this.start, "let is disallowed as a lexically bound name") - } decl.id = this.parseBindingAtom() this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false) } diff --git a/acorn/src/tokenize.js b/acorn/src/tokenize.js index acb9bf65f..f9f6b2f6f 100644 --- a/acorn/src/tokenize.js +++ b/acorn/src/tokenize.js @@ -427,10 +427,14 @@ pp.readInt = function(radix, len) { } pp.readRadixNumber = function(radix) { + let start = this.pos this.pos += 2 // 0x let val = this.readInt(radix) if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix) - if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) { + val = typeof BigInt !== "undefined" ? BigInt(this.input.slice(start, this.pos)) : null + ++this.pos + } else if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") return this.finishToken(tt.num, val) } @@ -443,6 +447,13 @@ pp.readNumber = function(startsWithDot) { if (octal && this.strict) this.raise(start, "Invalid number") if (octal && /[89]/.test(this.input.slice(start, this.pos))) octal = false let next = this.input.charCodeAt(this.pos) + if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) { + let str = this.input.slice(start, this.pos) + let val = typeof BigInt !== "undefined" ? BigInt(str) : null + ++this.pos + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + return this.finishToken(tt.num, val) + } if (next === 46 && !octal) { // '.' ++this.pos this.readInt(10) diff --git a/acorn/src/tokentype.js b/acorn/src/tokentype.js index 76b145fda..7a8c48a6d 100644 --- a/acorn/src/tokentype.js +++ b/acorn/src/tokentype.js @@ -136,7 +136,7 @@ export const types = { _class: kw("class", startsExpr), _extends: kw("extends", beforeExpr), _export: kw("export"), - _import: kw("import"), + _import: kw("import", startsExpr), _null: kw("null", startsExpr), _true: kw("true", startsExpr), _false: kw("false", startsExpr), diff --git a/acorn/src/unicode-property-data.js b/acorn/src/unicode-property-data.js index a2c125842..967ed1a36 100644 --- a/acorn/src/unicode-property-data.js +++ b/acorn/src/unicode-property-data.js @@ -6,9 +6,12 @@ import {wordsRegexp} from "./util.js" // #table-binary-unicode-properties const ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS" +const ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic" +const ecma11BinaryProperties = ecma10BinaryProperties const unicodeBinaryProperties = { 9: ecma9BinaryProperties, - 10: ecma9BinaryProperties + " Extended_Pictographic" + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties } // #table-unicode-general-category-values @@ -16,9 +19,12 @@ const unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Conne // #table-unicode-script-values const ecma9ScriptValues = "Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb" +const ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd" +const ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho" const unicodeScriptValues = { 9: ecma9ScriptValues, - 10: ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd" + 10: ecma10ScriptValues, + 11: ecma11ScriptValues } const data = {} @@ -38,5 +44,6 @@ function buildUnicodeData(ecmaVersion) { } buildUnicodeData(9) buildUnicodeData(10) +buildUnicodeData(11) export default data diff --git a/bin/generate-identifier-regex.js b/bin/generate-identifier-regex.js index 07e4540a0..d661d7224 100644 --- a/bin/generate-identifier-regex.js +++ b/bin/generate-identifier-regex.js @@ -18,7 +18,7 @@ function search(arr, ch, starting) { function esc(code) { let hex = code.toString(16) - return hex.length <= 2 ? hex.padStart(2, "0") : "\\u" + hex.padStart(4, "0") + return hex.length <= 2 ? "\\x" + hex.padStart(2, "0") : "\\u" + hex.padStart(4, "0") } function generate(chars) { diff --git a/bin/run_test262.js b/bin/run_test262.js index 6fbde08c9..c540507d7 100644 --- a/bin/run_test262.js +++ b/bin/run_test262.js @@ -4,21 +4,19 @@ const run = require("test262-parser-runner") const parse = require("../acorn").parse const unsupportedFeatures = [ - "BigInt", "class-fields-private", "class-fields-public", "class-methods-private", "class-static-fields-private", "class-static-fields-public", "class-static-methods-private", - "dynamic-import", "export-star-as-namespace-from-module", "import.meta", "numeric-separator-literal" ]; run( - (content, {sourceType}) => parse(content, {sourceType, ecmaVersion: 10}), + (content, {sourceType}) => parse(content, {sourceType, ecmaVersion: 11, allowHashBang: true}), { testsDirectory: path.dirname(require.resolve("test262/package.json")), skip: test => (test.attrs.features && unsupportedFeatures.some(f => test.attrs.features.includes(f))), diff --git a/package.json b/package.json index b208c9259..eb0dd1c73 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, { "name": "Adrian Heine", - "email": "http://adrianheine.de" + "web": "http://adrianheine.de" } ], "repository": { @@ -39,10 +39,11 @@ "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.5.0", "eslint-plugin-standard": "^3.0.1", - "rollup": "^0.45.0", - "rollup-plugin-buble": "^0.16.0", - "test262": "git+https://github.com/tc39/test262.git#e39604fa41b1ad0effdcf586e4d554ff2d8c3eb7", + "rollup": "^1.7.0", + "rollup-plugin-buble": "^0.19.0", + "test262": "git+https://github.com/tc39/test262.git#de567d3aa5de4eaa11e00131d26b9fe77997dfb0", "test262-parser-runner": "^0.5.0", - "unicode-11.0.0": "^0.7.7" + "test262-stream": "^1.2.1", + "unicode-12.0.0": "^0.7.9" } } diff --git a/test/driver.js b/test/driver.js index dc8fc6f65..b05cbb17a 100644 --- a/test/driver.js +++ b/test/driver.js @@ -61,7 +61,7 @@ exports.runTests = function(config, callback) { } }; -function ppJSON(v) { return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); } +function ppJSON(v) { return v instanceof RegExp ? v.toString() : (typeof v == "bigint" ? v.toString() : JSON.stringify(v, null, 2)); } function addPath(str, pt) { if (str.charAt(str.length-1) == ")") return str.slice(0, str.length-1) + "/" + pt + ")"; diff --git a/test/run.js b/test/run.js index 7fed58964..4ea981b90 100644 --- a/test/run.js +++ b/test/run.js @@ -14,6 +14,8 @@ require("./tests-regexp-2018.js"); require("./tests-json-superset.js"); require("./tests-optional-catch-binding.js"); + require("./tests-bigint.js"); + require("./tests-dynamic-import.js"); var acorn = require("../acorn") var acorn_loose = require("../acorn-loose") diff --git a/test/tests-bigint.js b/test/tests-bigint.js new file mode 100644 index 000000000..bb2d9d53e --- /dev/null +++ b/test/tests-bigint.js @@ -0,0 +1,197 @@ +if (typeof exports != "undefined") { + var test = require("./driver.js").test; + var testFail = require("./driver.js").testFail; +} + +const newBigIntLiteral = (start, stringValue) => ({ + start: start, + type: "Literal", + end: start + stringValue.length + 1, + value: typeof BigInt !== "undefined" ? BigInt(stringValue) : null, + raw: `${stringValue}n`, + bigint: stringValue +}) + +const digits = [ + {d: "0", ast: start => newBigIntLiteral(start, "0")}, + {d: "2", ast: start => newBigIntLiteral(start, "2")}, + {d: "0x2", ast: start => newBigIntLiteral(start, "0x2")}, + {d: "0o2", ast: start => newBigIntLiteral(start, "0o2")}, + {d: "0b10", ast: start => newBigIntLiteral(start, "0b10")}, + {d: "-0xbf2ed51ff75d380fd3be813ec6185780", ast: start => ({ + start: start, + type: "UnaryExpression", + end: start + 36, + operator: "-", + prefix: true, + argument: newBigIntLiteral(start + 1, "0xbf2ed51ff75d380fd3be813ec6185780") + })}, + {d: "02", error: start => `Identifier directly after number (1:${start + 2})`}, + {d: "2e2", error: start => `Identifier directly after number (1:${start + 3})`}, + {d: "2.4", error: start => `Identifier directly after number (1:${start + 3})`}, + {d: ".4", error: start => `Identifier directly after number (1:${start + 2})`}, +] +const statements = [ + {s: "let i = %s", ast: content => ({ + start: 0, + type: "VariableDeclaration", + end: content.end, + kind: "let", + declarations: [{ + start: 4, + type: "VariableDeclarator", + end: content.end, + id: { + start: 4, + type: "Identifier", + end: 5, + name: "i" + }, + init: content + }] + })}, + + {s: "i = %s", ast: content => ({ + start: 0, + type: "ExpressionStatement", + end: content.end, + expression: { + start: 0, + type: "AssignmentExpression", + end: content.end, + operator: "=", + left: { + start: 0, + type: "Identifier", + end: 1, + name: "i" + }, + right: content + } + })}, + + {s: "((i = %s) => {})", ast: content => ({ + start: 0, + type: "ExpressionStatement", + end: content.end + 8, + expression: { + start: 1, + type: "ArrowFunctionExpression", + end: content.end + 7, + id: null, + generator: false, + expression: false, + async: false, + params: [ + { + start: 2, + type: "AssignmentPattern", + end: content.end, + left: { + start: 2, + type: "Identifier", + end: 3, + name: "i" + }, + right: content + } + ], + body: { + start: content.end + 5, + type: "BlockStatement", + end: content.end + 7, + body: [] + } + } + })}, + + {s: "for (let i = 0n; i < %s;++i) {}", ast: content => ({ + start: 0, + type: "ForStatement", + end: content.end + 8, + init: { + start: 5, + type: "VariableDeclaration", + end: 15, + declarations: [ + { + start: 9, + type: "VariableDeclarator", + end: 15, + id: { + start: 9, + type: "Identifier", + end: 10, + name: "i" + }, + init: newBigIntLiteral(13, "0") + } + ], + kind: "let" + }, + test: { + start: 17, + type: "BinaryExpression", + end: content.end, + left: { + start: 17, + type: "Identifier", + start: 17, + end: 18, + name: "i" + }, + operator: "<", + right: content + }, + update: { + start: content.end + 1, + type: "UpdateExpression", + end: content.end + 4, + operator: "++", + prefix: true, + argument: { + start: content.end + 3, + type: "Identifier", + end: content.end + 4, + name: "i" + } + }, + body: { + start: content.end + 6, + type: "BlockStatement", + end: content.end + 8, + body: [] + } + })}, + + {s: "i + %s", ast: content => ({ + start: 0, + type: "ExpressionStatement", + end: content.end, + expression: { + start: 0, + type: "BinaryExpression", + end: content.end, + left: { + start: 0, + type: "Identifier", + start: 0, + end: 1, + name: "i" + }, + operator: "+", + right: content + } + })} +] +statements.forEach(statement => { + const start = statement.s.indexOf("%s") + digits.forEach(d => { + (d.error ? testFail : test)( + statement.s.replace("%s", `${d.d}n`), + d.error ? d.error(start) : { type: "Program", body: [ + statement.ast(d.ast(start)) + ]}, { ecmaVersion: 11 } + ) + }) +}) diff --git a/test/tests-dynamic-import.js b/test/tests-dynamic-import.js new file mode 100644 index 000000000..18c23d3a8 --- /dev/null +++ b/test/tests-dynamic-import.js @@ -0,0 +1,128 @@ +// Tests for ECMAScript 2020 dynamic import + +if (typeof exports != 'undefined') { + var test = require('./driver.js').test; + var testFail = require('./driver.js').testFail; +} + +test( + "import('dynamicImport.js')", + { + type: 'Program', + start: 0, + end: 26, + body: [ + { + type: 'ExpressionStatement', + start: 0, + end: 26, + expression: { + type: 'CallExpression', + start: 0, + end: 26, + callee: { type: 'Import', start: 0, end: 6 }, + arguments: [ + { + type: 'Literal', + start: 7, + end: 25, + value: 'dynamicImport.js', + raw: "'dynamicImport.js'" + } + ] + } + } + ], + sourceType: 'script' + }, + { ecmaVersion: 11 } +); + +test( + "function* a() { yield import('http'); }", + { + type: 'Program', + start: 0, + end: 39, + body: [ + { + type: 'FunctionDeclaration', + start: 0, + end: 39, + id: { type: 'Identifier', start: 10, end: 11, name: 'a' }, + expression: false, + generator: true, + async: false, + params: [], + body: { + type: 'BlockStatement', + start: 14, + end: 39, + body: [ + { + type: 'ExpressionStatement', + start: 16, + end: 37, + expression: { + type: 'YieldExpression', + start: 16, + end: 36, + delegate: false, + argument: { + type: 'CallExpression', + start: 22, + end: 36, + callee: { type: 'Import', start: 22, end: 28 }, + arguments: [{ type: 'Literal', start: 29, end: 35, value: 'http', raw: "'http'" }] + } + } + } + ] + } + } + ], + sourceType: 'script' + }, + { ecmaVersion: 11 } +); + +testFail('function failsParse() { return import.then(); }', 'Unexpected token (1:37)', { + ecmaVersion: 11, + loose: false +}); + +testFail("var dynImport = import; dynImport('http');", 'Unexpected token (1:22)', { + ecmaVersion: 11, + loose: false +}); + +testFail("import('test.js')", 'Unexpected token (1:6)', { + ecmaVersion: 10, + loose: false, + sourceType: 'module' +}); + +testFail("import()", 'import() requires exactly one argument (1:0)', { + ecmaVersion: 11, + loose: false +}); + +testFail("import(a, b)", 'import() requires exactly one argument (1:0)', { + ecmaVersion: 11, + loose: false +}); + +testFail("import(...[a])", '... is not allowed in import() (1:7)', { + ecmaVersion: 11, + loose: false +}); + +testFail("import(source,)", 'Unexpected token (1:14)', { + ecmaVersion: 11, + loose: false +}); + +testFail("new import(source)", 'Cannot use new with import(...) (1:4)', { + ecmaVersion: 11, + loose: false +}); diff --git a/test/tests-harmony.js b/test/tests-harmony.js index e37047489..ade46a220 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -6028,95 +6028,6 @@ test("for (var x of list) process(x);", { locations: true }); -test("for (var x = 42 of list) process(x);", { - type: "Program", - body: [{ - type: "ForOfStatement", - left: { - type: "VariableDeclaration", - declarations: [{ - type: "VariableDeclarator", - id: { - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 9}, - end: {line: 1, column: 10} - } - }, - init: { - type: "Literal", - value: 42, - raw: "42", - loc: { - start: {line: 1, column: 13}, - end: {line: 1, column: 15} - } - }, - loc: { - start: {line: 1, column: 9}, - end: {line: 1, column: 15} - } - }], - kind: "var", - loc: { - start: {line: 1, column: 5}, - end: {line: 1, column: 15} - } - }, - right: { - type: "Identifier", - name: "list", - loc: { - start: {line: 1, column: 19}, - end: {line: 1, column: 23} - } - }, - body: { - type: "ExpressionStatement", - expression: { - type: "CallExpression", - callee: { - type: "Identifier", - name: "process", - loc: { - start: {line: 1, column: 25}, - end: {line: 1, column: 32} - } - }, - arguments: [{ - type: "Identifier", - name: "x", - loc: { - start: {line: 1, column: 33}, - end: {line: 1, column: 34} - } - }], - loc: { - start: {line: 1, column: 25}, - end: {line: 1, column: 35} - } - }, - loc: { - start: {line: 1, column: 25}, - end: {line: 1, column: 36} - } - }, - loc: { - start: {line: 1, column: 0}, - end: {line: 1, column: 36} - } - }], - loc: { - start: {line: 1, column: 0}, - end: {line: 1, column: 36} - } -}, { - ecmaVersion: 6, - ranges: true, - locations: true -}); - test("for (let x of list) process(x);", { type: "Program", body: [{ @@ -13204,9 +13115,16 @@ testFail("\"use strict\"; ({ v: eval } = obj)", "Assigning to eval in strict mod testFail("\"use strict\"; ({ v: arguments } = obj)", "Assigning to arguments in strict mode (1:20)", {ecmaVersion: 6}); -testFail("for (let x = 42 in list) process(x);", "Unexpected token (1:16)", {ecmaVersion: 6}); +testFail("for (let x = 42 in list) process(x);", "for-in loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); +testFail("for (const x = 42 in list) process(x);", "for-in loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); -testFail("for (let x = 42 of list) process(x);", "Unexpected token (1:16)", {ecmaVersion: 6}); +testFail("for (let x = 42 of list) process(x);", "for-of loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); +testFail("for (const x = 42 of list) process(x);", "for-of loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); +testFail("for (var x = 42 of list) process(x);", "for-of loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); +testFail("for (var x = 42 of list) process(x);", "for-of loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 8}); +testFail("for (var {x} = 42 of list) process(x);", "for-of loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); +testFail("for (var [x] = 42 of list) process(x);", "for-of loop variable declaration may not have an initializer (1:5)", {ecmaVersion: 6}); +testFail("var x; for (x = 42 of list) process(x);", "Invalid left-hand side in for-loop (1:12)", {ecmaVersion: 6}); testFail("import foo", "Unexpected token (1:10)", {ecmaVersion: 6, sourceType: "module"}); @@ -13485,15 +13403,32 @@ test("var let = 1", { ] }, {ecmaVersion: 6}) -testFail("'use strict'; let + 1", "The keyword 'let' is reserved (1:14)", {ecmaVersion: 6}) testFail("let let", "let is disallowed as a lexically bound name (1:4)", {ecmaVersion: 6}) testFail("const let", "let is disallowed as a lexically bound name (1:6)", {ecmaVersion: 6}) -testFail("'use strict'; let let", "let is disallowed as a lexically bound name (1:18)", {ecmaVersion: 6}) +testFail("let { let } = {};", "let is disallowed as a lexically bound name (1:6)", {ecmaVersion: 6}) + +testFail("const { let } = {};", "let is disallowed as a lexically bound name (1:8)", {ecmaVersion: 6}) + +testFail("let [let] = [];", "let is disallowed as a lexically bound name (1:5)", {ecmaVersion: 6}) + +testFail("const [let] = [];", "let is disallowed as a lexically bound name (1:7)", {ecmaVersion: 6}) + +testFail("'use strict'; let + 1", "The keyword 'let' is reserved (1:14)", {ecmaVersion: 6}) + +testFail("'use strict'; let let", "The keyword 'let' is reserved (1:18)", {ecmaVersion: 6}) + +testFail("'use strict'; const let", "The keyword 'let' is reserved (1:20)", {ecmaVersion: 6}) + +testFail("'use strict'; let { let } = {};", "The keyword 'let' is reserved (1:20)", {ecmaVersion: 6}) + +testFail("'use strict'; const { let } = {};", "The keyword 'let' is reserved (1:22)", {ecmaVersion: 6}) + +testFail("'use strict'; let [let] = [];", "The keyword 'let' is reserved (1:19)", {ecmaVersion: 6}) -testFail("'use strict'; const let", "let is disallowed as a lexically bound name (1:20)", {ecmaVersion: 6}) +testFail("'use strict'; const [let] = [];", "The keyword 'let' is reserved (1:21)", {ecmaVersion: 6}) test("if (1) let\n{}", {}, {ecmaVersion: 6}) diff --git a/test/tests-regexp.js b/test/tests-regexp.js index 6c4719486..804e00a59 100644 --- a/test/tests-regexp.js +++ b/test/tests-regexp.js @@ -1049,6 +1049,7 @@ test("/[\\d][\\12-\\14]{1,}[^\\d]/", {}, { ecmaVersion: 2015 }) testFail("/[\\d][\\12-\\14]{1,}[^\\d]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 }) testFail("/[\\d][\\12-\\14]{1,}[^\\d]/u", "Invalid regular expression: /[\\d][\\12-\\14]{1,}[^\\d]/: Invalid class escape (1:1)", { ecmaVersion: 2015 }) test("/([a ]\\b)*\\b/", {}, { ecmaVersion: 5 }) +test("/[x-*]/u".replace("*", String.fromCharCode(0xd800)), {}, {ecmaVersion: 6}) /* // This is test case generator. diff --git a/test/tests.js b/test/tests.js index 5c6a0cdd6..35fe29ca5 100644 --- a/test/tests.js +++ b/test/tests.js @@ -7,6 +7,62 @@ if (typeof exports != "undefined") { var acorn = require("../acorn"); } +test("import ''", { + type: "Program", + start: 0, + end: 9, + body: [ + { + type: "ImportDeclaration", + start: 0, + end: 9, + specifiers: [], + source: { + type: "Literal", + start: 7, + end: 9, + value: "", + raw: "''" + } + } + ] +}, { + ecmaVersion: 5, + sourceType: "module" +}); + +testFail("import('')", "Unexpected token (1:6)", { + ecmaVersion: 5, + sourceType: "module" +}); + +test("new Object", { + type: "Program", + start: 0, + end: 10, + body: [ + { + type: "ExpressionStatement", + start: 0, + end: 10, + expression: { + type: "NewExpression", + start: 0, + end: 10, + callee: { + type: "Identifier", + start: 4, + end: 10, + name: "Object" + }, + arguments: [] + } + } + ] +}, { + allowReserved: "never" +}); + test("this\n", { type: "Program", body: [ @@ -19689,9 +19745,11 @@ test("for (var x in list) process(x);", { } } }); -testFail("var x; for (x = 0 in list) process(x);", "Invalid assignment in for-in loop head (1:12)", { ecmaVersion: 6 }) -testFail("'use strict'; for (var x = 0 in list) process(x);", "Invalid assignment in for-in loop head (1:19)") -testFail("for (var [x] = 0 in list) process(x);", "Invalid assignment in for-in loop head (1:5)", { ecmaVersion: 6 }) +testFail("var x; for (x = 0 in list) process(x);", "Invalid left-hand side in for-loop (1:12)", { ecmaVersion: 6 }) +testFail("'use strict'; for (var x = 0 in list) process(x);", "for-in loop variable declaration may not have an initializer (1:19)") +testFail("for (var [x] = 0 in list) process(x);", "for-in loop variable declaration may not have an initializer (1:5)", { ecmaVersion: 6 }) +testFail("for (var {x} = 0 in list) process(x);", "for-in loop variable declaration may not have an initializer (1:5)", { ecmaVersion: 6 }) +testFail("for (var x = 42 in list) process(x);", "for-in loop variable declaration may not have an initializer (1:5)", { ecmaVersion: 6 }) test("for (var x = 42 in list) process(x);", { type: "Program", @@ -19847,7 +19905,7 @@ test("for (var x = 42 in list) process(x);", { column: 36 } } -}); +}, { ecmaVersion: 8, locations: true }); test("for (var i = function() { return 10 in [] } in list) process(x);", { type: "Program", @@ -20074,7 +20132,7 @@ test("for (var i = function() { return 10 in [] } in list) process(x);", { column: 64 } } -}); +}, { ecmaVersion: 8, locations: true }); test("while (true) { continue; }", { type: "Program", @@ -29404,3 +29462,5 @@ test("'use strict'; let foo = function foo() {}", {}, {ecmaVersion: 6}) test("/**/ --> comment\n", {}) test("x.class++", {}) + +testFail("½", "Unexpected character '½' (1:0)")