/* * Codegen for `traverse`. * * Parses Rust AST type definitions from files in `crates/oxc_ast/src/ast`, and generates: * - `src/traverse.rs` * - `src/ancestor.rs` * - `src/walk.rs` * * This is a quick-and-dirty version written in JS for speed of implementation. * We should do this properly with a Rust build script using `syn` etc. */ import { exec } from 'child_process'; import { writeFile } from 'fs/promises'; import { join as pathJoin } from 'path'; import { fileURLToPath } from 'url'; import { promisify } from 'util'; import generateAncestorsCode from './lib/ancestor.mjs'; import getTypesFromCode from './lib/parse.mjs'; import generateScopesCollectorCode from './lib/scopes_collector.mjs'; import generateTraverseTraitCode from './lib/traverse.mjs'; import generateWalkFunctionsCode from './lib/walk.mjs'; const execAsync = promisify(exec); const PREAMBLE = '// Auto-generated code, DO NOT EDIT DIRECTLY!\n' + '// Generated by `oxc_traverse/scripts/build.mjs`.\n' + '// To alter this generated file you have to edit the codegen.\n\n'; const types = await getTypesFromCode(); const outputDirPath = pathJoin(fileURLToPath(import.meta.url), '../../src/generated'); await Promise.all([ writeToFile('traverse.rs', generateTraverseTraitCode(types)), writeToFile('ancestor.rs', generateAncestorsCode(types)), writeToFile('walk.rs', generateWalkFunctionsCode(types)), writeToFile('scopes_collector.rs', generateScopesCollectorCode(types)), ]); /** * @param {string} filename * @param {string} code */ async function writeToFile(filename, code) { code = `${PREAMBLE}${code}`; const path = pathJoin(outputDirPath, filename); console.log('Writing:', path); await writeFile(path, code); await execAsync(`rustfmt ${JSON.stringify(path)}`); }