diff --git a/napi/parser/wrap.mjs b/napi/parser/wrap.mjs index 667fa5e74671a..49c42c7b954ef 100644 --- a/napi/parser/wrap.mjs +++ b/napi/parser/wrap.mjs @@ -3,26 +3,7 @@ export function wrap(result) { return { get program() { if (!program) { - // Note: This code is repeated in `wasm/parser/update-bindings.mjs` and `crates/oxc-wasm/update-bindings.mjs`. - // Any changes should be applied in those 2 scripts too. - program = JSON.parse(result.program, function(key, value) { - // Set `value` field of `Literal`s for `BigInt`s and `RegExp`s. - // This is not possible to do on Rust side, as neither can be represented correctly in JSON. - if (value === null && key === 'value' && Object.hasOwn(this, 'type') && this.type === 'Literal') { - if (Object.hasOwn(this, 'bigint')) { - return BigInt(this.bigint); - } - if (Object.hasOwn(this, 'regex')) { - const { regex } = this; - try { - return RegExp(regex.pattern, regex.flags); - } catch (_err) { - // Invalid regexp, or valid regexp using syntax not supported by this version of NodeJS - } - } - } - return value; - }); + program = jsonParseAst(result.program); } return program; }, @@ -40,3 +21,25 @@ export function wrap(result) { }, }; } + +// Used by napi/playground/patch.mjs +export function jsonParseAst(ast) { + return JSON.parse(ast, function(key, value) { + // Set `value` field of `Literal`s for `BigInt`s and `RegExp`s. + // This is not possible to do on Rust side, as neither can be represented correctly in JSON. + if (value === null && key === 'value' && Object.hasOwn(this, 'type') && this.type === 'Literal') { + if (Object.hasOwn(this, 'bigint')) { + return BigInt(this.bigint); + } + if (Object.hasOwn(this, 'regex')) { + const { regex } = this; + try { + return RegExp(regex.pattern, regex.flags); + } catch (_err) { + // Invalid regexp, or valid regexp using syntax not supported by this version of NodeJS + } + } + } + return value; + }); +} diff --git a/napi/playground/index.d.ts b/napi/playground/index.d.ts index ec9fee3d118ff..721ff20de4a67 100644 --- a/napi/playground/index.d.ts +++ b/napi/playground/index.d.ts @@ -1,6 +1,7 @@ /* auto-generated by NAPI-RS */ /* eslint-disable */ export declare class Oxc { + ast: object astJson: string ir: string controlFlowGraph: string diff --git a/napi/playground/patch.mjs b/napi/playground/patch.mjs index 150dd6b49cfc4..5212f5018a6fd 100644 --- a/napi/playground/patch.mjs +++ b/napi/playground/patch.mjs @@ -7,5 +7,25 @@ let data = fs.readFileSync(filename, 'utf-8'); data = data.replace( '__emnapiInstantiateNapiModuleSync(__wasmFile', 'await (await import("@napi-rs/wasm-runtime")).instantiateNapiModule(__wasmFile', +).replace( + `export const Oxc = __napiModule.exports.Oxc`, + ` +import { jsonParseAst } from "../parser/wrap.mjs" + +export function Oxc() { + const oxc = new __napiModule.exports.Oxc(); + return new Proxy(oxc, { + get(_target, p, _receiver) { + if (p === 'ast') { + return jsonParseAst(oxc.astJson); + } + if (typeof oxc[p] === 'function') { + return oxc[p].bind(oxc); + } + return Reflect.get(...arguments); + } + }) +} +`, ); fs.writeFileSync(filename, data); diff --git a/napi/playground/playground.wasi-browser.js b/napi/playground/playground.wasi-browser.js index 124366bb78813..dd19e657f3232 100644 --- a/napi/playground/playground.wasi-browser.js +++ b/napi/playground/playground.wasi-browser.js @@ -53,5 +53,22 @@ const { } }, }) -export const Oxc = __napiModule.exports.Oxc + +import { jsonParseAst } from "../parser/wrap.mjs" + +export function Oxc() { + const oxc = new __napiModule.exports.Oxc(); + return new Proxy(oxc, { + get(_target, p, _receiver) { + if (p === 'ast') { + return jsonParseAst(oxc.astJson); + } + if (typeof oxc[p] === 'function') { + return oxc[p].bind(oxc); + } + return Reflect.get(...arguments); + } + }) +} + export const Severity = __napiModule.exports.Severity diff --git a/napi/playground/src/lib.rs b/napi/playground/src/lib.rs index 2014fd8b63fcf..fa74543a0bce9 100644 --- a/napi/playground/src/lib.rs +++ b/napi/playground/src/lib.rs @@ -37,6 +37,8 @@ mod options; #[derive(Default)] #[napi] pub struct Oxc { + #[napi(ts_type = "object")] + pub ast: (), pub ast_json: String, pub ir: String, pub control_flow_graph: String,