diff --git a/README.md b/README.md index 2e095e0..049b76c 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Leaves properties defined in [The ESTree Spec](https://github.com/estree/estree) - [ES2022](https://github.com/estree/estree/blob/master/es2022.md) - ES2023 - ES2024 +- [ES2025](https://github.com/estree/estree/blob/master/es2025.md) ### const customizedCloneFunctionWithAllowList = espurify.cloneWithAllowlist(allowList) @@ -90,7 +91,7 @@ Configuration options. If not passed, default options will be used. |:---------------------|:--------------| | `string` or `number` | `2022` | -Indicates the ECMAScript version to clone. Must be either 5, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +Indicates the ECMAScript version to clone. Must be either 5, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025. #### options.extra diff --git a/lib/ast-properties/es2025.js b/lib/ast-properties/es2025.js new file mode 100644 index 0000000..3dae8cc --- /dev/null +++ b/lib/ast-properties/es2025.js @@ -0,0 +1,75 @@ +// see: https://github.com/estree/estree/blob/master/es2025.md +module.exports = { + ArrayExpression: ['type', 'elements'], + ArrayPattern: ['type', 'elements'], + ArrowFunctionExpression: ['type', 'id', 'params', 'body', 'generator', 'expression', 'async'], + AssignmentExpression: ['type', 'operator', 'left', 'right'], + AssignmentPattern: ['type', 'left', 'right'], + AwaitExpression: ['type', 'argument'], + BinaryExpression: ['type', 'operator', 'left', 'right'], + BlockStatement: ['type', 'body'], + BreakStatement: ['type', 'label'], + CallExpression: ['type', 'callee', 'arguments', 'optional'], + CatchClause: ['type', 'param', 'body'], + ChainExpression: ['type', 'expression'], + ClassBody: ['type', 'body'], + ClassDeclaration: ['type', 'id', 'superClass', 'body'], + ClassExpression: ['type', 'id', 'superClass', 'body'], + ConditionalExpression: ['type', 'test', 'consequent', 'alternate'], + ContinueStatement: ['type', 'label'], + DebuggerStatement: ['type'], + DoWhileStatement: ['type', 'body', 'test'], + EmptyStatement: ['type'], + ExportAllDeclaration: ['type', 'source', 'exported', 'attributes'], + ExportDefaultDeclaration: ['type', 'declaration'], + ExportNamedDeclaration: ['type', 'declaration', 'specifiers', 'source', 'attributes'], + ExportSpecifier: ['type', 'exported', 'local'], + ExpressionStatement: ['type', 'expression', 'directive'], + ForInStatement: ['type', 'left', 'right', 'body'], + ForOfStatement: ['type', 'left', 'right', 'body', 'await'], + ForStatement: ['type', 'init', 'test', 'update', 'body'], + FunctionDeclaration: ['type', 'id', 'params', 'body', 'generator', 'async'], + FunctionExpression: ['type', 'id', 'params', 'body', 'generator', 'async'], + Identifier: ['type', 'name'], + IfStatement: ['type', 'test', 'consequent', 'alternate'], + ImportAttribute: ['type', 'key', 'value'], + ImportDeclaration: ['type', 'specifiers', 'source', 'attributes'], + ImportDefaultSpecifier: ['type', 'local'], + ImportExpression: ['type', 'source', 'options'], + ImportNamespaceSpecifier: ['type', 'local'], + ImportSpecifier: ['type', 'imported', 'local'], + LabeledStatement: ['type', 'label', 'body'], + Literal: ['type', 'value', 'regex', 'bigint'], + LogicalExpression: ['type', 'operator', 'left', 'right'], + MemberExpression: ['type', 'object', 'property', 'computed', 'optional'], + MetaProperty: ['type', 'meta', 'property'], + MethodDefinition: ['type', 'key', 'value', 'kind', 'computed', 'static'], + NewExpression: ['type', 'callee', 'arguments'], + ObjectExpression: ['type', 'properties'], + ObjectPattern: ['type', 'properties'], + PrivateIdentifier: ['type', 'name'], + Program: ['type', 'body', 'sourceType'], + Property: ['type', 'key', 'value', 'kind', 'method', 'shorthand', 'computed'], + PropertyDefinition: ['type', 'key', 'value', 'computed', 'static'], + RestElement: ['type', 'argument'], + ReturnStatement: ['type', 'argument'], + SequenceExpression: ['type', 'expressions'], + SpreadElement: ['type', 'argument'], + StaticBlock: ['type', 'body'], + Super: ['type'], + SwitchCase: ['type', 'test', 'consequent'], + SwitchStatement: ['type', 'discriminant', 'cases'], + TaggedTemplateExpression: ['type', 'tag', 'quasi'], + TemplateElement: ['type', 'tail', 'value'], + TemplateLiteral: ['type', 'quasis', 'expressions'], + ThisExpression: ['type'], + ThrowStatement: ['type', 'argument'], + TryStatement: ['type', 'block', 'handler', 'finalizer'], + UnaryExpression: ['type', 'operator', 'prefix', 'argument'], + UpdateExpression: ['type', 'operator', 'argument', 'prefix'], + VariableDeclaration: ['type', 'declarations', 'kind'], + VariableDeclarator: ['type', 'id', 'init'], + WhileStatement: ['type', 'test', 'body'], + WithStatement: ['type', 'object', 'body'], + YieldExpression: ['type', 'argument', 'delegate'] +}; diff --git a/lib/ast-properties/index.js b/lib/ast-properties/index.js index 770aa00..924e319 100644 --- a/lib/ast-properties/index.js +++ b/lib/ast-properties/index.js @@ -1,4 +1,5 @@ const ecmaVersions = { + 2025: require('./es2025'), 2024: require('./es2022'), // no change in AST Node level 2023: require('./es2022'), // no change in AST Node level 2022: require('./es2022'), diff --git a/test/ecmaversion_test.js b/test/ecmaversion_test.js index 138cf98..73a5f69 100644 --- a/test/ecmaversion_test.js +++ b/test/ecmaversion_test.js @@ -4,6 +4,54 @@ const acorn = require('acorn'); const { describe, it } = require('node:test'); describe('ecmaVersion option', function () { + describe('es2025', function () { + it('ImportAttributes', function () { + const clone = espurify.customize({ ecmaVersion: 2025 }); + const code = ` +import foo from "./foo.json" with { type: "json" } +`; + const ast = acorn.parse(code, { locations: true, ranges: true, ecmaVersion: 2025, sourceType: 'module' }); + const expected = { + type: 'Program', + body: [ + { + type: 'ImportDeclaration', + source: { + type: 'Literal', + value: './foo.json' + }, + specifiers: [ + { + type: 'ImportDefaultSpecifier', + local: { + type: 'Identifier', + name: 'foo' + } + } + ], + attributes: [ + { + type: 'ImportAttribute', + key: { + type: 'Identifier', + name: 'type' + }, + value: { + type: 'Literal', + value: 'json' + } + } + ] + } + ], + sourceType: 'module' + }; + assert.deepEqual(clone(ast), expected); + const clone2024 = espurify.customize({ ecmaVersion: 2024 }); + assert.notDeepEqual(clone2024(ast), expected); + }); + }); + describe('es2022', function () { it('PropertyDefinition, PrivateIdentifier and StaticBlock', function () { const clone = espurify.customize({ ecmaVersion: 2022 });