| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2ba2c93 commit 7643ce9
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,17 @@ | |||
| 1 | + ## 8.15.0 (2025-06-08) | ||
| 2 | + | ||
| 3 | + ### New features | ||
| 4 | + | ||
| 5 | + Support `using` and `await using` syntax. | ||
| 6 | + | ||
| 7 | + The `AnyNode` type is now defined in such a way that plugins can extend it. | ||
| 8 | + | ||
| 9 | + ### Bug fixes | ||
| 10 | + | ||
| 11 | + Fix an issue where the `bigint` property of literal nodes for non-decimal bigints had the wrong format. | ||
| 12 | + | ||
| 13 | + The `acorn` CLI tool no longer crashes when emitting a tree that contains a bigint. | ||
| 14 | + | ||
| 1 | 15 | ## 8.14.1 (2025-03-05) | |
| 2 | 16 | ||
| 3 | 17 | ### Bug fixes | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -169,7 +169,7 @@ export interface FunctionDeclaration extends Function { | |||
| 169 | 169 | export interface VariableDeclaration extends Node { | |
| 170 | 170 | type: "VariableDeclaration" | |
| 171 | 171 | declarations: Array<VariableDeclarator> | |
| 172 | - kind: "var" | "let" | "const" | ||
| 172 | + kind: "var" | "let" | "const" | "using" | "await using" | ||
| 173 | 173 | } | |
| 174 | 174 | ||
| 175 | 175 | export interface VariableDeclarator extends Node { | |
@@ -572,7 +572,24 @@ export type ModuleDeclaration = | |||
| 572 | 572 | | ExportDefaultDeclaration | |
| 573 | 573 | | ExportAllDeclaration | |
| 574 | 574 | ||
| 575 | - 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 | ||
| 575 | + /** | ||
| 576 | + * This interface is only used for defining {@link AnyNode}. | ||
| 577 | + * It exists so that it can be extended by plugins: | ||
| 578 | + * | ||
| 579 | + * @example | ||
| 580 | + * ```typescript | ||
| 581 | + * declare module 'acorn' { | ||
| 582 | + * interface NodeTypes { | ||
| 583 | + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode | ||
| 584 | + * } | ||
| 585 | + * } | ||
| 586 | + * ``` | ||
| 587 | + */ | ||
| 588 | + interface NodeTypes { | ||
| 589 | + 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 | ||
| 590 | + } | ||
| 591 | + | ||
| 592 | + export type AnyNode = NodeTypes[keyof NodeTypes] | ||
| 576 | 593 | ||
| 577 | 594 | export function parse(input: string, options: Options): Program | |
| 578 | 595 | ||
@@ -583,7 +600,7 @@ export function tokenizer(input: string, options: Options): { | |||
| 583 | 600 | [Symbol.iterator](): Iterator<Token> | |
| 584 | 601 | } | |
| 585 | 602 | ||
| 586 | - 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" | ||
| 603 | + 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" | ||
| 587 | 604 | ||
| 588 | 605 | export interface Options { | |
| 589 | 606 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -169,7 +169,7 @@ export interface FunctionDeclaration extends Function { | |||
| 169 | 169 | export interface VariableDeclaration extends Node { | |
| 170 | 170 | type: "VariableDeclaration" | |
| 171 | 171 | declarations: Array<VariableDeclarator> | |
| 172 | - kind: "var" | "let" | "const" | ||
| 172 | + kind: "var" | "let" | "const" | "using" | "await using" | ||
| 173 | 173 | } | |
| 174 | 174 | ||
| 175 | 175 | export interface VariableDeclarator extends Node { | |
@@ -572,7 +572,24 @@ export type ModuleDeclaration = | |||
| 572 | 572 | | ExportDefaultDeclaration | |
| 573 | 573 | | ExportAllDeclaration | |
| 574 | 574 | ||
| 575 | - 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 | ||
| 575 | + /** | ||
| 576 | + * This interface is only used for defining {@link AnyNode}. | ||
| 577 | + * It exists so that it can be extended by plugins: | ||
| 578 | + * | ||
| 579 | + * @example | ||
| 580 | + * ```typescript | ||
| 581 | + * declare module 'acorn' { | ||
| 582 | + * interface NodeTypes { | ||
| 583 | + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode | ||
| 584 | + * } | ||
| 585 | + * } | ||
| 586 | + * ``` | ||
| 587 | + */ | ||
| 588 | + interface NodeTypes { | ||
| 589 | + 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 | ||
| 590 | + } | ||
| 591 | + | ||
| 592 | + export type AnyNode = NodeTypes[keyof NodeTypes] | ||
| 576 | 593 | ||
| 577 | 594 | export function parse(input: string, options: Options): Program | |
| 578 | 595 | ||
@@ -583,7 +600,7 @@ export function tokenizer(input: string, options: Options): { | |||
| 583 | 600 | [Symbol.iterator](): Iterator<Token> | |
| 584 | 601 | } | |
| 585 | 602 | ||
| 586 | - 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" | ||
| 603 | + 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" | ||
| 587 | 604 | ||
| 588 | 605 | export interface Options { | |
| 589 | 606 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -887,6 +887,49 @@ | |||
| 887 | 887 | !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) | |
| 888 | 888 | }; | |
| 889 | 889 | ||
| 890 | + pp$8.isUsingKeyword = function(isAwaitUsing, isFor) { | ||
| 891 | + if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using")) | ||
| 892 | + { return false } | ||
| 893 | + | ||
| 894 | + skipWhiteSpace.lastIndex = this.pos; | ||
| 895 | + var skip = skipWhiteSpace.exec(this.input); | ||
| 896 | + var next = this.pos + skip[0].length; | ||
| 897 | + | ||
| 898 | + if (lineBreak.test(this.input.slice(this.pos, next))) { return false } | ||
| 899 | + | ||
| 900 | + if (isAwaitUsing) { | ||
| 901 | + var awaitEndPos = next + 5 /* await */, after; | ||
| 902 | + if (this.input.slice(next, awaitEndPos) !== "using" || | ||
| 903 | + awaitEndPos === this.input.length || | ||
| 904 | + isIdentifierChar(after = this.input.charCodeAt(awaitEndPos)) || | ||
| 905 | + (after > 0xd7ff && after < 0xdc00) | ||
| 906 | + ) { return false } | ||
| 907 | + | ||
| 908 | + skipWhiteSpace.lastIndex = awaitEndPos; | ||
| 909 | + var skipAfterUsing = skipWhiteSpace.exec(this.input); | ||
| 910 | + if (skipAfterUsing && lineBreak.test(this.input.slice(awaitEndPos, awaitEndPos + skipAfterUsing[0].length))) { return false } | ||
| 911 | + } | ||
| 912 | + | ||
| 913 | + if (isFor) { | ||
| 914 | + var ofEndPos = next + 2 /* of */, after$1; | ||
| 915 | + if (this.input.slice(next, ofEndPos) === "of") { | ||
| 916 | + if (ofEndPos === this.input.length || | ||
| 917 | + (!isIdentifierChar(after$1 = this.input.charCodeAt(ofEndPos)) && !(after$1 > 0xd7ff && after$1 < 0xdc00))) { return false } | ||
| 918 | + } | ||
| 919 | + } | ||
| 920 | + | ||
| 921 | + var ch = this.input.charCodeAt(next); | ||
| 922 | + return isIdentifierStart(ch, true) || ch === 92 // '\' | ||
| 923 | + }; | ||
| 924 | + | ||
| 925 | + pp$8.isAwaitUsing = function(isFor) { | ||
| 926 | + return this.isUsingKeyword(true, isFor) | ||
| 927 | + }; | ||
| 928 | + | ||
| 929 | + pp$8.isUsing = function(isFor) { | ||
| 930 | + return this.isUsingKeyword(false, isFor) | ||
| 931 | + }; | ||
| 932 | + | ||
| 890 | 933 | // Parse a single statement. | |
| 891 | 934 | // | |
| 892 | 935 | // If expecting a statement and finding a slash operator, parse a | |
@@ -963,6 +1006,23 @@ | |||
| 963 | 1006 | return this.parseFunctionStatement(node, true, !context) | |
| 964 | 1007 | } | |
| 965 | 1008 | ||
| 1009 | + var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null; | ||
| 1010 | + if (usingKind) { | ||
| 1011 | + if (topLevel && this.options.sourceType === "script") { | ||
| 1012 | + this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script`"); | ||
| 1013 | + } | ||
| 1014 | + if (usingKind === "await using") { | ||
| 1015 | + if (!this.canAwait) { | ||
| 1016 | + this.raise(this.start, "Await using cannot appear outside of async function"); | ||
| 1017 | + } | ||
| 1018 | + this.next(); | ||
| 1019 | + } | ||
| 1020 | + this.next(); | ||
| 1021 | + this.parseVar(node, false, usingKind); | ||
| 1022 | + this.semicolon(); | ||
| 1023 | + return this.finishNode(node, "VariableDeclaration") | ||
| 1024 | + } | ||
| 1025 | + | ||
| 966 | 1026 | var maybeName = this.value, expr = this.parseExpression(); | |
| 967 | 1027 | if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) | |
| 968 | 1028 | { return this.parseLabeledStatement(node, maybeName, expr, context) } | |
@@ -1038,18 +1098,19 @@ | |||
| 1038 | 1098 | this.next(); | |
| 1039 | 1099 | this.parseVar(init$1, true, kind); | |
| 1040 | 1100 | this.finishNode(init$1, "VariableDeclaration"); | |
| 1041 | - if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { | ||
| 1042 | - if (this.options.ecmaVersion >= 9) { | ||
| 1043 | - if (this.type === types$1._in) { | ||
| 1044 | - if (awaitAt > -1) { this.unexpected(awaitAt); } | ||
| 1045 | - } else { node.await = awaitAt > -1; } | ||
| 1046 | - } | ||
| 1047 | - return this.parseForIn(node, init$1) | ||
| 1048 | - } | ||
| 1049 | - if (awaitAt > -1) { this.unexpected(awaitAt); } | ||
| 1050 | - return this.parseFor(node, init$1) | ||
| 1101 | + return this.parseForAfterInit(node, init$1, awaitAt) | ||
| 1051 | 1102 | } | |
| 1052 | 1103 | var startsWithLet = this.isContextual("let"), isForOf = false; | |
| 1104 | + | ||
| 1105 | + var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null; | ||
| 1106 | + if (usingKind) { | ||
| 1107 | + var init$2 = this.startNode(); | ||
| 1108 | + this.next(); | ||
| 1109 | + if (usingKind === "await using") { this.next(); } | ||
| 1110 | + this.parseVar(init$2, true, usingKind); | ||
| 1111 | + this.finishNode(init$2, "VariableDeclaration"); | ||
| 1112 | + return this.parseForAfterInit(node, init$2, awaitAt) | ||
| 1113 | + } | ||
| 1053 | 1114 | var containsEsc = this.containsEsc; | |
| 1054 | 1115 | var refDestructuringErrors = new DestructuringErrors; | |
| 1055 | 1116 | var initPos = this.start; | |
@@ -1075,6 +1136,20 @@ | |||
| 1075 | 1136 | return this.parseFor(node, init) | |
| 1076 | 1137 | }; | |
| 1077 | 1138 | ||
| 1139 | + // Helper method to parse for loop after variable initialization | ||
| 1140 | + pp$8.parseForAfterInit = function(node, init, awaitAt) { | ||
| 1141 | + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { | ||
| 1142 | + if (this.options.ecmaVersion >= 9) { | ||
| 1143 | + if (this.type === types$1._in) { | ||
| 1144 | + if (awaitAt > -1) { this.unexpected(awaitAt); } | ||
| 1145 | + } else { node.await = awaitAt > -1; } | ||
| 1146 | + } | ||
| 1147 | + return this.parseForIn(node, init) | ||
| 1148 | + } | ||
| 1149 | + if (awaitAt > -1) { this.unexpected(awaitAt); } | ||
| 1150 | + return this.parseFor(node, init) | ||
| 1151 | + }; | ||
| 1152 | + | ||
| 1078 | 1153 | pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { | |
| 1079 | 1154 | this.next(); | |
| 1080 | 1155 | return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) | |
@@ -1331,6 +1406,8 @@ | |||
| 1331 | 1406 | decl.init = this.parseMaybeAssign(isFor); | |
| 1332 | 1407 | } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { | |
| 1333 | 1408 | this.unexpected(); | |
| 1409 | + } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) { | ||
| 1410 | + this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration")); | ||
| 1334 | 1411 | } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { | |
| 1335 | 1412 | this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); | |
| 1336 | 1413 | } else { | |
@@ -1343,7 +1420,10 @@ | |||
| 1343 | 1420 | }; | |
| 1344 | 1421 | ||
| 1345 | 1422 | pp$8.parseVarId = function(decl, kind) { | |
| 1346 | - decl.id = this.parseBindingAtom(); | ||
| 1423 | + decl.id = kind === "using" || kind === "await using" | ||
| 1424 | + ? this.parseIdent() | ||
| 1425 | + : this.parseBindingAtom(); | ||
| 1426 | + | ||
| 1347 | 1427 | this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); | |
| 1348 | 1428 | }; | |
| 1349 | 1429 | ||
@@ -3074,7 +3154,8 @@ | |||
| 3074 | 3154 | var node = this.startNode(); | |
| 3075 | 3155 | node.value = value; | |
| 3076 | 3156 | node.raw = this.input.slice(this.start, this.end); | |
| 3077 | - if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } | ||
| 3157 | + if (node.raw.charCodeAt(node.raw.length - 1) === 110) | ||
| 3158 | + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } | ||
| 3078 | 3159 | this.next(); | |
| 3079 | 3160 | return this.finishNode(node, "Literal") | |
| 3080 | 3161 | }; | |
@@ -6104,11 +6185,9 @@ | |||
| 6104 | 6185 | // Please use the [github bug tracker][ghbt] to report issues. | |
| 6105 | 6186 | // | |
| 6106 | 6187 | // [ghbt]: https://github.com/acornjs/acorn/issues | |
| 6107 | - // | ||
| 6108 | - // [walk]: util/walk.js | ||
| 6109 | 6188 | ||
| 6110 | 6189 | ||
| 6111 | - var version = "8.14.1"; | ||
| 6190 | + var version = "8.15.0"; | ||
| 6112 | 6191 | ||
| 6113 | 6192 | Parser.acorn = { | |
| 6114 | 6193 | Parser: Parser, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments