diff --git a/deps/acorn/acorn/CHANGELOG.md b/deps/acorn/acorn/CHANGELOG.md index 8b9ae8c4ed6..c86068cd71a 100644 --- a/deps/acorn/acorn/CHANGELOG.md +++ b/deps/acorn/acorn/CHANGELOG.md @@ -1,3 +1,17 @@ +## 8.15.0 (2025-06-08) + +### New features + +Support `using` and `await using` syntax. + +The `AnyNode` type is now defined in such a way that plugins can extend it. + +### Bug fixes + +Fix an issue where the `bigint` property of literal nodes for non-decimal bigints had the wrong format. + +The `acorn` CLI tool no longer crashes when emitting a tree that contains a bigint. + ## 8.14.1 (2025-03-05) ### Bug fixes diff --git a/deps/acorn/acorn/dist/acorn.d.mts b/deps/acorn/acorn/dist/acorn.d.mts index 81f4e38fdbf..f2ec5243bcb 100644 --- a/deps/acorn/acorn/dist/acorn.d.mts +++ b/deps/acorn/acorn/dist/acorn.d.mts @@ -169,7 +169,7 @@ export interface FunctionDeclaration extends Function { export interface VariableDeclaration extends Node { type: "VariableDeclaration" declarations: Array - kind: "var" | "let" | "const" + kind: "var" | "let" | "const" | "using" | "await using" } export interface VariableDeclarator extends Node { @@ -572,7 +572,24 @@ export type ModuleDeclaration = | ExportDefaultDeclaration | ExportAllDeclaration -export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] export function parse(input: string, options: Options): Program @@ -583,7 +600,7 @@ export function tokenizer(input: string, options: Options): { [Symbol.iterator](): Iterator } -export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | "latest" +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" export interface Options { /** diff --git a/deps/acorn/acorn/dist/acorn.d.ts b/deps/acorn/acorn/dist/acorn.d.ts index 81f4e38fdbf..f2ec5243bcb 100644 --- a/deps/acorn/acorn/dist/acorn.d.ts +++ b/deps/acorn/acorn/dist/acorn.d.ts @@ -169,7 +169,7 @@ export interface FunctionDeclaration extends Function { export interface VariableDeclaration extends Node { type: "VariableDeclaration" declarations: Array - kind: "var" | "let" | "const" + kind: "var" | "let" | "const" | "using" | "await using" } export interface VariableDeclarator extends Node { @@ -572,7 +572,24 @@ export type ModuleDeclaration = | ExportDefaultDeclaration | ExportAllDeclaration -export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] export function parse(input: string, options: Options): Program @@ -583,7 +600,7 @@ export function tokenizer(input: string, options: Options): { [Symbol.iterator](): Iterator } -export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | "latest" +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" export interface Options { /** diff --git a/deps/acorn/acorn/dist/acorn.js b/deps/acorn/acorn/dist/acorn.js index aacf9749a69..cb5628bf83c 100644 --- a/deps/acorn/acorn/dist/acorn.js +++ b/deps/acorn/acorn/dist/acorn.js @@ -887,6 +887,49 @@ !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) }; + pp$8.isUsingKeyword = function(isAwaitUsing, isFor) { + if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + + if (lineBreak.test(this.input.slice(this.pos, next))) { return false } + + if (isAwaitUsing) { + var awaitEndPos = next + 5 /* await */, after; + if (this.input.slice(next, awaitEndPos) !== "using" || + awaitEndPos === this.input.length || + isIdentifierChar(after = this.input.charCodeAt(awaitEndPos)) || + (after > 0xd7ff && after < 0xdc00) + ) { return false } + + skipWhiteSpace.lastIndex = awaitEndPos; + var skipAfterUsing = skipWhiteSpace.exec(this.input); + if (skipAfterUsing && lineBreak.test(this.input.slice(awaitEndPos, awaitEndPos + skipAfterUsing[0].length))) { return false } + } + + if (isFor) { + var ofEndPos = next + 2 /* of */, after$1; + if (this.input.slice(next, ofEndPos) === "of") { + if (ofEndPos === this.input.length || + (!isIdentifierChar(after$1 = this.input.charCodeAt(ofEndPos)) && !(after$1 > 0xd7ff && after$1 < 0xdc00))) { return false } + } + } + + var ch = this.input.charCodeAt(next); + return isIdentifierStart(ch, true) || ch === 92 // '\' + }; + + pp$8.isAwaitUsing = function(isFor) { + return this.isUsingKeyword(true, isFor) + }; + + pp$8.isUsing = function(isFor) { + return this.isUsingKeyword(false, isFor) + }; + // Parse a single statement. // // If expecting a statement and finding a slash operator, parse a @@ -963,6 +1006,23 @@ return this.parseFunctionStatement(node, true, !context) } + var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null; + if (usingKind) { + if (topLevel && this.options.sourceType === "script") { + this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script`"); + } + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.next(); + this.parseVar(node, false, usingKind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + } + var maybeName = this.value, expr = this.parseExpression(); if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) { return this.parseLabeledStatement(node, maybeName, expr, context) } @@ -1038,18 +1098,19 @@ this.next(); this.parseVar(init$1, true, kind); this.finishNode(init$1, "VariableDeclaration"); - if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types$1._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - return this.parseForIn(node, init$1) - } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init$1) + return this.parseForAfterInit(node, init$1, awaitAt) } var startsWithLet = this.isContextual("let"), isForOf = false; + + var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null; + if (usingKind) { + var init$2 = this.startNode(); + this.next(); + if (usingKind === "await using") { this.next(); } + this.parseVar(init$2, true, usingKind); + this.finishNode(init$2, "VariableDeclaration"); + return this.parseForAfterInit(node, init$2, awaitAt) + } var containsEsc = this.containsEsc; var refDestructuringErrors = new DestructuringErrors; var initPos = this.start; @@ -1075,6 +1136,20 @@ return this.parseFor(node, init) }; + // Helper method to parse for loop after variable initialization + pp$8.parseForAfterInit = function(node, init, awaitAt) { + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types$1._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { this.next(); return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) @@ -1331,6 +1406,8 @@ decl.init = this.parseMaybeAssign(isFor); } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { this.unexpected(); + } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) { + this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration")); } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); } else { @@ -1343,7 +1420,10 @@ }; pp$8.parseVarId = function(decl, kind) { - decl.id = this.parseBindingAtom(); + decl.id = kind === "using" || kind === "await using" + ? this.parseIdent() + : this.parseBindingAtom(); + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); }; @@ -3074,7 +3154,8 @@ var 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).replace(/_/g, ""); } + if (node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } this.next(); return this.finishNode(node, "Literal") }; @@ -6104,11 +6185,9 @@ // Please use the [github bug tracker][ghbt] to report issues. // // [ghbt]: https://github.com/acornjs/acorn/issues - // - // [walk]: util/walk.js - var version = "8.14.1"; + var version = "8.15.0"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/dist/acorn.mjs b/deps/acorn/acorn/dist/acorn.mjs index 05004ece0ef..74d5fc431be 100644 --- a/deps/acorn/acorn/dist/acorn.mjs +++ b/deps/acorn/acorn/dist/acorn.mjs @@ -881,6 +881,49 @@ pp$8.isAsyncFunction = function() { !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) }; +pp$8.isUsingKeyword = function(isAwaitUsing, isFor) { + if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + + if (lineBreak.test(this.input.slice(this.pos, next))) { return false } + + if (isAwaitUsing) { + var awaitEndPos = next + 5 /* await */, after; + if (this.input.slice(next, awaitEndPos) !== "using" || + awaitEndPos === this.input.length || + isIdentifierChar(after = this.input.charCodeAt(awaitEndPos)) || + (after > 0xd7ff && after < 0xdc00) + ) { return false } + + skipWhiteSpace.lastIndex = awaitEndPos; + var skipAfterUsing = skipWhiteSpace.exec(this.input); + if (skipAfterUsing && lineBreak.test(this.input.slice(awaitEndPos, awaitEndPos + skipAfterUsing[0].length))) { return false } + } + + if (isFor) { + var ofEndPos = next + 2 /* of */, after$1; + if (this.input.slice(next, ofEndPos) === "of") { + if (ofEndPos === this.input.length || + (!isIdentifierChar(after$1 = this.input.charCodeAt(ofEndPos)) && !(after$1 > 0xd7ff && after$1 < 0xdc00))) { return false } + } + } + + var ch = this.input.charCodeAt(next); + return isIdentifierStart(ch, true) || ch === 92 // '\' +}; + +pp$8.isAwaitUsing = function(isFor) { + return this.isUsingKeyword(true, isFor) +}; + +pp$8.isUsing = function(isFor) { + return this.isUsingKeyword(false, isFor) +}; + // Parse a single statement. // // If expecting a statement and finding a slash operator, parse a @@ -957,6 +1000,23 @@ pp$8.parseStatement = function(context, topLevel, exports) { return this.parseFunctionStatement(node, true, !context) } + var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null; + if (usingKind) { + if (topLevel && this.options.sourceType === "script") { + this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script`"); + } + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.next(); + this.parseVar(node, false, usingKind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + } + var maybeName = this.value, expr = this.parseExpression(); if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) { return this.parseLabeledStatement(node, maybeName, expr, context) } @@ -1032,18 +1092,19 @@ pp$8.parseForStatement = function(node) { this.next(); this.parseVar(init$1, true, kind); this.finishNode(init$1, "VariableDeclaration"); - if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types$1._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - return this.parseForIn(node, init$1) - } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init$1) + return this.parseForAfterInit(node, init$1, awaitAt) } var startsWithLet = this.isContextual("let"), isForOf = false; + + var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null; + if (usingKind) { + var init$2 = this.startNode(); + this.next(); + if (usingKind === "await using") { this.next(); } + this.parseVar(init$2, true, usingKind); + this.finishNode(init$2, "VariableDeclaration"); + return this.parseForAfterInit(node, init$2, awaitAt) + } var containsEsc = this.containsEsc; var refDestructuringErrors = new DestructuringErrors; var initPos = this.start; @@ -1069,6 +1130,20 @@ pp$8.parseForStatement = function(node) { return this.parseFor(node, init) }; +// Helper method to parse for loop after variable initialization +pp$8.parseForAfterInit = function(node, init, awaitAt) { + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types$1._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) +}; + pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { this.next(); return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) @@ -1325,6 +1400,8 @@ pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) { decl.init = this.parseMaybeAssign(isFor); } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { this.unexpected(); + } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) { + this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration")); } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); } else { @@ -1337,7 +1414,10 @@ pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) { }; pp$8.parseVarId = function(decl, kind) { - decl.id = this.parseBindingAtom(); + decl.id = kind === "using" || kind === "await using" + ? this.parseIdent() + : this.parseBindingAtom(); + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); }; @@ -3068,7 +3148,8 @@ pp$5.parseLiteral = function(value) { var 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).replace(/_/g, ""); } + if (node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } this.next(); return this.finishNode(node, "Literal") }; @@ -6098,11 +6179,9 @@ pp.readWord = function() { // Please use the [github bug tracker][ghbt] to report issues. // // [ghbt]: https://github.com/acornjs/acorn/issues -// -// [walk]: util/walk.js -var version = "8.14.1"; +var version = "8.15.0"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/dist/bin.js b/deps/acorn/acorn/dist/bin.js index 0bf3e5f8d12..c7d9b9f8ed8 100644 --- a/deps/acorn/acorn/dist/bin.js +++ b/deps/acorn/acorn/dist/bin.js @@ -77,7 +77,7 @@ function run(codeList) { console.error(fileMode ? e.message.replace(/\(\d+:\d+\)$/, function (m) { return m.slice(0, 1) + inputFilePaths[fileIdx] + " " + m.slice(1); }) : e.message); process.exit(1); } - if (!silent) { console.log(JSON.stringify(result, null, compact ? null : 2)); } + if (!silent) { console.log(JSON.stringify(result, function (_, value) { return typeof value === "bigint" ? null : value; }, compact ? null : 2)); } } if (fileMode = inputFilePaths.length && (forceFileName || !inputFilePaths.includes("-") || inputFilePaths.length !== 1)) { diff --git a/deps/acorn/acorn/package.json b/deps/acorn/acorn/package.json index 3c00dbac016..6f63ddbf620 100644 --- a/deps/acorn/acorn/package.json +++ b/deps/acorn/acorn/package.json @@ -16,7 +16,7 @@ ], "./package.json": "./package.json" }, - "version": "8.14.1", + "version": "8.15.0", "engines": { "node": ">=0.4.0" }, diff --git a/src/acorn_version.h b/src/acorn_version.h index 5a58b89d056..a8af314b687 100644 --- a/src/acorn_version.h +++ b/src/acorn_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-acorn.sh #ifndef SRC_ACORN_VERSION_H_ #define SRC_ACORN_VERSION_H_ -#define ACORN_VERSION "8.14.1" +#define ACORN_VERSION "8.15.0" #endif // SRC_ACORN_VERSION_H_