From 67a7bde4c659975b0d83a4c4dabb411d089f32a1 Mon Sep 17 00:00:00 2001 From: ottomated <31470743+ottomated@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:08:58 +0000 Subject: [PATCH] feat(napi/parser)!: add typings to napi/parser (#6796) - Added TypeScript annotation for `ParseResult.program` - Modified the entrypoint for `oxc-parser` to allow wrapping the napi functions - Updated `index.js` to parse the `program` string into a JSON object - Updated tests - Added a dependency on `@oxc/types` --- crates/oxc/src/napi/parse.rs | 1 + dprint.json | 3 +- napi/parser/bindings.js | 368 ++++++++++++++++++ napi/parser/index.d.ts | 2 +- napi/parser/index.js | 384 +------------------ napi/parser/package.json | 2 +- napi/parser/test/module_lexer.test.mjs | 4 +- napi/parser/test/parse.test.mjs | 8 +- npm/oxc-parser/.gitignore | 4 + npm/oxc-parser/package.json | 8 +- npm/oxc-parser/scripts/generate-packages.mjs | 2 +- npm/oxc-types/src/generated/types.d.ts | 176 ++++----- pnpm-lock.yaml | 6 +- tasks/ast_tools/src/generators/typescript.rs | 33 +- 14 files changed, 506 insertions(+), 495 deletions(-) create mode 100644 napi/parser/bindings.js create mode 100644 npm/oxc-parser/.gitignore diff --git a/crates/oxc/src/napi/parse.rs b/crates/oxc/src/napi/parse.rs index 9f2c94dd685ad..9a3fc3044736c 100644 --- a/crates/oxc/src/napi/parse.rs +++ b/crates/oxc/src/napi/parse.rs @@ -21,6 +21,7 @@ pub struct ParserOptions { #[napi(object)] pub struct ParseResult { + #[napi(ts_type = "import(\"@oxc/types\").Program")] pub program: String, pub comments: Vec, pub errors: Vec, diff --git a/dprint.json b/dprint.json index 35f975c189cc5..7efebc9ea9f3a 100644 --- a/dprint.json +++ b/dprint.json @@ -17,7 +17,8 @@ "**/CHANGELOG.md", "pnpm-workspace.yaml", "pnpm-lock.yaml", - "napi/{parser,transform}/index.js", + "napi/transform/index.js", + "napi/parser/bindings.js", "napi/{parser,transform}/index.d.ts", "npm/*/package.json", "npm/oxlint/configuration_schema.json", diff --git a/napi/parser/bindings.js b/napi/parser/bindings.js new file mode 100644 index 0000000000000..2b09b39f8c35a --- /dev/null +++ b/napi/parser/bindings.js @@ -0,0 +1,368 @@ +// prettier-ignore +/* eslint-disable */ +/* auto-generated by NAPI-RS */ + +const { readFileSync } = require('fs') + +let nativeBinding = null +const loadErrors = [] + +const isMusl = () => { + let musl = false + if (process.platform === 'linux') { + musl = isMuslFromFilesystem() + if (musl === null) { + musl = isMuslFromReport() + } + if (musl === null) { + musl = isMuslFromChildProcess() + } + } + return musl +} + +const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') + +const isMuslFromFilesystem = () => { + try { + return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') + } catch { + return null + } +} + +const isMuslFromReport = () => { + const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null + if (!report) { + return null + } + if (report.header && report.header.glibcVersionRuntime) { + return false + } + if (Array.isArray(report.sharedObjects)) { + if (report.sharedObjects.some(isFileMusl)) { + return true + } + } + return false +} + +const isMuslFromChildProcess = () => { + try { + return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') + } catch (e) { + // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false + return false + } +} + +function requireNative() { + if (process.platform === 'android') { + if (process.arch === 'arm64') { + try { + return require('./parser.android-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-android-arm64') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm') { + try { + return require('./parser.android-arm-eabi.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-android-arm-eabi') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) + } + } else if (process.platform === 'win32') { + if (process.arch === 'x64') { + try { + return require('./parser.win32-x64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-win32-x64-msvc') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'ia32') { + try { + return require('./parser.win32-ia32-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-win32-ia32-msvc') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm64') { + try { + return require('./parser.win32-arm64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-win32-arm64-msvc') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) + } + } else if (process.platform === 'darwin') { + try { + return require('./parser.darwin-universal.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-darwin-universal') + } catch (e) { + loadErrors.push(e) + } + + if (process.arch === 'x64') { + try { + return require('./parser.darwin-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-darwin-x64') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm64') { + try { + return require('./parser.darwin-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-darwin-arm64') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) + } + } else if (process.platform === 'freebsd') { + if (process.arch === 'x64') { + try { + return require('./parser.freebsd-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-freebsd-x64') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm64') { + try { + return require('./parser.freebsd-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-freebsd-arm64') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) + } + } else if (process.platform === 'linux') { + if (process.arch === 'x64') { + if (isMusl()) { + try { + return require('./parser.linux-x64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-x64-musl') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./parser.linux-x64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-x64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'arm64') { + if (isMusl()) { + try { + return require('./parser.linux-arm64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-arm64-musl') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./parser.linux-arm64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-arm64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'arm') { + if (isMusl()) { + try { + return require('./parser.linux-arm-musleabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-arm-musleabihf') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./parser.linux-arm-gnueabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-arm-gnueabihf') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'riscv64') { + if (isMusl()) { + try { + return require('./parser.linux-riscv64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-riscv64-musl') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./parser.linux-riscv64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-riscv64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'ppc64') { + try { + return require('./parser.linux-ppc64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-ppc64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 's390x') { + try { + return require('./parser.linux-s390x-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@oxc-parser/binding-linux-s390x-gnu') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) + } + } else { + loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) + } +} + +nativeBinding = requireNative() + +if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + try { + nativeBinding = require('./parser.wasi.cjs') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + console.error(err) + } + } + if (!nativeBinding) { + try { + nativeBinding = require('@oxc-parser/binding-wasm32-wasi') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + console.error(err) + } + } + } +} + +if (!nativeBinding) { + if (loadErrors.length > 0) { + // TODO Link to documentation with potential fixes + // - The package owner could build/publish bindings for this arch + // - The user may need to bundle the correct files + // - The user may need to re-install node_modules to get new packages + throw new Error('Failed to load native binding', { cause: loadErrors }) + } + throw new Error(`Failed to load native binding`) +} + +module.exports.moduleLexerAsync = nativeBinding.moduleLexerAsync +module.exports.moduleLexerSync = nativeBinding.moduleLexerSync +module.exports.parseAsync = nativeBinding.parseAsync +module.exports.parseSync = nativeBinding.parseSync +module.exports.parseWithoutReturn = nativeBinding.parseWithoutReturn diff --git a/napi/parser/index.d.ts b/napi/parser/index.d.ts index 33edf981a7540..790372d240cf3 100644 --- a/napi/parser/index.d.ts +++ b/napi/parser/index.d.ts @@ -91,7 +91,7 @@ export declare function moduleLexerSync(sourceText: string, options?: ParserOpti export declare function parseAsync(sourceText: string, options?: ParserOptions | undefined | null): Promise export interface ParseResult { - program: string + program: import("@oxc/types").Program comments: Array errors: Array } diff --git a/napi/parser/index.js b/napi/parser/index.js index 2b09b39f8c35a..fcedfd9cf3a0f 100644 --- a/napi/parser/index.js +++ b/napi/parser/index.js @@ -1,368 +1,16 @@ -// prettier-ignore -/* eslint-disable */ -/* auto-generated by NAPI-RS */ - -const { readFileSync } = require('fs') - -let nativeBinding = null -const loadErrors = [] - -const isMusl = () => { - let musl = false - if (process.platform === 'linux') { - musl = isMuslFromFilesystem() - if (musl === null) { - musl = isMuslFromReport() - } - if (musl === null) { - musl = isMuslFromChildProcess() - } - } - return musl -} - -const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') - -const isMuslFromFilesystem = () => { - try { - return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') - } catch { - return null - } -} - -const isMuslFromReport = () => { - const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null - if (!report) { - return null - } - if (report.header && report.header.glibcVersionRuntime) { - return false - } - if (Array.isArray(report.sharedObjects)) { - if (report.sharedObjects.some(isFileMusl)) { - return true - } - } - return false -} - -const isMuslFromChildProcess = () => { - try { - return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') - } catch (e) { - // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false - return false - } -} - -function requireNative() { - if (process.platform === 'android') { - if (process.arch === 'arm64') { - try { - return require('./parser.android-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-android-arm64') - } catch (e) { - loadErrors.push(e) - } - - } else if (process.arch === 'arm') { - try { - return require('./parser.android-arm-eabi.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-android-arm-eabi') - } catch (e) { - loadErrors.push(e) - } - - } else { - loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) - } - } else if (process.platform === 'win32') { - if (process.arch === 'x64') { - try { - return require('./parser.win32-x64-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-win32-x64-msvc') - } catch (e) { - loadErrors.push(e) - } - - } else if (process.arch === 'ia32') { - try { - return require('./parser.win32-ia32-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-win32-ia32-msvc') - } catch (e) { - loadErrors.push(e) - } - - } else if (process.arch === 'arm64') { - try { - return require('./parser.win32-arm64-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-win32-arm64-msvc') - } catch (e) { - loadErrors.push(e) - } - - } else { - loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) - } - } else if (process.platform === 'darwin') { - try { - return require('./parser.darwin-universal.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-darwin-universal') - } catch (e) { - loadErrors.push(e) - } - - if (process.arch === 'x64') { - try { - return require('./parser.darwin-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-darwin-x64') - } catch (e) { - loadErrors.push(e) - } - - } else if (process.arch === 'arm64') { - try { - return require('./parser.darwin-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-darwin-arm64') - } catch (e) { - loadErrors.push(e) - } - - } else { - loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) - } - } else if (process.platform === 'freebsd') { - if (process.arch === 'x64') { - try { - return require('./parser.freebsd-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-freebsd-x64') - } catch (e) { - loadErrors.push(e) - } - - } else if (process.arch === 'arm64') { - try { - return require('./parser.freebsd-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-freebsd-arm64') - } catch (e) { - loadErrors.push(e) - } - - } else { - loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) - } - } else if (process.platform === 'linux') { - if (process.arch === 'x64') { - if (isMusl()) { - try { - return require('./parser.linux-x64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-x64-musl') - } catch (e) { - loadErrors.push(e) - } - - } else { - try { - return require('./parser.linux-x64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-x64-gnu') - } catch (e) { - loadErrors.push(e) - } - - } - } else if (process.arch === 'arm64') { - if (isMusl()) { - try { - return require('./parser.linux-arm64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-arm64-musl') - } catch (e) { - loadErrors.push(e) - } - - } else { - try { - return require('./parser.linux-arm64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-arm64-gnu') - } catch (e) { - loadErrors.push(e) - } - - } - } else if (process.arch === 'arm') { - if (isMusl()) { - try { - return require('./parser.linux-arm-musleabihf.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-arm-musleabihf') - } catch (e) { - loadErrors.push(e) - } - - } else { - try { - return require('./parser.linux-arm-gnueabihf.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-arm-gnueabihf') - } catch (e) { - loadErrors.push(e) - } - - } - } else if (process.arch === 'riscv64') { - if (isMusl()) { - try { - return require('./parser.linux-riscv64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-riscv64-musl') - } catch (e) { - loadErrors.push(e) - } - - } else { - try { - return require('./parser.linux-riscv64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-riscv64-gnu') - } catch (e) { - loadErrors.push(e) - } - - } - } else if (process.arch === 'ppc64') { - try { - return require('./parser.linux-ppc64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-ppc64-gnu') - } catch (e) { - loadErrors.push(e) - } - - } else if (process.arch === 's390x') { - try { - return require('./parser.linux-s390x-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@oxc-parser/binding-linux-s390x-gnu') - } catch (e) { - loadErrors.push(e) - } - - } else { - loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) - } - } else { - loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) - } -} - -nativeBinding = requireNative() - -if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { - try { - nativeBinding = require('./parser.wasi.cjs') - } catch (err) { - if (process.env.NAPI_RS_FORCE_WASI) { - console.error(err) - } - } - if (!nativeBinding) { - try { - nativeBinding = require('@oxc-parser/binding-wasm32-wasi') - } catch (err) { - if (process.env.NAPI_RS_FORCE_WASI) { - console.error(err) - } - } - } -} - -if (!nativeBinding) { - if (loadErrors.length > 0) { - // TODO Link to documentation with potential fixes - // - The package owner could build/publish bindings for this arch - // - The user may need to bundle the correct files - // - The user may need to re-install node_modules to get new packages - throw new Error('Failed to load native binding', { cause: loadErrors }) - } - throw new Error(`Failed to load native binding`) -} - -module.exports.moduleLexerAsync = nativeBinding.moduleLexerAsync -module.exports.moduleLexerSync = nativeBinding.moduleLexerSync -module.exports.parseAsync = nativeBinding.parseAsync -module.exports.parseSync = nativeBinding.parseSync -module.exports.parseWithoutReturn = nativeBinding.parseWithoutReturn +const bindings = require('./bindings.js'); + +module.exports.moduleLexerAsync = bindings.moduleLexerAsync; +module.exports.moduleLexerSync = bindings.moduleLexerSync; +module.exports.parseWithoutReturn = bindings.parseWithoutReturn; + +module.exports.parseAsync = async function parseAsync(...args) { + const result = await bindings.parseAsync(...args); + result.program = JSON.parse(result.program); + return result; +}; +module.exports.parseSync = function parseSync(...args) { + const result = bindings.parseSync(...args); + result.program = JSON.parse(result.program); + return result; +}; diff --git a/napi/parser/package.json b/napi/parser/package.json index 92d95ac076860..c91599d4dece7 100644 --- a/napi/parser/package.json +++ b/napi/parser/package.json @@ -3,7 +3,7 @@ "packageManager": "pnpm@9.9.0", "private": true, "scripts": { - "build": "napi build --platform --release", + "build": "napi build --platform --release --js bindings.js", "test": "vitest run ./test" }, "engines": { diff --git a/napi/parser/test/module_lexer.test.mjs b/napi/parser/test/module_lexer.test.mjs index c6fddd9690df6..d5ecea021d3f2 100644 --- a/napi/parser/test/module_lexer.test.mjs +++ b/napi/parser/test/module_lexer.test.mjs @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; -import oxc from './index.js'; +import * as oxc from '../index.js'; describe('module lexer', () => { const code = 'export { foo }'; @@ -10,7 +10,7 @@ describe('module lexer', () => { assert(ret.exports.length == 1); }); - it('matches output async ', async () => { + it('matches output async', async () => { const ret = await oxc.moduleLexerAsync(code); assert(ret.exports.length == 1); }); diff --git a/napi/parser/test/parse.test.mjs b/napi/parser/test/parse.test.mjs index d4d1ea90494c8..9d49df1aae13c 100644 --- a/napi/parser/test/parse.test.mjs +++ b/napi/parser/test/parse.test.mjs @@ -1,20 +1,20 @@ import { assert, describe, it } from 'vitest'; -import oxc from './index.js'; +import * as oxc from '../index.js'; describe('parse', () => { const code = '/* comment */ foo'; it('matches output', () => { const ret = oxc.parseSync(code); - assert(JSON.parse(ret.program).body.length == 1); + assert(ret.program.body.length == 1); assert(ret.errors.length == 0); assert(ret.comments.length == 1); }); - it('matches output async ', async () => { + it('matches output async', async () => { const ret = await oxc.parseAsync(code); - assert(JSON.parse(ret.program).body.length == 1); + assert(ret.program.body.length == 1); assert(ret.errors.length == 0); assert(ret.comments.length == 1); }); diff --git a/npm/oxc-parser/.gitignore b/npm/oxc-parser/.gitignore new file mode 100644 index 0000000000000..0bdbd0492f016 --- /dev/null +++ b/npm/oxc-parser/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +index.js +bindings.js +index.d.ts \ No newline at end of file diff --git a/npm/oxc-parser/package.json b/npm/oxc-parser/package.json index 8dcb1cf82bb3b..0de44788cf50b 100644 --- a/npm/oxc-parser/package.json +++ b/npm/oxc-parser/package.json @@ -20,6 +20,10 @@ "main": "index.js", "files": [ "index.d.ts", - "index.js" - ] + "index.js", + "bindings.js" + ], + "devDependencies": { + "@oxc/types": "workspace:^" + } } \ No newline at end of file diff --git a/npm/oxc-parser/scripts/generate-packages.mjs b/npm/oxc-parser/scripts/generate-packages.mjs index 8ed558a1e96d1..624450780c309 100644 --- a/npm/oxc-parser/scripts/generate-packages.mjs +++ b/npm/oxc-parser/scripts/generate-packages.mjs @@ -95,7 +95,7 @@ function writeManifest() { const content = JSON.stringify(manifestData, null, 2); fs.writeFileSync(manifestPath, content); - let files = ['index.js', 'index.d.ts']; + let files = ['bindings.js', 'index.js', 'index.d.ts']; for (const file of files) { fs.copyFileSync(resolve(BINARY_ROOT, file), resolve(packageRoot, file)); } diff --git a/npm/oxc-types/src/generated/types.d.ts b/npm/oxc-types/src/generated/types.d.ts index 22292288e059c..f6593320727da 100644 --- a/npm/oxc-types/src/generated/types.d.ts +++ b/npm/oxc-types/src/generated/types.d.ts @@ -1,5 +1,5 @@ -// To edit this generated file you have to edit `tasks/ast_tools/src/generators/typescript.rs` // Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/generators/typescript.rs` export interface FormalParameterRest extends Span { type: 'RestElement'; @@ -78,7 +78,7 @@ export interface StringLiteral extends Span { export interface Program extends Span { type: 'Program'; sourceType: SourceType; - hashbang: (Hashbang) | null; + hashbang: Hashbang | null; directives: Array; body: Array; } @@ -168,7 +168,7 @@ export interface ObjectProperty extends Span { kind: PropertyKind; key: PropertyKey; value: Expression; - init: (Expression) | null; + init: Expression | null; method: boolean; shorthand: boolean; computed: boolean; @@ -232,7 +232,7 @@ export interface TaggedTemplateExpression extends Span { type: 'TaggedTemplateExpression'; tag: Expression; quasi: TemplateLiteral; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export interface TemplateElement extends Span { @@ -243,7 +243,7 @@ export interface TemplateElement extends Span { export interface TemplateElementValue { raw: string; - cooked: (string) | null; + cooked: string | null; } export type MemberExpression = ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression; @@ -272,7 +272,7 @@ export interface PrivateFieldExpression extends Span { export interface CallExpression extends Span { type: 'CallExpression'; callee: Expression; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; arguments: Array; optional: boolean; } @@ -281,7 +281,7 @@ export interface NewExpression extends Span { type: 'NewExpression'; callee: Expression; arguments: Array; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export interface MetaProperty extends Span { @@ -454,7 +454,7 @@ export type AssignmentTargetProperty = AssignmentTargetPropertyIdentifier | Assi export interface AssignmentTargetPropertyIdentifier extends Span { type: 'AssignmentTargetPropertyIdentifier'; binding: IdentifierReference; - init: (Expression) | null; + init: Expression | null; } export interface AssignmentTargetPropertyProperty extends Span { @@ -561,7 +561,7 @@ export type VariableDeclarationKind = 'var' | 'const' | 'let' | 'using' | 'await export interface VariableDeclarator extends Span { type: 'VariableDeclarator'; id: BindingPattern; - init: (Expression) | null; + init: Expression | null; definite: boolean; } @@ -578,7 +578,7 @@ export interface IfStatement extends Span { type: 'IfStatement'; test: Expression; consequent: Statement; - alternate: (Statement) | null; + alternate: Statement | null; } export interface DoWhileStatement extends Span { @@ -595,9 +595,9 @@ export interface WhileStatement extends Span { export interface ForStatement extends Span { type: 'ForStatement'; - init: (ForStatementInit) | null; - test: (Expression) | null; - update: (Expression) | null; + init: ForStatementInit | null; + test: Expression | null; + update: Expression | null; body: Statement; } @@ -677,17 +677,17 @@ export interface ForOfStatement extends Span { export interface ContinueStatement extends Span { type: 'ContinueStatement'; - label: (LabelIdentifier) | null; + label: LabelIdentifier | null; } export interface BreakStatement extends Span { type: 'BreakStatement'; - label: (LabelIdentifier) | null; + label: LabelIdentifier | null; } export interface ReturnStatement extends Span { type: 'ReturnStatement'; - argument: (Expression) | null; + argument: Expression | null; } export interface WithStatement extends Span { @@ -704,7 +704,7 @@ export interface SwitchStatement extends Span { export interface SwitchCase extends Span { type: 'SwitchCase'; - test: (Expression) | null; + test: Expression | null; consequent: Array; } @@ -722,13 +722,13 @@ export interface ThrowStatement extends Span { export interface TryStatement extends Span { type: 'TryStatement'; block: BlockStatement; - handler: (CatchClause) | null; - finalizer: (BlockStatement) | null; + handler: CatchClause | null; + finalizer: BlockStatement | null; } export interface CatchClause extends Span { type: 'CatchClause'; - param: (CatchParameter) | null; + param: CatchParameter | null; body: BlockStatement; } @@ -743,7 +743,7 @@ export interface DebuggerStatement extends Span { export type BindingPattern = & ({ - typeAnnotation: (TSTypeAnnotation) | null; + typeAnnotation: TSTypeAnnotation | null; optional: boolean; }) & (BindingIdentifier | ObjectPattern | ArrayPattern | AssignmentPattern); @@ -781,15 +781,15 @@ export interface BindingRestElement extends Span { export interface Function extends Span { type: FunctionType; - id: (BindingIdentifier) | null; + id: BindingIdentifier | null; generator: boolean; async: boolean; declare: boolean; - typeParameters: (TSTypeParameterDeclaration) | null; - thisParam: (TSThisParameter) | null; + typeParameters: TSTypeParameterDeclaration | null; + thisParam: TSThisParameter | null; params: FormalParameters; - returnType: (TSTypeAnnotation) | null; - body: (FunctionBody) | null; + returnType: TSTypeAnnotation | null; + body: FunctionBody | null; } export type FunctionType = @@ -808,7 +808,7 @@ export interface FormalParameter extends Span { type: 'FormalParameter'; decorators: Array; pattern: BindingPattern; - accessibility: (TSAccessibility) | null; + accessibility: TSAccessibility | null; readonly: boolean; override: boolean; } @@ -825,26 +825,26 @@ export interface ArrowFunctionExpression extends Span { type: 'ArrowFunctionExpression'; expression: boolean; async: boolean; - typeParameters: (TSTypeParameterDeclaration) | null; + typeParameters: TSTypeParameterDeclaration | null; params: FormalParameters; - returnType: (TSTypeAnnotation) | null; + returnType: TSTypeAnnotation | null; body: FunctionBody; } export interface YieldExpression extends Span { type: 'YieldExpression'; delegate: boolean; - argument: (Expression) | null; + argument: Expression | null; } export interface Class extends Span { type: ClassType; decorators: Array; - id: (BindingIdentifier) | null; - typeParameters: (TSTypeParameterDeclaration) | null; - superClass: (Expression) | null; - superTypeParameters: (TSTypeParameterInstantiation) | null; - implements: (Array) | null; + id: BindingIdentifier | null; + typeParameters: TSTypeParameterDeclaration | null; + superClass: Expression | null; + superTypeParameters: TSTypeParameterInstantiation | null; + implements: Array | null; body: ClassBody; abstract: boolean; declare: boolean; @@ -869,7 +869,7 @@ export interface MethodDefinition extends Span { static: boolean; override: boolean; optional: boolean; - accessibility: (TSAccessibility) | null; + accessibility: TSAccessibility | null; } export type MethodDefinitionType = 'MethodDefinition' | 'TSAbstractMethodDefinition'; @@ -878,7 +878,7 @@ export interface PropertyDefinition extends Span { type: PropertyDefinitionType; decorators: Array; key: PropertyKey; - value: (Expression) | null; + value: Expression | null; computed: boolean; static: boolean; declare: boolean; @@ -886,8 +886,8 @@ export interface PropertyDefinition extends Span { optional: boolean; definite: boolean; readonly: boolean; - typeAnnotation: (TSTypeAnnotation) | null; - accessibility: (TSAccessibility) | null; + typeAnnotation: TSTypeAnnotation | null; + accessibility: TSAccessibility | null; } export type PropertyDefinitionType = 'PropertyDefinition' | 'TSAbstractPropertyDefinition'; @@ -918,12 +918,12 @@ export interface AccessorProperty extends Span { type: AccessorPropertyType; decorators: Array; key: PropertyKey; - value: (Expression) | null; + value: Expression | null; computed: boolean; static: boolean; definite: boolean; - typeAnnotation: (TSTypeAnnotation) | null; - accessibility: (TSAccessibility) | null; + typeAnnotation: TSTypeAnnotation | null; + accessibility: TSAccessibility | null; } export interface ImportExpression extends Span { @@ -934,9 +934,9 @@ export interface ImportExpression extends Span { export interface ImportDeclaration extends Span { type: 'ImportDeclaration'; - specifiers: (Array) | null; + specifiers: Array | null; source: StringLiteral; - withClause: (WithClause) | null; + withClause: WithClause | null; importKind: ImportOrExportKind; } @@ -975,11 +975,11 @@ export type ImportAttributeKey = IdentifierName | StringLiteral; export interface ExportNamedDeclaration extends Span { type: 'ExportNamedDeclaration'; - declaration: (Declaration) | null; + declaration: Declaration | null; specifiers: Array; - source: (StringLiteral) | null; + source: StringLiteral | null; exportKind: ImportOrExportKind; - withClause: (WithClause) | null; + withClause: WithClause | null; } export interface ExportDefaultDeclaration extends Span { @@ -990,9 +990,9 @@ export interface ExportDefaultDeclaration extends Span { export interface ExportAllDeclaration extends Span { type: 'ExportAllDeclaration'; - exported: (ModuleExportName) | null; + exported: ModuleExportName | null; source: StringLiteral; - withClause: (WithClause) | null; + withClause: WithClause | null; exportKind: ImportOrExportKind; } @@ -1055,7 +1055,7 @@ export type ModuleExportName = IdentifierName | IdentifierReference | StringLite export interface TSThisParameter extends Span { type: 'TSThisParameter'; thisSpan: Span; - typeAnnotation: (TSTypeAnnotation) | null; + typeAnnotation: TSTypeAnnotation | null; } export interface TSEnumDeclaration extends Span { @@ -1069,7 +1069,7 @@ export interface TSEnumDeclaration extends Span { export interface TSEnumMember extends Span { type: 'TSEnumMember'; id: TSEnumMemberName; - initializer: (Expression) | null; + initializer: Expression | null; } export type TSEnumMemberName = @@ -1345,7 +1345,7 @@ export interface TSBigIntKeyword extends Span { export interface TSTypeReference extends Span { type: 'TSTypeReference'; typeName: TSTypeName; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export type TSTypeName = IdentifierReference | TSQualifiedName; @@ -1364,8 +1364,8 @@ export interface TSTypeParameterInstantiation extends Span { export interface TSTypeParameter extends Span { type: 'TSTypeParameter'; name: BindingIdentifier; - constraint: (TSType) | null; - default: (TSType) | null; + constraint: TSType | null; + default: TSType | null; in: boolean; out: boolean; const: boolean; @@ -1379,7 +1379,7 @@ export interface TSTypeParameterDeclaration extends Span { export interface TSTypeAliasDeclaration extends Span { type: 'TSTypeAliasDeclaration'; id: BindingIdentifier; - typeParameters: (TSTypeParameterDeclaration) | null; + typeParameters: TSTypeParameterDeclaration | null; typeAnnotation: TSType; declare: boolean; } @@ -1389,14 +1389,14 @@ export type TSAccessibility = 'private' | 'protected' | 'public'; export interface TSClassImplements extends Span { type: 'TSClassImplements'; expression: TSTypeName; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export interface TSInterfaceDeclaration extends Span { type: 'TSInterfaceDeclaration'; id: BindingIdentifier; - extends: (Array) | null; - typeParameters: (TSTypeParameterDeclaration) | null; + extends: Array | null; + typeParameters: TSTypeParameterDeclaration | null; body: TSInterfaceBody; declare: boolean; } @@ -1412,7 +1412,7 @@ export interface TSPropertySignature extends Span { optional: boolean; readonly: boolean; key: PropertyKey; - typeAnnotation: (TSTypeAnnotation) | null; + typeAnnotation: TSTypeAnnotation | null; } export type TSSignature = @@ -1431,10 +1431,10 @@ export interface TSIndexSignature extends Span { export interface TSCallSignatureDeclaration extends Span { type: 'TSCallSignatureDeclaration'; - typeParameters: (TSTypeParameterDeclaration) | null; - thisParam: (TSThisParameter) | null; + typeParameters: TSTypeParameterDeclaration | null; + thisParam: TSThisParameter | null; params: FormalParameters; - returnType: (TSTypeAnnotation) | null; + returnType: TSTypeAnnotation | null; } export type TSMethodSignatureKind = 'method' | 'get' | 'set'; @@ -1445,17 +1445,17 @@ export interface TSMethodSignature extends Span { computed: boolean; optional: boolean; kind: TSMethodSignatureKind; - typeParameters: (TSTypeParameterDeclaration) | null; - thisParam: (TSThisParameter) | null; + typeParameters: TSTypeParameterDeclaration | null; + thisParam: TSThisParameter | null; params: FormalParameters; - returnType: (TSTypeAnnotation) | null; + returnType: TSTypeAnnotation | null; } export interface TSConstructSignatureDeclaration extends Span { type: 'TSConstructSignatureDeclaration'; - typeParameters: (TSTypeParameterDeclaration) | null; + typeParameters: TSTypeParameterDeclaration | null; params: FormalParameters; - returnType: (TSTypeAnnotation) | null; + returnType: TSTypeAnnotation | null; } export interface TSIndexSignatureName extends Span { @@ -1467,14 +1467,14 @@ export interface TSIndexSignatureName extends Span { export interface TSInterfaceHeritage extends Span { type: 'TSInterfaceHeritage'; expression: Expression; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export interface TSTypePredicate extends Span { type: 'TSTypePredicate'; parameterName: TSTypePredicateName; asserts: boolean; - typeAnnotation: (TSTypeAnnotation) | null; + typeAnnotation: TSTypeAnnotation | null; } export type TSTypePredicateName = IdentifierName | TSThisType; @@ -1482,7 +1482,7 @@ export type TSTypePredicateName = IdentifierName | TSThisType; export interface TSModuleDeclaration extends Span { type: 'TSModuleDeclaration'; id: TSModuleDeclarationName; - body: (TSModuleDeclarationBody) | null; + body: TSModuleDeclarationBody | null; kind: TSModuleDeclarationKind; declare: boolean; } @@ -1511,7 +1511,7 @@ export interface TSInferType extends Span { export interface TSTypeQuery extends Span { type: 'TSTypeQuery'; exprName: TSTypeQueryExprName; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export type TSTypeQueryExprName = TSImportType | IdentifierReference | TSQualifiedName; @@ -1520,9 +1520,9 @@ export interface TSImportType extends Span { type: 'TSImportType'; isTypeOf: boolean; parameter: TSType; - qualifier: (TSTypeName) | null; - attributes: (TSImportAttributes) | null; - typeParameters: (TSTypeParameterInstantiation) | null; + qualifier: TSTypeName | null; + attributes: TSImportAttributes | null; + typeParameters: TSTypeParameterInstantiation | null; } export interface TSImportAttributes extends Span { @@ -1541,8 +1541,8 @@ export type TSImportAttributeName = IdentifierName | StringLiteral; export interface TSFunctionType extends Span { type: 'TSFunctionType'; - typeParameters: (TSTypeParameterDeclaration) | null; - thisParam: (TSThisParameter) | null; + typeParameters: TSTypeParameterDeclaration | null; + thisParam: TSThisParameter | null; params: FormalParameters; returnType: TSTypeAnnotation; } @@ -1550,7 +1550,7 @@ export interface TSFunctionType extends Span { export interface TSConstructorType extends Span { type: 'TSConstructorType'; abstract: boolean; - typeParameters: (TSTypeParameterDeclaration) | null; + typeParameters: TSTypeParameterDeclaration | null; params: FormalParameters; returnType: TSTypeAnnotation; } @@ -1558,8 +1558,8 @@ export interface TSConstructorType extends Span { export interface TSMappedType extends Span { type: 'TSMappedType'; typeParameter: TSTypeParameter; - nameType: (TSType) | null; - typeAnnotation: (TSType) | null; + nameType: TSType | null; + typeAnnotation: TSType | null; optional: TSMappedTypeModifierOperator; readonly: TSMappedTypeModifierOperator; } @@ -1651,7 +1651,7 @@ export interface JSDocUnknownType extends Span { export interface JSXElement extends Span { type: 'JSXElement'; openingElement: JSXOpeningElement; - closingElement: (JSXClosingElement) | null; + closingElement: JSXClosingElement | null; children: Array; } @@ -1660,7 +1660,7 @@ export interface JSXOpeningElement extends Span { selfClosing: boolean; name: JSXElementName; attributes: Array; - typeParameters: (TSTypeParameterInstantiation) | null; + typeParameters: TSTypeParameterInstantiation | null; } export interface JSXClosingElement extends Span { @@ -1754,7 +1754,7 @@ export type JSXAttributeItem = JSXAttribute | JSXSpreadAttribute; export interface JSXAttribute extends Span { type: 'JSXAttribute'; name: JSXAttributeName; - value: (JSXAttributeValue) | null; + value: JSXAttributeValue | null; } export interface JSXSpreadAttribute extends Span { @@ -1896,7 +1896,7 @@ export type LookAroundAssertionKind = 'lookahead' | 'negativeLookahead' | 'lookb export interface Quantifier extends Span { type: 'Quantifier'; min: number; - max: (number) | null; + max: number | null; greedy: boolean; body: Term; } @@ -1931,7 +1931,7 @@ export interface UnicodePropertyEscape extends Span { negative: boolean; strings: boolean; name: string; - value: (string) | null; + value: string | null; } export interface Dot extends Span { @@ -1976,20 +1976,20 @@ export interface ClassString extends Span { export interface CapturingGroup extends Span { type: 'CapturingGroup'; - name: (string) | null; + name: string | null; body: Disjunction; } export interface IgnoreGroup extends Span { type: 'IgnoreGroup'; - modifiers: (Modifiers) | null; + modifiers: Modifiers | null; body: Disjunction; } export interface Modifiers extends Span { type: 'Modifiers'; - enabling: (Modifier) | null; - disabling: (Modifier) | null; + enabling: Modifier | null; + disabling: Modifier | null; } export interface Modifier { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f66939a4186f..ba34384b77550 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,7 +58,11 @@ importers: napi/transform: {} - npm/oxc-parser: {} + npm/oxc-parser: + devDependencies: + '@oxc/types': + specifier: workspace:^ + version: link:../oxc-types npm/oxc-transform: {} diff --git a/tasks/ast_tools/src/generators/typescript.rs b/tasks/ast_tools/src/generators/typescript.rs index 5814334cd9bcf..81aa68581342e 100644 --- a/tasks/ast_tools/src/generators/typescript.rs +++ b/tasks/ast_tools/src/generators/typescript.rs @@ -27,10 +27,10 @@ impl Generator for TypescriptGenerator { let file = file!().replace('\\', "/"); let mut content = format!( "\ - // To edit this generated file you have to edit `{file}`\n\ - // Auto-generated code, DO NOT EDIT DIRECTLY!\n\n\ - {CUSTOM_TYPESCRIPT}\n\ - " + // Auto-generated code, DO NOT EDIT DIRECTLY!\n\ + // To edit this generated file you have to edit `{file}`\n\n\ + {CUSTOM_TYPESCRIPT}\n\ + " ); for def in ctx.schema() { @@ -53,8 +53,8 @@ impl Generator for TypescriptGenerator { } } -// Untagged enums: "type Expression = BooleanLiteral | NullLiteral" -// Tagged enums: "type PropertyKind = 'init' | 'get' | 'set'" +// Untagged enums: `type Expression = BooleanLiteral | NullLiteral` +// Tagged enums: `type PropertyKind = 'init' | 'get' | 'set'` fn typescript_enum(def: &EnumDef) -> Option { if def.markers.estree.custom_ts_def { return None; @@ -130,7 +130,7 @@ fn type_to_string(ty: &TypeName) -> String { TypeName::Box(type_name) | TypeName::Ref(type_name) | TypeName::Complex(type_name) => { type_to_string(type_name) } - TypeName::Opt(type_name) => format!("({}) | null", type_to_string(type_name)), + TypeName::Opt(type_name) => format!("{} | null", type_to_string(type_name)), } } @@ -149,22 +149,3 @@ fn format_typescript(source_text: &str) -> String { let output = dprint.wait_with_output().unwrap(); String::from_utf8(output.stdout).unwrap() } - -// Unusable until oxc_prettier supports comments -// fn format_typescript(source_text: &str) -> String { -// let allocator = Allocator::default(); -// let source_type = SourceType::ts(); -// let ret = Parser::new(&allocator, source_text, source_type) -// .with_options(ParseOptions { preserve_parens: false, ..ParseOptions::default() }) -// .parse(); -// Prettier::new( -// &allocator, -// PrettierOptions { -// semi: true, -// trailing_comma: TrailingComma::All, -// single_quote: true, -// ..PrettierOptions::default() -// }, -// ) -// .build(&ret.program) -// }