diff --git a/.changeset/fresh-baboons-destroy.md b/.changeset/fresh-baboons-destroy.md new file mode 100644 index 0000000..8470fb3 --- /dev/null +++ b/.changeset/fresh-baboons-destroy.md @@ -0,0 +1,5 @@ +--- +'esrap': patch +--- + +fix: support more typescript nodes diff --git a/package.json b/package.json index 0fa59ac..71d4eee 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@vitest/ui": "^2.1.1", "acorn": "^8.15.0", "dts-buddy": "^0.6.2", + "oxc-parser": "^0.75.0", "prettier": "^3.0.3", "typescript": "^5.7.2", "vitest": "^2.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53807dd..3dbf551 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,6 +30,9 @@ importers: dts-buddy: specifier: ^0.6.2 version: 0.6.2(typescript@5.7.2) + oxc-parser: + specifier: ^0.75.0 + version: 0.75.0 prettier: specifier: ^3.0.3 version: 3.3.3 @@ -104,6 +107,15 @@ packages: '@changesets/write@0.3.2': resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -269,6 +281,9 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@napi-rs/wasm-runtime@0.2.11': + resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -281,6 +296,98 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oxc-parser/binding-android-arm64@0.75.0': + resolution: {integrity: sha512-nSHUHCO59G+kbixFVc7dK1j3l1EU3nVNLkj47ysCyl7RW3Z9cwCITp7SVwm+gl3ufCuVU4bkaBpgFnesnqZeDg==} + engines: {node: '>=20.0.0'} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.75.0': + resolution: {integrity: sha512-Wnx2L/gX39/9ZkohpW9R46eQTavBFnqsoAFaRgOnUsLW/+rtZIacMwwxZCfBhLY/tNlBWEUbTxlN6bvN/hPbKw==} + engines: {node: '>=20.0.0'} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.75.0': + resolution: {integrity: sha512-jXOYe/K7YLE8xN2dDBcaZ78dxfXWXtPMZBOzg2j0YignThagLX4KgDCqEVlMbQY4MymzpqrY0TzSXjCI9MCfvA==} + engines: {node: '>=20.0.0'} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.75.0': + resolution: {integrity: sha512-Qz/iLccz8ecbeH0jterDVZcw9xmbuJn0/Jo+yc3+tqd3Iwirp+UbY/6c7SOkFFciF1dNN4G2FLpmDQSSWFZdjw==} + engines: {node: '>=20.0.0'} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.75.0': + resolution: {integrity: sha512-OQomvh7PfJjzKSfG0lNcTru+QYXYzETrU4YZsWBWcJyV4pKJ6ZoRn4BOlY9QVH3F8htN890/agTQfNtEAzp23g==} + engines: {node: '>=20.0.0'} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.75.0': + resolution: {integrity: sha512-solH8uhoWkqHaVLGdBjB6cxbKugqRjxiEdXOQYeNXJo5d5gJxLW6WFhLhRedajwVtxVaKhcNNW4vrwuhU85OXA==} + engines: {node: '>=20.0.0'} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.75.0': + resolution: {integrity: sha512-CrYqeI5/TY8x/G/KvprDaxB9V6Wpudby1sXVpncz4Azzoyg+mIRGgWOl+ZbX/O9uwpCrFr0TPf2JY7cl3baLAA==} + engines: {node: '>=20.0.0'} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-arm64-musl@0.75.0': + resolution: {integrity: sha512-dQK0rLN6ha5cGahgA4j7zqLH6rtDd5TdNApBo5JFannCLzpr9TQ1QUecYggx70+vLrmm/PMKCMnwR0uuvLbq8g==} + engines: {node: '>=20.0.0'} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-riscv64-gnu@0.75.0': + resolution: {integrity: sha512-thRPaGeeKuVFI1fTY+G5zeh5w34eUYszliA/2qpAsb1yWfq+imHgsdloFLi3wW1CiR1mnk6AhKFoj7u3JGVWTA==} + engines: {node: '>=20.0.0'} + cpu: [riscv64] + os: [linux] + + '@oxc-parser/binding-linux-s390x-gnu@0.75.0': + resolution: {integrity: sha512-ku2ckoJeXXLe6ZiWFXXYALpfmAtoPUzsWOlFf7HssOYbhHEm/RH9yw/GoUNRwZdz1uSi6tYzNvLZ915irffK/w==} + engines: {node: '>=20.0.0'} + cpu: [s390x] + os: [linux] + + '@oxc-parser/binding-linux-x64-gnu@0.75.0': + resolution: {integrity: sha512-223VDGrX7cnmhSSRimnL+/eOCp/ABU4Iobfnelz5zbQKRpijQQjk8Ohx2kb7aZ5Q0dY09fDSUNjY/iOBBFaRIg==} + engines: {node: '>=20.0.0'} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-linux-x64-musl@0.75.0': + resolution: {integrity: sha512-WVdpo3EA53PTZt3p2fdmPgoF9jIichRcpd2GmuZV58P3wlFWq9iKefdD4M87mskzdxwGUiMQlPiktNcsZZWMkQ==} + engines: {node: '>=20.0.0'} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-wasm32-wasi@0.75.0': + resolution: {integrity: sha512-SPXt1nYkmjuGDh7ZfnfarObQq8AnnvA+m+hmcOqXVSxLJWZQhXDF6AHaS0dzKhpIDHWjScbTp5c9eqINLbPh7g==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.75.0': + resolution: {integrity: sha512-YBEBK1K5nC6GkQykdtGjKCY+/QvmKiG2blmTOKNUXnsSyDNDivJSClpjb+UrziR87skxnvcn3GbMPY08aG2AVg==} + engines: {node: '>=20.0.0'} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.75.0': + resolution: {integrity: sha512-o1f+JB8zFObz+5fvmMlP0ykBUkcVN1STjEHmRahD0TOZG1EJeUvz6xaLXr7EHeRW8z5ftEEGJK5nLlitwLXxCQ==} + engines: {node: '>=20.0.0'} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.75.0': + resolution: {integrity: sha512-QMW+06WOXs7+F301Y3X0VpmWhwuQVc/X/RP2zF9OIwvSMmsif3xURS2wxbakFIABYsytgBcHpUcFepVS0Qnd3A==} + '@polka/url@1.0.0-next.25': resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} @@ -369,6 +476,9 @@ packages: peerDependencies: acorn: ^8.9.0 + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -682,6 +792,10 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + oxc-parser@0.75.0: + resolution: {integrity: sha512-WbgEAOXvO327lFz12U+utDzNDt5+gM9gRCLfi/q3oUaoVd7tzVNlbxhJCS9PBM97tEDghJQXbnr6vqzqvU2TPQ==} + engines: {node: '>=20.0.0'} + p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -889,6 +1003,9 @@ packages: peerDependencies: typescript: '>=4.2.0' + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + typescript@5.7.2: resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} engines: {node: '>=14.17'} @@ -1123,6 +1240,22 @@ snapshots: human-id: 1.0.2 prettier: 2.8.8 + '@emnapi/core@1.4.3': + dependencies: + '@emnapi/wasi-threads': 1.0.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.2': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -1230,6 +1363,13 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 + '@napi-rs/wasm-runtime@0.2.11': + dependencies: + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1242,6 +1382,55 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.18.0 + '@oxc-parser/binding-android-arm64@0.75.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.75.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.75.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.75.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.75.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.75.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.75.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.75.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.75.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.75.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.75.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.75.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.75.0': + dependencies: + '@napi-rs/wasm-runtime': 0.2.11 + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.75.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.75.0': + optional: true + + '@oxc-project/types@0.75.0': {} + '@polka/url@1.0.0-next.25': {} '@rollup/rollup-android-arm-eabi@4.20.0': @@ -1296,6 +1485,11 @@ snapshots: dependencies: acorn: 8.15.0 + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true + '@types/estree@1.0.5': {} '@types/node@12.20.55': {} @@ -1610,6 +1804,26 @@ snapshots: outdent@0.5.0: {} + oxc-parser@0.75.0: + dependencies: + '@oxc-project/types': 0.75.0 + optionalDependencies: + '@oxc-parser/binding-android-arm64': 0.75.0 + '@oxc-parser/binding-darwin-arm64': 0.75.0 + '@oxc-parser/binding-darwin-x64': 0.75.0 + '@oxc-parser/binding-freebsd-x64': 0.75.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.75.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.75.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.75.0 + '@oxc-parser/binding-linux-arm64-musl': 0.75.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.75.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.75.0 + '@oxc-parser/binding-linux-x64-gnu': 0.75.0 + '@oxc-parser/binding-linux-x64-musl': 0.75.0 + '@oxc-parser/binding-wasm32-wasi': 0.75.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.75.0 + '@oxc-parser/binding-win32-x64-msvc': 0.75.0 + p-filter@2.1.0: dependencies: p-map: 2.1.0 @@ -1780,6 +1994,9 @@ snapshots: dependencies: typescript: 5.7.2 + tslib@2.8.1: + optional: true + typescript@5.7.2: {} undici-types@5.26.5: diff --git a/src/languages/ts/index.js b/src/languages/ts/index.js index 7bb4f7c..18e76ef 100644 --- a/src/languages/ts/index.js +++ b/src/languages/ts/index.js @@ -505,6 +505,8 @@ export default (options = {}) => { context.write('declare '); } + if (node.abstract) context.write('abstract '); + context.write('class '); if (node.id) { @@ -571,6 +573,130 @@ export default (options = {}) => { context.visit(node.body); }, + /** + * @param {TSESTree.MethodDefinition | TSESTree.TSAbstractMethodDefinition} node + * @param {Context} context + */ + 'MethodDefinition|TSAbstractMethodDefinition': (node, context) => { + if (node.decorators) { + for (const decorator of node.decorators) { + context.visit(decorator); + } + } + + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + if (node.abstract || node.type === 'TSAbstractMethodDefinition') { + context.write('abstract '); + } + + if (node.static) { + context.write('static '); + } + + if (node.kind === 'get' || node.kind === 'set') { + // Getter or setter + context.write(node.kind + ' '); + } + + if (node.value.async) { + context.write('async '); + } + + if (node.value.generator) { + context.write('*'); + } + + if (node.computed) context.write('['); + context.visit(node.key); + if (node.computed) context.write(']'); + + context.write('('); + sequence( + context, + node.value.params, + (node.value.returnType ?? node.value.body)?.loc?.start ?? node.loc?.end ?? null, + false + ); + context.write(')'); + + if (node.value.returnType) context.visit(node.value.returnType); + + context.write(' '); + + if (node.value.body) context.visit(node.value.body); + }, + + /** + * @param {TSESTree.PropertyDefinition | TSESTree.TSAbstractPropertyDefinition | TSESTree.AccessorProperty | TSESTree.TSAbstractAccessorProperty} node + * @param {Context} context + */ + 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty': ( + node, + context + ) => { + if (node.decorators) { + for (const decorator of node.decorators) { + context.visit(decorator); + } + } + + if (node.accessibility) { + context.write(node.accessibility + ' '); + } + + if ( + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + node.abstract || + node.type === 'TSAbstractPropertyDefinition' || + node.type === 'TSAbstractAccessorProperty' + ) { + context.write('abstract '); + } + + if (node.static) { + context.write('static '); + } + + if ( + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + node.accessor || + node.type === 'AccessorProperty' || + node.type === 'TSAbstractAccessorProperty' + ) { + context.write('accessor '); + } + + if (node.computed) { + context.write('['); + context.visit(node.key); + context.write(']'); + } else { + context.visit(node.key); + } + + if (node.typeAnnotation) { + if (node.type === 'AccessorProperty' || node.type === 'TSAbstractAccessorProperty') { + context.visit(node.typeAnnotation); + } else { + context.write(': '); + context.visit(node.typeAnnotation.typeAnnotation); + } + } + + if (node.value) { + context.write(' = '); + context.visit(node.value); + } + + context.write(';'); + + flush_trailing_comments( + context, + (node.value ?? node.typeAnnotation ?? node.key).loc?.end ?? null, + null + ); + }, + /** * @param {TSESTree.RestElement | TSESTree.SpreadElement} node * @param {Context} context @@ -581,6 +707,63 @@ export default (options = {}) => { // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions if (node.typeAnnotation) context.visit(node.typeAnnotation); + }, + + /** + * @param {TSESTree.TSConstructSignatureDeclaration | TSESTree.TSCallSignatureDeclaration} node + * @param {Context} context + */ + 'TSConstructSignatureDeclaration|TSCallSignatureDeclaration': (node, context) => { + if (node.type === 'TSConstructSignatureDeclaration') context.write('new'); + + if (node.typeParameters) { + context.visit(node.typeParameters); + } + + context.write('('); + + sequence( + context, + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + node.parameters ?? node.params, + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + (node.typeAnnotation ?? node.returnType)?.loc?.start ?? null, + false + ); + context.write(')'); + + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + if (node.typeAnnotation || node.returnType) { + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + context.visit(node.typeAnnotation ?? node.returnType); + } + }, + + /** + * @param {TSESTree.TSFunctionType | TSESTree.TSConstructorType} node + * @param {Context} context + */ + 'TSFunctionType|TSConstructorType': (node, context) => { + if (node.type === 'TSConstructorType') context.write('new '); + if (node.typeParameters) context.visit(node.typeParameters); + + context.write('('); + + sequence( + context, + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + node.parameters ?? node.params, + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + node.typeAnnotation?.typeAnnotation?.loc?.start ?? + node.returnType?.typeAnnotation?.loc?.start ?? + null, + false + ); + + context.write(') => '); + + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + context.visit(node.typeAnnotation?.typeAnnotation ?? node.returnType?.typeAnnotation); } }; @@ -593,6 +776,11 @@ export default (options = {}) => { visit(node); }, + AccessorProperty: + shared[ + 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty' + ], + ArrayExpression: shared['ArrayExpression|ArrayPattern'], ArrayPattern: shared['ArrayExpression|ArrayPattern'], @@ -1005,49 +1193,7 @@ export default (options = {}) => { context.visit(node.property); }, - MethodDefinition(node, context) { - if (node.decorators) { - for (const decorator of node.decorators) { - context.visit(decorator); - } - } - - if (node.static) { - context.write('static '); - } - - if (node.kind === 'get' || node.kind === 'set') { - // Getter or setter - context.write(node.kind + ' '); - } - - if (node.value.async) { - context.write('async '); - } - - if (node.value.generator) { - context.write('*'); - } - - if (node.computed) context.write('['); - context.visit(node.key); - if (node.computed) context.write(']'); - - context.write('('); - sequence( - context, - node.value.params, - (node.value.returnType ?? node.value.body)?.loc?.start ?? node.loc?.end ?? null, - false - ); - context.write(')'); - - if (node.value.returnType) context.visit(node.value.returnType); - - context.write(' '); - - if (node.value.body) context.visit(node.value.body); - }, + MethodDefinition: shared['MethodDefinition|TSAbstractMethodDefinition'], NewExpression: shared['CallExpression|NewExpression'], @@ -1067,7 +1213,9 @@ export default (options = {}) => { // @ts-expect-error this isn't a real node type, but Acorn produces it ParenthesizedExpression(node, context) { - return context.visit(node.expression); + context.write('('); + context.visit(node.expression); + context.write(')'); }, PrivateIdentifier(node, context) { @@ -1124,47 +1272,10 @@ export default (options = {}) => { } }, - PropertyDefinition(node, context) { - if (node.decorators) { - for (const decorator of node.decorators) { - context.visit(decorator); - } - } - - if (node.accessibility) { - context.write(node.accessibility + ' '); - } - - if (node.static) { - context.write('static '); - } - - if (node.computed) { - context.write('['); - context.visit(node.key); - context.write(']'); - } else { - context.visit(node.key); - } - - if (node.typeAnnotation) { - context.write(': '); - context.visit(node.typeAnnotation.typeAnnotation); - } - - if (node.value) { - context.write(' = '); - context.visit(node.value); - } - - context.write(';'); - - flush_trailing_comments( - context, - (node.value ?? node.typeAnnotation ?? node.key).loc?.end ?? null, - null - ); - }, + PropertyDefinition: + shared[ + 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty' + ], RestElement: shared['RestElement|SpreadElement'], @@ -1369,6 +1480,18 @@ export default (options = {}) => { } }, + TSAbstractMethodDefinition: shared['MethodDefinition|TSAbstractMethodDefinition'], + + TSAbstractAccessorProperty: + shared[ + 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty' + ], + + TSAbstractPropertyDefinition: + shared[ + 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty' + ], + TSDeclareFunction(node, context) { context.write('declare '); @@ -1442,6 +1565,18 @@ export default (options = {}) => { context.write('undefined', node); }, + TSObjectKeyword(node, context) { + context.write('object', node); + }, + + TSBigIntKeyword(node, context) { + context.write('bigint', node); + }, + + TSIntrinsicKeyword(node, context) { + context.write('intrinsic', node); + }, + TSArrayType(node, context) { context.visit(node.elementType); context.write('[]'); @@ -1472,11 +1607,70 @@ export default (options = {}) => { } }, + TSTypeOperator(node, context) { + context.write(node.operator + ' '); + if (node.typeAnnotation) { + context.visit(node.typeAnnotation); + } + }, + + TSTemplateLiteralType(node, context) { + context.write('`'); + const { quasis, types } = node; + for (let i = 0; i < types.length; i++) { + const raw = quasis[i].value.raw; + + context.write(raw + '${'); + context.visit(types[i]); + context.write('}'); + + if (/\n/.test(raw)) context.multiline = true; + } + context.write('`'); + }, + + TSParameterProperty(node, context) { + if (node.accessibility) { + context.write(node.accessibility + ' '); + } + + if (node.readonly) { + context.write('readonly '); + } + + context.visit(node.parameter); + }, + + TSExportAssignment(node, context) { + context.write('export = '); + context.visit(node.expression); + context.write(';'); + }, + + TSNamespaceExportDeclaration(node, context) { + context.write('export as namespace '); + context.visit(node.id); + context.write(';'); + }, + //@ts-expect-error I don't know why, but this is relied upon in the tests, but doesn't exist in the TSESTree types TSExpressionWithTypeArguments(node, context) { context.visit(node.expression); }, + TSTypeAssertion(node, context) { + context.write('<'); + context.visit(node.typeAnnotation); + context.write('>'); + if (EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSTypeAssertion) { + context.write('('); + context.visit(node.expression); + context.write(')'); + } else { + context.visit(node.expression); + } + }, + TSTypeParameterInstantiation(node, context) { context.write('<'); for (let i = 0; i < node.params.length; i++) { @@ -1496,8 +1690,9 @@ export default (options = {}) => { }, TSTypeParameter(node, context) { + if (node.name && node.name.type) context.visit(node.name); // @ts-expect-error type mismatch TSESTree and acorn-typescript? - context.write(node.name, node); + else context.write(node.name, node); if (node.constraint) { context.write(' extends '); @@ -1505,11 +1700,35 @@ export default (options = {}) => { } }, + TSTypePredicate(node, context) { + if (node.parameterName) { + context.visit(node.parameterName); + } else if (node.typeAnnotation) { + context.visit(node.typeAnnotation); + } + + if (node.asserts) { + context.write(' asserts '); + } else { + context.write(' is '); + } + + if (node.typeAnnotation) { + context.visit(node.typeAnnotation.typeAnnotation); + } + }, + TSTypeQuery(node, context) { context.write('typeof '); context.visit(node.exprName); }, + TSClassImplements(node, context) { + if (node.expression) { + context.visit(node.expression); + } + }, + TSEnumMember(node, context) { context.visit(node.id); if (node.initializer) { @@ -1518,25 +1737,7 @@ export default (options = {}) => { } }, - TSFunctionType(node, context) { - if (node.typeParameters) context.visit(node.typeParameters); - - context.write('('); - - sequence( - context, - // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions - node.parameters, - // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions - node.typeAnnotation.typeAnnotation.loc?.start ?? null, - false - ); - - context.write(') => '); - - // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions - context.visit(node.typeAnnotation.typeAnnotation); - }, + TSFunctionType: shared['TSFunctionType|TSConstructorType'], TSIndexSignature(node, context) { context.write('['); @@ -1549,17 +1750,45 @@ export default (options = {}) => { context.visit(node.typeAnnotation); }, + TSMappedType(node, context) { + context.write('{['); + + if (node.typeParameter) { + context.visit(node.typeParameter); + } else { + context.visit(node.key); + context.write(' in '); + context.visit(node.constraint); + } + + context.write(']'); + if (node.typeAnnotation) { + context.write(': '); + context.visit(node.typeAnnotation); + } + context.write('}'); + }, + TSMethodSignature(node, context) { context.visit(node.key); context.write('('); - // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions - sequence(context, node.parameters, node.typeAnnotation.loc?.start ?? null, false); + sequence( + context, + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + node.parameters ?? node.params, + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + (node.typeAnnotation ?? node.returnType)?.loc?.start ?? null, + false + ); context.write(')'); // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions - context.visit(node.typeAnnotation); + if (node.typeAnnotation || node.returnType) { + // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions + context.visit(node.typeAnnotation ?? node.returnType); + } }, TSTupleType(node, context) { @@ -1582,10 +1811,18 @@ export default (options = {}) => { sequence(context, node.types, node.loc?.end ?? null, false, ' &'); }, + TSInferType(node, context) { + context.write('infer '); + context.visit(node.typeParameter); + }, + TSLiteralType(node, context) { context.visit(node.literal); }, + TSCallSignatureDeclaration: + shared['TSConstructSignatureDeclaration|TSCallSignatureDeclaration'], + TSConditionalType(node, context) { context.visit(node.checkType); context.write(' extends '); @@ -1596,6 +1833,17 @@ export default (options = {}) => { context.visit(node.falseType); }, + TSConstructSignatureDeclaration: + shared['TSConstructSignatureDeclaration|TSCallSignatureDeclaration'], + + TSConstructorType: shared['TSFunctionType|TSConstructorType'], + + TSExternalModuleReference(node, context) { + context.write('require('); + context.visit(node.expression); + context.write(');'); + }, + TSIndexedAccessType(node, context) { context.visit(node.objectType); context.write('['); @@ -1603,6 +1851,13 @@ export default (options = {}) => { context.write(']'); }, + TSImportEqualsDeclaration(node, context) { + context.write('import '); + context.visit(node.id); + context.write(' = '); + context.visit(node.moduleReference); + }, + TSImportType(node, context) { context.write('import('); context.visit(node.argument); @@ -1614,6 +1869,20 @@ export default (options = {}) => { } }, + TSOptionalType(node, context) { + context.visit(node.typeAnnotation); + context.write('?'); + }, + + TSRestType(node, context) { + context.write('...'); + context.visit(node.typeAnnotation); + }, + + TSThisType(node, context) { + context.write('this', node); + }, + TSAsExpression(node, context) { if (node.expression) { const needs_parens = @@ -1637,7 +1906,7 @@ export default (options = {}) => { context.write(' {'); context.indent(); context.newline(); - sequence(context, node.members, node.loc?.end ?? null, false); + sequence(context, node.members ?? node.body.members, node.loc?.end ?? null, false); context.dedent(); context.newline(); context.write('}'); @@ -1676,7 +1945,7 @@ export default (options = {}) => { context.write('interface '); context.visit(node.id); if (node.typeParameters) context.visit(node.typeParameters); - if (node.extends) { + if (node.extends && node.extends.length > 0) { context.write(' extends '); sequence(context, node.extends, node.body.loc?.start ?? null, false); } @@ -1685,6 +1954,24 @@ export default (options = {}) => { context.write('}'); }, + TSInstantiationExpression(node, context) { + context.visit(node.expression); + context.visit(node.typeArguments); + }, + + TSInterfaceHeritage(node, context) { + if (node.expression) { + context.visit(node.expression); + } + }, + + //@ts-expect-error I don't know why, but this is relied upon in the tests, but doesn't exist in the TSESTree types + TSParenthesizedType(node, context) { + context.write('('); + context.visit(node.typeAnnotation); + context.write(')'); + }, + TSSatisfiesExpression(node, context) { if (node.expression) { const needs_parens = diff --git a/test/esrap.test.js b/test/esrap.test.js index 939e55c..95d6738 100644 --- a/test/esrap.test.js +++ b/test/esrap.test.js @@ -7,6 +7,7 @@ import { walk } from 'zimmerframe'; import { print } from '../src/index.js'; import { acornTs, acornTsx, load } from './common.js'; import tsx from '../src/languages/tsx/index.js'; +// import { parseSync } from 'oxc-parser'; /** @param {TSESTree.Node} ast */ function clean(ast) { @@ -55,6 +56,9 @@ function clean(ast) { return cleaned; } +const oxc = false; +const acorn = true; + for (const dir of fs.readdirSync(`${__dirname}/samples`)) { if (dir[0] === '.') continue; const tsMode = dir.startsWith('ts-') || dir.startsWith('tsx-'); @@ -74,20 +78,28 @@ for (const dir of fs.readdirSync(`${__dirname}/samples`)) { } catch (error) {} /** @type {TSESTree.Program} */ - let ast; + let acorn_ast; + /** @type {TSESTree.Program} */ + let oxc_ast; /** @type {TSESTree.Comment[]} */ - let comments; + let acorn_comments; + /** @type {TSESTree.Comment[]} */ + let oxc_comments; /** @type {PrintOptions} */ let opts; if (input_json.length > 0) { - ast = JSON.parse(input_json); - comments = []; + acorn_ast = JSON.parse(input_json); + acorn_comments = []; + oxc_ast = JSON.parse(input_json); + oxc_comments = []; opts = {}; } else { - ({ ast, comments } = load(input_js, { jsx: true })); + ({ ast: acorn_ast, comments: acorn_comments } = load(input_js, { jsx: true })); + + // ({ program: oxc_ast, comments: oxc_comments } = parseSync('input.ts', input_js)); opts = { sourceMapSource: 'input.js', @@ -95,37 +107,54 @@ for (const dir of fs.readdirSync(`${__dirname}/samples`)) { }; } - const { code, map } = print(ast, tsx({ comments }), opts); - - fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.${fileExtension}`, code); - fs.writeFileSync( - `${__dirname}/samples/${dir}/_actual.${fileExtension}.map`, - JSON.stringify(map, null, '\t') - ); - - const parsed = (jsxMode ? acornTsx : acornTs).parse(code, { - ecmaVersion: 'latest', - sourceType: input_json.length > 0 ? 'script' : 'module', - locations: true - }); - - fs.writeFileSync( - `${__dirname}/samples/${dir}/_actual.json`, - JSON.stringify( - parsed, - (key, value) => (typeof value === 'bigint' ? Number(value) : value), - '\t' - ) - ); - - expect(code.trim().replace(/^\t+$/gm, '').replaceAll('\r', '')).toMatchFileSnapshot( - `${__dirname}/samples/${dir}/expected.${fileExtension}` - ); - - expect(JSON.stringify(map, null, ' ').replaceAll('\\r', '')).toMatchFileSnapshot( - `${__dirname}/samples/${dir}/expected.${fileExtension}.map` + const { code: acorn_code, map: acorn_map } = print( + acorn_ast, + tsx({ comments: acorn_comments }), + opts ); + // const { code: oxc_code } = print(oxc_ast, tsx({ comments: oxc_comments }), opts); + + if (acorn) { + fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.${fileExtension}`, acorn_code); + fs.writeFileSync( + `${__dirname}/samples/${dir}/_actual.${fileExtension}.map`, + JSON.stringify(acorn_map, null, '\t') + ); + + const parsed = (jsxMode ? acornTsx : acornTs).parse(acorn_code, { + ecmaVersion: 'latest', + sourceType: input_json.length > 0 ? 'script' : 'module', + locations: true + }); + + fs.writeFileSync( + `${__dirname}/samples/${dir}/_actual.json`, + JSON.stringify( + parsed, + (key, value) => (typeof value === 'bigint' ? Number(value) : value), + '\t' + ) + ); + + expect(acorn_code.trim().replace(/^\t+$/gm, '').replaceAll('\r', '')).toMatchFileSnapshot( + `${__dirname}/samples/${dir}/expected.${fileExtension}`, + 'acorn' + ); + + expect(JSON.stringify(acorn_map, null, ' ').replaceAll('\\r', '')).toMatchFileSnapshot( + `${__dirname}/samples/${dir}/expected.${fileExtension}.map` + ); + + expect(clean(/** @type {TSESTree.Node} */ (/** @type {any} */ (parsed)))).toEqual( + clean(acorn_ast) + ); + } - expect(clean(/** @type {TSESTree.Node} */ (/** @type {any} */ (parsed)))).toEqual(clean(ast)); + if (oxc) { + // expect(oxc_code.trim().replace(/^\t+$/gm, '').replaceAll('\r', '')).toMatchFileSnapshot( + // `${__dirname}/samples/${dir}/expected.${fileExtension}`, + // 'oxc' + // ); + } }); } diff --git a/test/samples/ts-abstract-class/expected.ts b/test/samples/ts-abstract-class/expected.ts new file mode 100644 index 0000000..f5eaea5 --- /dev/null +++ b/test/samples/ts-abstract-class/expected.ts @@ -0,0 +1,7 @@ +abstract class A { + abstract foo: string; + abstract bar: string; + + abstract get a() + abstract set b(x: string) +} \ No newline at end of file diff --git a/test/samples/ts-abstract-class/expected.ts.map b/test/samples/ts-abstract-class/expected.ts.map new file mode 100644 index 0000000..6fed80d --- /dev/null +++ b/test/samples/ts-abstract-class/expected.ts.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "names": [], + "sources": [ + "input.js" + ], + "sourcesContent": [ + "abstract class A {\n\tabstract foo: string;\n\tabstract bar: string;\n\n\tabstract get a();\n\tabstract set b(x: string);\n}\n" + ], + "mappings": "eAAe,CAAC,CAAC,CAAC;UACR,GAAG,EAAE,MAAM;UACX,GAAG,EAAE,MAAM;;cAEP,CAAC;cACD,CAAC,CAAC,CAAS,EAAN,MAAM;AACzB,CAAC" +} \ No newline at end of file diff --git a/test/samples/ts-abstract-class/input.ts b/test/samples/ts-abstract-class/input.ts new file mode 100644 index 0000000..690cb36 --- /dev/null +++ b/test/samples/ts-abstract-class/input.ts @@ -0,0 +1,7 @@ +abstract class A { + abstract foo: string; + abstract bar: string; + + abstract get a(); + abstract set b(x: string); +} diff --git a/test/samples/ts-accessor-properties/expected.ts b/test/samples/ts-accessor-properties/expected.ts new file mode 100644 index 0000000..34acd02 --- /dev/null +++ b/test/samples/ts-accessor-properties/expected.ts @@ -0,0 +1,15 @@ +class Example { + accessor count: number = 0; + private accessor privateCount: number; + public accessor publicCount: number = 5; + protected accessor protectedCount: number; +} + +abstract class AbstractExample { + abstract accessor abstractCount: number; + protected abstract accessor protectedAbstractCount: number; +} + +class MyClass { + constructor(protected x: number, private y: string) {} +} \ No newline at end of file diff --git a/test/samples/ts-accessor-properties/expected.ts.map b/test/samples/ts-accessor-properties/expected.ts.map new file mode 100644 index 0000000..59a6063 --- /dev/null +++ b/test/samples/ts-accessor-properties/expected.ts.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "names": [], + "sources": [ + "input.js" + ], + "sourcesContent": [ + "class Example {\n\taccessor count: number = 0;\n\tprivate accessor privateCount: number;\n\tpublic accessor publicCount: number = 5;\n\tprotected accessor protectedCount: number;\n}\n\nabstract class AbstractExample {\n\tabstract accessor abstractCount: number;\n\tprotected abstract accessor protectedAbstractCount: number;\n}\n\nclass MyClass {\n\tconstructor(\n\t\tprotected x: number,\n\t\tprivate y: string\n\t) {}\n}\n" + ], + "mappings": "MAAM,OAAO,CAAC,CAAC;UACL,KAAK,EAAE,MAAM,GAAG,CAAC;kBACT,YAAY,EAAE,MAAM;iBACrB,WAAW,EAAE,MAAM,GAAG,CAAC;oBACpB,cAAc,EAAE,MAAM;AAC1C,CAAC;;eAEc,eAAe,CAAC,CAAC;mBACb,aAAa,EAAE,MAAM;6BACX,sBAAsB,EAAE,MAAM;AAC3D,CAAC;;MAEK,OAAO,CAAC,CAAC;CACd,WAAW,WACA,CAAS,EAAN,MAAM,UACX,CAAS,EAAN,MAAM,EAChB,CAAC,AAAA,CAAC;AACL,CAAC" +} \ No newline at end of file diff --git a/test/samples/ts-accessor-properties/input.ts b/test/samples/ts-accessor-properties/input.ts new file mode 100644 index 0000000..dc4f38a --- /dev/null +++ b/test/samples/ts-accessor-properties/input.ts @@ -0,0 +1,18 @@ +class Example { + accessor count: number = 0; + private accessor privateCount: number; + public accessor publicCount: number = 5; + protected accessor protectedCount: number; +} + +abstract class AbstractExample { + abstract accessor abstractCount: number; + protected abstract accessor protectedAbstractCount: number; +} + +class MyClass { + constructor( + protected x: number, + private y: string + ) {} +} diff --git a/test/samples/ts-as-expression/expected.ts b/test/samples/ts-as-expression/expected.ts index aebcdd6..78d2d9d 100644 --- a/test/samples/ts-as-expression/expected.ts +++ b/test/samples/ts-as-expression/expected.ts @@ -5,4 +5,5 @@ type C = { name: string }; type D = { firstName: string }; const e: C = { name: 'foo' } as unknown as D; -const f = (Math.random() > 0.5 ? { firstName: 'name1' } : { firstName: 'name2' }) as unknown as D; \ No newline at end of file +const f = (Math.random() > 0.5 ? { firstName: 'name1' } : { firstName: 'name2' }) as unknown as D; +const g = h(e['name']) as (scope: ng.IScope) => b; \ No newline at end of file diff --git a/test/samples/ts-as-expression/expected.ts.map b/test/samples/ts-as-expression/expected.ts.map index c610937..d3ba6a0 100644 --- a/test/samples/ts-as-expression/expected.ts.map +++ b/test/samples/ts-as-expression/expected.ts.map @@ -5,7 +5,7 @@ "input.js" ], "sourcesContent": [ - "const a: number = 42;\nconst b = a as unknown as string;\n\ntype C = {\n\tname: string;\n};\n\ntype D = {\n\tfirstName: string;\n};\n\nconst e: C = {\n\tname: 'foo'\n} as unknown as D;\n\nconst f = (Math.random() > 0.5 ? { firstName: 'name1' } : { firstName: 'name2' }) as unknown as D;\n" + "const a: number = 42;\nconst b = a as unknown as string;\n\ntype C = {\n\tname: string;\n};\n\ntype D = {\n\tfirstName: string;\n};\n\nconst e: C = {\n\tname: 'foo'\n} as unknown as D;\n\nconst f = (Math.random() > 0.5 ? { firstName: 'name1' } : { firstName: 'name2' }) as unknown as D;\n\nconst g = h(e['name']) as (scope: ng.IScope) => b;\n" ], - "mappings": "MAAM,CAAS,EAAN,MAAM,GAAG,EAAE;MACd,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,MAAM;;KAE3B,CAAC,KACL,IAAI,EAAE,MAAM;KAGR,CAAC,KACL,SAAS,EAAE,MAAM;;MAGZ,CAAI,EAAD,CAAC,KACT,IAAI,EAAE,KAAK,MACP,OAAO,IAAI,CAAC;MAEX,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,KAAK,SAAS,EAAE,OAAO,OAAO,SAAS,EAAE,OAAO,OAAO,OAAO,IAAI,CAAC" + "mappings": "MAAM,CAAS,EAAN,MAAM,GAAG,EAAE;MACd,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,MAAM;;KAE3B,CAAC,KACL,IAAI,EAAE,MAAM;KAGR,CAAC,KACL,SAAS,EAAE,MAAM;;MAGZ,CAAI,EAAD,CAAC,KACT,IAAI,EAAE,KAAK,MACP,OAAO,IAAI,CAAC;MAEX,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,KAAK,SAAS,EAAE,OAAO,OAAO,SAAS,EAAE,OAAO,OAAO,OAAO,IAAI,CAAC;MAE3F,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,OAAO,KAAgB,EAAT,EAAE,CAAC,MAAM,KAAK,CAAC" } \ No newline at end of file diff --git a/test/samples/ts-as-expression/input.ts b/test/samples/ts-as-expression/input.ts index a72dab4..c174e58 100644 --- a/test/samples/ts-as-expression/input.ts +++ b/test/samples/ts-as-expression/input.ts @@ -14,3 +14,5 @@ const e: C = { } as unknown as D; const f = (Math.random() > 0.5 ? { firstName: 'name1' } : { firstName: 'name2' }) as unknown as D; + +const g = h(e['name']) as (scope: ng.IScope) => b; diff --git a/test/samples/ts-export/expected.ts b/test/samples/ts-export/expected.ts index bebe129..ceac0af 100644 --- a/test/samples/ts-export/expected.ts +++ b/test/samples/ts-export/expected.ts @@ -6,4 +6,10 @@ type Z = number; export type { Y }; export { type Z }; -// export type * from './elsewhere'; \ No newline at end of file +// TODO: commented because acorn doesn't support export = syntax but oxc does +// declare module 'hello' { +// export = Y; +// } +export as namespace MyNamespace; + +// export type * from './elsewhere'; diff --git a/test/samples/ts-export/expected.ts.map b/test/samples/ts-export/expected.ts.map index 8e38343..ee819c9 100644 --- a/test/samples/ts-export/expected.ts.map +++ b/test/samples/ts-export/expected.ts.map @@ -5,7 +5,7 @@ "input.js" ], "sourcesContent": [ - "export type X = number;\n\ntype Y = number;\ntype Z = number;\nexport type { Y };\nexport { type Z };\n\n// export type * from './elsewhere';\n" + "export type X = number;\n\ntype Y = number;\ntype Z = number;\nexport type { Y };\nexport { type Z };\n\n// TODO: commented because acorn doesn't support export = syntax but oxc does\n// declare module 'hello' {\n// export = Y;\n// }\n\nexport as namespace MyNamespace;\n\n// export type * from './elsewhere';\n" ], - "mappings": "YAAY,CAAC,GAAG,MAAM;;KAEjB,CAAC,GAAG,MAAM;KACV,CAAC,GAAG,MAAM;;cACD,CAAC;cACD,CAAC;;" + "mappings": "YAAY,CAAC,GAAG,MAAM;;KAEjB,CAAC,GAAG,MAAM;KACV,CAAC,GAAG,MAAM;;cACD,CAAC;cACD,CAAC;;;;;;oBAOK,WAAW;;" } \ No newline at end of file diff --git a/test/samples/ts-export/input.ts b/test/samples/ts-export/input.ts index 8d1f72a..b96b7fc 100644 --- a/test/samples/ts-export/input.ts +++ b/test/samples/ts-export/input.ts @@ -5,4 +5,11 @@ type Z = number; export type { Y }; export { type Z }; +// TODO: commented because acorn doesn't support export = syntax but oxc does +// declare module 'hello' { +// export = Y; +// } + +export as namespace MyNamespace; + // export type * from './elsewhere'; diff --git a/test/samples/ts-import-type/expected.ts b/test/samples/ts-import-type/expected.ts index 486cfe8..95821ab 100644 --- a/test/samples/ts-import-type/expected.ts +++ b/test/samples/ts-import-type/expected.ts @@ -1,2 +1,4 @@ +import baz = require('baz'); + const foo: import('foo/bar') = 123; const bar: import('foo/bar').baz = 234; \ No newline at end of file diff --git a/test/samples/ts-import-type/expected.ts.map b/test/samples/ts-import-type/expected.ts.map index 6159fb2..640f716 100644 --- a/test/samples/ts-import-type/expected.ts.map +++ b/test/samples/ts-import-type/expected.ts.map @@ -5,7 +5,7 @@ "input.js" ], "sourcesContent": [ - "const foo: import('foo/bar') = 123;\nconst bar: import('foo/bar').baz = 234;\n" + "import baz = require('baz');\n\nconst foo: import('foo/bar') = 123;\nconst bar: import('foo/bar').baz = 234;\n" ], - "mappings": "MAAM,GAAsB,SAAV,SAAS,IAAI,GAAG;MAC5B,GAA0B,SAAd,SAAS,EAAE,GAAG,GAAG,GAAG" + "mappings": "OAAO,GAAG,WAAW,KAAK;;MAEpB,GAAsB,SAAV,SAAS,IAAI,GAAG;MAC5B,GAA0B,SAAd,SAAS,EAAE,GAAG,GAAG,GAAG" } \ No newline at end of file diff --git a/test/samples/ts-import-type/input.ts b/test/samples/ts-import-type/input.ts index 54fdd12..d9154d8 100644 --- a/test/samples/ts-import-type/input.ts +++ b/test/samples/ts-import-type/input.ts @@ -1,2 +1,4 @@ +import baz = require('baz'); + const foo: import('foo/bar') = 123; const bar: import('foo/bar').baz = 234; diff --git a/test/samples/ts-infer-extends/expected.ts b/test/samples/ts-infer-extends/expected.ts new file mode 100644 index 0000000..f938134 --- /dev/null +++ b/test/samples/ts-infer-extends/expected.ts @@ -0,0 +1,9 @@ +type X3 = T extends [infer U extends number] ? MustBeNumber : never; +type X4 = T extends [infer U extends number, infer U extends number] ? MustBeNumber : never; +type X5 = T extends [infer U extends number, infer U] ? MustBeNumber : never; +type X6 = T extends [infer U, infer U extends number] ? MustBeNumber : never; +type X7 = T extends [infer U extends string, infer U extends number] ? U : never; +type X8 = T extends infer U extends number ? U : T; +type X9 = T extends (infer U extends number ? U : T) ? U : T; +type X10 = T extends (infer U extends number) | { a: infer U extends number } ? U : never; +type X11 = T extends (infer U extends number) & { a: infer U extends number } ? U : never; \ No newline at end of file diff --git a/test/samples/ts-infer-extends/expected.ts.map b/test/samples/ts-infer-extends/expected.ts.map new file mode 100644 index 0000000..3def685 --- /dev/null +++ b/test/samples/ts-infer-extends/expected.ts.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "names": [], + "sources": [ + "input.js" + ], + "sourcesContent": [ + "type X3 = T extends [infer U extends number] ? MustBeNumber : never;\ntype X4 = T extends [infer U extends number, infer U extends number] ? MustBeNumber : never;\ntype X5 = T extends [infer U extends number, infer U] ? MustBeNumber : never;\ntype X6 = T extends [infer U, infer U extends number] ? MustBeNumber : never;\ntype X7 = T extends [infer U extends string, infer U extends number] ? U : never;\ntype X8 = T extends infer U extends number ? U : T;\ntype X9 = T extends (infer U extends number ? U : T) ? U : T;\ntype X10 = T extends (infer U extends number) | { a: infer U extends number } ? U : never;\ntype X11 = T extends (infer U extends number) & { a: infer U extends number } ? U : never;\n" + ], + "mappings": "KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAgB,SAAN,MAAM,IAAI,YAAY,CAAC,CAAC,IAAI,KAAK;KACpE,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAgB,SAAN,MAAM,QAAQ,CAAgB,SAAN,MAAM,IAAI,YAAY,CAAC,CAAC,IAAI,KAAK;KAC5F,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAgB,SAAN,MAAM,QAAQ,CAAC,IAAI,YAAY,CAAC,CAAC,IAAI,KAAK;KAC7E,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAgB,SAAN,MAAM,IAAI,YAAY,CAAC,CAAC,IAAI,KAAK;KAC7E,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAgB,SAAN,MAAM,QAAQ,CAAgB,SAAN,MAAM,IAAI,CAAC,GAAG,KAAK;KAC9E,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAgB,SAAN,MAAM,GAAG,CAAC,GAAG,CAAC;KACnD,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAC7D,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAgB,SAAN,MAAM,MAAM,CAAC,QAAQ,CAAgB,SAAN,MAAM,KAAK,CAAC,GAAG,KAAK;KACvF,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAgB,SAAN,MAAM,MAAM,CAAC,QAAQ,CAAgB,SAAN,MAAM,KAAK,CAAC,GAAG,KAAK" +} \ No newline at end of file diff --git a/test/samples/ts-infer-extends/input.ts b/test/samples/ts-infer-extends/input.ts new file mode 100644 index 0000000..1da66a2 --- /dev/null +++ b/test/samples/ts-infer-extends/input.ts @@ -0,0 +1,9 @@ +type X3 = T extends [infer U extends number] ? MustBeNumber : never; +type X4 = T extends [infer U extends number, infer U extends number] ? MustBeNumber : never; +type X5 = T extends [infer U extends number, infer U] ? MustBeNumber : never; +type X6 = T extends [infer U, infer U extends number] ? MustBeNumber : never; +type X7 = T extends [infer U extends string, infer U extends number] ? U : never; +type X8 = T extends infer U extends number ? U : T; +type X9 = T extends (infer U extends number ? U : T) ? U : T; +type X10 = T extends (infer U extends number) | { a: infer U extends number } ? U : never; +type X11 = T extends (infer U extends number) & { a: infer U extends number } ? U : never; diff --git a/test/samples/ts-instantiation-expression/expected.ts b/test/samples/ts-instantiation-expression/expected.ts new file mode 100644 index 0000000..4791bbb --- /dev/null +++ b/test/samples/ts-instantiation-expression/expected.ts @@ -0,0 +1,2 @@ +// basic +const foo = bar; \ No newline at end of file diff --git a/test/samples/ts-null-keyword/expected.ts.map b/test/samples/ts-instantiation-expression/expected.ts.map similarity index 51% rename from test/samples/ts-null-keyword/expected.ts.map rename to test/samples/ts-instantiation-expression/expected.ts.map index e61feb8..f7b3d8e 100644 --- a/test/samples/ts-null-keyword/expected.ts.map +++ b/test/samples/ts-instantiation-expression/expected.ts.map @@ -5,7 +5,7 @@ "input.js" ], "sourcesContent": [ - "let a: string | null = null" + "// basic\nconst foo = bar;\n" ], - "mappings": "IAAI,CAAgB,EAAb,MAAM,GAAG,IAAI,GAAG,IAAI" + "mappings": ";MACM,GAAG,GAAG,GAAG,CAAC,CAAC" } \ No newline at end of file diff --git a/test/samples/ts-instantiation-expression/input.ts b/test/samples/ts-instantiation-expression/input.ts new file mode 100644 index 0000000..6bba4f1 --- /dev/null +++ b/test/samples/ts-instantiation-expression/input.ts @@ -0,0 +1,2 @@ +// basic +const foo = bar; diff --git a/test/samples/ts-interfaces/expected.ts b/test/samples/ts-interfaces/expected.ts index 7cfedbf..f041b0f 100644 --- a/test/samples/ts-interfaces/expected.ts +++ b/test/samples/ts-interfaces/expected.ts @@ -11,7 +11,7 @@ class Control { private state: any; } -interface SelectableControl extends Control { select(): void } +interface SelectableControl extends Control { select(): void; bar() } class Button extends Control implements SelectableControl { select() {} diff --git a/test/samples/ts-interfaces/expected.ts.map b/test/samples/ts-interfaces/expected.ts.map index 95ca8e3..4f77acb 100644 --- a/test/samples/ts-interfaces/expected.ts.map +++ b/test/samples/ts-interfaces/expected.ts.map @@ -5,7 +5,7 @@ "input.js" ], "sourcesContent": [ - "interface Test {\n\tfunc: (a: string) => Promise;\n\tfunc2: () => Promise;\n\ta: number;\n\tb: boolean;\n}\n\ninterface IndexSignature {\n\t[key: string]: string;\n}\n\nclass Control {\n\tprivate state: any;\n}\n\ninterface SelectableControl extends Control {\n\tselect(): void;\n}\n\nclass Button extends Control implements SelectableControl {\n\tselect() {}\n}\n\nclass TextBox extends Control {\n\tselect() {}\n}\n" + "interface Test {\n\tfunc: (a: string) => Promise;\n\tfunc2: () => Promise;\n\ta: number;\n\tb: boolean;\n}\n\ninterface IndexSignature {\n\t[key: string]: string;\n}\n\nclass Control {\n\tprivate state: any;\n}\n\ninterface SelectableControl extends Control {\n\tselect(): void;\n\tbar();\n}\n\nclass Button extends Control implements SelectableControl {\n\tselect() {}\n}\n\nclass TextBox extends Control {\n\tselect() {}\n}\n" ], - "mappings": "UAAU,IAAI;CACb,IAAI,GAAG,CAAS,EAAN,MAAM,KAAK,OAAO,CAAC,IAAI;CACjC,KAAK,QAAQ,OAAO,CAAC,IAAI;CACzB,CAAC,EAAE,MAAM;CACT,CAAC,EAAE,OAAO;;;UAGD,cAAc,IACtB,GAAW,EAAN,MAAM,GAAG,MAAM;;MAGhB,OAAO,CAAC,CAAC;SACN,KAAK,EAAE,GAAG;AACnB,CAAC;;UAES,iBAAiB,SAAS,OAAO,GAC1C,MAAM,IAAI,IAAI;;MAGT,MAAM,SAAS,OAAO,YAAY,iBAAiB,CAAC,CAAC;CAC1D,MAAM,GAAG,CAAC,AAAA,CAAC;AACZ,CAAC;;MAEK,OAAO,SAAS,OAAO,CAAC,CAAC;CAC9B,MAAM,GAAG,CAAC,AAAA,CAAC;AACZ,CAAC" + "mappings": "UAAU,IAAI;CACb,IAAI,GAAG,CAAS,EAAN,MAAM,KAAK,OAAO,CAAC,IAAI;CACjC,KAAK,QAAQ,OAAO,CAAC,IAAI;CACzB,CAAC,EAAE,MAAM;CACT,CAAC,EAAE,OAAO;;;UAGD,cAAc,IACtB,GAAW,EAAN,MAAM,GAAG,MAAM;;MAGhB,OAAO,CAAC,CAAC;SACN,KAAK,EAAE,GAAG;AACnB,CAAC;;UAES,iBAAiB,SAAS,OAAO,GAC1C,MAAM,IAAI,IAAI,EACd,GAAG;;MAGE,MAAM,SAAS,OAAO,YAAY,iBAAiB,CAAC,CAAC;CAC1D,MAAM,GAAG,CAAC,AAAA,CAAC;AACZ,CAAC;;MAEK,OAAO,SAAS,OAAO,CAAC,CAAC;CAC9B,MAAM,GAAG,CAAC,AAAA,CAAC;AACZ,CAAC" } \ No newline at end of file diff --git a/test/samples/ts-interfaces/input.ts b/test/samples/ts-interfaces/input.ts index fc86877..ef30cc1 100644 --- a/test/samples/ts-interfaces/input.ts +++ b/test/samples/ts-interfaces/input.ts @@ -15,6 +15,7 @@ class Control { interface SelectableControl extends Control { select(): void; + bar(); } class Button extends Control implements SelectableControl { diff --git a/test/samples/ts-keywords/expected.ts b/test/samples/ts-keywords/expected.ts new file mode 100644 index 0000000..d1216f2 --- /dev/null +++ b/test/samples/ts-keywords/expected.ts @@ -0,0 +1,17 @@ +let n: number = 42; +let s: string = 'Hello, TypeScript!'; +let b: boolean = true; +let u: unknown = 'whatever'; +let un: undefined = undefined; +let o: object = { name: 'Object' }; +let bi: bigint = 1234567890123456789012345678901234567890n; +let ne: never; +let sy: symbol = Symbol('unique'); +let a: any = { key: 'value' }; +let v: () => void = () => {}; +let arr: number[] = [1, 2, 3]; +let snu: string | null = null; +let nun: number | undefined = undefined; + +// TODO: commented because acorn doesn't support type assertions but oxc does +// let ta = true; diff --git a/test/samples/ts-keywords/expected.ts.map b/test/samples/ts-keywords/expected.ts.map new file mode 100644 index 0000000..93a5e49 --- /dev/null +++ b/test/samples/ts-keywords/expected.ts.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "names": [], + "sources": [ + "input.js" + ], + "sourcesContent": [ + "let n: number = 42;\nlet s: string = 'Hello, TypeScript!';\nlet b: boolean = true;\nlet u: unknown = 'whatever';\nlet un: undefined = undefined;\nlet o: object = { name: 'Object' };\nlet bi: bigint = 1234567890123456789012345678901234567890n;\nlet ne: never;\nlet sy: symbol = Symbol('unique');\nlet a: any = { key: 'value' };\nlet v: () => void = () => {};\nlet arr: number[] = [1, 2, 3];\nlet snu: string | null = null;\nlet nun: number | undefined = undefined;\n\n// TODO: commented because acorn doesn't support type assertions but oxc does\n// let ta = true;\n" + ], + "mappings": "IAAI,CAAS,EAAN,MAAM,GAAG,EAAE;IACd,CAAS,EAAN,MAAM,GAAG,oBAAoB;IAChC,CAAU,EAAP,OAAO,GAAG,IAAI;IACjB,CAAU,EAAP,OAAO,GAAG,UAAU;IACvB,EAAa,EAAT,SAAS,GAAG,SAAS;IACzB,CAAS,EAAN,MAAM,KAAK,IAAI,EAAE,QAAQ;IAC5B,EAAU,EAAN,MAAM,GAAG,yCAAyC;IACtD,EAAS,EAAL,KAAK;IACT,EAAU,EAAN,MAAM,GAAG,MAAM,CAAC,QAAQ;IAC5B,CAAM,EAAH,GAAG,KAAK,GAAG,EAAE,OAAO;IACvB,CAAa,QAAJ,IAAI,SAAS,CAAC,AAAA,CAAC;IACxB,GAAa,EAAR,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IACxB,GAAkB,EAAb,MAAM,GAAG,IAAI,GAAG,IAAI;IACzB,GAAuB,EAAlB,MAAM,GAAG,SAAS,GAAG,SAAS;;;" +} \ No newline at end of file diff --git a/test/samples/ts-keywords/input.ts b/test/samples/ts-keywords/input.ts new file mode 100644 index 0000000..d1216f2 --- /dev/null +++ b/test/samples/ts-keywords/input.ts @@ -0,0 +1,17 @@ +let n: number = 42; +let s: string = 'Hello, TypeScript!'; +let b: boolean = true; +let u: unknown = 'whatever'; +let un: undefined = undefined; +let o: object = { name: 'Object' }; +let bi: bigint = 1234567890123456789012345678901234567890n; +let ne: never; +let sy: symbol = Symbol('unique'); +let a: any = { key: 'value' }; +let v: () => void = () => {}; +let arr: number[] = [1, 2, 3]; +let snu: string | null = null; +let nun: number | undefined = undefined; + +// TODO: commented because acorn doesn't support type assertions but oxc does +// let ta = true; diff --git a/test/samples/ts-null-keyword/expected.ts b/test/samples/ts-null-keyword/expected.ts deleted file mode 100644 index 7e89405..0000000 --- a/test/samples/ts-null-keyword/expected.ts +++ /dev/null @@ -1 +0,0 @@ -let a: string | null = null; \ No newline at end of file diff --git a/test/samples/ts-null-keyword/input.ts b/test/samples/ts-null-keyword/input.ts deleted file mode 100644 index 5369a51..0000000 --- a/test/samples/ts-null-keyword/input.ts +++ /dev/null @@ -1 +0,0 @@ -let a: string | null = null \ No newline at end of file diff --git a/test/samples/ts-signatures/expected.ts b/test/samples/ts-signatures/expected.ts new file mode 100644 index 0000000..e8d6a6a --- /dev/null +++ b/test/samples/ts-signatures/expected.ts @@ -0,0 +1,8 @@ +interface Constructable { + new(): any; + new(value: string): MyClass; + new(value: T): GenericClass; + (name: string): string +} + +type Constructor = { new(): object; new(name: string, age: number): Person }; \ No newline at end of file diff --git a/test/samples/ts-signatures/expected.ts.map b/test/samples/ts-signatures/expected.ts.map new file mode 100644 index 0000000..ee65d1e --- /dev/null +++ b/test/samples/ts-signatures/expected.ts.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "names": [], + "sources": [ + "input.js" + ], + "sourcesContent": [ + "interface Constructable {\n\tnew (): any;\n\tnew (value: string): MyClass;\n\tnew (value: T): GenericClass;\n\t(name: string): string;\n}\n\ntype Constructor = {\n\tnew (): object;\n\tnew (name: string, age: number): Person;\n};\n" + ], + "mappings": "UAAU,aAAa;QACd,GAAG;KACN,KAAa,EAAN,MAAM,GAAG,OAAO;KACvB,CAAC,EAAE,KAAQ,EAAD,CAAC,GAAG,YAAY,CAAC,CAAC;EAChC,IAAY,EAAN,MAAM,GAAG,MAAM;;;KAGlB,WAAW,YACP,MAAM,MACT,IAAY,EAAN,MAAM,EAAE,GAAW,EAAN,MAAM,GAAG,MAAM" +} \ No newline at end of file diff --git a/test/samples/ts-signatures/input.ts b/test/samples/ts-signatures/input.ts new file mode 100644 index 0000000..3892af8 --- /dev/null +++ b/test/samples/ts-signatures/input.ts @@ -0,0 +1,11 @@ +interface Constructable { + new (): any; + new (value: string): MyClass; + new (value: T): GenericClass; + (name: string): string; +} + +type Constructor = { + new (): object; + new (name: string, age: number): Person; +}; diff --git a/test/samples/ts-types/expected.ts b/test/samples/ts-types/expected.ts index e228047..8643ac5 100644 --- a/test/samples/ts-types/expected.ts +++ b/test/samples/ts-types/expected.ts @@ -4,9 +4,23 @@ type C = 'foo' | 'bar'; type D = C | A | B | 'foobar'; type E = A & B; type F = C & 'foobar'; + +// TODO: commented because acorn doesn't support intrinsic but oxc does +// type G = { [a in C]: string }; +type H = this; + +type I = `Hello, ${keyof C}`; +type J = () => this is string; type Bird = { legs: 2 }; type Dog = { legs: 4 }; type Wolf = { legs: 4 }; type Animals = Bird | Dog | Wolf; type HasFourLegs = Animal extends { legs: 4 } ? Animal : never; -type FourLegs = HasFourLegs; \ No newline at end of file +type FourLegs = HasFourLegs; +type T = [('a' | 'b')?]; +type CT = new (tpl: TemplateStringsArray, ...args: Array) => (replacements: B) => A; +type X = [...number[]]; +type TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])]; + +// TODO: commented because acorn doesn't support intrinsic but oxc does +// type Uppercase = intrinsic; \ No newline at end of file diff --git a/test/samples/ts-types/expected.ts.map b/test/samples/ts-types/expected.ts.map index 1d4cef4..412da92 100644 --- a/test/samples/ts-types/expected.ts.map +++ b/test/samples/ts-types/expected.ts.map @@ -5,7 +5,7 @@ "input.js" ], "sourcesContent": [ - "type A = [x: number, y: string];\ntype B = { a: string; b: number };\n\ntype C = 'foo' | 'bar';\ntype D = C | A | B | 'foobar';\n\ntype E = A & B;\ntype F = C & 'foobar';\n\ntype Bird = { legs: 2 };\ntype Dog = { legs: 4 };\ntype Wolf = { legs: 4 };\ntype Animals = Bird | Dog | Wolf;\ntype HasFourLegs = Animal extends { legs: 4 } ? Animal : never;\ntype FourLegs = HasFourLegs;\n" + "type A = [x: number, y: string];\ntype B = { a: string; b: number };\n\ntype C = 'foo' | 'bar';\ntype D = C | A | B | 'foobar';\n\ntype E = A & B;\ntype F = C & 'foobar';\n\n// TODO: commented because acorn doesn't support intrinsic but oxc does\n// type G = { [a in C]: string };\n\ntype H = this;\ntype I = `Hello, ${keyof C}`;\ntype J = () => this is string;\n\ntype Bird = { legs: 2 };\ntype Dog = { legs: 4 };\ntype Wolf = { legs: 4 };\ntype Animals = Bird | Dog | Wolf;\ntype HasFourLegs = Animal extends { legs: 4 } ? Animal : never;\ntype FourLegs = HasFourLegs;\n\ntype T = [('a' | 'b')?];\n\ntype CT = new (tpl: TemplateStringsArray, ...args: Array) => (replacements: B) => A;\n\ntype X = [...number[]];\ntype TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])];\n\n// TODO: commented because acorn doesn't support intrinsic but oxc does\n// type Uppercase = intrinsic;\n" ], - "mappings": "KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;KACzB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;KAE1B,CAAC,GAAG,KAAK,GAAG,KAAK;KACjB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ;KAExB,CAAC,GAAG,CAAC,GAAG,CAAC;KACT,CAAC,GAAG,CAAC,GAAG,QAAQ;KAEhB,IAAI,KAAK,IAAI,EAAE,CAAC;KAChB,GAAG,KAAK,IAAI,EAAE,CAAC;KACf,IAAI,KAAK,IAAI,EAAE,CAAC;KAChB,OAAO,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI;KAC3B,WAAW,CAAC,MAAM,IAAI,MAAM,WAAW,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK;KACjE,QAAQ,GAAG,WAAW,CAAC,OAAO" + "mappings": "KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;KACzB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;KAE1B,CAAC,GAAG,KAAK,GAAG,KAAK;KACjB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ;KAExB,CAAC,GAAG,CAAC,GAAG,CAAC;KACT,CAAC,GAAG,CAAC,GAAG,QAAQ;;;;KAKhB,CAAC,GAAG,IAAI;;KACR,CAAC,mBAAmB,CAAC;KACrB,CAAC,SAAS,IAAI,IAAI,MAAM;KAExB,IAAI,KAAK,IAAI,EAAE,CAAC;KAChB,GAAG,KAAK,IAAI,EAAE,CAAC;KACf,IAAI,KAAK,IAAI,EAAE,CAAC;KAChB,OAAO,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI;KAC3B,WAAW,CAAC,MAAM,IAAI,MAAM,WAAW,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK;KACjE,QAAQ,GAAG,WAAW,CAAC,OAAO;KAE9B,CAAC,KAAK,GAAG,GAAG,GAAG;KAEf,EAAE,QAAQ,GAAyB,EAApB,oBAAoB,KAAK,IAAI,EAAE,KAAK,CAAC,OAAO,OAAO,YAAe,EAAD,CAAC,KAAK,CAAC;KAEvF,CAAC,OAAO,MAAM;KACd,aAAa,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,KAAK,MAAM;;;" } \ No newline at end of file diff --git a/test/samples/ts-types/input.ts b/test/samples/ts-types/input.ts index d5a990b..51ac958 100644 --- a/test/samples/ts-types/input.ts +++ b/test/samples/ts-types/input.ts @@ -7,9 +7,26 @@ type D = C | A | B | 'foobar'; type E = A & B; type F = C & 'foobar'; +// TODO: commented because acorn doesn't support intrinsic but oxc does +// type G = { [a in C]: string }; + +type H = this; +type I = `Hello, ${keyof C}`; +type J = () => this is string; + type Bird = { legs: 2 }; type Dog = { legs: 4 }; type Wolf = { legs: 4 }; type Animals = Bird | Dog | Wolf; type HasFourLegs = Animal extends { legs: 4 } ? Animal : never; type FourLegs = HasFourLegs; + +type T = [('a' | 'b')?]; + +type CT = new (tpl: TemplateStringsArray, ...args: Array) => (replacements: B) => A; + +type X = [...number[]]; +type TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])]; + +// TODO: commented because acorn doesn't support intrinsic but oxc does +// type Uppercase = intrinsic; diff --git a/test/samples/ts-undefined-keyword/expected.ts b/test/samples/ts-undefined-keyword/expected.ts deleted file mode 100644 index 77bbb54..0000000 --- a/test/samples/ts-undefined-keyword/expected.ts +++ /dev/null @@ -1,3 +0,0 @@ -let a: number | undefined; - -a = 2; \ No newline at end of file diff --git a/test/samples/ts-undefined-keyword/expected.ts.map b/test/samples/ts-undefined-keyword/expected.ts.map deleted file mode 100644 index f133c38..0000000 --- a/test/samples/ts-undefined-keyword/expected.ts.map +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 3, - "names": [], - "sources": [ - "input.js" - ], - "sourcesContent": [ - "let a: number | undefined\na = 2" - ], - "mappings": "IAAI,CAAqB,EAAlB,MAAM,GAAG,SAAS;;AACzB,CAAC,GAAG,CAAC" -} \ No newline at end of file diff --git a/test/samples/ts-undefined-keyword/input.ts b/test/samples/ts-undefined-keyword/input.ts deleted file mode 100644 index 2756c56..0000000 --- a/test/samples/ts-undefined-keyword/input.ts +++ /dev/null @@ -1,2 +0,0 @@ -let a: number | undefined -a = 2 \ No newline at end of file